blob: e65bd92f6e70d213baef2896f9f7b2a433f04fd8
1 | #include <string.h> |
2 | #include <stdlib.h> |
3 | #include <errno.h> |
4 | #include <fcntl.h> |
5 | #include <sys/ioctl.h> |
6 | //#include <linux/ion.h> |
7 | //#include <ion/ion.h> |
8 | #include <linux/fb.h> |
9 | |
10 | //#define LOG_NDEBUG 0 |
11 | #define LOG_TAG "FrameBuffer" |
12 | |
13 | #include <cutils/log.h> |
14 | #include <sys/time.h> |
15 | #include <utils/Timers.h> |
16 | #include <cutils/atomic.h> |
17 | #include <cutils/properties.h> |
18 | #include <hardware/hardware.h> |
19 | #include <hardware/gralloc.h> |
20 | #include "framebuffer.h" |
21 | |
22 | #include <hardware/hwcomposer_defs.h> |
23 | #include <GLES/gl.h> |
24 | |
25 | #include <linux/ion.h> |
26 | #include <ion/ion.h> |
27 | |
28 | #ifndef __gl_h_ |
29 | #error a |
30 | #endif |
31 | |
32 | #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE |
33 | #include "gralloc_vsync_report.h" |
34 | #endif |
35 | |
36 | #include "gralloc_priv.h" |
37 | #include "gralloc_helper.h" |
38 | |
39 | |
40 | #ifdef DEBUG_EXTERNAL_DISPLAY_ON_PANEL |
41 | // 3 for panel, 3 for hdmi |
42 | #define NUM_BUFFERS (6) |
43 | |
44 | #else |
45 | |
46 | // numbers of buffers for page flipping |
47 | #ifndef NUM_BUFFERS |
48 | #define NUM_BUFFERS (2) |
49 | #endif |
50 | |
51 | #endif |
52 | |
53 | enum |
54 | { |
55 | PAGE_FLIP = 0x00000001, |
56 | }; |
57 | /* |
58 | framebuffer interface api to other module to use. |
59 | */ |
60 | |
61 | int bits_per_pixel() |
62 | { |
63 | char fb_bits[PROPERTY_VALUE_MAX]; |
64 | int bits_per_pixel = 16; |
65 | |
66 | if (property_get("sys.fb.bits", fb_bits, NULL) > 0 && atoi(fb_bits) == 32) |
67 | { |
68 | return 32; |
69 | } |
70 | return 16; |
71 | } |
72 | |
73 | #if PLATFORM_SDK_VERSION < 24 |
74 | #define OSD_AFBCD "/sys/class/graphics/fb0/osd_afbcd" |
75 | |
76 | static void write_sys_int(const char *path, int val) |
77 | { |
78 | char cmd[16]; |
79 | int fd = open(path, O_RDWR); |
80 | |
81 | if (fd >= 0) { |
82 | sprintf(cmd, "%d", val); |
83 | write(fd, cmd, strlen(cmd)); |
84 | close(fd); |
85 | } |
86 | } |
87 | #endif |
88 | |
89 | bool osd_afbcd_enable() |
90 | { |
91 | char osd_afbcd[PROPERTY_VALUE_MAX]; |
92 | if (property_get("osd.afbcd.enable", osd_afbcd, NULL ) > 0 && atoi(osd_afbcd) == 0) |
93 | { |
94 | return false; |
95 | } |
96 | return true; |
97 | } |
98 | |
99 | #ifndef SINGLE_EXTERNAL_DISPLAY_USE_FB1 |
100 | int update_cursor_buffer_locked(struct framebuffer_info_t* cbinfo, int xres, int yres) |
101 | { |
102 | char const * const device_template[] = |
103 | { |
104 | "/dev/graphics/fb%u", |
105 | "/dev/fb%u", |
106 | NULL |
107 | }; |
108 | |
109 | int i = 0; |
110 | char name[64]; |
111 | |
112 | while ((cbinfo->fd == -1) && device_template[i]) |
113 | { |
114 | snprintf(name, 64, device_template[i], cbinfo->fbIdx); |
115 | cbinfo->fd = open(name, O_RDWR, 0); |
116 | i++; |
117 | } |
118 | |
119 | ALOGE("update_cursor_buffer_locked of fb idx (%d)",cbinfo->fbIdx); |
120 | |
121 | if (cbinfo->fd < 0) |
122 | { |
123 | return -errno; |
124 | } |
125 | |
126 | struct fb_fix_screeninfo finfo; |
127 | if (ioctl(cbinfo->fd, FBIOGET_FSCREENINFO, &finfo) == -1) |
128 | { |
129 | return -errno; |
130 | } |
131 | |
132 | struct fb_var_screeninfo info; |
133 | if (ioctl(cbinfo->fd, FBIOGET_VSCREENINFO, &info) == -1) |
134 | { |
135 | return -errno; |
136 | } |
137 | |
138 | ALOGE("vinfo. %d %d", info.xres, info.yres); |
139 | |
140 | info.xoffset = info.yoffset = 0; |
141 | info.bits_per_pixel = 32; |
142 | |
143 | /* |
144 | * Explicitly request 8/8/8/8 |
145 | */ |
146 | info.bits_per_pixel = 32; |
147 | info.red.offset = 0; |
148 | info.red.length = 8; |
149 | info.green.offset = 8; |
150 | info.green.length = 8; |
151 | info.blue.offset = 16; |
152 | info.blue.length = 8; |
153 | info.transp.offset = 24; |
154 | info.transp.length = 8; |
155 | |
156 | info.xres_virtual = info.xres = xres; |
157 | info.yres_virtual = info.yres = yres; |
158 | |
159 | if (ioctl(cbinfo->fd, FBIOPUT_VSCREENINFO, &info) == -1) |
160 | { |
161 | ALOGE("set vinfo fail\n"); |
162 | } |
163 | |
164 | if (ioctl(cbinfo->fd, FBIOGET_VSCREENINFO, &info) == -1) |
165 | { |
166 | ALOGE("get info fail\n"); |
167 | return -errno; |
168 | } |
169 | |
170 | if (int(info.width) <= 0 || int(info.height) <= 0) |
171 | { |
172 | // the driver doesn't return that information |
173 | // default to 160 dpi |
174 | info.width = ((info.xres * 25.4f)/160.0f + 0.5f); |
175 | info.height = ((info.yres * 25.4f)/160.0f + 0.5f); |
176 | } |
177 | |
178 | AINF("using (fd=%d)\n" |
179 | "id = %s\n" |
180 | "xres = %d px\n" |
181 | "yres = %d px\n" |
182 | "xres_virtual = %d px\n" |
183 | "yres_virtual = %d px\n" |
184 | "bpp = %d\n", |
185 | cbinfo->fd, |
186 | finfo.id, |
187 | info.xres, |
188 | info.yres, |
189 | info.xres_virtual, |
190 | info.yres_virtual, |
191 | info.bits_per_pixel); |
192 | |
193 | AINF("width = %d mm \n" |
194 | "height = %d mm \n", |
195 | info.width, |
196 | info.height); |
197 | |
198 | if (ioctl(cbinfo->fd, FBIOGET_FSCREENINFO, &finfo) == -1) |
199 | { |
200 | return -errno; |
201 | } |
202 | |
203 | if (finfo.smem_len <= 0) |
204 | { |
205 | return -errno; |
206 | } |
207 | |
208 | cbinfo->info = info; |
209 | cbinfo->finfo = finfo; |
210 | ALOGD("update_cursor_buffer_locked: finfo.line_length is 0x%x,info.yres_virtual is 0x%x", finfo.line_length, info.yres_virtual); |
211 | cbinfo->fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual); |
212 | |
213 | return 0; |
214 | } |
215 | |
216 | |
217 | int init_cursor_buffer_locked(struct framebuffer_info_t* cbinfo) |
218 | { |
219 | char const * const device_template[] = |
220 | { |
221 | "/dev/graphics/fb%u", |
222 | "/dev/fb%u", |
223 | NULL |
224 | }; |
225 | |
226 | int fd = -1; |
227 | int i = 0; |
228 | char name[64]; |
229 | |
230 | while ((fd == -1) && device_template[i]) |
231 | { |
232 | snprintf(name, 64, device_template[i], cbinfo->fbIdx); |
233 | fd = open(name, O_RDWR, 0); |
234 | i++; |
235 | } |
236 | |
237 | ALOGE("init_cursor_buffer_locked of dev:(%s),fb idx (%d)",name,cbinfo->fbIdx); |
238 | |
239 | if (fd < 0) |
240 | { |
241 | return -errno; |
242 | } |
243 | |
244 | struct fb_fix_screeninfo finfo; |
245 | if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) |
246 | { |
247 | return -errno; |
248 | } |
249 | |
250 | struct fb_var_screeninfo info; |
251 | if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) |
252 | { |
253 | return -errno; |
254 | } |
255 | |
256 | ALOGE("vinfo. %d %d", info.xres, info.yres); |
257 | |
258 | info.xoffset = info.yoffset = 0; |
259 | info.bits_per_pixel = 32; |
260 | |
261 | if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) |
262 | { |
263 | ALOGE("set vinfo fail\n"); |
264 | } |
265 | |
266 | if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) |
267 | { |
268 | ALOGE("get info fail\n"); |
269 | return -errno; |
270 | } |
271 | |
272 | if (int(info.width) <= 0 || int(info.height) <= 0) |
273 | { |
274 | // the driver doesn't return that information |
275 | // default to 160 dpi |
276 | info.width = ((info.xres * 25.4f)/160.0f + 0.5f); |
277 | info.height = ((info.yres * 25.4f)/160.0f + 0.5f); |
278 | } |
279 | |
280 | //float xdpi = (info.xres * 25.4f) / info.width; |
281 | //float ydpi = (info.yres * 25.4f) / info.height; |
282 | |
283 | AINF("using (fd=%d)\n" |
284 | "id = %s\n" |
285 | "xres = %d px\n" |
286 | "yres = %d px\n" |
287 | "xres_virtual = %d px\n" |
288 | "yres_virtual = %d px\n" |
289 | "bpp = %d\n", |
290 | fd, |
291 | finfo.id, |
292 | info.xres, |
293 | info.yres, |
294 | info.xres_virtual, |
295 | info.yres_virtual, |
296 | info.bits_per_pixel); |
297 | |
298 | AINF("width = %d mm \n" |
299 | "height = %d mm \n", |
300 | info.width, |
301 | info.height); |
302 | |
303 | if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) |
304 | { |
305 | return -errno; |
306 | } |
307 | |
308 | if (finfo.smem_len <= 0) |
309 | { |
310 | return -errno; |
311 | } |
312 | |
313 | cbinfo->info = info; |
314 | cbinfo->finfo = finfo; |
315 | cbinfo->fd = fd; |
316 | ALOGE("init_cursor_buffer_locked: finfo.line_length is 0x%x,info.yres_virtual is 0x%x", finfo.line_length, info.yres_virtual); |
317 | cbinfo->fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual); |
318 | |
319 | return 0; |
320 | } |
321 | #endif |
322 | |
323 | |
324 | int init_frame_buffer_locked(struct framebuffer_info_t* fbinfo) |
325 | { |
326 | char const * const device_template[] = |
327 | { |
328 | "/dev/graphics/fb%u", |
329 | "/dev/fb%u", |
330 | NULL |
331 | }; |
332 | |
333 | int fd = -1; |
334 | int i = 0; |
335 | char name[64]; |
336 | |
337 | #if PLATFORM_SDK_VERSION < 24 |
338 | if (osd_afbcd_enable()) { |
339 | write_sys_int(OSD_AFBCD, 1); |
340 | } else { |
341 | write_sys_int(OSD_AFBCD, 0); |
342 | } |
343 | #endif |
344 | |
345 | while ((fd == -1) && device_template[i]) |
346 | { |
347 | snprintf(name, 64, device_template[i], fbinfo->fbIdx); |
348 | fd = open(name, O_RDWR, 0); |
349 | i++; |
350 | } |
351 | |
352 | ALOGE("init_frame_buffer_locked of dev:(%s),fb idx (%d)",name,fbinfo->fbIdx); |
353 | |
354 | if (fd < 0) |
355 | { |
356 | return -errno; |
357 | } |
358 | |
359 | struct fb_fix_screeninfo finfo; |
360 | if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) |
361 | { |
362 | return -errno; |
363 | } |
364 | |
365 | struct fb_var_screeninfo info; |
366 | if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) |
367 | { |
368 | return -errno; |
369 | } |
370 | |
371 | info.reserved[0] = 0; |
372 | info.reserved[1] = 0; |
373 | info.reserved[2] = 0; |
374 | info.xoffset = 0; |
375 | info.yoffset = 0; |
376 | info.activate = FB_ACTIVATE_NOW; |
377 | |
378 | if (bits_per_pixel() == 16) |
379 | { |
380 | /* |
381 | * Explicitly request 5/6/5 |
382 | */ |
383 | info.bits_per_pixel = 16; |
384 | info.red.offset = 11; |
385 | info.red.length = 5; |
386 | info.green.offset = 5; |
387 | info.green.length = 6; |
388 | info.blue.offset = 0; |
389 | info.blue.length = 5; |
390 | info.transp.offset = 0; |
391 | info.transp.length = 0; |
392 | } |
393 | else |
394 | { |
395 | /* |
396 | * Explicitly request 8/8/8/8 |
397 | */ |
398 | info.bits_per_pixel = 32; |
399 | info.red.offset = 0; |
400 | info.red.length = 8; |
401 | info.green.offset = 8; |
402 | info.green.length = 8; |
403 | info.blue.offset = 16; |
404 | info.blue.length = 8; |
405 | info.transp.offset = 24; |
406 | info.transp.length = 8; |
407 | } |
408 | |
409 | /* |
410 | * Request NUM_BUFFERS screens (at lest 2 for page flipping) |
411 | */ |
412 | info.yres_virtual = info.yres * NUM_BUFFERS; |
413 | |
414 | uint32_t flags = PAGE_FLIP; |
415 | if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) |
416 | { |
417 | info.yres_virtual = info.yres; |
418 | flags &= ~PAGE_FLIP; |
419 | AWAR( "FBIOPUT_VSCREENINFO failed, page flipping not supported fd: %d", fd ); |
420 | } |
421 | |
422 | if (info.yres_virtual < info.yres * 2) |
423 | { |
424 | // we need at least 2 for page-flipping |
425 | info.yres_virtual = info.yres; |
426 | flags &= ~PAGE_FLIP; |
427 | AWAR( "page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres*2 ); |
428 | } |
429 | |
430 | if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) |
431 | { |
432 | return -errno; |
433 | } |
434 | |
435 | int refreshRate = 0; |
436 | if ( info.pixclock > 0 ) |
437 | { |
438 | refreshRate = 1000000000000000LLU / |
439 | ( |
440 | uint64_t( info.upper_margin + info.lower_margin + info.yres + info.hsync_len ) |
441 | * ( info.left_margin + info.right_margin + info.xres + info.vsync_len ) |
442 | * info.pixclock |
443 | ); |
444 | } |
445 | else |
446 | { |
447 | AWAR( "fbdev pixclock is zero for fd: %d", fd ); |
448 | } |
449 | |
450 | if (refreshRate == 0) |
451 | { |
452 | //refreshRate = 50*1000; // 50 Hz |
453 | refreshRate = 60*1000; // 60 Hz |
454 | } |
455 | |
456 | if (int(info.width) <= 16 || int(info.height) <= 9) |
457 | { |
458 | // the driver doesn't return that information |
459 | // default to 160 dpi |
460 | info.width = ((info.xres * 25.4f)/160.0f + 0.5f); |
461 | info.height = ((info.yres * 25.4f)/160.0f + 0.5f); |
462 | } |
463 | |
464 | float xdpi = (info.xres * 25.4f) / info.width; |
465 | float ydpi = (info.yres * 25.4f) / info.height; |
466 | float fps = refreshRate / 1000.0f; |
467 | |
468 | AINF("using (fd=%d)\n" |
469 | "id = %s\n" |
470 | "xres = %d px\n" |
471 | "yres = %d px\n" |
472 | "xres_virtual = %d px\n" |
473 | "yres_virtual = %d px\n" |
474 | "bpp = %d\n" |
475 | "r = %2u:%u\n" |
476 | "g = %2u:%u\n" |
477 | "b = %2u:%u\n", |
478 | fd, |
479 | finfo.id, |
480 | info.xres, |
481 | info.yres, |
482 | info.xres_virtual, |
483 | info.yres_virtual, |
484 | info.bits_per_pixel, |
485 | info.red.offset, info.red.length, |
486 | info.green.offset, info.green.length, |
487 | info.blue.offset, info.blue.length); |
488 | |
489 | AINF("width = %d mm (%f dpi)\n" |
490 | "height = %d mm (%f dpi)\n" |
491 | "refresh rate = %.2f Hz\n", |
492 | info.width, xdpi, |
493 | info.height, ydpi, |
494 | fps); |
495 | |
496 | if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) |
497 | { |
498 | return -errno; |
499 | } |
500 | |
501 | if (finfo.smem_len <= 0) |
502 | { |
503 | return -errno; |
504 | } |
505 | |
506 | fbinfo->info = info; |
507 | fbinfo->finfo = finfo; |
508 | fbinfo->xdpi = xdpi; |
509 | fbinfo->ydpi = ydpi; |
510 | fbinfo->fps = fps; |
511 | fbinfo->fd = fd; |
512 | fbinfo->flipFlags = flags; |
513 | fbinfo->fbSize = round_up_to_page_size(finfo.line_length * info.yres_virtual); |
514 | |
515 | return 0; |
516 | } |
517 | |
518 | #define FBIOPUT_OSD_SYNC_ADD 0x4518 |
519 | #define FBIOPUT_OSD_SYNC_RENDER_ADD 0x4519 |
520 | int fb_post_with_fence_locked( |
521 | struct framebuffer_info_t* fbinfo, |
522 | buffer_handle_t hnd, |
523 | int in_fence) |
524 | { |
525 | typedef struct { |
526 | unsigned int xoffset; |
527 | unsigned int yoffset; |
528 | int in_fen_fd; |
529 | int out_fen_fd; |
530 | } fb_sync_request_t; |
531 | |
532 | private_handle_t const* buffer = reinterpret_cast<private_handle_t const*>(hnd); |
533 | fb_sync_request_t sync_req; |
534 | |
535 | memset(&sync_req, 0, sizeof(fb_sync_request_t)); |
536 | sync_req.xoffset = fbinfo->info.xoffset; |
537 | sync_req.yoffset = buffer->offset / fbinfo->finfo.line_length; |
538 | // acquire fence. |
539 | sync_req.in_fen_fd = in_fence; |
540 | |
541 | ALOGV( "req offset: %d\n", sync_req.yoffset); |
542 | ioctl(fbinfo->fd, FBIOPUT_OSD_SYNC_ADD, &sync_req); |
543 | |
544 | return sync_req.out_fen_fd; |
545 | } |
546 | |
547 | int hwc_fb_post_with_fence_locked( |
548 | struct framebuffer_info_t* fbinfo, |
549 | struct hwc_fb_sync_request_t* sync_req, |
550 | buffer_handle_t hnd) |
551 | { |
552 | sync_req->shared_fd = -1; |
553 | |
554 | if (hnd) { |
555 | private_handle_t const* buffer = private_handle_t::dynamicCast(hnd); |
556 | switch (sync_req->type) { |
557 | case GLES_COMPOSE_MODE: |
558 | #if PLATFORM_SDK_VERSION >= 26 |
559 | ALOGV("gles pass to direct compose mode."); |
560 | sync_req->type = DIRECT_COMPOSE_MODE; |
561 | sync_req->xoffset = sync_req->dst_x = 0; |
562 | sync_req->yoffset = sync_req->dst_y = 0; |
563 | sync_req->width = sync_req->dst_w = buffer->width; |
564 | sync_req->height = sync_req->dst_h = buffer->height; |
565 | #else |
566 | sync_req->xoffset = fbinfo->info.xoffset; |
567 | sync_req->yoffset = buffer->offset / fbinfo->finfo.line_length; |
568 | ALOGV( "GLES, req offset: %d",sync_req->yoffset); |
569 | break; |
570 | #endif |
571 | case DIRECT_COMPOSE_MODE: |
572 | sync_req->format = buffer->format; |
573 | sync_req->shared_fd = buffer->share_fd; |
574 | sync_req->byte_stride = buffer->byte_stride; |
575 | sync_req->stride = buffer->stride; |
576 | ALOGV( "Direct, src: (%d, %d, %d, %d), dst: (%d, %d, %d, %d)", |
577 | sync_req->xoffset, |
578 | sync_req->yoffset, |
579 | sync_req->width, |
580 | sync_req->height, |
581 | sync_req->dst_x, |
582 | sync_req->dst_y, |
583 | sync_req->dst_w, |
584 | sync_req->dst_h); |
585 | break; |
586 | case GE2D_COMPOSE_MODE: |
587 | sync_req->width = fbinfo->info.xres; |
588 | sync_req->height = fbinfo->info.yres; |
589 | sync_req->format = HAL_PIXEL_FORMAT_RGBA_8888; |
590 | sync_req->yoffset = fbinfo->yOffset; |
591 | sync_req->shared_fd = buffer->share_fd; |
592 | ALOGV( "GE2D, width: %d, height: %d", |
593 | sync_req->width, |
594 | sync_req->height); |
595 | break; |
596 | default: |
597 | ALOGE("hwc unknown compose mode!!!"); |
598 | break; |
599 | } |
600 | } else { |
601 | ALOGV("hwc FB post blank without buffer."); |
602 | } |
603 | ALOGV( "hwc format: %d, shared_fd: %d, op: 0x%x, byte_stride: %d, pixel_stride: %d", |
604 | sync_req->format, |
605 | sync_req->shared_fd, |
606 | sync_req->op, |
607 | sync_req->byte_stride, |
608 | sync_req->stride); |
609 | ioctl(fbinfo->fd, FBIOPUT_OSD_SYNC_RENDER_ADD, sync_req); |
610 | return sync_req->out_fen_fd; |
611 | } |
612 | |
613 | #if PLATFORM_SDK_VERSION < 26 |
614 | #define FB_SYNC_REQUEST_MAGIC 0x54376812 |
615 | #define FB_SYNC_REQUEST_RENDER_MAGIC 0x55386816 |
616 | int hwc_old_fb_post_with_fence_locked( |
617 | struct framebuffer_info_t* fbinfo, |
618 | struct hwc_fb_sync_request_t* fb_sync_req, |
619 | buffer_handle_t hnd) |
620 | { |
621 | typedef struct { |
622 | int magic; |
623 | int len; |
624 | unsigned int xoffset; |
625 | unsigned int yoffset; |
626 | int in_fen_fd; |
627 | int out_fen_fd; |
628 | int format; |
629 | int reserved[3]; |
630 | } hwc_old_fb_sync_request_t; |
631 | |
632 | private_handle_t const* buffer = reinterpret_cast<private_handle_t const*>(hnd); |
633 | hwc_old_fb_sync_request_t sync_req; |
634 | |
635 | memset(&sync_req, 0, sizeof(hwc_old_fb_sync_request_t)); |
636 | sync_req.magic = FB_SYNC_REQUEST_MAGIC; |
637 | sync_req.len = sizeof(hwc_old_fb_sync_request_t); |
638 | sync_req.xoffset = fbinfo->info.xoffset; |
639 | sync_req.yoffset = buffer->offset / fbinfo->finfo.line_length; |
640 | // acquire fence. |
641 | sync_req.format = fb_sync_req->format; |
642 | sync_req.in_fen_fd = fb_sync_req->in_fen_fd; |
643 | |
644 | ALOGV( "len: %d, req offset: %d\n", sync_req.len, sync_req.yoffset); |
645 | ioctl(fbinfo->fd, FBIOPUT_OSD_SYNC_ADD, &sync_req); |
646 | |
647 | return sync_req.out_fen_fd; |
648 | } |
649 | |
650 | int hwc_new_fb_post_with_fence_locked( |
651 | struct framebuffer_info_t* fbinfo, |
652 | struct hwc_fb_sync_request_t* sync_req, |
653 | buffer_handle_t hnd) |
654 | { |
655 | sync_req->shared_fd = -1; |
656 | |
657 | if (hnd) { |
658 | private_handle_t const* buffer = private_handle_t::dynamicCast(hnd); |
659 | switch (sync_req->type) { |
660 | case GLES_COMPOSE_MODE: |
661 | #if PLATFORM_SDK_VERSION >= 26 |
662 | ALOGV("gles pass to direct compose mode."); |
663 | sync_req->type = DIRECT_COMPOSE_MODE; |
664 | sync_req->xoffset = sync_req->dst_x = 0; |
665 | sync_req->yoffset = sync_req->dst_y = 0; |
666 | sync_req->width = sync_req->dst_w = buffer->width; |
667 | sync_req->height = sync_req->dst_h = buffer->height; |
668 | #else |
669 | sync_req->xoffset = fbinfo->info.xoffset; |
670 | sync_req->yoffset = buffer->offset / fbinfo->finfo.line_length; |
671 | ALOGV( "GLES, req offset: %d",sync_req->yoffset); |
672 | break; |
673 | #endif |
674 | case DIRECT_COMPOSE_MODE: |
675 | // sync_req->format = buffer->format; |
676 | sync_req->shared_fd = buffer->share_fd; |
677 | sync_req->byte_stride = buffer->byte_stride; |
678 | sync_req->stride = buffer->stride; |
679 | ALOGV( "Direct, src: (%d, %d, %d, %d), dst: (%d, %d, %d, %d)", |
680 | sync_req->xoffset, |
681 | sync_req->yoffset, |
682 | sync_req->width, |
683 | sync_req->height, |
684 | sync_req->dst_x, |
685 | sync_req->dst_y, |
686 | sync_req->dst_w, |
687 | sync_req->dst_h); |
688 | break; |
689 | case GE2D_COMPOSE_MODE: |
690 | sync_req->width = fbinfo->info.xres; |
691 | sync_req->height = fbinfo->info.yres; |
692 | // sync_req->format = HAL_PIXEL_FORMAT_RGBA_8888; |
693 | sync_req->yoffset = fbinfo->yOffset; |
694 | sync_req->shared_fd = buffer->share_fd; |
695 | ALOGV( "GE2D, width: %d, height: %d", |
696 | sync_req->width, |
697 | sync_req->height); |
698 | break; |
699 | default: |
700 | ALOGE("hwc unknown compose mode!!!"); |
701 | break; |
702 | } |
703 | } else { |
704 | ALOGV("hwc FB post blank without buffer."); |
705 | } |
706 | sync_req->magic = FB_SYNC_REQUEST_RENDER_MAGIC; |
707 | sync_req->len = sizeof(hwc_fb_sync_request_t); |
708 | ALOGV( "hwc len: %d, format: %d, shared_fd: %d, op: 0x%x, byte_stride: %d, pixel_stride: %d", |
709 | sync_req->len, |
710 | sync_req->format, |
711 | sync_req->shared_fd, |
712 | sync_req->op, |
713 | sync_req->byte_stride, |
714 | sync_req->stride); |
715 | ioctl(fbinfo->fd, FBIOPUT_OSD_SYNC_RENDER_ADD, sync_req); |
716 | return sync_req->out_fen_fd; |
717 | } |
718 | #endif |
719 | |
720 | int fb_post_locked(struct framebuffer_info_t* fbinfo, buffer_handle_t hnd) |
721 | { |
722 | private_handle_t const* buffer = reinterpret_cast<private_handle_t const*>(hnd); |
723 | fbinfo->info.activate = FB_ACTIVATE_VBL; |
724 | fbinfo->info.yoffset = buffer->offset / fbinfo->finfo.line_length; |
725 | |
726 | //ALOGD("fbpost on slot (%d)",fbinfo->info.yoffset/fbinfo->info.yres); |
727 | |
728 | #ifdef STANDARD_LINUX_SCREEN |
729 | int interrupt; |
730 | #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) |
731 | #define S3CFB_SET_VSYNC_INT _IOW('F', 206, unsigned int) |
732 | if (ioctl(fbinfo->fd, FBIOPAN_DISPLAY, &fbinfo->info) == -1) |
733 | { |
734 | AERR( "FBIOPAN_DISPLAY failed for fd: %d", fbinfo->fd ); |
735 | return 0; |
736 | } |
737 | #if PLATFORM_SDK_VERSION >= 16 |
738 | if (swapInterval == 1 && !(buffer->usage & GRALLOC_USAGE_HW_COMPOSER)) |
739 | #else |
740 | if (swapInterval == 1) |
741 | #endif |
742 | { |
743 | // enable VSYNC |
744 | interrupt = 1; |
745 | if (ioctl(fbinfo->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0) |
746 | { |
747 | AERR( "S3CFB_SET_VSYNC_INT enable failed for fd: %d", fbinfo->fd ); |
748 | return 0; |
749 | } |
750 | // wait for VSYNC |
751 | #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE |
752 | gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT); |
753 | #endif |
754 | int crtc = 0; |
755 | if (ioctl(fbinfo->fd, FBIO_WAITFORVSYNC, &crtc) < 0) |
756 | { |
757 | AERR( "FBIO_WAITFORVSYNC failed for fd: %d", fbinfo->fd ); |
758 | #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE |
759 | gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); |
760 | #endif |
761 | return 0; |
762 | } |
763 | #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE |
764 | gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); |
765 | #endif |
766 | // disable VSYNC |
767 | interrupt = 0; |
768 | if (ioctl(fbinfo->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0) |
769 | { |
770 | AERR( "S3CFB_SET_VSYNC_INT disable failed for fd: %d", fbinfo->fd ); |
771 | return 0; |
772 | } |
773 | } |
774 | #else |
775 | /*Standard Android way*/ |
776 | #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE |
777 | gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT); |
778 | #endif |
779 | ALOGD("current yoffset %d\n",fbinfo->info.yoffset); |
780 | //if (ioctl(fbinfo->fd, FBIOPUT_VSCREENINFO, &fbinfo->info) == -1) |
781 | if (ioctl(fbinfo->fd, FBIOPAN_DISPLAY, &fbinfo->info) == -1) |
782 | { |
783 | AERR( "FBIOPUT_VSCREENINFO failed for fd: %d", fbinfo->fd ); |
784 | #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE |
785 | gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); |
786 | #endif |
787 | return -errno; |
788 | } |
789 | #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE |
790 | gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT); |
791 | #endif |
792 | #endif |
793 | |
794 | fbinfo->currentBuffer = buffer; |
795 | |
796 | return 0; |
797 | } |
798 | |
799 | int getOsdIdx(int display_type) |
800 | { |
801 | #ifdef DEBUG_EXTERNAL_DISPLAY_ON_PANEL |
802 | return 0; |
803 | #else |
804 | if (display_type == HWC_DISPLAY_PRIMARY) |
805 | return 0; |
806 | if (display_type == HWC_DISPLAY_EXTERNAL) |
807 | { |
808 | #ifndef SINGLE_EXTERNAL_DISPLAY_USE_FB1 |
809 | return 2; |
810 | #else |
811 | return 1; |
812 | #endif |
813 | } |
814 | #endif |
815 | return -1; |
816 | } |
817 | |
818 | |
819 | unsigned int get_num_fb_buffers() { |
820 | ALOGD("****************************** %d\n",NUM_BUFFERS); |
821 | return NUM_BUFFERS; |
822 | } |
823 | |
824 |