blob: 580af297acc374172d5bf371138be9761a996ee6 [file] [log] [blame]
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Dima Zavin4daf48a2011-08-30 11:59:20 -070017#include <stdbool.h>
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080018#include <stdlib.h>
19#include <unistd.h>
20
Dees Troy62b75ab2014-05-02 13:20:33 +000021#include <errno.h>
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080022#include <fcntl.h>
23#include <stdio.h>
24
25#include <sys/ioctl.h>
26#include <sys/mman.h>
27#include <sys/types.h>
28
29#include <linux/fb.h>
30#include <linux/kd.h>
31
Ethan Yonkera33161b2014-11-06 15:11:20 -060032#include <pixelflinger/pixelflinger.h>
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080033
maxwen44d59ea2015-07-14 00:41:14 +020034#ifdef BOARD_USE_CUSTOM_RECOVERY_FONT
35#include BOARD_USE_CUSTOM_RECOVERY_FONT
36#else
Doug Zongker6fd59ac2013-03-06 15:01:11 -080037#include "font_10x18.h"
maxwen44d59ea2015-07-14 00:41:14 +020038#endif
39
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080040#include "minui.h"
Ethan Yonkera33161b2014-11-06 15:11:20 -060041
42#if defined(RECOVERY_BGRA)
43#define PIXEL_FORMAT GGL_PIXEL_FORMAT_BGRA_8888
44#define PIXEL_SIZE 4
Kra1o577568592015-10-14 18:09:54 +020045#elif defined(RECOVERY_RGBA)
46#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGBA_8888
47#define PIXEL_SIZE 4
Ethan Yonkera33161b2014-11-06 15:11:20 -060048#elif defined(RECOVERY_RGBX)
49#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGBX_8888
50#define PIXEL_SIZE 4
51#else
52#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGB_565
53#define PIXEL_SIZE 2
54#endif
55
56#define NUM_BUFFERS 2
Devin Kim862d0262012-07-19 10:47:34 -070057
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080058typedef struct {
Ethan Yonkera33161b2014-11-06 15:11:20 -060059 GGLSurface* texture;
60 unsigned cwidth;
61 unsigned cheight;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080062} GRFont;
63
Ethan Yonkera33161b2014-11-06 15:11:20 -060064static GRFont *gr_font = 0;
65static GGLContext *gr_context = 0;
66static GGLSurface gr_font_texture;
67static GGLSurface gr_framebuffer[NUM_BUFFERS];
68static GGLSurface gr_mem_surface;
69static unsigned gr_active_fb = 0;
70static unsigned double_buffering = 0;
Doug Zongkerc560a672012-12-18 16:31:27 -080071static int overscan_percent = OVERSCAN_PERCENT;
72static int overscan_offset_x = 0;
73static int overscan_offset_y = 0;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080074
Ethan Yonkera33161b2014-11-06 15:11:20 -060075static int gr_fb_fd = -1;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080076static int gr_vt_fd = -1;
77
78static struct fb_var_screeninfo vi;
Michael Ward9d1bcdf2011-06-22 14:30:34 -070079static struct fb_fix_screeninfo fi;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080080
Dees Troy62b75ab2014-05-02 13:20:33 +000081static bool has_overlay = false;
82
83bool target_has_overlay(char *version);
84int free_ion_mem(void);
85int alloc_ion_mem(unsigned int size);
86int allocate_overlay(int fd, GGLSurface gr_fb[]);
87int free_overlay(int fd);
88int overlay_display_frame(int fd, GGLubyte* data, size_t size);
89
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080090static int get_framebuffer(GGLSurface *fb)
91{
92 int fd;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080093 void *bits;
94
95 fd = open("/dev/graphics/fb0", O_RDWR);
96 if (fd < 0) {
97 perror("cannot open fb0");
98 return -1;
99 }
100
Michael Ward3dbe66b2011-06-23 19:28:53 -0700101 if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800102 perror("failed to get fb0 info");
103 close(fd);
104 return -1;
105 }
106
Michael Ward3dbe66b2011-06-23 19:28:53 -0700107 vi.bits_per_pixel = PIXEL_SIZE * 8;
108 if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_BGRA_8888) {
109 vi.red.offset = 8;
110 vi.red.length = 8;
111 vi.green.offset = 16;
112 vi.green.length = 8;
113 vi.blue.offset = 24;
114 vi.blue.length = 8;
115 vi.transp.offset = 0;
116 vi.transp.length = 8;
Kra1o577568592015-10-14 18:09:54 +0200117 } else if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_RGBA_8888) {
118 vi.red.offset = 0;
119 vi.red.length = 8;
120 vi.green.offset = 8;
121 vi.green.length = 8;
122 vi.blue.offset = 16;
123 vi.blue.length = 8;
124 vi.transp.offset = 24;
125 vi.transp.length = 8;
Michael Ward3dbe66b2011-06-23 19:28:53 -0700126 } else if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_RGBX_8888) {
127 vi.red.offset = 24;
128 vi.red.length = 8;
129 vi.green.offset = 16;
130 vi.green.length = 8;
131 vi.blue.offset = 8;
132 vi.blue.length = 8;
133 vi.transp.offset = 0;
134 vi.transp.length = 8;
135 } else { /* RGB565*/
136 vi.red.offset = 11;
137 vi.red.length = 5;
138 vi.green.offset = 5;
139 vi.green.length = 6;
140 vi.blue.offset = 0;
141 vi.blue.length = 5;
142 vi.transp.offset = 0;
143 vi.transp.length = 0;
144 }
145 if (ioctl(fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
146 perror("failed to put fb0 info");
147 close(fd);
148 return -1;
149 }
150
151 if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800152 perror("failed to get fb0 info");
153 close(fd);
154 return -1;
155 }
156
Dees Troy62b75ab2014-05-02 13:20:33 +0000157 has_overlay = target_has_overlay(fi.id);
158
159 if (!has_overlay) {
160 bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
161 if (bits == MAP_FAILED) {
162 perror("failed to mmap framebuffer");
163 close(fd);
164 return -1;
165 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800166 }
167
Doug Zongkerc560a672012-12-18 16:31:27 -0800168 overscan_offset_x = vi.xres * overscan_percent / 100;
169 overscan_offset_y = vi.yres * overscan_percent / 100;
170
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800171 fb->version = sizeof(*fb);
172 fb->width = vi.xres;
173 fb->height = vi.yres;
Michael Ward9d1bcdf2011-06-22 14:30:34 -0700174 fb->stride = fi.line_length/PIXEL_SIZE;
Doug Zongkerbe3e6f12011-01-13 16:43:44 -0800175 fb->format = PIXEL_FORMAT;
Dees Troy62b75ab2014-05-02 13:20:33 +0000176 if (!has_overlay) {
177 fb->data = bits;
178 memset(fb->data, 0, vi.yres * fi.line_length);
179 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800180
181 fb++;
182
Octavian Purdila0e348802011-07-01 17:57:45 +0300183 /* check if we can use double buffering */
184 if (vi.yres * fi.line_length * 2 > fi.smem_len)
185 return fd;
186
Ethan Yonkera33161b2014-11-06 15:11:20 -0600187 double_buffering = 1;
188
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800189 fb->version = sizeof(*fb);
190 fb->width = vi.xres;
191 fb->height = vi.yres;
Michael Ward9d1bcdf2011-06-22 14:30:34 -0700192 fb->stride = fi.line_length/PIXEL_SIZE;
Doug Zongkerbe3e6f12011-01-13 16:43:44 -0800193 fb->format = PIXEL_FORMAT;
Dees Troy62b75ab2014-05-02 13:20:33 +0000194 if (!has_overlay) {
Ethan Yonkerbcc502c2014-11-10 11:22:10 -0600195 fb->data = (void*) (((unsigned long) bits) + vi.yres * fi.line_length);
Dees Troy62b75ab2014-05-02 13:20:33 +0000196 memset(fb->data, 0, vi.yres * fi.line_length);
197 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800198
199 return fd;
200}
201
202static void get_memory_surface(GGLSurface* ms) {
203 ms->version = sizeof(*ms);
204 ms->width = vi.xres;
205 ms->height = vi.yres;
Michael Ward9d1bcdf2011-06-22 14:30:34 -0700206 ms->stride = fi.line_length/PIXEL_SIZE;
207 ms->data = malloc(fi.line_length * vi.yres);
Doug Zongkerbe3e6f12011-01-13 16:43:44 -0800208 ms->format = PIXEL_FORMAT;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800209}
210
211static void set_active_framebuffer(unsigned n)
212{
Octavian Purdila0e348802011-07-01 17:57:45 +0300213 if (n > 1 || !double_buffering) return;
Devin Kim862d0262012-07-19 10:47:34 -0700214 vi.yres_virtual = vi.yres * NUM_BUFFERS;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800215 vi.yoffset = n * vi.yres;
Doug Zongkerbe3e6f12011-01-13 16:43:44 -0800216 vi.bits_per_pixel = PIXEL_SIZE * 8;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800217 if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
218 perror("active fb swap failed");
219 }
220}
221
222void gr_flip(void)
223{
Dees Troy62b75ab2014-05-02 13:20:33 +0000224 if (-EINVAL == overlay_display_frame(gr_fb_fd, gr_mem_surface.data,
225 (fi.line_length * vi.yres))) {
226 GGLContext *gl = gr_context;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800227
Dees Troy62b75ab2014-05-02 13:20:33 +0000228 /* swap front and back buffers */
229 if (double_buffering)
230 gr_active_fb = (gr_active_fb + 1) & 1;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800231
Dees Troy62b75ab2014-05-02 13:20:33 +0000232 /* copy data from the in-memory surface to the buffer we're about
233 * to make active. */
234 memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data,
235 fi.line_length * vi.yres);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800236
Dees Troy62b75ab2014-05-02 13:20:33 +0000237 /* inform the display driver */
238 set_active_framebuffer(gr_active_fb);
239 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800240}
241
242void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
243{
244 GGLContext *gl = gr_context;
245 GGLint color[4];
246 color[0] = ((r << 8) | r) + 1;
247 color[1] = ((g << 8) | g) + 1;
248 color[2] = ((b << 8) | b) + 1;
249 color[3] = ((a << 8) | a) + 1;
250 gl->color4xv(gl, color);
251}
252
253int gr_measure(const char *s)
254{
255 return gr_font->cwidth * strlen(s);
256}
257
Dima Zavin3c7f00e2011-08-30 11:58:24 -0700258void gr_font_size(int *x, int *y)
259{
260 *x = gr_font->cwidth;
261 *y = gr_font->cheight;
262}
263
Vojtech Bocek65fdcdd2013-09-06 21:32:22 +0200264int gr_text(int x, int y, const char *s, ...)
265{
266 return gr_text_impl(x, y, s, 0);
267}
268
269int gr_text_impl(int x, int y, const char *s, int bold)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800270{
Ethan Yonkera33161b2014-11-06 15:11:20 -0600271 GGLContext *gl = gr_context;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800272 GRFont *font = gr_font;
273 unsigned off;
274
Ethan Yonkera33161b2014-11-06 15:11:20 -0600275 if (!font->texture) return x;
Doug Zongker55a36ac2013-03-04 15:49:02 -0800276
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800277 bold = bold && (font->texture->height != font->cheight);
278
Doug Zongkerc560a672012-12-18 16:31:27 -0800279 x += overscan_offset_x;
280 y += overscan_offset_y;
281
Ethan Yonkera33161b2014-11-06 15:11:20 -0600282 gl->bindTexture(gl, font->texture);
283 gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
284 gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
285 gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
286 gl->enable(gl, GGL_TEXTURE_2D);
287
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800288 while((off = *s++)) {
289 off -= 32;
290 if (off < 96) {
Ethan Yonkera33161b2014-11-06 15:11:20 -0600291 gl->texCoord2i(gl, (off * font->cwidth) - x,
292 (bold ? font->cheight : 0) - y);
293 gl->recti(gl, x, y, x + font->cwidth, y + font->cheight);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800294 }
295 x += font->cwidth;
296 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600297
298 return x;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800299}
300
Ethan Yonkera33161b2014-11-06 15:11:20 -0600301void gr_texticon(int x, int y, gr_surface icon) {
302 if (gr_context == NULL || icon == NULL) {
Doug Zongker52eeea4f2012-09-04 14:28:25 -0700303 return;
304 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600305 GGLContext* gl = gr_context;
Doug Zongker02ec6b82012-08-22 17:26:40 -0700306
Doug Zongkerc560a672012-12-18 16:31:27 -0800307 x += overscan_offset_x;
308 y += overscan_offset_y;
309
Ethan Yonkera33161b2014-11-06 15:11:20 -0600310 gl->bindTexture(gl, (GGLSurface*) icon);
311 gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
312 gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
313 gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
314 gl->enable(gl, GGL_TEXTURE_2D);
Doug Zongker02ec6b82012-08-22 17:26:40 -0700315
Ethan Yonkera33161b2014-11-06 15:11:20 -0600316 int w = gr_get_width(icon);
317 int h = gr_get_height(icon);
Doug Zongker02ec6b82012-08-22 17:26:40 -0700318
Ethan Yonkera33161b2014-11-06 15:11:20 -0600319 gl->texCoord2i(gl, -x, -y);
320 gl->recti(gl, x, y, x+gr_get_width(icon), y+gr_get_height(icon));
Doug Zongker02ec6b82012-08-22 17:26:40 -0700321}
322
Doug Zongkerc560a672012-12-18 16:31:27 -0800323void gr_fill(int x1, int y1, int x2, int y2)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800324{
Doug Zongkerc560a672012-12-18 16:31:27 -0800325 x1 += overscan_offset_x;
326 y1 += overscan_offset_y;
327
328 x2 += overscan_offset_x;
329 y2 += overscan_offset_y;
330
Ethan Yonkera33161b2014-11-06 15:11:20 -0600331 GGLContext *gl = gr_context;
332 gl->disable(gl, GGL_TEXTURE_2D);
333 gl->recti(gl, x1, y1, x2, y2);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800334}
335
Ethan Yonkera33161b2014-11-06 15:11:20 -0600336void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) {
337 if (gr_context == NULL || source == NULL) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800338 return;
339 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600340 GGLContext *gl = gr_context;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800341
Doug Zongkerc560a672012-12-18 16:31:27 -0800342 dx += overscan_offset_x;
343 dy += overscan_offset_y;
344
Ethan Yonkera33161b2014-11-06 15:11:20 -0600345 gl->bindTexture(gl, (GGLSurface*) source);
346 gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
347 gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
348 gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
349 gl->enable(gl, GGL_TEXTURE_2D);
350 gl->texCoord2i(gl, sx - dx, sy - dy);
351 gl->recti(gl, dx, dy, dx + w, dy + h);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800352}
353
Ethan Yonkera33161b2014-11-06 15:11:20 -0600354unsigned int gr_get_width(gr_surface surface) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800355 if (surface == NULL) {
356 return 0;
357 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600358 return ((GGLSurface*) surface)->width;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800359}
360
Ethan Yonkera33161b2014-11-06 15:11:20 -0600361unsigned int gr_get_height(gr_surface surface) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800362 if (surface == NULL) {
363 return 0;
364 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600365 return ((GGLSurface*) surface)->height;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800366}
367
368static void gr_init_font(void)
369{
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800370 gr_font = calloc(sizeof(*gr_font), 1);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800371
Ethan Yonkera33161b2014-11-06 15:11:20 -0600372 int res = res_create_surface("font", (void**)&(gr_font->texture));
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800373 if (res == 0) {
374 // The font image should be a 96x2 array of character images. The
375 // columns are the printable ASCII characters 0x20 - 0x7f. The
376 // top row is regular text; the bottom row is bold.
377 gr_font->cwidth = gr_font->texture->width / 96;
378 gr_font->cheight = gr_font->texture->height / 2;
379 } else {
Doug Zongker55a36ac2013-03-04 15:49:02 -0800380 printf("failed to read font: res=%d\n", res);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800381
382 // fall back to the compiled-in font.
383 gr_font->texture = malloc(sizeof(*gr_font->texture));
384 gr_font->texture->width = font.width;
385 gr_font->texture->height = font.height;
Ethan Yonkera33161b2014-11-06 15:11:20 -0600386 gr_font->texture->stride = font.width;
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800387
388 unsigned char* bits = malloc(font.width * font.height);
389 gr_font->texture->data = (void*) bits;
390
391 unsigned char data;
392 unsigned char* in = font.rundata;
393 while((data = *in++)) {
394 memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
395 bits += (data & 0x7f);
396 }
397
398 gr_font->cwidth = font.cwidth;
399 gr_font->cheight = font.cheight;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800400 }
401
Ethan Yonkera33161b2014-11-06 15:11:20 -0600402 // interpret the grayscale as alpha
403 gr_font->texture->format = GGL_PIXEL_FORMAT_A_8;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800404}
405
406int gr_init(void)
407{
Ethan Yonkera33161b2014-11-06 15:11:20 -0600408 gglInit(&gr_context);
409 GGLContext *gl = gr_context;
Doug Zongker16f97c32014-03-06 16:16:05 -0800410
Ethan Yonkera33161b2014-11-06 15:11:20 -0600411 gr_init_font();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800412 gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC);
413 if (gr_vt_fd < 0) {
414 // This is non-fatal; post-Cupcake kernels don't have tty0.
415 perror("can't open /dev/tty0");
416 } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) {
417 // However, if we do open tty0, we expect the ioctl to work.
418 perror("failed KDSETMODE to KD_GRAPHICS on tty0");
419 gr_exit();
420 return -1;
421 }
422
Ethan Yonkera33161b2014-11-06 15:11:20 -0600423 gr_fb_fd = get_framebuffer(gr_framebuffer);
424 if (gr_fb_fd < 0) {
425 gr_exit();
426 return -1;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800427 }
428
429 get_memory_surface(&gr_mem_surface);
430
Dees Troy62b75ab2014-05-02 13:20:33 +0000431 fprintf(stderr, "framebuffer: fd %d (%d x %d)\n",
432 gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800433
Dees Troy62b75ab2014-05-02 13:20:33 +0000434 /* start with 0 as front (displayed) and 1 as back (drawing) */
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800435 gr_active_fb = 0;
Dees Troy62b75ab2014-05-02 13:20:33 +0000436 if (!has_overlay)
437 set_active_framebuffer(0);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800438 gl->colorBuffer(gl, &gr_mem_surface);
439
Ethan Yonkera33161b2014-11-06 15:11:20 -0600440 gl->activeTexture(gl, 0);
441 gl->enable(gl, GGL_BLEND);
442 gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800443
Ethan Yonkera33161b2014-11-06 15:11:20 -0600444 gr_fb_blank(true);
445 gr_fb_blank(false);
Doug Zongkerf6abd402011-09-27 13:09:48 -0700446
Dees Troy62b75ab2014-05-02 13:20:33 +0000447 if (!alloc_ion_mem(fi.line_length * vi.yres))
448 allocate_overlay(gr_fb_fd, gr_framebuffer);
449
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800450 return 0;
451}
452
453void gr_exit(void)
454{
Dees Troy62b75ab2014-05-02 13:20:33 +0000455 free_overlay(gr_fb_fd);
456 free_ion_mem();
457
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800458 close(gr_fb_fd);
459 gr_fb_fd = -1;
460
461 free(gr_mem_surface.data);
462
463 ioctl(gr_vt_fd, KDSETMODE, (void*) KD_TEXT);
464 close(gr_vt_fd);
465 gr_vt_fd = -1;
466}
467
468int gr_fb_width(void)
469{
Ethan Yonkera33161b2014-11-06 15:11:20 -0600470 return gr_framebuffer[0].width - 2*overscan_offset_x;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800471}
472
473int gr_fb_height(void)
474{
Ethan Yonkera33161b2014-11-06 15:11:20 -0600475 return gr_framebuffer[0].height - 2*overscan_offset_y;
476}
477
478gr_pixel *gr_fb_data(void)
479{
480 return (unsigned short *) gr_mem_surface.data;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800481}
Dima Zavin4daf48a2011-08-30 11:59:20 -0700482
483void gr_fb_blank(bool blank)
484{
Matt Mower4a5db2d2014-01-20 16:14:25 -0600485#if defined(TW_NO_SCREEN_BLANK) && defined(TW_BRIGHTNESS_PATH) && defined(TW_MAX_BRIGHTNESS)
Ethan Chen0940e412013-10-22 13:48:50 -0700486 int fd;
Matt Mower4a5db2d2014-01-20 16:14:25 -0600487 char brightness[4];
488 snprintf(brightness, 4, "%03d", TW_MAX_BRIGHTNESS/2);
Ethan Chen0940e412013-10-22 13:48:50 -0700489
Matt Mower4a5db2d2014-01-20 16:14:25 -0600490 fd = open(TW_BRIGHTNESS_PATH, O_RDWR);
Ethan Chen0940e412013-10-22 13:48:50 -0700491 if (fd < 0) {
492 perror("cannot open LCD backlight");
493 return;
494 }
Matt Mower4a5db2d2014-01-20 16:14:25 -0600495 write(fd, blank ? "000" : brightness, 3);
Ethan Chen0940e412013-10-22 13:48:50 -0700496 close(fd);
497#else
Ethan Yonkera33161b2014-11-06 15:11:20 -0600498 int ret;
Dees Troy62b75ab2014-05-02 13:20:33 +0000499 if (blank)
500 free_overlay(gr_fb_fd);
Dima Zavin4daf48a2011-08-30 11:59:20 -0700501
Ethan Yonkera33161b2014-11-06 15:11:20 -0600502 ret = ioctl(gr_fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
503 if (ret < 0)
504 perror("ioctl(): blank");
505
Dees Troy62b75ab2014-05-02 13:20:33 +0000506 if (!blank)
507 allocate_overlay(gr_fb_fd, gr_framebuffer);
Ethan Chen0940e412013-10-22 13:48:50 -0700508#endif
Dima Zavin4daf48a2011-08-30 11:59:20 -0700509}
Dees Troy62b75ab2014-05-02 13:20:33 +0000510
511void gr_get_memory_surface(gr_surface surface)
512{
513 get_memory_surface( (GGLSurface*) surface);
514}
Ethan Yonker304f32f2014-11-07 10:14:05 -0600515
516// These are new graphics functions from 5.0 that were not available in
517// 4.4 that are required by charger and healthd
518void gr_clear()
519{
520 return;
521}
522