blob: cce02a9635c3aaaaa9d5968370e34ac0081bfbaa [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
45#elif defined(RECOVERY_RGBX)
46#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGBX_8888
47#define PIXEL_SIZE 4
48#else
49#define PIXEL_FORMAT GGL_PIXEL_FORMAT_RGB_565
50#define PIXEL_SIZE 2
51#endif
52
53#define NUM_BUFFERS 2
Devin Kim862d0262012-07-19 10:47:34 -070054
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080055typedef struct {
Ethan Yonkera33161b2014-11-06 15:11:20 -060056 GGLSurface* texture;
57 unsigned cwidth;
58 unsigned cheight;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080059} GRFont;
60
Ethan Yonkera33161b2014-11-06 15:11:20 -060061static GRFont *gr_font = 0;
62static GGLContext *gr_context = 0;
63static GGLSurface gr_font_texture;
64static GGLSurface gr_framebuffer[NUM_BUFFERS];
65static GGLSurface gr_mem_surface;
66static unsigned gr_active_fb = 0;
67static unsigned double_buffering = 0;
Doug Zongkerc560a672012-12-18 16:31:27 -080068static int overscan_percent = OVERSCAN_PERCENT;
69static int overscan_offset_x = 0;
70static int overscan_offset_y = 0;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080071
Ethan Yonkera33161b2014-11-06 15:11:20 -060072static int gr_fb_fd = -1;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080073static int gr_vt_fd = -1;
74
75static struct fb_var_screeninfo vi;
Michael Ward9d1bcdf2011-06-22 14:30:34 -070076static struct fb_fix_screeninfo fi;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080077
Dees Troy62b75ab2014-05-02 13:20:33 +000078static bool has_overlay = false;
79
80bool target_has_overlay(char *version);
81int free_ion_mem(void);
82int alloc_ion_mem(unsigned int size);
83int allocate_overlay(int fd, GGLSurface gr_fb[]);
84int free_overlay(int fd);
85int overlay_display_frame(int fd, GGLubyte* data, size_t size);
86
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080087static int get_framebuffer(GGLSurface *fb)
88{
89 int fd;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080090 void *bits;
91
92 fd = open("/dev/graphics/fb0", O_RDWR);
93 if (fd < 0) {
94 perror("cannot open fb0");
95 return -1;
96 }
97
Michael Ward3dbe66b2011-06-23 19:28:53 -070098 if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080099 perror("failed to get fb0 info");
100 close(fd);
101 return -1;
102 }
103
Michael Ward3dbe66b2011-06-23 19:28:53 -0700104 vi.bits_per_pixel = PIXEL_SIZE * 8;
105 if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_BGRA_8888) {
106 vi.red.offset = 8;
107 vi.red.length = 8;
108 vi.green.offset = 16;
109 vi.green.length = 8;
110 vi.blue.offset = 24;
111 vi.blue.length = 8;
112 vi.transp.offset = 0;
113 vi.transp.length = 8;
114 } else if (PIXEL_FORMAT == GGL_PIXEL_FORMAT_RGBX_8888) {
115 vi.red.offset = 24;
116 vi.red.length = 8;
117 vi.green.offset = 16;
118 vi.green.length = 8;
119 vi.blue.offset = 8;
120 vi.blue.length = 8;
121 vi.transp.offset = 0;
122 vi.transp.length = 8;
123 } else { /* RGB565*/
124 vi.red.offset = 11;
125 vi.red.length = 5;
126 vi.green.offset = 5;
127 vi.green.length = 6;
128 vi.blue.offset = 0;
129 vi.blue.length = 5;
130 vi.transp.offset = 0;
131 vi.transp.length = 0;
132 }
133 if (ioctl(fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
134 perror("failed to put fb0 info");
135 close(fd);
136 return -1;
137 }
138
139 if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800140 perror("failed to get fb0 info");
141 close(fd);
142 return -1;
143 }
144
Dees Troy62b75ab2014-05-02 13:20:33 +0000145 has_overlay = target_has_overlay(fi.id);
146
147 if (!has_overlay) {
148 bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
149 if (bits == MAP_FAILED) {
150 perror("failed to mmap framebuffer");
151 close(fd);
152 return -1;
153 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800154 }
155
Doug Zongkerc560a672012-12-18 16:31:27 -0800156 overscan_offset_x = vi.xres * overscan_percent / 100;
157 overscan_offset_y = vi.yres * overscan_percent / 100;
158
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800159 fb->version = sizeof(*fb);
160 fb->width = vi.xres;
161 fb->height = vi.yres;
Michael Ward9d1bcdf2011-06-22 14:30:34 -0700162 fb->stride = fi.line_length/PIXEL_SIZE;
Doug Zongkerbe3e6f12011-01-13 16:43:44 -0800163 fb->format = PIXEL_FORMAT;
Dees Troy62b75ab2014-05-02 13:20:33 +0000164 if (!has_overlay) {
165 fb->data = bits;
166 memset(fb->data, 0, vi.yres * fi.line_length);
167 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800168
169 fb++;
170
Octavian Purdila0e348802011-07-01 17:57:45 +0300171 /* check if we can use double buffering */
172 if (vi.yres * fi.line_length * 2 > fi.smem_len)
173 return fd;
174
Ethan Yonkera33161b2014-11-06 15:11:20 -0600175 double_buffering = 1;
176
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800177 fb->version = sizeof(*fb);
178 fb->width = vi.xres;
179 fb->height = vi.yres;
Michael Ward9d1bcdf2011-06-22 14:30:34 -0700180 fb->stride = fi.line_length/PIXEL_SIZE;
Doug Zongkerbe3e6f12011-01-13 16:43:44 -0800181 fb->format = PIXEL_FORMAT;
Dees Troy62b75ab2014-05-02 13:20:33 +0000182 if (!has_overlay) {
Ethan Yonkerbcc502c2014-11-10 11:22:10 -0600183 fb->data = (void*) (((unsigned long) bits) + vi.yres * fi.line_length);
Dees Troy62b75ab2014-05-02 13:20:33 +0000184 memset(fb->data, 0, vi.yres * fi.line_length);
185 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800186
187 return fd;
188}
189
190static void get_memory_surface(GGLSurface* ms) {
191 ms->version = sizeof(*ms);
192 ms->width = vi.xres;
193 ms->height = vi.yres;
Michael Ward9d1bcdf2011-06-22 14:30:34 -0700194 ms->stride = fi.line_length/PIXEL_SIZE;
195 ms->data = malloc(fi.line_length * vi.yres);
Doug Zongkerbe3e6f12011-01-13 16:43:44 -0800196 ms->format = PIXEL_FORMAT;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800197}
198
199static void set_active_framebuffer(unsigned n)
200{
Octavian Purdila0e348802011-07-01 17:57:45 +0300201 if (n > 1 || !double_buffering) return;
Devin Kim862d0262012-07-19 10:47:34 -0700202 vi.yres_virtual = vi.yres * NUM_BUFFERS;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800203 vi.yoffset = n * vi.yres;
Doug Zongkerbe3e6f12011-01-13 16:43:44 -0800204 vi.bits_per_pixel = PIXEL_SIZE * 8;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800205 if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
206 perror("active fb swap failed");
207 }
208}
209
210void gr_flip(void)
211{
Dees Troy62b75ab2014-05-02 13:20:33 +0000212 if (-EINVAL == overlay_display_frame(gr_fb_fd, gr_mem_surface.data,
213 (fi.line_length * vi.yres))) {
214 GGLContext *gl = gr_context;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800215
Dees Troy62b75ab2014-05-02 13:20:33 +0000216 /* swap front and back buffers */
217 if (double_buffering)
218 gr_active_fb = (gr_active_fb + 1) & 1;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800219
Dees Troy62b75ab2014-05-02 13:20:33 +0000220 /* copy data from the in-memory surface to the buffer we're about
221 * to make active. */
222 memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data,
223 fi.line_length * vi.yres);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800224
Dees Troy62b75ab2014-05-02 13:20:33 +0000225 /* inform the display driver */
226 set_active_framebuffer(gr_active_fb);
227 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800228}
229
230void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
231{
232 GGLContext *gl = gr_context;
233 GGLint color[4];
234 color[0] = ((r << 8) | r) + 1;
235 color[1] = ((g << 8) | g) + 1;
236 color[2] = ((b << 8) | b) + 1;
237 color[3] = ((a << 8) | a) + 1;
238 gl->color4xv(gl, color);
239}
240
241int gr_measure(const char *s)
242{
243 return gr_font->cwidth * strlen(s);
244}
245
Dima Zavin3c7f00e2011-08-30 11:58:24 -0700246void gr_font_size(int *x, int *y)
247{
248 *x = gr_font->cwidth;
249 *y = gr_font->cheight;
250}
251
Vojtech Bocek65fdcdd2013-09-06 21:32:22 +0200252int gr_text(int x, int y, const char *s, ...)
253{
254 return gr_text_impl(x, y, s, 0);
255}
256
257int gr_text_impl(int x, int y, const char *s, int bold)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800258{
Ethan Yonkera33161b2014-11-06 15:11:20 -0600259 GGLContext *gl = gr_context;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800260 GRFont *font = gr_font;
261 unsigned off;
262
Ethan Yonkera33161b2014-11-06 15:11:20 -0600263 if (!font->texture) return x;
Doug Zongker55a36ac2013-03-04 15:49:02 -0800264
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800265 bold = bold && (font->texture->height != font->cheight);
266
Doug Zongkerc560a672012-12-18 16:31:27 -0800267 x += overscan_offset_x;
268 y += overscan_offset_y;
269
Ethan Yonkera33161b2014-11-06 15:11:20 -0600270 gl->bindTexture(gl, font->texture);
271 gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
272 gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
273 gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
274 gl->enable(gl, GGL_TEXTURE_2D);
275
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800276 while((off = *s++)) {
277 off -= 32;
278 if (off < 96) {
Ethan Yonkera33161b2014-11-06 15:11:20 -0600279 gl->texCoord2i(gl, (off * font->cwidth) - x,
280 (bold ? font->cheight : 0) - y);
281 gl->recti(gl, x, y, x + font->cwidth, y + font->cheight);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800282 }
283 x += font->cwidth;
284 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600285
286 return x;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800287}
288
Ethan Yonkera33161b2014-11-06 15:11:20 -0600289void gr_texticon(int x, int y, gr_surface icon) {
290 if (gr_context == NULL || icon == NULL) {
Doug Zongker52eeea4f2012-09-04 14:28:25 -0700291 return;
292 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600293 GGLContext* gl = gr_context;
Doug Zongker02ec6b82012-08-22 17:26:40 -0700294
Doug Zongkerc560a672012-12-18 16:31:27 -0800295 x += overscan_offset_x;
296 y += overscan_offset_y;
297
Ethan Yonkera33161b2014-11-06 15:11:20 -0600298 gl->bindTexture(gl, (GGLSurface*) icon);
299 gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
300 gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
301 gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
302 gl->enable(gl, GGL_TEXTURE_2D);
Doug Zongker02ec6b82012-08-22 17:26:40 -0700303
Ethan Yonkera33161b2014-11-06 15:11:20 -0600304 int w = gr_get_width(icon);
305 int h = gr_get_height(icon);
Doug Zongker02ec6b82012-08-22 17:26:40 -0700306
Ethan Yonkera33161b2014-11-06 15:11:20 -0600307 gl->texCoord2i(gl, -x, -y);
308 gl->recti(gl, x, y, x+gr_get_width(icon), y+gr_get_height(icon));
Doug Zongker02ec6b82012-08-22 17:26:40 -0700309}
310
Doug Zongkerc560a672012-12-18 16:31:27 -0800311void gr_fill(int x1, int y1, int x2, int y2)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800312{
Doug Zongkerc560a672012-12-18 16:31:27 -0800313 x1 += overscan_offset_x;
314 y1 += overscan_offset_y;
315
316 x2 += overscan_offset_x;
317 y2 += overscan_offset_y;
318
Ethan Yonkera33161b2014-11-06 15:11:20 -0600319 GGLContext *gl = gr_context;
320 gl->disable(gl, GGL_TEXTURE_2D);
321 gl->recti(gl, x1, y1, x2, y2);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800322}
323
Ethan Yonkera33161b2014-11-06 15:11:20 -0600324void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) {
325 if (gr_context == NULL || source == NULL) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800326 return;
327 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600328 GGLContext *gl = gr_context;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800329
Doug Zongkerc560a672012-12-18 16:31:27 -0800330 dx += overscan_offset_x;
331 dy += overscan_offset_y;
332
Ethan Yonkera33161b2014-11-06 15:11:20 -0600333 gl->bindTexture(gl, (GGLSurface*) source);
334 gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
335 gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
336 gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
337 gl->enable(gl, GGL_TEXTURE_2D);
338 gl->texCoord2i(gl, sx - dx, sy - dy);
339 gl->recti(gl, dx, dy, dx + w, dy + h);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800340}
341
Ethan Yonkera33161b2014-11-06 15:11:20 -0600342unsigned int gr_get_width(gr_surface surface) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800343 if (surface == NULL) {
344 return 0;
345 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600346 return ((GGLSurface*) surface)->width;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800347}
348
Ethan Yonkera33161b2014-11-06 15:11:20 -0600349unsigned int gr_get_height(gr_surface surface) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800350 if (surface == NULL) {
351 return 0;
352 }
Ethan Yonkera33161b2014-11-06 15:11:20 -0600353 return ((GGLSurface*) surface)->height;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800354}
355
356static void gr_init_font(void)
357{
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800358 gr_font = calloc(sizeof(*gr_font), 1);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800359
Ethan Yonkera33161b2014-11-06 15:11:20 -0600360 int res = res_create_surface("font", (void**)&(gr_font->texture));
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800361 if (res == 0) {
362 // The font image should be a 96x2 array of character images. The
363 // columns are the printable ASCII characters 0x20 - 0x7f. The
364 // top row is regular text; the bottom row is bold.
365 gr_font->cwidth = gr_font->texture->width / 96;
366 gr_font->cheight = gr_font->texture->height / 2;
367 } else {
Doug Zongker55a36ac2013-03-04 15:49:02 -0800368 printf("failed to read font: res=%d\n", res);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800369
370 // fall back to the compiled-in font.
371 gr_font->texture = malloc(sizeof(*gr_font->texture));
372 gr_font->texture->width = font.width;
373 gr_font->texture->height = font.height;
Ethan Yonkera33161b2014-11-06 15:11:20 -0600374 gr_font->texture->stride = font.width;
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800375
376 unsigned char* bits = malloc(font.width * font.height);
377 gr_font->texture->data = (void*) bits;
378
379 unsigned char data;
380 unsigned char* in = font.rundata;
381 while((data = *in++)) {
382 memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
383 bits += (data & 0x7f);
384 }
385
386 gr_font->cwidth = font.cwidth;
387 gr_font->cheight = font.cheight;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800388 }
389
Ethan Yonkera33161b2014-11-06 15:11:20 -0600390 // interpret the grayscale as alpha
391 gr_font->texture->format = GGL_PIXEL_FORMAT_A_8;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800392}
393
394int gr_init(void)
395{
Ethan Yonkera33161b2014-11-06 15:11:20 -0600396 gglInit(&gr_context);
397 GGLContext *gl = gr_context;
Doug Zongker16f97c32014-03-06 16:16:05 -0800398
Ethan Yonkera33161b2014-11-06 15:11:20 -0600399 gr_init_font();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800400 gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC);
401 if (gr_vt_fd < 0) {
402 // This is non-fatal; post-Cupcake kernels don't have tty0.
403 perror("can't open /dev/tty0");
404 } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) {
405 // However, if we do open tty0, we expect the ioctl to work.
406 perror("failed KDSETMODE to KD_GRAPHICS on tty0");
407 gr_exit();
408 return -1;
409 }
410
Ethan Yonkera33161b2014-11-06 15:11:20 -0600411 gr_fb_fd = get_framebuffer(gr_framebuffer);
412 if (gr_fb_fd < 0) {
413 gr_exit();
414 return -1;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800415 }
416
417 get_memory_surface(&gr_mem_surface);
418
Dees Troy62b75ab2014-05-02 13:20:33 +0000419 fprintf(stderr, "framebuffer: fd %d (%d x %d)\n",
420 gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800421
Dees Troy62b75ab2014-05-02 13:20:33 +0000422 /* start with 0 as front (displayed) and 1 as back (drawing) */
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800423 gr_active_fb = 0;
Dees Troy62b75ab2014-05-02 13:20:33 +0000424 if (!has_overlay)
425 set_active_framebuffer(0);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800426 gl->colorBuffer(gl, &gr_mem_surface);
427
Ethan Yonkera33161b2014-11-06 15:11:20 -0600428 gl->activeTexture(gl, 0);
429 gl->enable(gl, GGL_BLEND);
430 gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800431
Ethan Yonkera33161b2014-11-06 15:11:20 -0600432 gr_fb_blank(true);
433 gr_fb_blank(false);
Doug Zongkerf6abd402011-09-27 13:09:48 -0700434
Dees Troy62b75ab2014-05-02 13:20:33 +0000435 if (!alloc_ion_mem(fi.line_length * vi.yres))
436 allocate_overlay(gr_fb_fd, gr_framebuffer);
437
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800438 return 0;
439}
440
441void gr_exit(void)
442{
Dees Troy62b75ab2014-05-02 13:20:33 +0000443 free_overlay(gr_fb_fd);
444 free_ion_mem();
445
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800446 close(gr_fb_fd);
447 gr_fb_fd = -1;
448
449 free(gr_mem_surface.data);
450
451 ioctl(gr_vt_fd, KDSETMODE, (void*) KD_TEXT);
452 close(gr_vt_fd);
453 gr_vt_fd = -1;
454}
455
456int gr_fb_width(void)
457{
Ethan Yonkera33161b2014-11-06 15:11:20 -0600458 return gr_framebuffer[0].width - 2*overscan_offset_x;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800459}
460
461int gr_fb_height(void)
462{
Ethan Yonkera33161b2014-11-06 15:11:20 -0600463 return gr_framebuffer[0].height - 2*overscan_offset_y;
464}
465
466gr_pixel *gr_fb_data(void)
467{
468 return (unsigned short *) gr_mem_surface.data;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800469}
Dima Zavin4daf48a2011-08-30 11:59:20 -0700470
471void gr_fb_blank(bool blank)
472{
Matt Mower4a5db2d2014-01-20 16:14:25 -0600473#if defined(TW_NO_SCREEN_BLANK) && defined(TW_BRIGHTNESS_PATH) && defined(TW_MAX_BRIGHTNESS)
Ethan Chen0940e412013-10-22 13:48:50 -0700474 int fd;
Matt Mower4a5db2d2014-01-20 16:14:25 -0600475 char brightness[4];
476 snprintf(brightness, 4, "%03d", TW_MAX_BRIGHTNESS/2);
Ethan Chen0940e412013-10-22 13:48:50 -0700477
Matt Mower4a5db2d2014-01-20 16:14:25 -0600478 fd = open(TW_BRIGHTNESS_PATH, O_RDWR);
Ethan Chen0940e412013-10-22 13:48:50 -0700479 if (fd < 0) {
480 perror("cannot open LCD backlight");
481 return;
482 }
Matt Mower4a5db2d2014-01-20 16:14:25 -0600483 write(fd, blank ? "000" : brightness, 3);
Ethan Chen0940e412013-10-22 13:48:50 -0700484 close(fd);
485#else
Ethan Yonkera33161b2014-11-06 15:11:20 -0600486 int ret;
Dees Troy62b75ab2014-05-02 13:20:33 +0000487 if (blank)
488 free_overlay(gr_fb_fd);
Dima Zavin4daf48a2011-08-30 11:59:20 -0700489
Ethan Yonkera33161b2014-11-06 15:11:20 -0600490 ret = ioctl(gr_fb_fd, FBIOBLANK, blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK);
491 if (ret < 0)
492 perror("ioctl(): blank");
493
Dees Troy62b75ab2014-05-02 13:20:33 +0000494 if (!blank)
495 allocate_overlay(gr_fb_fd, gr_framebuffer);
Ethan Chen0940e412013-10-22 13:48:50 -0700496#endif
Dima Zavin4daf48a2011-08-30 11:59:20 -0700497}
Dees Troy62b75ab2014-05-02 13:20:33 +0000498
499void gr_get_memory_surface(gr_surface surface)
500{
501 get_memory_surface( (GGLSurface*) surface);
502}
Ethan Yonker304f32f2014-11-07 10:14:05 -0600503
504// These are new graphics functions from 5.0 that were not available in
505// 4.4 that are required by charger and healthd
506void gr_clear()
507{
508 return;
509}
510