blob: eceaeee1156f9ffacb89da0f4c19a50a4bda2913 [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>
Elliott Hughescd3c55a2015-01-29 20:50:08 -080019#include <string.h>
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080020#include <unistd.h>
21
22#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
Doug Zongker16f97c32014-03-06 16:16:05 -080032#include <time.h>
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080033
maxwen39624d42015-12-01 22:02:07 +010034#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"
maxwen39624d42015-12-01 22:02:07 +010038#endif
39
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080040#include "minui.h"
Doug Zongker5290f202014-03-11 13:22:04 -070041#include "graphics.h"
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080042
Elliott Hughes07cfb8f2015-04-10 13:12:05 -070043struct GRFont {
Doug Zongker16f97c32014-03-06 16:16:05 -080044 GRSurface* texture;
45 int cwidth;
46 int cheight;
Elliott Hughes07cfb8f2015-04-10 13:12:05 -070047};
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080048
Doug Zongker16f97c32014-03-06 16:16:05 -080049static GRFont* gr_font = NULL;
Doug Zongker5290f202014-03-11 13:22:04 -070050static minui_backend* gr_backend = NULL;
Doug Zongker16f97c32014-03-06 16:16:05 -080051
Doug Zongkerc560a672012-12-18 16:31:27 -080052static int overscan_percent = OVERSCAN_PERCENT;
53static int overscan_offset_x = 0;
54static int overscan_offset_y = 0;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080055
Doug Zongker16f97c32014-03-06 16:16:05 -080056static unsigned char gr_current_r = 255;
57static unsigned char gr_current_g = 255;
58static unsigned char gr_current_b = 255;
59static unsigned char gr_current_a = 255;
Ethan Yonkere96182e2015-10-13 19:32:03 -050060static unsigned char rgb_555[2];
61static unsigned char gr_current_r5 = 31;
62static unsigned char gr_current_g5 = 63;
63static unsigned char gr_current_b5 = 31;
Doug Zongker16f97c32014-03-06 16:16:05 -080064
Doug Zongker5290f202014-03-11 13:22:04 -070065static GRSurface* gr_draw = NULL;
Doug Zongker16f97c32014-03-06 16:16:05 -080066
67static bool outside(int x, int y)
68{
69 return x < 0 || x >= gr_draw->width || y < 0 || y >= gr_draw->height;
70}
71
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080072int gr_measure(const char *s)
73{
74 return gr_font->cwidth * strlen(s);
75}
76
Dima Zavin3c7f00e2011-08-30 11:58:24 -070077void gr_font_size(int *x, int *y)
78{
79 *x = gr_font->cwidth;
80 *y = gr_font->cheight;
81}
82
Ethan Yonkere96182e2015-10-13 19:32:03 -050083void blend_16bpp(unsigned char* px, unsigned r5, unsigned g5, unsigned b5, unsigned char a)
84{
85 unsigned char orig[2];
86 orig[0] = px[0];
87 orig[1] = px[1];
88
89 /* This code is a little easier to read
90 unsigned oldred = (orig[1] >> 3);
91 unsigned oldgreen = (((orig[0] >> 5) << 3) + (orig[1] & 0x7));
92 unsigned oldblue = (orig[0] & 0x1F);
93
94 unsigned newred = (oldred * (255-a) + r5 * a) / 255;
95 unsigned newgreen = (oldgreen * (255-a) + g5 * a) / 255;
96 unsigned newblue = (oldblue * (255-a) + b5 * a) / 255;
97 */
98
99 unsigned newred = ((orig[1] >> 3) * (255-a) + r5 * a) / 255;
100 unsigned newgreen = ((((orig[0] >> 5) << 3) + (orig[1] & 0x7)) * (255-a) + g5 * a) / 255;
101 unsigned newblue = ((orig[0] & 0x1F) * (255-a) + b5 * a) / 255;
102
103 *px++ = (newgreen << 5) + (newblue);
104 *px++ = (newred << 3) + (newgreen >> 3);
105}
106
Doug Zongker16f97c32014-03-06 16:16:05 -0800107static void text_blend(unsigned char* src_p, int src_row_bytes,
108 unsigned char* dst_p, int dst_row_bytes,
109 int width, int height)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800110{
Elliott Hughes01a4d082015-03-24 15:21:48 -0700111 for (int j = 0; j < height; ++j) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800112 unsigned char* sx = src_p;
113 unsigned char* px = dst_p;
Elliott Hughes01a4d082015-03-24 15:21:48 -0700114 for (int i = 0; i < width; ++i) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800115 unsigned char a = *sx++;
116 if (gr_current_a < 255) a = ((int)a * gr_current_a) / 255;
117 if (a == 255) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500118 if (gr_draw->pixel_bytes == 2) {
119 *px++ = rgb_555[0];
120 *px++ = rgb_555[1];
121 } else {
122 *px++ = gr_current_r;
123 *px++ = gr_current_g;
124 *px++ = gr_current_b;
125 px++;
126 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800127 } else if (a > 0) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500128 if (gr_draw->pixel_bytes == 2) {
129 blend_16bpp(px, gr_current_r5, gr_current_g5, gr_current_b5, a);
130 px += gr_draw->pixel_bytes;
131 } else {
132 *px = (*px * (255-a) + gr_current_r * a) / 255;
133 ++px;
134 *px = (*px * (255-a) + gr_current_g * a) / 255;
135 ++px;
136 *px = (*px * (255-a) + gr_current_b * a) / 255;
137 ++px;
138 ++px;
139 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800140 } else {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500141 px += gr_draw->pixel_bytes;
Doug Zongker16f97c32014-03-06 16:16:05 -0800142 }
143 }
144 src_p += src_row_bytes;
145 dst_p += dst_row_bytes;
146 }
147}
148
Elliott Hughes8fd86d72015-04-13 14:36:02 -0700149void gr_text(int x, int y, const char *s, bool bold)
Doug Zongker16f97c32014-03-06 16:16:05 -0800150{
Elliott Hughes01a4d082015-03-24 15:21:48 -0700151 GRFont* font = gr_font;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800152
Elliott Hughes01a4d082015-03-24 15:21:48 -0700153 if (!font->texture || gr_current_a == 0) return;
Doug Zongker55a36ac2013-03-04 15:49:02 -0800154
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800155 bold = bold && (font->texture->height != font->cheight);
156
Doug Zongkerc560a672012-12-18 16:31:27 -0800157 x += overscan_offset_x;
158 y += overscan_offset_y;
159
Elliott Hughes01a4d082015-03-24 15:21:48 -0700160 unsigned char ch;
161 while ((ch = *s++)) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800162 if (outside(x, y) || outside(x+font->cwidth-1, y+font->cheight-1)) break;
Doug Zongker16f97c32014-03-06 16:16:05 -0800163
Elliott Hughes01a4d082015-03-24 15:21:48 -0700164 if (ch < ' ' || ch > '~') {
165 ch = '?';
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800166 }
Elliott Hughes01a4d082015-03-24 15:21:48 -0700167
168 unsigned char* src_p = font->texture->data + ((ch - ' ') * font->cwidth) +
169 (bold ? font->cheight * font->texture->row_bytes : 0);
170 unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
171
172 text_blend(src_p, font->texture->row_bytes,
173 dst_p, gr_draw->row_bytes,
174 font->cwidth, font->cheight);
175
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800176 x += font->cwidth;
177 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800178}
179
Doug Zongker16f97c32014-03-06 16:16:05 -0800180void gr_texticon(int x, int y, GRSurface* icon) {
181 if (icon == NULL) return;
182
183 if (icon->pixel_bytes != 1) {
184 printf("gr_texticon: source has wrong format\n");
Doug Zongker52eeea4f2012-09-04 14:28:25 -0700185 return;
186 }
Doug Zongker02ec6b82012-08-22 17:26:40 -0700187
Doug Zongkerc560a672012-12-18 16:31:27 -0800188 x += overscan_offset_x;
189 y += overscan_offset_y;
190
Doug Zongker16f97c32014-03-06 16:16:05 -0800191 if (outside(x, y) || outside(x+icon->width-1, y+icon->height-1)) return;
Doug Zongker02ec6b82012-08-22 17:26:40 -0700192
Doug Zongker16f97c32014-03-06 16:16:05 -0800193 unsigned char* src_p = icon->data;
194 unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
Doug Zongker02ec6b82012-08-22 17:26:40 -0700195
Doug Zongker16f97c32014-03-06 16:16:05 -0800196 text_blend(src_p, icon->row_bytes,
197 dst_p, gr_draw->row_bytes,
198 icon->width, icon->height);
199}
200
Ethan Yonkere96182e2015-10-13 19:32:03 -0500201void gr_convert_rgb_555()
202{
203 gr_current_r5 = (((gr_current_r & 0xFF) * 0x1F) + 0x7F) / 0xFF;
204 gr_current_g5 = (((gr_current_g & 0xFF) * 0x3F) + 0x7F) / 0xFF;
205 gr_current_b5 = (((gr_current_b & 0xFF) * 0x1F) + 0x7F) / 0xFF;
206
207 rgb_555[0] = (gr_current_g5 << 5) + (gr_current_b5);
208 rgb_555[1] = (gr_current_r5 << 3) + (gr_current_g5 >> 3);
209}
210
Doug Zongker16f97c32014-03-06 16:16:05 -0800211void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
212{
Tony Kuofd778e32015-02-05 21:25:56 +0800213#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
214 gr_current_r = b;
215 gr_current_g = g;
216 gr_current_b = r;
217 gr_current_a = a;
218#else
Doug Zongker16f97c32014-03-06 16:16:05 -0800219 gr_current_r = r;
220 gr_current_g = g;
221 gr_current_b = b;
222 gr_current_a = a;
Tony Kuofd778e32015-02-05 21:25:56 +0800223#endif
Ethan Yonkere96182e2015-10-13 19:32:03 -0500224 if (gr_draw->pixel_bytes == 2) {
225 gr_convert_rgb_555();
226 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800227}
228
229void gr_clear()
230{
Ethan Yonkere96182e2015-10-13 19:32:03 -0500231 if (gr_draw->pixel_bytes == 2) {
232 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
233 return;
234 }
235
236 // This code only works on 32bpp devices
Elliott Hughes01a4d082015-03-24 15:21:48 -0700237 if (gr_current_r == gr_current_g && gr_current_r == gr_current_b) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800238 memset(gr_draw->data, gr_current_r, gr_draw->height * gr_draw->row_bytes);
239 } else {
Doug Zongker16f97c32014-03-06 16:16:05 -0800240 unsigned char* px = gr_draw->data;
Elliott Hughes01a4d082015-03-24 15:21:48 -0700241 for (int y = 0; y < gr_draw->height; ++y) {
242 for (int x = 0; x < gr_draw->width; ++x) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800243 *px++ = gr_current_r;
244 *px++ = gr_current_g;
245 *px++ = gr_current_b;
246 px++;
247 }
248 px += gr_draw->row_bytes - (gr_draw->width * gr_draw->pixel_bytes);
249 }
250 }
Doug Zongker02ec6b82012-08-22 17:26:40 -0700251}
252
Doug Zongkerc560a672012-12-18 16:31:27 -0800253void gr_fill(int x1, int y1, int x2, int y2)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800254{
Doug Zongkerc560a672012-12-18 16:31:27 -0800255 x1 += overscan_offset_x;
256 y1 += overscan_offset_y;
257
258 x2 += overscan_offset_x;
259 y2 += overscan_offset_y;
260
Doug Zongker16f97c32014-03-06 16:16:05 -0800261 if (outside(x1, y1) || outside(x2-1, y2-1)) return;
262
263 unsigned char* p = gr_draw->data + y1 * gr_draw->row_bytes + x1 * gr_draw->pixel_bytes;
264 if (gr_current_a == 255) {
265 int x, y;
266 for (y = y1; y < y2; ++y) {
267 unsigned char* px = p;
268 for (x = x1; x < x2; ++x) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500269 if (gr_draw->pixel_bytes == 2) {
270 *px++ = rgb_555[0];
271 *px++ = rgb_555[1];
272 } else {
273 *px++ = gr_current_r;
274 *px++ = gr_current_g;
275 *px++ = gr_current_b;
276 px++;
277 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800278 }
279 p += gr_draw->row_bytes;
280 }
281 } else if (gr_current_a > 0) {
282 int x, y;
283 for (y = y1; y < y2; ++y) {
284 unsigned char* px = p;
285 for (x = x1; x < x2; ++x) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500286 if (gr_draw->pixel_bytes == 2) {
287 blend_16bpp(px, gr_current_r5, gr_current_g5, gr_current_b5, gr_current_a);
288 px += gr_draw->row_bytes;
289 } else {
290 *px = (*px * (255-gr_current_a) + gr_current_r * gr_current_a) / 255;
291 ++px;
292 *px = (*px * (255-gr_current_a) + gr_current_g * gr_current_a) / 255;
293 ++px;
294 *px = (*px * (255-gr_current_a) + gr_current_b * gr_current_a) / 255;
295 ++px;
296 ++px;
297 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800298 }
299 p += gr_draw->row_bytes;
300 }
301 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800302}
303
Ethan Yonkere96182e2015-10-13 19:32:03 -0500304void gr_blit_32to16(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) {
305 dx += overscan_offset_x;
306 dy += overscan_offset_y;
307
308 if (outside(dx, dy) || outside(dx+w-1, dy+h-1)) return;
309
310 unsigned char* src_p = source->data + sy*source->row_bytes + sx*source->pixel_bytes;
311 unsigned char* dst_p = gr_draw->data + dy*gr_draw->row_bytes + dx*gr_draw->pixel_bytes;
312
313 int i, j;
314 for (i = 0; i < h; ++i) {
315 unsigned char* spx = src_p;
316 unsigned char* dpx = dst_p;
317
318 for (j = 0; j < w; ++j) {
319 unsigned a = spx[3];
320
321 if (a == 0) {
322 spx += source->pixel_bytes;
323 dpx += gr_draw->pixel_bytes;
324 } else {
325 unsigned r5 = (((*spx++ & 0xFF) * 0x1F) + 0x7F) / 0xFF;
326 unsigned g5 = (((*spx++ & 0xFF) * 0x3F) + 0x7F) / 0xFF;
327 unsigned b5 = (((*spx++ & 0xFF) * 0x1F) + 0x7F) / 0xFF;
328 spx++;
329 if (a == 255) {
330 *dpx++ = (g5 << 5) + (b5);
331 *dpx++ = (r5 << 3) + (g5 >> 3);
332 } else {
333 blend_16bpp(dpx, r5, g5, b5, a);
334 spx += source->pixel_bytes;
335 }
336 }
337 }
338 src_p += source->row_bytes;
339 dst_p += gr_draw->row_bytes;
340 }
341}
342
Doug Zongker16f97c32014-03-06 16:16:05 -0800343void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) {
344 if (source == NULL) return;
345
346 if (gr_draw->pixel_bytes != source->pixel_bytes) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500347 if (gr_draw->pixel_bytes == 2 && source->pixel_bytes == 4) {
348 gr_blit_32to16(source, sx, sy, w, h, dx, dy);
349 return;
350 } else {
351 printf("gr_blit: source has wrong format\n");
352 return;
353 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800354 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800355
Doug Zongkerc560a672012-12-18 16:31:27 -0800356 dx += overscan_offset_x;
357 dy += overscan_offset_y;
358
Doug Zongker16f97c32014-03-06 16:16:05 -0800359 if (outside(dx, dy) || outside(dx+w-1, dy+h-1)) return;
360
361 unsigned char* src_p = source->data + sy*source->row_bytes + sx*source->pixel_bytes;
362 unsigned char* dst_p = gr_draw->data + dy*gr_draw->row_bytes + dx*gr_draw->pixel_bytes;
363
364 int i;
365 for (i = 0; i < h; ++i) {
366 memcpy(dst_p, src_p, w * source->pixel_bytes);
367 src_p += source->row_bytes;
368 dst_p += gr_draw->row_bytes;
369 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800370}
371
Doug Zongker16f97c32014-03-06 16:16:05 -0800372unsigned int gr_get_width(GRSurface* surface) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800373 if (surface == NULL) {
374 return 0;
375 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800376 return surface->width;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800377}
378
Doug Zongker16f97c32014-03-06 16:16:05 -0800379unsigned int gr_get_height(GRSurface* surface) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800380 if (surface == NULL) {
381 return 0;
382 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800383 return surface->height;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800384}
385
386static void gr_init_font(void)
387{
Elliott Hughes07cfb8f2015-04-10 13:12:05 -0700388 gr_font = reinterpret_cast<GRFont*>(calloc(sizeof(*gr_font), 1));
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800389
Doug Zongkera418aa72014-03-17 12:10:02 -0700390 int res = res_create_alpha_surface("font", &(gr_font->texture));
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800391 if (res == 0) {
392 // The font image should be a 96x2 array of character images. The
393 // columns are the printable ASCII characters 0x20 - 0x7f. The
394 // top row is regular text; the bottom row is bold.
395 gr_font->cwidth = gr_font->texture->width / 96;
396 gr_font->cheight = gr_font->texture->height / 2;
397 } else {
Doug Zongker55a36ac2013-03-04 15:49:02 -0800398 printf("failed to read font: res=%d\n", res);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800399
400 // fall back to the compiled-in font.
Elliott Hughes07cfb8f2015-04-10 13:12:05 -0700401 gr_font->texture = reinterpret_cast<GRSurface*>(malloc(sizeof(*gr_font->texture)));
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800402 gr_font->texture->width = font.width;
403 gr_font->texture->height = font.height;
Doug Zongker16f97c32014-03-06 16:16:05 -0800404 gr_font->texture->row_bytes = font.width;
405 gr_font->texture->pixel_bytes = 1;
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800406
Elliott Hughes07cfb8f2015-04-10 13:12:05 -0700407 unsigned char* bits = reinterpret_cast<unsigned char*>(malloc(font.width * font.height));
408 gr_font->texture->data = reinterpret_cast<unsigned char*>(bits);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800409
410 unsigned char data;
411 unsigned char* in = font.rundata;
412 while((data = *in++)) {
413 memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
414 bits += (data & 0x7f);
415 }
416
417 gr_font->cwidth = font.cwidth;
418 gr_font->cheight = font.cheight;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800419 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800420}
421
Doug Zongker16f97c32014-03-06 16:16:05 -0800422#if 0
423// Exercises many of the gr_*() functions; useful for testing.
424static void gr_test() {
425 GRSurface** images;
426 int frames;
427 int result = res_create_multi_surface("icon_installing", &frames, &images);
428 if (result < 0) {
429 printf("create surface %d\n", result);
430 gr_exit();
431 return;
432 }
433
434 time_t start = time(NULL);
435 int x;
436 for (x = 0; x <= 1200; ++x) {
437 if (x < 400) {
438 gr_color(0, 0, 0, 255);
439 } else {
440 gr_color(0, (x-400)%128, 0, 255);
441 }
442 gr_clear();
443
444 gr_color(255, 0, 0, 255);
Elliott Hughes0a5cb0c2015-04-15 10:58:56 -0700445 GRSurface* frame = images[x%frames];
Doug Zongker16f97c32014-03-06 16:16:05 -0800446 gr_blit(frame, 0, 0, frame->width, frame->height, x, 0);
447
448 gr_color(255, 0, 0, 128);
449 gr_fill(400, 150, 600, 350);
450
451 gr_color(255, 255, 255, 255);
452 gr_text(500, 225, "hello, world!", 0);
453 gr_color(255, 255, 0, 128);
454 gr_text(300+x, 275, "pack my box with five dozen liquor jugs", 1);
455
456 gr_color(0, 0, 255, 128);
457 gr_fill(gr_draw->width - 200 - x, 300, gr_draw->width - x, 500);
458
Doug Zongker5290f202014-03-11 13:22:04 -0700459 gr_draw = gr_backend->flip(gr_backend);
Doug Zongker16f97c32014-03-06 16:16:05 -0800460 }
461 printf("getting end time\n");
462 time_t end = time(NULL);
463 printf("got end time\n");
464 printf("start %ld end %ld\n", (long)start, (long)end);
465 if (end > start) {
466 printf("%.2f fps\n", ((double)x) / (end-start));
467 }
468}
469#endif
470
Doug Zongker5290f202014-03-11 13:22:04 -0700471void gr_flip() {
472 gr_draw = gr_backend->flip(gr_backend);
473}
474
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800475int gr_init(void)
476{
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800477 gr_init_font();
Ethan Yonkera59da092015-10-13 19:35:05 -0500478 gr_draw = NULL;
Doug Zongker16f97c32014-03-06 16:16:05 -0800479
Ethan Yonkera59da092015-10-13 19:35:05 -0500480 gr_backend = open_overlay();
Greg Hackmann41909dd2014-04-25 10:39:50 -0700481 if (gr_backend) {
482 gr_draw = gr_backend->init(gr_backend);
483 if (!gr_draw) {
484 gr_backend->exit(gr_backend);
Ethan Yonkera59da092015-10-13 19:35:05 -0500485 } else
486 printf("Using overlay graphics.\n");
487 }
488
489#ifndef MSM_BSP
490 if (!gr_draw) {
491 gr_backend = open_adf();
492 if (gr_backend) {
493 gr_draw = gr_backend->init(gr_backend);
494 if (!gr_draw) {
495 gr_backend->exit(gr_backend);
496 } else
497 printf("Using adf graphics.\n");
Greg Hackmann41909dd2014-04-25 10:39:50 -0700498 }
499 }
Ethan Yonkera59da092015-10-13 19:35:05 -0500500#else
501 printf("Skipping adf graphics because TW_TARGET_USES_QCOM_BSP := true\n");
502#endif
Greg Hackmann41909dd2014-04-25 10:39:50 -0700503
504 if (!gr_draw) {
Stéphane Marchesin1a92c442015-06-29 20:05:48 -0700505 gr_backend = open_drm();
506 gr_draw = gr_backend->init(gr_backend);
Ethan Yonkera59da092015-10-13 19:35:05 -0500507 if (gr_draw)
508 printf("Using drm graphics.\n");
Stéphane Marchesin1a92c442015-06-29 20:05:48 -0700509 }
510
511 if (!gr_draw) {
Greg Hackmann41909dd2014-04-25 10:39:50 -0700512 gr_backend = open_fbdev();
513 gr_draw = gr_backend->init(gr_backend);
514 if (gr_draw == NULL) {
515 return -1;
Ethan Yonkera59da092015-10-13 19:35:05 -0500516 } else
517 printf("Using fbdev graphics.\n");
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800518 }
519
Doug Zongker5290f202014-03-11 13:22:04 -0700520 overscan_offset_x = gr_draw->width * overscan_percent / 100;
521 overscan_offset_y = gr_draw->height * overscan_percent / 100;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800522
Doug Zongker16f97c32014-03-06 16:16:05 -0800523 gr_flip();
524 gr_flip();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800525
526 return 0;
527}
528
529void gr_exit(void)
530{
Doug Zongker5290f202014-03-11 13:22:04 -0700531 gr_backend->exit(gr_backend);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800532}
533
534int gr_fb_width(void)
535{
Doug Zongker16f97c32014-03-06 16:16:05 -0800536 return gr_draw->width - 2*overscan_offset_x;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800537}
538
539int gr_fb_height(void)
540{
Doug Zongker16f97c32014-03-06 16:16:05 -0800541 return gr_draw->height - 2*overscan_offset_y;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800542}
Dima Zavin4daf48a2011-08-30 11:59:20 -0700543
544void gr_fb_blank(bool blank)
545{
Doug Zongker5290f202014-03-11 13:22:04 -0700546 gr_backend->blank(gr_backend, blank);
Dima Zavin4daf48a2011-08-30 11:59:20 -0700547}