blob: 76ef56e70266261e740b917f0f2efa3a88664c2b [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
Doug Zongker6fd59ac2013-03-06 15:01:11 -080034#include "font_10x18.h"
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080035#include "minui.h"
Doug Zongker5290f202014-03-11 13:22:04 -070036#include "graphics.h"
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080037
Elliott Hughes07cfb8f2015-04-10 13:12:05 -070038struct GRFont {
Doug Zongker16f97c32014-03-06 16:16:05 -080039 GRSurface* texture;
40 int cwidth;
41 int cheight;
Elliott Hughes07cfb8f2015-04-10 13:12:05 -070042};
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080043
Doug Zongker16f97c32014-03-06 16:16:05 -080044static GRFont* gr_font = NULL;
Doug Zongker5290f202014-03-11 13:22:04 -070045static minui_backend* gr_backend = NULL;
Doug Zongker16f97c32014-03-06 16:16:05 -080046
Doug Zongkerc560a672012-12-18 16:31:27 -080047static int overscan_percent = OVERSCAN_PERCENT;
48static int overscan_offset_x = 0;
49static int overscan_offset_y = 0;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080050
Doug Zongker16f97c32014-03-06 16:16:05 -080051static unsigned char gr_current_r = 255;
52static unsigned char gr_current_g = 255;
53static unsigned char gr_current_b = 255;
54static unsigned char gr_current_a = 255;
Ethan Yonkere96182e2015-10-13 19:32:03 -050055static unsigned char rgb_555[2];
56static unsigned char gr_current_r5 = 31;
57static unsigned char gr_current_g5 = 63;
58static unsigned char gr_current_b5 = 31;
Doug Zongker16f97c32014-03-06 16:16:05 -080059
Doug Zongker5290f202014-03-11 13:22:04 -070060static GRSurface* gr_draw = NULL;
Doug Zongker16f97c32014-03-06 16:16:05 -080061
62static bool outside(int x, int y)
63{
64 return x < 0 || x >= gr_draw->width || y < 0 || y >= gr_draw->height;
65}
66
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080067int gr_measure(const char *s)
68{
69 return gr_font->cwidth * strlen(s);
70}
71
Dima Zavin3c7f00e2011-08-30 11:58:24 -070072void gr_font_size(int *x, int *y)
73{
74 *x = gr_font->cwidth;
75 *y = gr_font->cheight;
76}
77
Ethan Yonkere96182e2015-10-13 19:32:03 -050078void blend_16bpp(unsigned char* px, unsigned r5, unsigned g5, unsigned b5, unsigned char a)
79{
80 unsigned char orig[2];
81 orig[0] = px[0];
82 orig[1] = px[1];
83
84 /* This code is a little easier to read
85 unsigned oldred = (orig[1] >> 3);
86 unsigned oldgreen = (((orig[0] >> 5) << 3) + (orig[1] & 0x7));
87 unsigned oldblue = (orig[0] & 0x1F);
88
89 unsigned newred = (oldred * (255-a) + r5 * a) / 255;
90 unsigned newgreen = (oldgreen * (255-a) + g5 * a) / 255;
91 unsigned newblue = (oldblue * (255-a) + b5 * a) / 255;
92 */
93
94 unsigned newred = ((orig[1] >> 3) * (255-a) + r5 * a) / 255;
95 unsigned newgreen = ((((orig[0] >> 5) << 3) + (orig[1] & 0x7)) * (255-a) + g5 * a) / 255;
96 unsigned newblue = ((orig[0] & 0x1F) * (255-a) + b5 * a) / 255;
97
98 *px++ = (newgreen << 5) + (newblue);
99 *px++ = (newred << 3) + (newgreen >> 3);
100}
101
Doug Zongker16f97c32014-03-06 16:16:05 -0800102static void text_blend(unsigned char* src_p, int src_row_bytes,
103 unsigned char* dst_p, int dst_row_bytes,
104 int width, int height)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800105{
Elliott Hughes01a4d082015-03-24 15:21:48 -0700106 for (int j = 0; j < height; ++j) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800107 unsigned char* sx = src_p;
108 unsigned char* px = dst_p;
Elliott Hughes01a4d082015-03-24 15:21:48 -0700109 for (int i = 0; i < width; ++i) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800110 unsigned char a = *sx++;
111 if (gr_current_a < 255) a = ((int)a * gr_current_a) / 255;
112 if (a == 255) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500113 if (gr_draw->pixel_bytes == 2) {
114 *px++ = rgb_555[0];
115 *px++ = rgb_555[1];
116 } else {
117 *px++ = gr_current_r;
118 *px++ = gr_current_g;
119 *px++ = gr_current_b;
120 px++;
121 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800122 } else if (a > 0) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500123 if (gr_draw->pixel_bytes == 2) {
124 blend_16bpp(px, gr_current_r5, gr_current_g5, gr_current_b5, a);
125 px += gr_draw->pixel_bytes;
126 } else {
127 *px = (*px * (255-a) + gr_current_r * a) / 255;
128 ++px;
129 *px = (*px * (255-a) + gr_current_g * a) / 255;
130 ++px;
131 *px = (*px * (255-a) + gr_current_b * a) / 255;
132 ++px;
133 ++px;
134 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800135 } else {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500136 px += gr_draw->pixel_bytes;
Doug Zongker16f97c32014-03-06 16:16:05 -0800137 }
138 }
139 src_p += src_row_bytes;
140 dst_p += dst_row_bytes;
141 }
142}
143
Elliott Hughes8fd86d72015-04-13 14:36:02 -0700144void gr_text(int x, int y, const char *s, bool bold)
Doug Zongker16f97c32014-03-06 16:16:05 -0800145{
Elliott Hughes01a4d082015-03-24 15:21:48 -0700146 GRFont* font = gr_font;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800147
Elliott Hughes01a4d082015-03-24 15:21:48 -0700148 if (!font->texture || gr_current_a == 0) return;
Doug Zongker55a36ac2013-03-04 15:49:02 -0800149
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800150 bold = bold && (font->texture->height != font->cheight);
151
Doug Zongkerc560a672012-12-18 16:31:27 -0800152 x += overscan_offset_x;
153 y += overscan_offset_y;
154
Elliott Hughes01a4d082015-03-24 15:21:48 -0700155 unsigned char ch;
156 while ((ch = *s++)) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800157 if (outside(x, y) || outside(x+font->cwidth-1, y+font->cheight-1)) break;
Doug Zongker16f97c32014-03-06 16:16:05 -0800158
Elliott Hughes01a4d082015-03-24 15:21:48 -0700159 if (ch < ' ' || ch > '~') {
160 ch = '?';
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800161 }
Elliott Hughes01a4d082015-03-24 15:21:48 -0700162
163 unsigned char* src_p = font->texture->data + ((ch - ' ') * font->cwidth) +
164 (bold ? font->cheight * font->texture->row_bytes : 0);
165 unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
166
167 text_blend(src_p, font->texture->row_bytes,
168 dst_p, gr_draw->row_bytes,
169 font->cwidth, font->cheight);
170
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800171 x += font->cwidth;
172 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800173}
174
Doug Zongker16f97c32014-03-06 16:16:05 -0800175void gr_texticon(int x, int y, GRSurface* icon) {
176 if (icon == NULL) return;
177
178 if (icon->pixel_bytes != 1) {
179 printf("gr_texticon: source has wrong format\n");
Doug Zongker52eeea4f2012-09-04 14:28:25 -0700180 return;
181 }
Doug Zongker02ec6b82012-08-22 17:26:40 -0700182
Doug Zongkerc560a672012-12-18 16:31:27 -0800183 x += overscan_offset_x;
184 y += overscan_offset_y;
185
Doug Zongker16f97c32014-03-06 16:16:05 -0800186 if (outside(x, y) || outside(x+icon->width-1, y+icon->height-1)) return;
Doug Zongker02ec6b82012-08-22 17:26:40 -0700187
Doug Zongker16f97c32014-03-06 16:16:05 -0800188 unsigned char* src_p = icon->data;
189 unsigned char* dst_p = gr_draw->data + y*gr_draw->row_bytes + x*gr_draw->pixel_bytes;
Doug Zongker02ec6b82012-08-22 17:26:40 -0700190
Doug Zongker16f97c32014-03-06 16:16:05 -0800191 text_blend(src_p, icon->row_bytes,
192 dst_p, gr_draw->row_bytes,
193 icon->width, icon->height);
194}
195
Ethan Yonkere96182e2015-10-13 19:32:03 -0500196void gr_convert_rgb_555()
197{
198 gr_current_r5 = (((gr_current_r & 0xFF) * 0x1F) + 0x7F) / 0xFF;
199 gr_current_g5 = (((gr_current_g & 0xFF) * 0x3F) + 0x7F) / 0xFF;
200 gr_current_b5 = (((gr_current_b & 0xFF) * 0x1F) + 0x7F) / 0xFF;
201
202 rgb_555[0] = (gr_current_g5 << 5) + (gr_current_b5);
203 rgb_555[1] = (gr_current_r5 << 3) + (gr_current_g5 >> 3);
204}
205
Doug Zongker16f97c32014-03-06 16:16:05 -0800206void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
207{
Tony Kuofd778e32015-02-05 21:25:56 +0800208#if defined(RECOVERY_ABGR) || defined(RECOVERY_BGRA)
209 gr_current_r = b;
210 gr_current_g = g;
211 gr_current_b = r;
212 gr_current_a = a;
213#else
Doug Zongker16f97c32014-03-06 16:16:05 -0800214 gr_current_r = r;
215 gr_current_g = g;
216 gr_current_b = b;
217 gr_current_a = a;
Tony Kuofd778e32015-02-05 21:25:56 +0800218#endif
Ethan Yonkere96182e2015-10-13 19:32:03 -0500219 if (gr_draw->pixel_bytes == 2) {
220 gr_convert_rgb_555();
221 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800222}
223
224void gr_clear()
225{
Ethan Yonkere96182e2015-10-13 19:32:03 -0500226 if (gr_draw->pixel_bytes == 2) {
227 gr_fill(0, 0, gr_fb_width(), gr_fb_height());
228 return;
229 }
230
231 // This code only works on 32bpp devices
Elliott Hughes01a4d082015-03-24 15:21:48 -0700232 if (gr_current_r == gr_current_g && gr_current_r == gr_current_b) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800233 memset(gr_draw->data, gr_current_r, gr_draw->height * gr_draw->row_bytes);
234 } else {
Doug Zongker16f97c32014-03-06 16:16:05 -0800235 unsigned char* px = gr_draw->data;
Elliott Hughes01a4d082015-03-24 15:21:48 -0700236 for (int y = 0; y < gr_draw->height; ++y) {
237 for (int x = 0; x < gr_draw->width; ++x) {
Doug Zongker16f97c32014-03-06 16:16:05 -0800238 *px++ = gr_current_r;
239 *px++ = gr_current_g;
240 *px++ = gr_current_b;
241 px++;
242 }
243 px += gr_draw->row_bytes - (gr_draw->width * gr_draw->pixel_bytes);
244 }
245 }
Doug Zongker02ec6b82012-08-22 17:26:40 -0700246}
247
Doug Zongkerc560a672012-12-18 16:31:27 -0800248void gr_fill(int x1, int y1, int x2, int y2)
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800249{
Doug Zongkerc560a672012-12-18 16:31:27 -0800250 x1 += overscan_offset_x;
251 y1 += overscan_offset_y;
252
253 x2 += overscan_offset_x;
254 y2 += overscan_offset_y;
255
Doug Zongker16f97c32014-03-06 16:16:05 -0800256 if (outside(x1, y1) || outside(x2-1, y2-1)) return;
257
258 unsigned char* p = gr_draw->data + y1 * gr_draw->row_bytes + x1 * gr_draw->pixel_bytes;
259 if (gr_current_a == 255) {
260 int x, y;
261 for (y = y1; y < y2; ++y) {
262 unsigned char* px = p;
263 for (x = x1; x < x2; ++x) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500264 if (gr_draw->pixel_bytes == 2) {
265 *px++ = rgb_555[0];
266 *px++ = rgb_555[1];
267 } else {
268 *px++ = gr_current_r;
269 *px++ = gr_current_g;
270 *px++ = gr_current_b;
271 px++;
272 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800273 }
274 p += gr_draw->row_bytes;
275 }
276 } else if (gr_current_a > 0) {
277 int x, y;
278 for (y = y1; y < y2; ++y) {
279 unsigned char* px = p;
280 for (x = x1; x < x2; ++x) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500281 if (gr_draw->pixel_bytes == 2) {
282 blend_16bpp(px, gr_current_r5, gr_current_g5, gr_current_b5, gr_current_a);
283 px += gr_draw->row_bytes;
284 } else {
285 *px = (*px * (255-gr_current_a) + gr_current_r * gr_current_a) / 255;
286 ++px;
287 *px = (*px * (255-gr_current_a) + gr_current_g * gr_current_a) / 255;
288 ++px;
289 *px = (*px * (255-gr_current_a) + gr_current_b * gr_current_a) / 255;
290 ++px;
291 ++px;
292 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800293 }
294 p += gr_draw->row_bytes;
295 }
296 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800297}
298
Ethan Yonkere96182e2015-10-13 19:32:03 -0500299void gr_blit_32to16(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) {
300 dx += overscan_offset_x;
301 dy += overscan_offset_y;
302
303 if (outside(dx, dy) || outside(dx+w-1, dy+h-1)) return;
304
305 unsigned char* src_p = source->data + sy*source->row_bytes + sx*source->pixel_bytes;
306 unsigned char* dst_p = gr_draw->data + dy*gr_draw->row_bytes + dx*gr_draw->pixel_bytes;
307
308 int i, j;
309 for (i = 0; i < h; ++i) {
310 unsigned char* spx = src_p;
311 unsigned char* dpx = dst_p;
312
313 for (j = 0; j < w; ++j) {
314 unsigned a = spx[3];
315
316 if (a == 0) {
317 spx += source->pixel_bytes;
318 dpx += gr_draw->pixel_bytes;
319 } else {
320 unsigned r5 = (((*spx++ & 0xFF) * 0x1F) + 0x7F) / 0xFF;
321 unsigned g5 = (((*spx++ & 0xFF) * 0x3F) + 0x7F) / 0xFF;
322 unsigned b5 = (((*spx++ & 0xFF) * 0x1F) + 0x7F) / 0xFF;
323 spx++;
324 if (a == 255) {
325 *dpx++ = (g5 << 5) + (b5);
326 *dpx++ = (r5 << 3) + (g5 >> 3);
327 } else {
328 blend_16bpp(dpx, r5, g5, b5, a);
329 spx += source->pixel_bytes;
330 }
331 }
332 }
333 src_p += source->row_bytes;
334 dst_p += gr_draw->row_bytes;
335 }
336}
337
Doug Zongker16f97c32014-03-06 16:16:05 -0800338void gr_blit(GRSurface* source, int sx, int sy, int w, int h, int dx, int dy) {
339 if (source == NULL) return;
340
341 if (gr_draw->pixel_bytes != source->pixel_bytes) {
Ethan Yonkere96182e2015-10-13 19:32:03 -0500342 if (gr_draw->pixel_bytes == 2 && source->pixel_bytes == 4) {
343 gr_blit_32to16(source, sx, sy, w, h, dx, dy);
344 return;
345 } else {
346 printf("gr_blit: source has wrong format\n");
347 return;
348 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800349 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800350
Doug Zongkerc560a672012-12-18 16:31:27 -0800351 dx += overscan_offset_x;
352 dy += overscan_offset_y;
353
Doug Zongker16f97c32014-03-06 16:16:05 -0800354 if (outside(dx, dy) || outside(dx+w-1, dy+h-1)) return;
355
356 unsigned char* src_p = source->data + sy*source->row_bytes + sx*source->pixel_bytes;
357 unsigned char* dst_p = gr_draw->data + dy*gr_draw->row_bytes + dx*gr_draw->pixel_bytes;
358
359 int i;
360 for (i = 0; i < h; ++i) {
361 memcpy(dst_p, src_p, w * source->pixel_bytes);
362 src_p += source->row_bytes;
363 dst_p += gr_draw->row_bytes;
364 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800365}
366
Doug Zongker16f97c32014-03-06 16:16:05 -0800367unsigned int gr_get_width(GRSurface* surface) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800368 if (surface == NULL) {
369 return 0;
370 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800371 return surface->width;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800372}
373
Doug Zongker16f97c32014-03-06 16:16:05 -0800374unsigned int gr_get_height(GRSurface* surface) {
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800375 if (surface == NULL) {
376 return 0;
377 }
Doug Zongker16f97c32014-03-06 16:16:05 -0800378 return surface->height;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800379}
380
381static void gr_init_font(void)
382{
Elliott Hughes07cfb8f2015-04-10 13:12:05 -0700383 gr_font = reinterpret_cast<GRFont*>(calloc(sizeof(*gr_font), 1));
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800384
Doug Zongkera418aa72014-03-17 12:10:02 -0700385 int res = res_create_alpha_surface("font", &(gr_font->texture));
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800386 if (res == 0) {
387 // The font image should be a 96x2 array of character images. The
388 // columns are the printable ASCII characters 0x20 - 0x7f. The
389 // top row is regular text; the bottom row is bold.
390 gr_font->cwidth = gr_font->texture->width / 96;
391 gr_font->cheight = gr_font->texture->height / 2;
392 } else {
Doug Zongker55a36ac2013-03-04 15:49:02 -0800393 printf("failed to read font: res=%d\n", res);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800394
395 // fall back to the compiled-in font.
Elliott Hughes07cfb8f2015-04-10 13:12:05 -0700396 gr_font->texture = reinterpret_cast<GRSurface*>(malloc(sizeof(*gr_font->texture)));
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800397 gr_font->texture->width = font.width;
398 gr_font->texture->height = font.height;
Doug Zongker16f97c32014-03-06 16:16:05 -0800399 gr_font->texture->row_bytes = font.width;
400 gr_font->texture->pixel_bytes = 1;
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800401
Elliott Hughes07cfb8f2015-04-10 13:12:05 -0700402 unsigned char* bits = reinterpret_cast<unsigned char*>(malloc(font.width * font.height));
403 gr_font->texture->data = reinterpret_cast<unsigned char*>(bits);
Doug Zongker6fd59ac2013-03-06 15:01:11 -0800404
405 unsigned char data;
406 unsigned char* in = font.rundata;
407 while((data = *in++)) {
408 memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
409 bits += (data & 0x7f);
410 }
411
412 gr_font->cwidth = font.cwidth;
413 gr_font->cheight = font.cheight;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800414 }
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800415}
416
Doug Zongker16f97c32014-03-06 16:16:05 -0800417#if 0
418// Exercises many of the gr_*() functions; useful for testing.
419static void gr_test() {
420 GRSurface** images;
421 int frames;
422 int result = res_create_multi_surface("icon_installing", &frames, &images);
423 if (result < 0) {
424 printf("create surface %d\n", result);
425 gr_exit();
426 return;
427 }
428
429 time_t start = time(NULL);
430 int x;
431 for (x = 0; x <= 1200; ++x) {
432 if (x < 400) {
433 gr_color(0, 0, 0, 255);
434 } else {
435 gr_color(0, (x-400)%128, 0, 255);
436 }
437 gr_clear();
438
439 gr_color(255, 0, 0, 255);
Elliott Hughes0a5cb0c2015-04-15 10:58:56 -0700440 GRSurface* frame = images[x%frames];
Doug Zongker16f97c32014-03-06 16:16:05 -0800441 gr_blit(frame, 0, 0, frame->width, frame->height, x, 0);
442
443 gr_color(255, 0, 0, 128);
444 gr_fill(400, 150, 600, 350);
445
446 gr_color(255, 255, 255, 255);
447 gr_text(500, 225, "hello, world!", 0);
448 gr_color(255, 255, 0, 128);
449 gr_text(300+x, 275, "pack my box with five dozen liquor jugs", 1);
450
451 gr_color(0, 0, 255, 128);
452 gr_fill(gr_draw->width - 200 - x, 300, gr_draw->width - x, 500);
453
Doug Zongker5290f202014-03-11 13:22:04 -0700454 gr_draw = gr_backend->flip(gr_backend);
Doug Zongker16f97c32014-03-06 16:16:05 -0800455 }
456 printf("getting end time\n");
457 time_t end = time(NULL);
458 printf("got end time\n");
459 printf("start %ld end %ld\n", (long)start, (long)end);
460 if (end > start) {
461 printf("%.2f fps\n", ((double)x) / (end-start));
462 }
463}
464#endif
465
Doug Zongker5290f202014-03-11 13:22:04 -0700466void gr_flip() {
467 gr_draw = gr_backend->flip(gr_backend);
468}
469
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800470int gr_init(void)
471{
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800472 gr_init_font();
Ethan Yonkera59da092015-10-13 19:35:05 -0500473 gr_draw = NULL;
Doug Zongker16f97c32014-03-06 16:16:05 -0800474
Ethan Yonkera59da092015-10-13 19:35:05 -0500475 gr_backend = open_overlay();
Greg Hackmann41909dd2014-04-25 10:39:50 -0700476 if (gr_backend) {
477 gr_draw = gr_backend->init(gr_backend);
478 if (!gr_draw) {
479 gr_backend->exit(gr_backend);
Ethan Yonkera59da092015-10-13 19:35:05 -0500480 } else
481 printf("Using overlay graphics.\n");
482 }
483
484#ifndef MSM_BSP
485 if (!gr_draw) {
486 gr_backend = open_adf();
487 if (gr_backend) {
488 gr_draw = gr_backend->init(gr_backend);
489 if (!gr_draw) {
490 gr_backend->exit(gr_backend);
491 } else
492 printf("Using adf graphics.\n");
Greg Hackmann41909dd2014-04-25 10:39:50 -0700493 }
494 }
Ethan Yonkera59da092015-10-13 19:35:05 -0500495#else
496 printf("Skipping adf graphics because TW_TARGET_USES_QCOM_BSP := true\n");
497#endif
Greg Hackmann41909dd2014-04-25 10:39:50 -0700498
499 if (!gr_draw) {
Stéphane Marchesin1a92c442015-06-29 20:05:48 -0700500 gr_backend = open_drm();
501 gr_draw = gr_backend->init(gr_backend);
Ethan Yonkera59da092015-10-13 19:35:05 -0500502 if (gr_draw)
503 printf("Using drm graphics.\n");
Stéphane Marchesin1a92c442015-06-29 20:05:48 -0700504 }
505
506 if (!gr_draw) {
Greg Hackmann41909dd2014-04-25 10:39:50 -0700507 gr_backend = open_fbdev();
508 gr_draw = gr_backend->init(gr_backend);
509 if (gr_draw == NULL) {
510 return -1;
Ethan Yonkera59da092015-10-13 19:35:05 -0500511 } else
512 printf("Using fbdev graphics.\n");
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800513 }
514
Doug Zongker5290f202014-03-11 13:22:04 -0700515 overscan_offset_x = gr_draw->width * overscan_percent / 100;
516 overscan_offset_y = gr_draw->height * overscan_percent / 100;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800517
Doug Zongker16f97c32014-03-06 16:16:05 -0800518 gr_flip();
519 gr_flip();
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800520
521 return 0;
522}
523
524void gr_exit(void)
525{
Doug Zongker5290f202014-03-11 13:22:04 -0700526 gr_backend->exit(gr_backend);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800527}
528
529int gr_fb_width(void)
530{
Doug Zongker16f97c32014-03-06 16:16:05 -0800531 return gr_draw->width - 2*overscan_offset_x;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800532}
533
534int gr_fb_height(void)
535{
Doug Zongker16f97c32014-03-06 16:16:05 -0800536 return gr_draw->height - 2*overscan_offset_y;
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800537}
Dima Zavin4daf48a2011-08-30 11:59:20 -0700538
539void gr_fb_blank(bool blank)
540{
Doug Zongker5290f202014-03-11 13:22:04 -0700541 gr_backend->blank(gr_backend, blank);
Dima Zavin4daf48a2011-08-30 11:59:20 -0700542}