1 /*
2  * Copyright (C) Texas Instruments - http://www.ti.com/
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 
17 #include <errno.h>
18 #include <malloc.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <fcntl.h>
22 #include <poll.h>
23 #include <sys/eventfd.h>
24 #include <sys/ioctl.h>
25 #include <linux/fb.h>
26 #include <linux/omapfb.h>
27 #include <sys/mman.h>
28 #include <sys/resource.h>
29 
30 #include <cutils/properties.h>
31 #include <cutils/log.h>
32 #include <cutils/native_handle.h>
33 #define HWC_REMOVE_DEPRECATED_VERSIONS 0
34 #include <hardware/hardware.h>
35 #include <hardware/hwcomposer.h>
36 #include <EGL/egl.h>
37 #include <hardware_legacy/uevent.h>
38 #include <png.h>
39 #include <utils/Timers.h>
40 
41 #include <system/graphics.h>
42 #include <linux/bltsville.h>
43 
44 #define MAX_HWC_LAYERS 32
45 
46 #define ASPECT_RATIO_TOLERANCE 0.02f
47 
48 #define min(a, b) ( { typeof(a) __a = (a), __b = (b); __a < __b ? __a : __b; } )
49 #define max(a, b) ( { typeof(a) __a = (a), __b = (b); __a > __b ? __a : __b; } )
50 #define swap(a, b) do { typeof(a) __a = (a); (a) = (b); (b) = __a; } while (0)
51 
52 #define WIDTH(rect) ((rect).right - (rect).left)
53 #define HEIGHT(rect) ((rect).bottom - (rect).top)
54 
55 #define DIV_ROUND_UP(a, b) (((a) + (b) - 1) / (b))
56 
57 #include <video/dsscomp.h>
58 #include <video/omap_hwc.h>
59 
60 #include "hal_public.h"
61 #include "rgz_2d.h"
62 
63 #include <linux/ion.h>
64 #include <linux/omap_ion.h>
65 #include <ion/ion.h>
66 
67 #define MAX_HW_OVERLAYS 4
68 #define NUM_NONSCALING_OVERLAYS 1
69 #define NUM_EXT_DISPLAY_BACK_BUFFERS 2
70 
71 struct ext_transform_t {
72     __u8 rotation : 3;          /* 90-degree clockwise rotations */
73     __u8 hflip    : 1;          /* flip l-r (after rotation) */
74     __u8 enabled  : 1;          /* cloning enabled */
75     __u8 docking  : 1;          /* docking vs. mirroring - used for state */
76 };
77 
78 /* cloning support and state */
79 struct omap4_hwc_ext {
80     /* support */
81     struct ext_transform_t mirror;      /* mirroring settings */
82     struct ext_transform_t dock;        /* docking settings */
83     float lcd_xpy;                      /* pixel ratio for UI */
84     __u8 avoid_mode_change;             /* use HDMI mode used for mirroring if possible */
85     __u8 force_dock;                     /* must dock */
86     __u8 hdmi_state;                     /* whether HDMI is connected */
87 
88     /* state */
89     __u8 on_tv;                         /* using a tv */
90     struct ext_transform_t current;     /* current settings */
91     struct ext_transform_t last;        /* last-used settings */
92 
93     /* configuration */
94     __u32 last_xres_used;               /* resolution and pixel ratio used for mode selection */
95     __u32 last_yres_used;
96     __u32 last_mode;                    /* 2-s complement of last HDMI mode set, 0 if none */
97     __u32 mirror_mode;                  /* 2-s complement of mode used when mirroring */
98     float last_xpy;
99     __u16 width;                        /* external screen dimensions */
100     __u16 height;
101     __u32 xres;                         /* external screen resolution */
102     __u32 yres;
103     float m[2][3];                      /* external transformation matrix */
104     hwc_rect_t mirror_region;           /* region of screen to mirror */
105 };
106 typedef struct omap4_hwc_ext omap4_hwc_ext_t;
107 
108 /* used by property settings */
109 enum {
110     EXT_ROTATION    = 3,        /* rotation while mirroring */
111     EXT_HFLIP       = (1 << 2), /* flip l-r on output (after rotation) */
112 };
113 
114 enum bltpolicy {
115     BLTPOLICY_DISABLED = 0,
116     BLTPOLICY_DEFAULT = 1,    /* Default blit policy */
117     BLTPOLICY_ALL,            /* Test mode to attempt to blit all */
118 };
119 
120 enum bltmode {
121     BLTMODE_PAINT = 0,    /* Attempt to blit layer by layer */
122     BLTMODE_REGION = 1,   /* Attempt to blit layers via regions */
123 };
124 
125 /* ARGB image */
126 struct omap4_hwc_img {
127     int width;
128     int height;
129     int rowbytes;
130     int size;
131     unsigned char *ptr;
132 } dock_image = { .rowbytes = 0 };
133 
134 struct omap4_hwc_module {
135     hwc_module_t base;
136 
137     IMG_framebuffer_device_public_t *fb_dev;
138 };
139 typedef struct omap4_hwc_module omap4_hwc_module_t;
140 
141 struct counts {
142     unsigned int possible_overlay_layers;
143     unsigned int composited_layers;
144     unsigned int scaled_layers;
145     unsigned int RGB;
146     unsigned int BGR;
147     unsigned int NV12;
148     unsigned int dockable;
149     unsigned int protected;
150 
151     unsigned int max_hw_overlays;
152     unsigned int max_scaling_overlays;
153     unsigned int mem;
154     unsigned int s3d;
155 
156     unsigned int large_rgb32_layers;
157 };
158 
159 struct omap4_hwc_device {
160     /* static data */
161     hwc_composer_device_1_t base;
162     hwc_procs_t *procs;
163     pthread_t hdmi_thread;
164     pthread_mutex_t lock;
165 
166     IMG_framebuffer_device_public_t *fb_dev;
167     struct dsscomp_display_info fb_dis;
168     int fb_fd;                  /* file descriptor for /dev/fb0 */
169     int dsscomp_fd;             /* file descriptor for /dev/dsscomp */
170     int hdmi_fb_fd;             /* file descriptor for /dev/fb1 */
171     int wakeup_evt;             /* eventfd used to wakeup event thread */
172 
173     int img_mem_size;           /* size of fb for hdmi */
174     void *img_mem_ptr;          /* start of fb for hdmi */
175 
176     int flags_rgb_order;
177     int flags_nv12_only;
178     float upscaled_nv12_limit;
179 
180     int on_tv;                  /* using a tv */
181     int force_sgx;
182     omap4_hwc_ext_t ext;        /* external mirroring data */
183     int idle;
184 
185     float primary_m[2][3];          /* internal transformation matrix */
186     int primary_transform;
187     int primary_rotation;
188     hwc_rect_t primary_region;
189 
190     buffer_handle_t *buffers;
191     int use_sgx;
192     int swap_rb;
193     unsigned int post2_layers; /* Buffers used with DSS pipes*/
194     unsigned int post2_blit_buffers; /* Buffers used with blit */
195     int ext_ovls;               /* # of overlays on external display for current composition */
196     int ext_ovls_wanted;        /* # of overlays that should be on external display for current composition */
197     int last_ext_ovls;          /* # of overlays on external/internal display for last composition */
198     int last_int_ovls;
199 
200     enum bltmode blt_mode;
201     enum bltpolicy blt_policy;
202 
203     int blit_flags;
204     int blit_num;
205     struct omap_hwc_data comp_data; /* This is a kernel data structure */
206     struct rgz_blt_entry blit_ops[RGZ_MAX_BLITS];
207     struct counts stats;
208     int    ion_fd;
209     struct ion_handle *ion_handles[2];
210 
211     /* fake vsync event state */
212     pthread_mutex_t vsync_lock;
213     int vsync_enabled;
214     uint64_t last_vsync_time;
215     int last_vsync_time_valid;
216     uint64_t fake_vsync_period;
217 };
218 typedef struct omap4_hwc_device omap4_hwc_device_t;
219 
220 #define HAL_FMT(f) ((f) == HAL_PIXEL_FORMAT_TI_NV12 ? "NV12" : \
221                     (f) == HAL_PIXEL_FORMAT_TI_NV12_1D ? "NV12" : \
222                     (f) == HAL_PIXEL_FORMAT_YV12 ? "YV12" : \
223                     (f) == HAL_PIXEL_FORMAT_BGRX_8888 ? "xRGB32" : \
224                     (f) == HAL_PIXEL_FORMAT_RGBX_8888 ? "xBGR32" : \
225                     (f) == HAL_PIXEL_FORMAT_BGRA_8888 ? "ARGB32" : \
226                     (f) == HAL_PIXEL_FORMAT_RGBA_8888 ? "ABGR32" : \
227                     (f) == HAL_PIXEL_FORMAT_RGB_565 ? "RGB565" : "??")
228 
229 #define DSS_FMT(f) ((f) == OMAP_DSS_COLOR_NV12 ? "NV12" : \
230                     (f) == OMAP_DSS_COLOR_RGB24U ? "xRGB32" : \
231                     (f) == OMAP_DSS_COLOR_ARGB32 ? "ARGB32" : \
232                     (f) == OMAP_DSS_COLOR_RGB16 ? "RGB565" : "??")
233 
234 static int debug = 0;
235 static int debugpost2 = 0;
236 static int debugblt = 0;
237 static rgz_t grgz;
238 static struct bvsurfgeom gscrngeom;
239 
showfps(void)240 static void showfps(void)
241 {
242     static int framecount = 0;
243     static int lastframecount = 0;
244     static nsecs_t lastfpstime = 0;
245     static float fps = 0;
246     char value[PROPERTY_VALUE_MAX];
247 
248     property_get("debug.hwc.showfps", value, "0");
249     if (!atoi(value)) {
250         return;
251     }
252 
253     framecount++;
254     if (!(framecount & 0x7)) {
255         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
256         nsecs_t diff = now - lastfpstime;
257         fps = ((framecount - lastframecount) * (float)(s2ns(1))) / diff;
258         lastfpstime = now;
259         lastframecount = framecount;
260         ALOGI("%d Frames, %f FPS", framecount, fps);
261     }
262 }
263 
dump_layer(hwc_layer_1_t const * l)264 static void dump_layer(hwc_layer_1_t const* l)
265 {
266     ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}",
267          l->compositionType, l->flags, l->handle, l->transform, l->blending,
268          l->sourceCrop.left,
269          l->sourceCrop.top,
270          l->sourceCrop.right,
271          l->sourceCrop.bottom,
272          l->displayFrame.left,
273          l->displayFrame.top,
274          l->displayFrame.right,
275          l->displayFrame.bottom);
276 }
277 
dump_dsscomp(struct dsscomp_setup_dispc_data * d)278 static void dump_dsscomp(struct dsscomp_setup_dispc_data *d)
279 {
280     unsigned i;
281 
282     ALOGD("[%08x] set: %c%c%c %d ovls\n",
283          d->sync_id,
284          (d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-',
285          (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-',
286          (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-',
287          d->num_ovls);
288 
289     for (i = 0; i < d->num_mgrs; i++) {
290         struct dss2_mgr_info *mi = &d->mgrs[i];
291         ALOGD(" (dis%d alpha=%d col=%08x ilace=%d)\n",
292              mi->ix,
293              mi->alpha_blending, mi->default_color,
294              mi->interlaced);
295     }
296 
297     for (i = 0; i < d->num_ovls; i++) {
298         struct dss2_ovl_info *oi = &d->ovls[i];
299         struct dss2_ovl_cfg *c = &oi->cfg;
300         if (c->zonly)
301             ALOGD("ovl%d(%s z%d)\n",
302                  c->ix, c->enabled ? "ON" : "off", c->zorder);
303         else
304             ALOGD("ovl%d(%s z%d %s%s *%d%% %d*%d:%d,%d+%d,%d rot%d%s => %d,%d+%d,%d %p/%p|%d)\n",
305                  c->ix, c->enabled ? "ON" : "off", c->zorder, DSS_FMT(c->color_mode),
306                  c->pre_mult_alpha ? " premult" : "",
307                  (c->global_alpha * 100 + 128) / 255,
308                  c->width, c->height, c->crop.x, c->crop.y,
309                  c->crop.w, c->crop.h,
310                  c->rotation, c->mirror ? "+mir" : "",
311                  c->win.x, c->win.y, c->win.w, c->win.h,
312                  (void *) oi->ba, (void *) oi->uv, c->stride);
313     }
314 }
315 
316 struct dump_buf {
317     char *buf;
318     int buf_len;
319     int len;
320 };
321 
dump_printf(struct dump_buf * buf,const char * fmt,...)322 static void dump_printf(struct dump_buf *buf, const char *fmt, ...)
323 {
324     va_list ap;
325 
326     va_start(ap, fmt);
327     buf->len += vsnprintf(buf->buf + buf->len, buf->buf_len - buf->len, fmt, ap);
328     va_end(ap);
329 }
330 
dump_set_info(omap4_hwc_device_t * hwc_dev,hwc_display_contents_1_t * list)331 static void dump_set_info(omap4_hwc_device_t *hwc_dev, hwc_display_contents_1_t* list)
332 {
333     struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
334     char logbuf[1024];
335     struct dump_buf log = {
336         .buf = logbuf,
337         .buf_len = sizeof(logbuf),
338     };
339     unsigned int i;
340 
341     dump_printf(&log, "set H{");
342     for (i = 0; list && i < list->numHwLayers; i++) {
343         if (i)
344             dump_printf(&log, " ");
345         hwc_layer_1_t *layer = &list->hwLayers[i];
346         IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
347         if (hwc_dev->post2_blit_buffers) {
348             if ((i + 1) < hwc_dev->post2_layers)
349                 dump_printf(&log, "%p:%s,", handle, "DSS");
350             else
351                 dump_printf(&log, "%p:%s,", handle, "BV2D");
352         }
353         else
354             dump_printf(&log, "%p:%s,", handle, layer->compositionType == HWC_OVERLAY ? "DSS" : "SGX");
355         if ((layer->flags & HWC_SKIP_LAYER) || !handle) {
356             dump_printf(&log, "SKIP");
357             continue;
358         }
359         if (layer->flags & HWC_HINT_CLEAR_FB)
360             dump_printf(&log, "CLR,");
361         dump_printf(&log, "%d*%d(%s)", handle->iWidth, handle->iHeight, HAL_FMT(handle->iFormat));
362         if (layer->transform)
363             dump_printf(&log, "~%d", layer->transform);
364     }
365     dump_printf(&log, "} D{");
366     for (i = 0; i < dsscomp->num_ovls; i++) {
367         if (i)
368             dump_printf(&log, " ");
369         dump_printf(&log, "%d=", dsscomp->ovls[i].cfg.ix);
370         if (dsscomp->ovls[i].cfg.enabled)
371             dump_printf(&log, "%08x:%d*%d,%s",
372                         dsscomp->ovls[i].ba,
373                         dsscomp->ovls[i].cfg.width,
374                         dsscomp->ovls[i].cfg.height,
375                         DSS_FMT(dsscomp->ovls[i].cfg.color_mode));
376         else
377             dump_printf(&log, "-");
378     }
379     dump_printf(&log, "} L{");
380     for (i = 0; i < hwc_dev->post2_layers; i++) {
381         if (i)
382             dump_printf(&log, " ");
383         dump_printf(&log, "%p", hwc_dev->buffers[i]);
384     }
385     if (hwc_dev->post2_blit_buffers) {
386         dump_printf(&log, "} B{");
387         for (i = hwc_dev->post2_layers;
388              i < hwc_dev->post2_blit_buffers + hwc_dev->post2_layers; i++) {
389             dump_printf(&log, "%p ", hwc_dev->buffers[i]);
390         }
391     }
392     dump_printf(&log, "}%s\n", hwc_dev->use_sgx ? " swap" : "");
393 
394     ALOGD("%s", log.buf);
395 }
396 
397 static int sync_id = 0;
398 
omap4_hwc_is_valid_format(int format)399 static int omap4_hwc_is_valid_format(int format)
400 {
401     switch(format) {
402     case HAL_PIXEL_FORMAT_RGB_565:
403     case HAL_PIXEL_FORMAT_RGBX_8888:
404     case HAL_PIXEL_FORMAT_RGBA_8888:
405     case HAL_PIXEL_FORMAT_BGRA_8888:
406     case HAL_PIXEL_FORMAT_BGRX_8888:
407     case HAL_PIXEL_FORMAT_TI_NV12:
408     case HAL_PIXEL_FORMAT_TI_NV12_1D:
409         return 1;
410 
411     default:
412         return 0;
413     }
414 }
415 
scaled(hwc_layer_1_t * layer)416 static int scaled(hwc_layer_1_t *layer)
417 {
418     int w = WIDTH(layer->sourceCrop);
419     int h = HEIGHT(layer->sourceCrop);
420 
421     if (layer->transform & HWC_TRANSFORM_ROT_90)
422         swap(w, h);
423 
424     return WIDTH(layer->displayFrame) != w || HEIGHT(layer->displayFrame) != h;
425 }
426 
is_protected(hwc_layer_1_t * layer)427 static int is_protected(hwc_layer_1_t *layer)
428 {
429     IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
430 
431     return (handle->usage & GRALLOC_USAGE_PROTECTED);
432 }
433 
434 #define is_BLENDED(layer) ((layer)->blending != HWC_BLENDING_NONE)
435 
is_RGB32(IMG_native_handle_t * handle)436 static int is_RGB32(IMG_native_handle_t *handle)
437 {
438     switch(handle->iFormat)
439     {
440     case HAL_PIXEL_FORMAT_BGRA_8888:
441     case HAL_PIXEL_FORMAT_BGRX_8888:
442         return 1;
443     default:
444         return 0;
445     }
446 }
447 
is_RGB(IMG_native_handle_t * handle)448 static int is_RGB(IMG_native_handle_t *handle)
449 {
450     switch(handle->iFormat)
451     {
452     case HAL_PIXEL_FORMAT_BGRA_8888:
453     case HAL_PIXEL_FORMAT_BGRX_8888:
454     case HAL_PIXEL_FORMAT_RGB_565:
455         return 1;
456     default:
457         return 0;
458     }
459 }
get_rgb_bpp(IMG_native_handle_t * handle)460 static int get_rgb_bpp(IMG_native_handle_t *handle)
461 {
462     switch(handle->iFormat)
463     {
464     case HAL_PIXEL_FORMAT_BGRA_8888:
465     case HAL_PIXEL_FORMAT_BGRX_8888:
466     case HAL_PIXEL_FORMAT_RGBX_8888:
467     case HAL_PIXEL_FORMAT_RGBA_8888:
468         return 32;
469     case HAL_PIXEL_FORMAT_RGB_565:
470         return 16;
471     default:
472         return 0;
473     }
474 }
475 
is_BGR_format(int format)476 static int is_BGR_format(int format)
477 {
478     switch (format) {
479     case HAL_PIXEL_FORMAT_RGBX_8888:
480     case HAL_PIXEL_FORMAT_RGBA_8888:
481         return 1;
482     default:
483         return 0;
484     }
485 }
486 
is_BGR(IMG_native_handle_t * handle)487 static int is_BGR(IMG_native_handle_t *handle)
488 {
489     return is_BGR_format(handle->iFormat);
490 }
491 
is_NV12(IMG_native_handle_t * handle)492 static int is_NV12(IMG_native_handle_t *handle)
493 {
494     switch(handle->iFormat)
495     {
496     case HAL_PIXEL_FORMAT_TI_NV12:
497     case HAL_PIXEL_FORMAT_TI_NV12_1D:
498         return 1;
499     default:
500         return 0;
501     }
502 }
503 
is_upscaled_NV12(omap4_hwc_device_t * hwc_dev,hwc_layer_1_t * layer)504 static int is_upscaled_NV12(omap4_hwc_device_t *hwc_dev, hwc_layer_1_t *layer)
505 {
506     if (!layer)
507         return 0;
508 
509     IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
510     if (!is_NV12(handle))
511         return 0;
512 
513     int w = WIDTH(layer->sourceCrop);
514     int h = HEIGHT(layer->sourceCrop);
515 
516     if (layer->transform & HWC_TRANSFORM_ROT_90)
517         swap(w, h);
518 
519     return (WIDTH(layer->displayFrame) >= w * hwc_dev->upscaled_nv12_limit ||
520             HEIGHT(layer->displayFrame) >= h * hwc_dev->upscaled_nv12_limit);
521 }
522 
dockable(hwc_layer_1_t * layer)523 static int dockable(hwc_layer_1_t *layer)
524 {
525     IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
526 
527     return (handle->usage & GRALLOC_USAGE_EXTERNAL_DISP);
528 }
529 
530 /* test if layer appears to be RGB32 (4 Bpp) and > 1280x720 */
is_large_rgb32_layer(const hwc_layer_1_t * layer)531 static int is_large_rgb32_layer(const hwc_layer_1_t *layer)
532 {
533     IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
534 
535     return is_RGB32(handle) &&
536         (((layer->sourceCrop.right - layer->sourceCrop.left) > 1280) ||
537         ((layer->sourceCrop.bottom - layer->sourceCrop.top) > 720));
538 }
539 
vsync_clock_now()540 static uint64_t vsync_clock_now()
541 {
542     uint64_t now = 0;
543     struct timespec ts;
544 
545     if (!clock_gettime(CLOCK_MONOTONIC, &ts))
546         now = ((uint64_t)ts.tv_sec) * 1000000000ull + ts.tv_nsec;
547 
548     return now;
549 }
550 
wakeup_hdmi_thread(omap4_hwc_device_t * hwc_dev)551 static void wakeup_hdmi_thread(omap4_hwc_device_t *hwc_dev)
552 {
553     uint64_t tmp = 1;
554     write(hwc_dev->wakeup_evt, &tmp, sizeof(tmp));
555 }
556 
fire_vsync_event(omap4_hwc_device_t * hwc_dev,uint64_t timestamp)557 static void fire_vsync_event(omap4_hwc_device_t *hwc_dev, uint64_t timestamp)
558 {
559     pthread_mutex_lock(&hwc_dev->vsync_lock);
560 
561     hwc_dev->last_vsync_time_valid = 1;
562     hwc_dev->last_vsync_time = timestamp;
563 
564     pthread_mutex_unlock(&hwc_dev->vsync_lock);
565 
566     if (hwc_dev->procs && hwc_dev->procs->vsync)
567         hwc_dev->procs->vsync(hwc_dev->procs, 0, timestamp);
568 }
569 
mem1d(IMG_native_handle_t * handle)570 static unsigned int mem1d(IMG_native_handle_t *handle)
571 {
572     if (handle == NULL || is_NV12(handle))
573         return 0;
574 
575     int bpp = handle->iFormat == HAL_PIXEL_FORMAT_RGB_565 ? 2 : 4;
576     int stride = ALIGN(handle->iWidth, HW_ALIGN) * bpp;
577     return stride * handle->iHeight;
578 }
579 
580 static void
omap4_hwc_setup_layer_base(struct dss2_ovl_cfg * oc,int index,int format,int blended,int width,int height)581 omap4_hwc_setup_layer_base(struct dss2_ovl_cfg *oc, int index, int format, int blended, int width, int height)
582 {
583     unsigned int bits_per_pixel;
584 
585     /* YUV2RGB conversion */
586     const struct omap_dss_cconv_coefs ctbl_bt601_5 = {
587         298,  409,    0,  298, -208, -100,  298,    0,  517, 0,
588     };
589 
590     /* convert color format */
591     switch (format) {
592     case HAL_PIXEL_FORMAT_RGBA_8888:
593     case HAL_PIXEL_FORMAT_BGRA_8888:
594         oc->color_mode = OMAP_DSS_COLOR_ARGB32;
595         bits_per_pixel = 32;
596         if (blended)
597                 break;
598 
599     case HAL_PIXEL_FORMAT_RGBX_8888:
600     case HAL_PIXEL_FORMAT_BGRX_8888:
601         oc->color_mode = OMAP_DSS_COLOR_RGB24U;
602         bits_per_pixel = 32;
603         break;
604 
605     case HAL_PIXEL_FORMAT_RGB_565:
606         oc->color_mode = OMAP_DSS_COLOR_RGB16;
607         bits_per_pixel = 16;
608         break;
609 
610     case HAL_PIXEL_FORMAT_TI_NV12:
611     case HAL_PIXEL_FORMAT_TI_NV12_1D:
612         oc->color_mode = OMAP_DSS_COLOR_NV12;
613         bits_per_pixel = 8;
614         oc->cconv = ctbl_bt601_5;
615         break;
616 
617     default:
618         /* Should have been filtered out */
619         ALOGV("Unsupported pixel format");
620         return;
621     }
622 
623     oc->width = width;
624     oc->height = height;
625     oc->stride = ALIGN(width, HW_ALIGN) * bits_per_pixel / 8;
626 
627     oc->enabled = 1;
628     oc->global_alpha = 255;
629     oc->zorder = index;
630     oc->ix = 0;
631 
632     /* defaults for SGX framebuffer renders */
633     oc->crop.w = oc->win.w = width;
634     oc->crop.h = oc->win.h = height;
635 
636     /* for now interlacing and vc1 info is not supplied */
637     oc->ilace = OMAP_DSS_ILACE_NONE;
638     oc->vc1.enable = 0;
639 }
640 
641 static void
omap4_hwc_setup_layer(omap4_hwc_device_t * hwc_dev,struct dss2_ovl_info * ovl,hwc_layer_1_t * layer,int index,int format,int width,int height)642 omap4_hwc_setup_layer(omap4_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl,
643                       hwc_layer_1_t *layer, int index,
644                       int format, int width, int height)
645 {
646     struct dss2_ovl_cfg *oc = &ovl->cfg;
647 
648     //dump_layer(layer);
649 
650     omap4_hwc_setup_layer_base(oc, index, format, is_BLENDED(layer), width, height);
651 
652     /* convert transformation - assuming 0-set config */
653     if (layer->transform & HWC_TRANSFORM_FLIP_H)
654         oc->mirror = 1;
655     if (layer->transform & HWC_TRANSFORM_FLIP_V) {
656         oc->rotation = 2;
657         oc->mirror = !oc->mirror;
658     }
659     if (layer->transform & HWC_TRANSFORM_ROT_90) {
660         oc->rotation += oc->mirror ? -1 : 1;
661         oc->rotation &= 3;
662     }
663 
664     oc->pre_mult_alpha = layer->blending == HWC_BLENDING_PREMULT;
665 
666     /* display position */
667     oc->win.x = layer->displayFrame.left;
668     oc->win.y = layer->displayFrame.top;
669     oc->win.w = WIDTH(layer->displayFrame);
670     oc->win.h = HEIGHT(layer->displayFrame);
671 
672     /* crop */
673     oc->crop.x = layer->sourceCrop.left;
674     oc->crop.y = layer->sourceCrop.top;
675     oc->crop.w = WIDTH(layer->sourceCrop);
676     oc->crop.h = HEIGHT(layer->sourceCrop);
677 }
678 
679 const float m_unit[2][3] = { { 1., 0., 0. }, { 0., 1., 0. } };
680 
m_translate(float m[2][3],int dx,int dy)681 static inline void m_translate(float m[2][3], int dx, int dy)
682 {
683     m[0][2] += dx;
684     m[1][2] += dy;
685 }
686 
m_scale1(float m[3],int from,int to)687 static inline void m_scale1(float m[3], int from, int to)
688 {
689     m[0] = m[0] * to / from;
690     m[1] = m[1] * to / from;
691     m[2] = m[2] * to / from;
692 }
693 
m_scale(float m[2][3],int x_from,int x_to,int y_from,int y_to)694 static inline void m_scale(float m[2][3], int x_from, int x_to, int y_from, int y_to)
695 {
696     m_scale1(m[0], x_from, x_to);
697     m_scale1(m[1], y_from, y_to);
698 }
699 
m_rotate(float m[2][3],int quarter_turns)700 static void m_rotate(float m[2][3], int quarter_turns)
701 {
702     if (quarter_turns & 2)
703         m_scale(m, 1, -1, 1, -1);
704     if (quarter_turns & 1) {
705         int q;
706         q = m[0][0]; m[0][0] = -m[1][0]; m[1][0] = q;
707         q = m[0][1]; m[0][1] = -m[1][1]; m[1][1] = q;
708         q = m[0][2]; m[0][2] = -m[1][2]; m[1][2] = q;
709     }
710 }
711 
m_round(float x)712 static inline int m_round(float x)
713 {
714     /* int truncates towards 0 */
715     return (int) (x < 0 ? x - 0.5 : x + 0.5);
716 }
717 
718 /*
719  * assuming xpy (xratio:yratio) original pixel ratio, calculate the adjusted width
720  * and height for a screen of xres/yres and physical size of width/height.
721  * The adjusted size is the largest that fits into the screen.
722  */
get_max_dimensions(__u32 orig_xres,__u32 orig_yres,float xpy,__u32 scr_xres,__u32 scr_yres,__u32 scr_width,__u32 scr_height,__u32 * adj_xres,__u32 * adj_yres)723 static void get_max_dimensions(__u32 orig_xres, __u32 orig_yres,
724                                float xpy,
725                                __u32 scr_xres, __u32 scr_yres,
726                                __u32 scr_width, __u32 scr_height,
727                                __u32 *adj_xres, __u32 *adj_yres)
728 {
729     /* assume full screen (largest size)*/
730     *adj_xres = scr_xres;
731     *adj_yres = scr_yres;
732 
733     /* assume 1:1 pixel ratios if none supplied */
734     if (!scr_width || !scr_height) {
735         scr_width = scr_xres;
736         scr_height = scr_yres;
737     }
738 
739     /* trim to keep aspect ratio */
740     float x_factor = orig_xres * xpy * scr_height;
741     float y_factor = orig_yres *       scr_width;
742 
743     /* allow for tolerance so we avoid scaling if framebuffer is standard size */
744     if (x_factor < y_factor * (1.f - ASPECT_RATIO_TOLERANCE))
745         *adj_xres = (__u32) (x_factor * *adj_xres / y_factor + 0.5);
746     else if (x_factor * (1.f - ASPECT_RATIO_TOLERANCE) > y_factor)
747         *adj_yres = (__u32) (y_factor * *adj_yres / x_factor + 0.5);
748 }
749 
set_ext_matrix(omap4_hwc_ext_t * ext,struct hwc_rect region)750 static void set_ext_matrix(omap4_hwc_ext_t *ext, struct hwc_rect region)
751 {
752     int orig_w = WIDTH(region);
753     int orig_h = HEIGHT(region);
754     float xpy = ext->lcd_xpy;
755 
756     /* reorientation matrix is:
757        m = (center-from-target-center) * (scale-to-target) * (mirror) * (rotate) * (center-to-original-center) */
758 
759     memcpy(ext->m, m_unit, sizeof(m_unit));
760     m_translate(ext->m, -(orig_w >> 1) - region.left, -(orig_h >> 1) - region.top);
761     m_rotate(ext->m, ext->current.rotation);
762     if (ext->current.hflip)
763         m_scale(ext->m, 1, -1, 1, 1);
764 
765     if (ext->current.rotation & 1) {
766         swap(orig_w, orig_h);
767         xpy = 1. / xpy;
768     }
769 
770     /* get target size */
771     __u32 adj_xres, adj_yres;
772     get_max_dimensions(orig_w, orig_h, xpy,
773                        ext->xres, ext->yres, ext->width, ext->height,
774                        &adj_xres, &adj_yres);
775 
776     m_scale(ext->m, orig_w, adj_xres, orig_h, adj_yres);
777     m_translate(ext->m, ext->xres >> 1, ext->yres >> 1);
778 }
779 
780 static int
crop_to_rect(struct dss2_ovl_cfg * cfg,struct hwc_rect vis_rect)781 crop_to_rect(struct dss2_ovl_cfg *cfg, struct hwc_rect vis_rect)
782 {
783     struct {
784         int xy[2];
785         int wh[2];
786     } crop, win;
787     struct {
788         int lt[2];
789         int rb[2];
790     } vis;
791     win.xy[0] = cfg->win.x; win.xy[1] = cfg->win.y;
792     win.wh[0] = cfg->win.w; win.wh[1] = cfg->win.h;
793     crop.xy[0] = cfg->crop.x; crop.xy[1] = cfg->crop.y;
794     crop.wh[0] = cfg->crop.w; crop.wh[1] = cfg->crop.h;
795     vis.lt[0] = vis_rect.left; vis.lt[1] = vis_rect.top;
796     vis.rb[0] = vis_rect.right; vis.rb[1] = vis_rect.bottom;
797 
798     int c, swap = cfg->rotation & 1;
799 
800     /* align crop window with display coordinates */
801     if (swap)
802         crop.xy[1] -= (crop.wh[1] = -crop.wh[1]);
803     if (cfg->rotation & 2)
804         crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]);
805     if ((!cfg->mirror) ^ !(cfg->rotation & 2))
806         crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]);
807 
808     for (c = 0; c < 2; c++) {
809         /* see if complete buffer is outside the vis or it is
810           fully cropped or scaled to 0 */
811         if (win.wh[c] <= 0 || vis.rb[c] <= vis.lt[c] ||
812             win.xy[c] + win.wh[c] <= vis.lt[c] ||
813             win.xy[c] >= vis.rb[c] ||
814             !crop.wh[c ^ swap])
815             return -ENOENT;
816 
817         /* crop left/top */
818         if (win.xy[c] < vis.lt[c]) {
819             /* correction term */
820             int a = (vis.lt[c] - win.xy[c]) * crop.wh[c ^ swap] / win.wh[c];
821             crop.xy[c ^ swap] += a;
822             crop.wh[c ^ swap] -= a;
823             win.wh[c] -= vis.lt[c] - win.xy[c];
824             win.xy[c] = vis.lt[c];
825         }
826         /* crop right/bottom */
827         if (win.xy[c] + win.wh[c] > vis.rb[c]) {
828             crop.wh[c ^ swap] = crop.wh[c ^ swap] * (vis.rb[c] - win.xy[c]) / win.wh[c];
829             win.wh[c] = vis.rb[c] - win.xy[c];
830         }
831 
832         if (!crop.wh[c ^ swap] || !win.wh[c])
833             return -ENOENT;
834     }
835 
836     /* realign crop window to buffer coordinates */
837     if (cfg->rotation & 2)
838         crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]);
839     if ((!cfg->mirror) ^ !(cfg->rotation & 2))
840         crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]);
841     if (swap)
842         crop.xy[1] -= (crop.wh[1] = -crop.wh[1]);
843 
844     cfg->win.x = win.xy[0]; cfg->win.y = win.xy[1];
845     cfg->win.w = win.wh[0]; cfg->win.h = win.wh[1];
846     cfg->crop.x = crop.xy[0]; cfg->crop.y = crop.xy[1];
847     cfg->crop.w = crop.wh[0]; cfg->crop.h = crop.wh[1];
848 
849     return 0;
850 }
851 
852 static void
omap4_hwc_apply_transform(float transform[2][3],struct dss2_ovl_cfg * oc)853 omap4_hwc_apply_transform(float transform[2][3],struct dss2_ovl_cfg *oc)
854 {
855     float x, y, w, h;
856 
857     /* display position */
858     x = transform[0][0] * oc->win.x + transform[0][1] * oc->win.y + transform[0][2];
859     y = transform[1][0] * oc->win.x + transform[1][1] * oc->win.y + transform[1][2];
860     w = transform[0][0] * oc->win.w + transform[0][1] * oc->win.h;
861     h = transform[1][0] * oc->win.w + transform[1][1] * oc->win.h;
862     oc->win.x = m_round(w > 0 ? x : x + w);
863     oc->win.y = m_round(h > 0 ? y : y + h);
864     oc->win.w = m_round(w > 0 ? w : -w);
865     oc->win.h = m_round(h > 0 ? h : -h);
866 }
867 
868 static void
omap4_hwc_adjust_ext_layer(omap4_hwc_ext_t * ext,struct dss2_ovl_info * ovl)869 omap4_hwc_adjust_ext_layer(omap4_hwc_ext_t *ext, struct dss2_ovl_info *ovl)
870 {
871     struct dss2_ovl_cfg *oc = &ovl->cfg;
872 
873     /* crop to clone region if mirroring */
874     if (!ext->current.docking &&
875         crop_to_rect(&ovl->cfg, ext->mirror_region) != 0) {
876         ovl->cfg.enabled = 0;
877         return;
878     }
879 
880     omap4_hwc_apply_transform(ext->m, oc);
881 
882     /* combining transformations: F^a*R^b*F^i*R^j = F^(a+b)*R^(j+b*(-1)^i), because F*R = R^(-1)*F */
883     oc->rotation += (oc->mirror ? -1 : 1) * ext->current.rotation;
884     oc->rotation &= 3;
885     if (ext->current.hflip)
886         oc->mirror = !oc->mirror;
887 }
888 
889 static struct dsscomp_platform_info limits;
890 
891 static void
omap4_hwc_adjust_primary_display_layer(omap4_hwc_device_t * hwc_dev,struct dss2_ovl_info * ovl)892 omap4_hwc_adjust_primary_display_layer(omap4_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl)
893 {
894     struct dss2_ovl_cfg *oc = &ovl->cfg;
895 
896     if (crop_to_rect(&ovl->cfg, hwc_dev->primary_region) != 0) {
897         ovl->cfg.enabled = 0;
898         return;
899     }
900 
901     omap4_hwc_apply_transform(hwc_dev->primary_m, oc);
902 
903     /* combining transformations: F^a*R^b*F^i*R^j = F^(a+b)*R^(j+b*(-1)^i), because F*R = R^(-1)*F */
904     oc->rotation += (oc->mirror ? -1 : 1) * hwc_dev->primary_rotation;
905     oc->rotation &= 3;
906 }
907 
omap4_hwc_can_scale(__u32 src_w,__u32 src_h,__u32 dst_w,__u32 dst_h,int is_2d,struct dsscomp_display_info * dis,struct dsscomp_platform_info * limits,__u32 pclk,void * handle)908 static int omap4_hwc_can_scale(__u32 src_w, __u32 src_h, __u32 dst_w, __u32 dst_h, int is_2d,
909                                struct dsscomp_display_info *dis, struct dsscomp_platform_info *limits,
910                                __u32 pclk, void *handle)
911 {
912     __u32 fclk = limits->fclk / 1000;
913     __u32 min_src_w = DIV_ROUND_UP(src_w, is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d);
914     __u32 min_src_h = DIV_ROUND_UP(src_h, is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d);
915 
916     /* ERRATAs */
917     /* cannot render 1-width layers on DSI video mode panels - we just disallow all 1-width LCD layers */
918     if (dis->channel != OMAP_DSS_CHANNEL_DIGIT && dst_w < limits->min_width)
919         return 0;
920 
921     /* NOTE: no support for checking YUV422 layers that are tricky to scale */
922 
923     /* FIXME: limit vertical downscale well below theoretical limit as we saw display artifacts */
924     if (dst_h < src_h / 4)
925         return 0;
926 
927     /* max downscale */
928     if (dst_h * limits->max_downscale < min_src_h)
929         return 0;
930 
931     /* for manual panels pclk is 0, and there are no pclk based scaling limits */
932     if (!pclk)
933         return !(dst_w < src_w / limits->max_downscale / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d));
934 
935     /* :HACK: limit horizontal downscale well below theoretical limit as we saw display artifacts */
936     if (dst_w * 4 < src_w)
937         return 0;
938 
939     if (handle)
940         if (get_rgb_bpp(handle) == 32 && src_w > 1280 && dst_w * 3 < src_w)
941             return 0;
942 
943     /* max horizontal downscale is 4, or the fclk/pixclk */
944     if (fclk > pclk * limits->max_downscale)
945         fclk = pclk * limits->max_downscale;
946     /* for small parts, we need to use integer fclk/pixclk */
947     if (src_w < limits->integer_scale_ratio_limit)
948         fclk = fclk / pclk * pclk;
949     if ((__u32) dst_w * fclk < min_src_w * pclk)
950         return 0;
951 
952     return 1;
953 }
954 
omap4_hwc_can_scale_layer(omap4_hwc_device_t * hwc_dev,hwc_layer_1_t * layer,IMG_native_handle_t * handle)955 static int omap4_hwc_can_scale_layer(omap4_hwc_device_t *hwc_dev, hwc_layer_1_t *layer, IMG_native_handle_t *handle)
956 {
957     int src_w = WIDTH(layer->sourceCrop);
958     int src_h = HEIGHT(layer->sourceCrop);
959     int dst_w = WIDTH(layer->displayFrame);
960     int dst_h = HEIGHT(layer->displayFrame);
961 
962     /* account for 90-degree rotation */
963     if (layer->transform & HWC_TRANSFORM_ROT_90)
964         swap(src_w, src_h);
965 
966     /* NOTE: layers should be able to be scaled externally since
967        framebuffer is able to be scaled on selected external resolution */
968     return omap4_hwc_can_scale(src_w, src_h, dst_w, dst_h, is_NV12(handle), &hwc_dev->fb_dis, &limits,
969                                hwc_dev->fb_dis.timings.pixel_clock, handle);
970 }
971 
omap4_hwc_is_valid_layer(omap4_hwc_device_t * hwc_dev,hwc_layer_1_t * layer,IMG_native_handle_t * handle)972 static int omap4_hwc_is_valid_layer(omap4_hwc_device_t *hwc_dev,
973                                     hwc_layer_1_t *layer,
974                                     IMG_native_handle_t *handle)
975 {
976     /* Skip layers are handled by SF */
977     if ((layer->flags & HWC_SKIP_LAYER) || !handle)
978         return 0;
979 
980     if (!omap4_hwc_is_valid_format(handle->iFormat))
981         return 0;
982 
983     /* 1D buffers: no transform, must fit in TILER slot */
984     if (!is_NV12(handle)) {
985         if (layer->transform)
986             return 0;
987         if (mem1d(handle) > limits.tiler1d_slot_size)
988             return 0;
989     }
990 
991     return omap4_hwc_can_scale_layer(hwc_dev, layer, handle);
992 }
993 
add_scaling_score(__u32 score,__u32 xres,__u32 yres,__u32 refresh,__u32 ext_xres,__u32 ext_yres,__u32 mode_xres,__u32 mode_yres,__u32 mode_refresh)994 static __u32 add_scaling_score(__u32 score,
995                                __u32 xres, __u32 yres, __u32 refresh,
996                                __u32 ext_xres, __u32 ext_yres,
997                                __u32 mode_xres, __u32 mode_yres, __u32 mode_refresh)
998 {
999     __u32 area = xres * yres;
1000     __u32 ext_area = ext_xres * ext_yres;
1001     __u32 mode_area = mode_xres * mode_yres;
1002 
1003     /* prefer to upscale (1% tolerance) [0..1] (insert after 1st bit) */
1004     int upscale = (ext_xres >= xres * 99 / 100 && ext_yres >= yres * 99 / 100);
1005     score = (((score & ~1) | upscale) << 1) | (score & 1);
1006 
1007     /* pick minimum scaling [0..16] */
1008     if (ext_area > area)
1009         score = (score << 5) | (16 * area / ext_area);
1010     else
1011         score = (score << 5) | (16 * ext_area / area);
1012 
1013     /* pick smallest leftover area [0..16] */
1014     score = (score << 5) | ((16 * ext_area + (mode_area >> 1)) / mode_area);
1015 
1016     /* adjust mode refresh rate */
1017     mode_refresh += mode_refresh % 6 == 5;
1018 
1019     /* prefer same or higher frame rate */
1020     upscale = (mode_refresh >= refresh);
1021     score = (score << 1) | upscale;
1022 
1023     /* pick closest frame rate */
1024     if (mode_refresh > refresh)
1025         score = (score << 8) | (240 * refresh / mode_refresh);
1026     else
1027         score = (score << 8) | (240 * mode_refresh / refresh);
1028 
1029     return score;
1030 }
1031 
omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t * hwc_dev,__u32 xres,__u32 yres,float xpy)1032 static int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres, __u32 yres,
1033                                         float xpy)
1034 {
1035     int dis_ix = hwc_dev->on_tv ? 0 : 1;
1036     int forced_preferred_mode = 0;
1037 
1038     struct _qdis {
1039         struct dsscomp_display_info dis;
1040         struct dsscomp_videomode modedb[32];
1041     } d = { .dis = { .ix = dis_ix } };
1042     omap4_hwc_ext_t *ext = &hwc_dev->ext;
1043 
1044     d.dis.modedb_len = sizeof(d.modedb) / sizeof(*d.modedb);
1045     int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &d);
1046     if (ret)
1047         return ret;
1048 
1049     if (d.dis.timings.x_res * d.dis.timings.y_res == 0 ||
1050         xres * yres == 0)
1051         return -EINVAL;
1052 
1053     __u32 i, best = ~0, best_score = 0;
1054     ext->width = d.dis.width_in_mm;
1055     ext->height = d.dis.height_in_mm;
1056     ext->xres = d.dis.timings.x_res;
1057     ext->yres = d.dis.timings.y_res;
1058 
1059     /* use VGA external resolution as default */
1060     if (!ext->xres || !ext->yres) {
1061         ext->xres = 640;
1062         ext->yres = 480;
1063     }
1064 
1065     /*
1066      * copy the xres/yres from the preferred mode
1067      */
1068     __u32 preferred_mode_xres = 0;
1069     __u32 preferred_mode_yres = 0;
1070 
1071     char value[PROPERTY_VALUE_MAX];
1072     if (property_get("persist.hwc.preferred_mode", value, "") <= 0 ||
1073         sscanf(value, "%dx%d", &preferred_mode_xres,
1074                &preferred_mode_yres) != 2) {
1075         for (i = 0; i < d.dis.modedb_len; i++) {
1076             if (d.modedb[i].flag & FB_FLAG_PREFERRED) {
1077                 preferred_mode_xres = d.modedb[i].xres;
1078                 preferred_mode_yres = d.modedb[i].yres;
1079                 ALOGD("preferred mode %d: xres %u yres %u\n",
1080                     i, d.modedb[i].xres, d.modedb[i].yres);
1081                 break;
1082             }
1083         }
1084     } else {
1085         ALOGD("forced preferred mode xres %u yres %u\n",
1086              preferred_mode_xres, preferred_mode_yres);
1087         forced_preferred_mode = 1;
1088     }
1089 
1090     __u32 ext_fb_xres, ext_fb_yres;
1091     for (i = 0; i < d.dis.modedb_len; i++) {
1092         __u32 score = 0;
1093         __u32 mode_xres = d.modedb[i].xres;
1094         __u32 mode_yres = d.modedb[i].yres;
1095         __u32 ext_width = d.dis.width_in_mm;
1096         __u32 ext_height = d.dis.height_in_mm;
1097 
1098         /* reject it because the hw says it can't actually use this mode */
1099         if ((d.modedb[i].flag & FB_FLAG_HW_CAPABLE) == 0)
1100             continue;
1101 
1102         if (d.modedb[i].vmode & FB_VMODE_INTERLACED)
1103             mode_yres /= 2;
1104 
1105         if (d.modedb[i].flag & FB_FLAG_RATIO_4_3) {
1106             ext_width = 4;
1107             ext_height = 3;
1108         } else if (d.modedb[i].flag & FB_FLAG_RATIO_16_9) {
1109             ext_width = 16;
1110             ext_height = 9;
1111         }
1112 
1113         if (!mode_xres || !mode_yres)
1114             continue;
1115 
1116         get_max_dimensions(xres, yres, xpy, mode_xres, mode_yres,
1117                            ext_width, ext_height, &ext_fb_xres, &ext_fb_yres);
1118 
1119         /* we need to ensure that even TILER2D buffers can be scaled */
1120         if (!d.modedb[i].pixclock ||
1121             (d.modedb[i].vmode & ~FB_VMODE_INTERLACED) ||
1122             !omap4_hwc_can_scale(xres, yres, ext_fb_xres, ext_fb_yres,
1123                                  1, &d.dis, &limits,
1124                                  1000000000 / d.modedb[i].pixclock, NULL))
1125             continue;
1126 
1127         /* prefer CEA modes */
1128         if (d.modedb[i].flag & (FB_FLAG_RATIO_4_3 | FB_FLAG_RATIO_16_9))
1129             score += 1;
1130 
1131         /* prefer modes that match the preferred mode's resolution */
1132         if (d.modedb[i].xres == preferred_mode_xres &&
1133             d.modedb[i].yres == preferred_mode_yres) {
1134             if (forced_preferred_mode)
1135                 score += 10;
1136             else
1137                 score += 1;
1138         }
1139 
1140         /* prefer modes the kernel has hinted is the correct mode */
1141         if (!forced_preferred_mode && (d.modedb[i].flag & FB_FLAG_PREFERRED))
1142             score += 1;
1143 
1144         /* prefer the same mode as we use for mirroring to avoid mode change */
1145         score = (score << 1) | (i == ~ext->mirror_mode && ext->avoid_mode_change);
1146 
1147         score = add_scaling_score(score, xres, yres, 60, ext_fb_xres, ext_fb_yres,
1148                                   mode_xres, mode_yres, d.modedb[i].refresh ? : 1);
1149 
1150         ALOGD("#%d: %dx%d %dHz flag 0x%x vmode 0x%x, score 0x%x",
1151              i, mode_xres, mode_yres,
1152              d.modedb[i].refresh, d.modedb[i].flag, d.modedb[i].vmode,
1153              score);
1154 
1155         if (debug)
1156             ALOGD("  score=0x%x adj.res=%dx%d", score, ext_fb_xres, ext_fb_yres);
1157         if (best_score < score) {
1158             ext->width = ext_width;
1159             ext->height = ext_height;
1160             ext->xres = mode_xres;
1161             ext->yres = mode_yres;
1162             best = i;
1163             best_score = score;
1164         }
1165     }
1166     if (~best) {
1167         struct dsscomp_setup_display_data sdis = { .ix = dis_ix, };
1168         sdis.mode = d.dis.modedb[best];
1169         ALOGD("picking #%d", best);
1170         /* only reconfigure on change */
1171         if (ext->last_mode != ~best) {
1172             /* set a property that apps that care (e.g. YouTube) can use
1173              * to determine whether or not to stream lower resolution
1174              * videos when the hdmi mode is < 1080p.
1175              * otherwise, they'd give us 1080p and we'd just scale it
1176              * down to the hdmi mode res.  UI apps are always going
1177              * to draw at 1080p and we'll scale down because the
1178              * system can't support dynamic dpi changes.
1179              */
1180             char display[PROPERTY_VALUE_MAX];
1181             snprintf(display, sizeof(display), "%dx%d",
1182                      d.modedb[best].xres, d.modedb[best].yres);
1183             ALOGD("setting property sys.display-size to %s", display);
1184             property_set("sys.display-size", display);
1185 
1186             ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPLAY, &sdis);
1187         }
1188         ext->last_mode = ~best;
1189     } else {
1190         __u32 ext_width = d.dis.width_in_mm;
1191         __u32 ext_height = d.dis.height_in_mm;
1192         __u32 ext_fb_xres, ext_fb_yres;
1193 
1194         get_max_dimensions(xres, yres, xpy, d.dis.timings.x_res, d.dis.timings.y_res,
1195                            ext_width, ext_height, &ext_fb_xres, &ext_fb_yres);
1196         if (!d.dis.timings.pixel_clock ||
1197             !omap4_hwc_can_scale(xres, yres, ext_fb_xres, ext_fb_yres,
1198                                  1, &d.dis, &limits,
1199                                  d.dis.timings.pixel_clock, NULL)) {
1200             ALOGW("DSS scaler cannot support HDMI cloning");
1201             return -1;
1202         }
1203     }
1204     ext->last_xres_used = xres;
1205     ext->last_yres_used = yres;
1206     ext->last_xpy = xpy;
1207     if (d.dis.channel == OMAP_DSS_CHANNEL_DIGIT)
1208         ext->on_tv = 1;
1209     return 0;
1210 }
1211 
gather_layer_statistics(omap4_hwc_device_t * hwc_dev,struct counts * num,hwc_display_contents_1_t * list)1212 static void gather_layer_statistics(omap4_hwc_device_t *hwc_dev, struct counts *num, hwc_display_contents_1_t *list)
1213 {
1214     unsigned int i;
1215 
1216     /* Figure out how many layers we can support via DSS */
1217     for (i = 0; list && i < list->numHwLayers; i++) {
1218         hwc_layer_1_t *layer = &list->hwLayers[i];
1219         IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
1220 
1221         layer->compositionType = HWC_FRAMEBUFFER;
1222 
1223         if (omap4_hwc_is_valid_layer(hwc_dev, layer, handle)) {
1224             num->possible_overlay_layers++;
1225 
1226             /* NV12 layers can only be rendered on scaling overlays */
1227             if (scaled(layer) || is_NV12(handle) || hwc_dev->primary_transform)
1228                 num->scaled_layers++;
1229 
1230             if (is_BGR(handle))
1231                 num->BGR++;
1232             else if (is_RGB(handle))
1233                 num->RGB++;
1234             else if (is_NV12(handle))
1235                 num->NV12++;
1236 
1237             if (dockable(layer))
1238                 num->dockable++;
1239 
1240             if (is_protected(layer))
1241                 num->protected++;
1242 
1243             num->mem += mem1d(handle);
1244 
1245             if (is_large_rgb32_layer(layer))
1246                 num->large_rgb32_layers++;
1247         }
1248     }
1249     hwc_dev->stats = *num;
1250 }
1251 
decide_supported_cloning(omap4_hwc_device_t * hwc_dev,struct counts * num)1252 static void decide_supported_cloning(omap4_hwc_device_t *hwc_dev, struct counts *num)
1253 {
1254     omap4_hwc_ext_t *ext = &hwc_dev->ext;
1255     int nonscaling_ovls = NUM_NONSCALING_OVERLAYS;
1256     num->max_hw_overlays = MAX_HW_OVERLAYS;
1257 
1258     /*
1259      * We cannot atomically switch overlays from one display to another.  First, they
1260      * have to be disabled, and the disabling has to take effect on the current display.
1261      * We keep track of the available number of overlays here.
1262      */
1263     if (ext->dock.enabled && !(ext->mirror.enabled && !(num->dockable || ext->force_dock))) {
1264         /* some overlays may already be used by the external display, so we account for this */
1265 
1266         /* reserve just a video pipeline for HDMI if docking */
1267         hwc_dev->ext_ovls = (num->dockable || ext->force_dock) ? 1 : 0;
1268         num->max_hw_overlays -= max(hwc_dev->ext_ovls, hwc_dev->last_ext_ovls);
1269 
1270         /* use mirroring transform if we are auto-switching to docking mode while mirroring*/
1271         if (ext->mirror.enabled) {
1272             ext->current = ext->mirror;
1273             ext->current.docking = 1;
1274         } else {
1275             ext->current = ext->dock;
1276         }
1277     } else if (ext->mirror.enabled) {
1278         /*
1279          * otherwise, manage just from half the pipelines.  NOTE: there is
1280          * no danger of having used too many overlays for external display here.
1281          */
1282 
1283         num->max_hw_overlays >>= 1;
1284         nonscaling_ovls >>= 1;
1285         hwc_dev->ext_ovls = MAX_HW_OVERLAYS - num->max_hw_overlays;
1286         ext->current = ext->mirror;
1287     } else {
1288         num->max_hw_overlays -= hwc_dev->last_ext_ovls;
1289         hwc_dev->ext_ovls = 0;
1290         ext->current.enabled = 0;
1291     }
1292 
1293     /*
1294      * :TRICKY: We may not have enough overlays on the external display.  We "reserve" them
1295      * here to figure out if mirroring is supported, but may not do mirroring for the first
1296      * frame while the overlays required for it are cleared.
1297      */
1298     hwc_dev->ext_ovls_wanted = hwc_dev->ext_ovls;
1299     hwc_dev->ext_ovls = min(MAX_HW_OVERLAYS - hwc_dev->last_int_ovls, hwc_dev->ext_ovls);
1300 
1301     /* if mirroring, we are limited by both internal and external overlays.  However,
1302        ext_ovls is always <= MAX_HW_OVERLAYS / 2 <= max_hw_overlays */
1303     if (!num->protected && hwc_dev->ext_ovls && ext->current.enabled && !ext->current.docking)
1304         num->max_hw_overlays = hwc_dev->ext_ovls;
1305 
1306     /* If FB is not same resolution as LCD don't use GFX pipe line*/
1307     if (hwc_dev->primary_transform) {
1308         num->max_hw_overlays -= NUM_NONSCALING_OVERLAYS;
1309         num->max_scaling_overlays = num->max_hw_overlays;
1310     } else
1311         num->max_scaling_overlays = num->max_hw_overlays - nonscaling_ovls;
1312 }
1313 
1314 /* how many large layers can be composited by the DSS */
1315 static const unsigned int MAX_DSS_LARGE_LAYERS = 4;
1316 
can_dss_render_all(omap4_hwc_device_t * hwc_dev,struct counts * num)1317 static int can_dss_render_all(omap4_hwc_device_t *hwc_dev, struct counts *num)
1318 {
1319     omap4_hwc_ext_t *ext = &hwc_dev->ext;
1320     int on_tv = hwc_dev->on_tv || (ext->on_tv && ext->current.enabled);
1321     int tform = ext->current.enabled && (ext->current.rotation || ext->current.hflip);
1322 
1323     return  !hwc_dev->force_sgx &&
1324             /* must have at least one layer if using composition bypass to get sync object */
1325             num->possible_overlay_layers &&
1326             num->possible_overlay_layers <= num->max_hw_overlays &&
1327             num->possible_overlay_layers == num->composited_layers &&
1328             num->scaled_layers <= num->max_scaling_overlays &&
1329             num->NV12 <= num->max_scaling_overlays &&
1330             /* fits into TILER slot */
1331             num->mem <= limits.tiler1d_slot_size &&
1332             /* we cannot clone non-NV12 transformed layers */
1333             (!tform || (num->NV12 == num->possible_overlay_layers) ||
1334             (num->NV12 && ext->current.docking)) &&
1335             /* HDMI cannot display BGR */
1336             (num->BGR == 0 || (num->RGB == 0 && !on_tv) || !hwc_dev->flags_rgb_order) &&
1337             /* current hardware can only handle a limited number of 'large' RGB32 layers */
1338             num->large_rgb32_layers <= MAX_DSS_LARGE_LAYERS;
1339 }
1340 
can_dss_render_layer(omap4_hwc_device_t * hwc_dev,hwc_layer_1_t * layer)1341 static inline int can_dss_render_layer(omap4_hwc_device_t *hwc_dev,
1342             hwc_layer_1_t *layer)
1343 {
1344     IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
1345 
1346     omap4_hwc_ext_t *ext = &hwc_dev->ext;
1347     int cloning = ext->current.enabled && (!ext->current.docking || (handle!=NULL ? dockable(layer) : 0));
1348     int on_tv = hwc_dev->on_tv || (ext->on_tv && cloning);
1349     int tform = cloning && (ext->current.rotation || ext->current.hflip);
1350 
1351     return omap4_hwc_is_valid_layer(hwc_dev, layer, handle) &&
1352            /* cannot rotate non-NV12 layers on external display */
1353            (!tform || is_NV12(handle)) &&
1354            /* skip non-NV12 layers if also using SGX (if nv12_only flag is set) */
1355            (!hwc_dev->flags_nv12_only || (!hwc_dev->use_sgx || is_NV12(handle))) &&
1356            /* make sure RGB ordering is consistent (if rgb_order flag is set) */
1357            (!(hwc_dev->swap_rb ? is_RGB(handle) : is_BGR(handle)) ||
1358             !hwc_dev->flags_rgb_order) &&
1359            /* TV can only render RGB */
1360            !(on_tv && is_BGR(handle));
1361 }
1362 
display_area(struct dss2_ovl_info * o)1363 static inline int display_area(struct dss2_ovl_info *o)
1364 {
1365     return o->cfg.win.w * o->cfg.win.h;
1366 }
1367 
clone_layer(omap4_hwc_device_t * hwc_dev,int ix)1368 static int clone_layer(omap4_hwc_device_t *hwc_dev, int ix) {
1369     struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
1370     omap4_hwc_ext_t *ext = &hwc_dev->ext;
1371     int ext_ovl_ix = dsscomp->num_ovls - hwc_dev->post2_layers;
1372     struct dss2_ovl_info *o = &dsscomp->ovls[dsscomp->num_ovls];
1373 
1374     if (dsscomp->num_ovls >= MAX_HW_OVERLAYS) {
1375         ALOGE("**** cannot clone layer #%d. using all %d overlays.", ix, dsscomp->num_ovls);
1376         return -EBUSY;
1377     }
1378 
1379     memcpy(o, dsscomp->ovls + ix, sizeof(*o));
1380 
1381     /* reserve overlays at end for other display */
1382     o->cfg.ix = MAX_HW_OVERLAYS - 1 - ext_ovl_ix;
1383     o->cfg.mgr_ix = 1;
1384     /*
1385     * Here the assumption is that overlay0 is the one attached to FB.
1386     * Hence this clone_layer call is for FB cloning (provided use_sgx is true).
1387     */
1388     /* For the external displays whose transform is the same as
1389     * that of primary display, ion_handles would be NULL hence
1390     * the below logic doesn't execute.
1391     */
1392     if (ix == 0 && hwc_dev->ion_handles[sync_id%2] && hwc_dev->use_sgx) {
1393         o->addressing = OMAP_DSS_BUFADDR_ION;
1394         o->ba = (int)hwc_dev->ion_handles[sync_id%2];
1395     } else {
1396         o->addressing = OMAP_DSS_BUFADDR_OVL_IX;
1397         o->ba = ix;
1398     }
1399 
1400     /* use distinct z values (to simplify z-order checking) */
1401     o->cfg.zorder += hwc_dev->post2_layers;
1402 
1403     omap4_hwc_adjust_ext_layer(&hwc_dev->ext, o);
1404     dsscomp->num_ovls++;
1405     return 0;
1406 }
1407 
clone_external_layer(omap4_hwc_device_t * hwc_dev,int ix)1408 static int clone_external_layer(omap4_hwc_device_t *hwc_dev, int ix) {
1409     struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
1410     omap4_hwc_ext_t *ext = &hwc_dev->ext;
1411 
1412     /* mirror only 1 external layer */
1413     struct dss2_ovl_info *o = &dsscomp->ovls[ix];
1414 
1415     /* full screen video after transformation */
1416     __u32 xres = o->cfg.crop.w, yres = o->cfg.crop.h;
1417     if ((ext->current.rotation + o->cfg.rotation) & 1)
1418         swap(xres, yres);
1419     float xpy = ext->lcd_xpy * o->cfg.win.w / o->cfg.win.h;
1420     if (o->cfg.rotation & 1)
1421         xpy = o->cfg.crop.h / xpy / o->cfg.crop.w;
1422     else
1423         xpy = o->cfg.crop.h * xpy / o->cfg.crop.w;
1424     if (ext->current.rotation & 1)
1425         xpy = 1. / xpy;
1426 
1427     /* adjust hdmi mode based on resolution */
1428     if (xres != ext->last_xres_used ||
1429         yres != ext->last_yres_used ||
1430         xpy < ext->last_xpy * (1.f - ASPECT_RATIO_TOLERANCE) ||
1431         xpy * (1.f - ASPECT_RATIO_TOLERANCE) > ext->last_xpy) {
1432         ALOGD("set up HDMI for %d*%d\n", xres, yres);
1433         if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, xpy)) {
1434             ext->current.enabled = 0;
1435             return -ENODEV;
1436         }
1437     }
1438 
1439     struct hwc_rect region = {
1440         .left = o->cfg.win.x, .top = o->cfg.win.y,
1441         .right = o->cfg.win.x + o->cfg.win.w,
1442         .bottom = o->cfg.win.y + o->cfg.win.h
1443     };
1444     set_ext_matrix(&hwc_dev->ext, region);
1445 
1446     return clone_layer(hwc_dev, ix);
1447 }
1448 
setup_mirroring(omap4_hwc_device_t * hwc_dev)1449 static int setup_mirroring(omap4_hwc_device_t *hwc_dev)
1450 {
1451     omap4_hwc_ext_t *ext = &hwc_dev->ext;
1452 
1453     __u32 xres = WIDTH(ext->mirror_region);
1454     __u32 yres = HEIGHT(ext->mirror_region);
1455     if (ext->current.rotation & 1)
1456        swap(xres, yres);
1457     if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, ext->lcd_xpy))
1458         return -ENODEV;
1459     set_ext_matrix(ext, ext->mirror_region);
1460     return 0;
1461 }
1462 
1463 /*
1464  * We're using "implicit" synchronization, so make sure we aren't passing any
1465  * sync object descriptors around.
1466  */
check_sync_fds(size_t numDisplays,hwc_display_contents_1_t ** displays)1467 static void check_sync_fds(size_t numDisplays, hwc_display_contents_1_t** displays)
1468 {
1469     //ALOGD("checking sync FDs");
1470     unsigned int i, j;
1471     for (i = 0; i < numDisplays; i++) {
1472         hwc_display_contents_1_t* list = displays[i];
1473         if (list->retireFenceFd >= 0) {
1474             ALOGW("retireFenceFd[%u] was %d", i, list->retireFenceFd);
1475             list->retireFenceFd = -1;
1476         }
1477 
1478         for (j = 0; j < list->numHwLayers; j++) {
1479             hwc_layer_1_t* layer = &list->hwLayers[j];
1480             if (layer->acquireFenceFd >= 0) {
1481                 ALOGW("acquireFenceFd[%u][%u] was %d, closing", i, j, layer->acquireFenceFd);
1482                 close(layer->acquireFenceFd);
1483                 layer->acquireFenceFd = -1;
1484             }
1485             if (layer->releaseFenceFd >= 0) {
1486                 ALOGW("releaseFenceFd[%u][%u] was %d", i, j, layer->releaseFenceFd);
1487                 layer->releaseFenceFd = -1;
1488             }
1489         }
1490     }
1491 }
1492 
blit_reset(omap4_hwc_device_t * hwc_dev,int flags)1493 static void blit_reset(omap4_hwc_device_t *hwc_dev, int flags)
1494 {
1495     hwc_dev->blit_flags = 0;
1496     hwc_dev->blit_num = 0;
1497     hwc_dev->post2_blit_buffers = 0;
1498     hwc_dev->comp_data.blit_data.rgz_items = 0;
1499 
1500     /* We want to maintain the rgz dirty region data if there are no geometry changes */
1501     if (flags & HWC_GEOMETRY_CHANGED)
1502         rgz_release(&grgz);
1503 }
1504 
blit_layers(omap4_hwc_device_t * hwc_dev,hwc_display_contents_1_t * list,int bufoff)1505 static int blit_layers(omap4_hwc_device_t *hwc_dev, hwc_display_contents_1_t *list, int bufoff)
1506 {
1507     /* Do not blit if this frame will be composed entirely by the GPU */
1508     if (!list || hwc_dev->force_sgx)
1509         goto err_out;
1510 
1511     int rgz_in_op;
1512     int rgz_out_op;
1513 
1514     switch (hwc_dev->blt_mode) {
1515         case BLTMODE_PAINT:
1516             rgz_in_op = RGZ_IN_HWCCHK;
1517             rgz_out_op = RGZ_OUT_BVCMD_PAINT;
1518             break;
1519         case BLTMODE_REGION:
1520         default:
1521             rgz_in_op = RGZ_IN_HWC;
1522             rgz_out_op = RGZ_OUT_BVCMD_REGION;
1523             break;
1524     }
1525 
1526     rgz_in_params_t in = {
1527         .op = rgz_in_op,
1528         .data = {
1529             .hwc = {
1530                 .dstgeom = &gscrngeom,
1531                 .layers = list->hwLayers,
1532                 .layerno = list->numHwLayers
1533             }
1534         }
1535     };
1536 
1537     /*
1538      * This means if all the layers marked for the FRAMEBUFFER cannot be
1539      * blitted, do not blit, for e.g. SKIP layers
1540      */
1541     if (rgz_in(&in, &grgz) != RGZ_ALL)
1542         goto err_out;
1543 
1544     unsigned int i, count = 0;
1545     for (i = 0; i < list->numHwLayers; i++) {
1546         if (list->hwLayers[i].compositionType != HWC_OVERLAY) {
1547             count++;
1548         }
1549     }
1550 
1551     rgz_out_params_t out = {
1552         .op = rgz_out_op,
1553         .data = {
1554             .bvc = {
1555                 .dstgeom = &gscrngeom,
1556                 .noblend = 0,
1557             }
1558         }
1559     };
1560 
1561     if (rgz_out(&grgz, &out) != 0) {
1562         ALOGE("Failed generating blits");
1563         goto err_out;
1564     }
1565 
1566     /* This is a special situation where the regionizer decided no blits are
1567      * needed for this frame but there are blit buffers to synchronize with. Can
1568      * happen only if the regionizer is enabled otherwise it's likely a bug
1569      */
1570     if (rgz_out_op != RGZ_OUT_BVCMD_REGION && out.data.bvc.out_blits == 0 && out.data.bvc.out_nhndls > 0) {
1571         ALOGE("Regionizer invalid output blit_num %d, post2_blit_buffers %d", out.data.bvc.out_blits, out.data.bvc.out_nhndls);
1572         goto err_out;
1573     }
1574 
1575     hwc_dev->blit_flags |= HWC_BLT_FLAG_USE_FB;
1576     hwc_dev->blit_num = out.data.bvc.out_blits;
1577     hwc_dev->post2_blit_buffers = out.data.bvc.out_nhndls;
1578     for (i = 0; i < hwc_dev->post2_blit_buffers; i++) {
1579         //ALOGI("blit buffers[%d] = %p", bufoff, out.data.bvc.out_hndls[i]);
1580         hwc_dev->buffers[bufoff++] = out.data.bvc.out_hndls[i];
1581     }
1582 
1583     struct rgz_blt_entry *res_blit_ops = (struct rgz_blt_entry *) out.data.bvc.cmdp;
1584     memcpy(hwc_dev->comp_data.blit_data.rgz_blts, res_blit_ops, sizeof(*res_blit_ops) * out.data.bvc.cmdlen);
1585     ALOGI_IF(debugblt, "blt struct sz %d", sizeof(*res_blit_ops) * out.data.bvc.cmdlen);
1586     ALOGE_IF(hwc_dev->blit_num != out.data.bvc.cmdlen,"blit_num != out.data.bvc.cmdlen, %d != %d", hwc_dev->blit_num, out.data.bvc.cmdlen);
1587 
1588     /* all layers will be rendered without SGX help either via DSS or blitter */
1589     for (i = 0; i < list->numHwLayers; i++) {
1590         if (list->hwLayers[i].compositionType != HWC_OVERLAY) {
1591             list->hwLayers[i].compositionType = HWC_OVERLAY;
1592             //ALOGI("blitting layer %d", i);
1593             list->hwLayers[i].hints &= ~HWC_HINT_TRIPLE_BUFFER;
1594         }
1595         list->hwLayers[i].hints &= ~HWC_HINT_CLEAR_FB;
1596     }
1597     return 1;
1598 
1599 err_out:
1600     rgz_release(&grgz);
1601     return 0;
1602 }
1603 
debug_post2(omap4_hwc_device_t * hwc_dev,int nbufs)1604 void debug_post2(omap4_hwc_device_t *hwc_dev, int nbufs)
1605 {
1606     if (!debugpost2)
1607         return;
1608     struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
1609     int i;
1610     for (i=0; i<nbufs; i++) {
1611         ALOGI("buf[%d] hndl %p", i, hwc_dev->buffers[i]);
1612     }
1613     for (i=0; i < dsscomp->num_ovls; i++) {
1614         ALOGI("ovl[%d] ba %d", i, dsscomp->ovls[i].ba);
1615     }
1616 }
1617 
free_tiler2d_buffers(omap4_hwc_device_t * hwc_dev)1618 static int free_tiler2d_buffers(omap4_hwc_device_t *hwc_dev)
1619 {
1620     int i;
1621 
1622     for (i = 0 ; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) {
1623         ion_free(hwc_dev->ion_fd, hwc_dev->ion_handles[i]);
1624         hwc_dev->ion_handles[i] = NULL;
1625     }
1626     return 0;
1627 }
1628 
allocate_tiler2d_buffers(omap4_hwc_device_t * hwc_dev)1629 static int allocate_tiler2d_buffers(omap4_hwc_device_t *hwc_dev)
1630 {
1631     int ret, i;
1632     size_t stride;
1633 
1634     if (hwc_dev->ion_fd < 0) {
1635         ALOGE("No ion fd, hence can't allocate tiler2d buffers");
1636         return -1;
1637     }
1638 
1639     for (i = 0; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) {
1640         if (hwc_dev->ion_handles[i])
1641             return 0;
1642     }
1643 
1644     for (i = 0 ; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) {
1645         ret = ion_alloc_tiler(hwc_dev->ion_fd, hwc_dev->fb_dev->base.width, hwc_dev->fb_dev->base.height,
1646                                             TILER_PIXEL_FMT_32BIT, 0, &hwc_dev->ion_handles[i], &stride);
1647         if (ret)
1648             goto handle_error;
1649 
1650         ALOGI("ion handle[%d][%p]", i, hwc_dev->ion_handles[i]);
1651     }
1652     return 0;
1653 
1654 handle_error:
1655     free_tiler2d_buffers(hwc_dev);
1656     return -1;
1657 }
1658 
omap4_hwc_prepare(struct hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)1659 static int omap4_hwc_prepare(struct hwc_composer_device_1 *dev, size_t numDisplays,
1660         hwc_display_contents_1_t** displays)
1661 {
1662     if (!numDisplays || displays == NULL) {
1663         return 0;
1664     }
1665 
1666     hwc_display_contents_1_t* list = displays[0];  // ignore displays beyond the first
1667     omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev;
1668     struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
1669     struct counts num = { .composited_layers = list ? list->numHwLayers : 0 };
1670     unsigned int i, ix;
1671 
1672     pthread_mutex_lock(&hwc_dev->lock);
1673     memset(dsscomp, 0x0, sizeof(*dsscomp));
1674     dsscomp->sync_id = sync_id++;
1675 
1676     gather_layer_statistics(hwc_dev, &num, list);
1677 
1678     decide_supported_cloning(hwc_dev, &num);
1679 
1680     /* phase 3 logic */
1681     if (can_dss_render_all(hwc_dev, &num)) {
1682         /* All layers can be handled by the DSS -- don't use SGX for composition */
1683         hwc_dev->use_sgx = 0;
1684         hwc_dev->swap_rb = num.BGR != 0;
1685     } else {
1686         /* Use SGX for composition plus first 3 layers that are DSS renderable */
1687         hwc_dev->use_sgx = 1;
1688         hwc_dev->swap_rb = is_BGR_format(hwc_dev->fb_dev->base.format);
1689     }
1690 
1691     /* setup pipes */
1692     int z = 0;
1693     int fb_z = -1;
1694     int scaled_gfx = 0;
1695     int ix_docking = -1;
1696     unsigned int big_layers = 0;
1697 
1698     int blit_all = 0;
1699     blit_reset(hwc_dev, list ? list->flags : 0);
1700 
1701     /* If the SGX is used or we are going to blit something we need a framebuffer
1702      * and a DSS pipe
1703      */
1704     int needs_fb = hwc_dev->use_sgx;
1705 
1706     if (hwc_dev->blt_policy == BLTPOLICY_ALL) {
1707         /* Check if we can blit everything */
1708         blit_all = blit_layers(hwc_dev, list, 0);
1709         if (blit_all) {
1710             needs_fb = 1;
1711             hwc_dev->use_sgx = 0;
1712         }
1713     }
1714 
1715     /* If a framebuffer is needed, begin using VID1 for DSS overlay layers,
1716      * we need GFX for FB
1717      */
1718     dsscomp->num_ovls = needs_fb ? 1 /*VID1*/ : 0 /*GFX*/;
1719 
1720     /* set up if DSS layers */
1721     unsigned int mem_used = 0;
1722     for (i = 0; list && i < list->numHwLayers && !blit_all; i++) {
1723         hwc_layer_1_t *layer = &list->hwLayers[i];
1724         IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle;
1725 
1726         if (dsscomp->num_ovls < num.max_hw_overlays &&
1727             can_dss_render_layer(hwc_dev, layer) &&
1728             (!hwc_dev->force_sgx ||
1729              /* render protected and dockable layers via DSS */
1730              is_protected(layer) ||
1731              is_upscaled_NV12(hwc_dev, layer) ||
1732              (hwc_dev->ext.current.docking && hwc_dev->ext.current.enabled && dockable(layer))) &&
1733             mem_used + mem1d(handle) <= limits.tiler1d_slot_size &&
1734             /* can't have a transparent overlay in the middle of the framebuffer stack */
1735             !(is_BLENDED(layer) && fb_z >= 0) &&
1736             /* current hardware can only handle a limited number of 'large' RGB32 layers */
1737             !(is_large_rgb32_layer(layer) && big_layers >= MAX_DSS_LARGE_LAYERS)) {
1738 
1739             /* render via DSS overlay */
1740             mem_used += mem1d(handle);
1741             layer->compositionType = HWC_OVERLAY;
1742             /*
1743              * This hint will not be used in vanilla ICS, but maybe in
1744              * JellyBean, it is useful to distinguish between blts and true
1745              * overlays
1746              */
1747             layer->hints |= HWC_HINT_TRIPLE_BUFFER;
1748 
1749             /* clear FB above all opaque layers if rendering via SGX */
1750             if (hwc_dev->use_sgx && !is_BLENDED(layer))
1751                 layer->hints |= HWC_HINT_CLEAR_FB;
1752 
1753             hwc_dev->buffers[dsscomp->num_ovls] = layer->handle;
1754 
1755             omap4_hwc_setup_layer(hwc_dev,
1756                                   &dsscomp->ovls[dsscomp->num_ovls],
1757                                   layer,
1758                                   z,
1759                                   handle->iFormat,
1760                                   handle->iWidth,
1761                                   handle->iHeight);
1762 
1763             dsscomp->ovls[dsscomp->num_ovls].cfg.ix = dsscomp->num_ovls + hwc_dev->primary_transform;
1764             dsscomp->ovls[dsscomp->num_ovls].addressing = OMAP_DSS_BUFADDR_LAYER_IX;
1765             dsscomp->ovls[dsscomp->num_ovls].ba = dsscomp->num_ovls;
1766 
1767             /* ensure GFX layer is never scaled */
1768             if ((dsscomp->num_ovls == 0) && (!hwc_dev->primary_transform)) {
1769                 scaled_gfx = scaled(layer) || is_NV12(handle);
1770             } else if (scaled_gfx && !scaled(layer) && !is_NV12(handle)) {
1771                 /* swap GFX layer with this one */
1772                 dsscomp->ovls[dsscomp->num_ovls].cfg.ix = 0;
1773                 dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls;
1774                 scaled_gfx = 0;
1775             }
1776 
1777             /* remember largest dockable layer */
1778             if (dockable(layer) &&
1779                 (ix_docking < 0 ||
1780                  display_area(&dsscomp->ovls[dsscomp->num_ovls]) > display_area(&dsscomp->ovls[ix_docking])))
1781                 ix_docking = dsscomp->num_ovls;
1782 
1783             dsscomp->num_ovls++;
1784             z++;
1785 
1786             /* record whether or not this was a 'big' RGB32 layer */
1787             if (is_large_rgb32_layer(layer)) {
1788                 big_layers++;
1789             }
1790         } else if (hwc_dev->use_sgx) {
1791             if (fb_z < 0) {
1792                 /* NOTE: we are not handling transparent cutout for now */
1793                 fb_z = z;
1794                 z++;
1795             } else {
1796                 /* move fb z-order up (by lowering dss layers) */
1797                 while (fb_z < z - 1)
1798                     dsscomp->ovls[1 + fb_z++].cfg.zorder--;
1799             }
1800         }
1801     }
1802 
1803     /* if scaling GFX (e.g. only 1 scaled surface) use a VID pipe */
1804     if (scaled_gfx)
1805         dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls;
1806 
1807     if (hwc_dev->blt_policy == BLTPOLICY_DEFAULT) {
1808         if (hwc_dev->use_sgx) {
1809             if (blit_layers(hwc_dev, list, dsscomp->num_ovls == 1 ? 0 : dsscomp->num_ovls)) {
1810                 hwc_dev->use_sgx = 0;
1811             }
1812         }
1813     }
1814 
1815     /* If the SGX is not used and there is blit data we need a framebuffer and
1816      * a DSS pipe well configured for it
1817      */
1818     if (needs_fb) {
1819         /* assign a z-layer for fb */
1820         if (fb_z < 0) {
1821             if (!hwc_dev->blt_policy != BLTPOLICY_DISABLED && num.composited_layers)
1822                 ALOGE("**** should have assigned z-layer for fb");
1823             fb_z = z++;
1824         }
1825         /*
1826          * This is needed because if we blit all we would lose the handle of
1827          * the first layer
1828          */
1829         if (hwc_dev->use_sgx) {
1830             hwc_dev->buffers[0] = NULL;
1831         }
1832         omap4_hwc_setup_layer_base(&dsscomp->ovls[0].cfg, fb_z,
1833                                    hwc_dev->fb_dev->base.format,
1834                                    1,   /* FB is always premultiplied */
1835                                    hwc_dev->fb_dev->base.width,
1836                                    hwc_dev->fb_dev->base.height);
1837         dsscomp->ovls[0].cfg.pre_mult_alpha = 1;
1838         dsscomp->ovls[0].addressing = OMAP_DSS_BUFADDR_LAYER_IX;
1839         dsscomp->ovls[0].ba = 0;
1840         dsscomp->ovls[0].cfg.ix = hwc_dev->primary_transform;
1841     }
1842 
1843     /* mirror layers */
1844     hwc_dev->post2_layers = dsscomp->num_ovls;
1845 
1846     omap4_hwc_ext_t *ext = &hwc_dev->ext;
1847     if (ext->current.enabled && hwc_dev->ext_ovls) {
1848         if (ext->current.docking && ix_docking >= 0) {
1849             if (clone_external_layer(hwc_dev, ix_docking) == 0)
1850                 dsscomp->ovls[dsscomp->num_ovls - 1].cfg.zorder = z++;
1851         } else if (ext->current.docking && ix_docking < 0 && ext->force_dock) {
1852             ix_docking = dsscomp->num_ovls;
1853             struct dss2_ovl_info *oi = &dsscomp->ovls[ix_docking];
1854             omap4_hwc_setup_layer_base(&oi->cfg, 0, HAL_PIXEL_FORMAT_BGRA_8888, 1,
1855                                        dock_image.width, dock_image.height);
1856             oi->cfg.stride = dock_image.rowbytes;
1857             if (clone_external_layer(hwc_dev, ix_docking) == 0) {
1858                 oi->addressing = OMAP_DSS_BUFADDR_FB;
1859                 oi->ba = 0;
1860                 z++;
1861             }
1862         } else if (!ext->current.docking) {
1863             int res = 0;
1864 
1865             /* reset mode if we are coming from docking */
1866             if (ext->last.docking)
1867                 res = setup_mirroring(hwc_dev);
1868 
1869             /* mirror all layers */
1870             for (ix = 0; res == 0 && ix < hwc_dev->post2_layers; ix++) {
1871                 if (clone_layer(hwc_dev, ix))
1872                     break;
1873                 z++;
1874             }
1875         }
1876     }
1877 
1878     /* Apply transform for primary display */
1879     if (hwc_dev->primary_transform)
1880         for (i = 0; i < dsscomp->num_ovls; i++) {
1881             if(dsscomp->ovls[i].cfg.mgr_ix == 0)
1882                 omap4_hwc_adjust_primary_display_layer(hwc_dev, &dsscomp->ovls[i]);
1883         }
1884 
1885     ext->last = ext->current;
1886 
1887     if (z != dsscomp->num_ovls || dsscomp->num_ovls > MAX_HW_OVERLAYS)
1888         ALOGE("**** used %d z-layers for %d overlays\n", z, dsscomp->num_ovls);
1889 
1890     /* verify all z-orders and overlay indices are distinct */
1891     for (i = z = ix = 0; i < dsscomp->num_ovls; i++) {
1892         struct dss2_ovl_cfg *c = &dsscomp->ovls[i].cfg;
1893 
1894         if (z & (1 << c->zorder))
1895             ALOGE("**** used z-order #%d multiple times", c->zorder);
1896         if (ix & (1 << c->ix))
1897             ALOGE("**** used ovl index #%d multiple times", c->ix);
1898         z |= 1 << c->zorder;
1899         ix |= 1 << c->ix;
1900     }
1901     dsscomp->mode = DSSCOMP_SETUP_DISPLAY;
1902     dsscomp->mgrs[0].ix = 0;
1903     dsscomp->mgrs[0].alpha_blending = 1;
1904     dsscomp->mgrs[0].swap_rb = hwc_dev->swap_rb;
1905     dsscomp->num_mgrs = 1;
1906 
1907     if (ext->current.enabled || hwc_dev->last_ext_ovls) {
1908         dsscomp->mgrs[1] = dsscomp->mgrs[0];
1909         dsscomp->mgrs[1].ix = 1;
1910         dsscomp->num_mgrs++;
1911         hwc_dev->ext_ovls = dsscomp->num_ovls - hwc_dev->post2_layers;
1912     }
1913 
1914     /*
1915      * Whilst the mode of the display is being changed drop compositions to the
1916      * display
1917      */
1918     if (ext->last_mode == 0 && hwc_dev->on_tv) {
1919         dsscomp->num_ovls = 0;
1920     }
1921 
1922     if (debug) {
1923         ALOGD("prepare (%d) - %s (comp=%d, poss=%d/%d scaled, RGB=%d,BGR=%d,NV12=%d) (ext=%s%s%ddeg%s %dex/%dmx (last %dex,%din)\n",
1924              dsscomp->sync_id,
1925              hwc_dev->use_sgx ? "SGX+OVL" : "all-OVL",
1926              num.composited_layers,
1927              num.possible_overlay_layers, num.scaled_layers,
1928              num.RGB, num.BGR, num.NV12,
1929              ext->on_tv ? "tv+" : "",
1930              ext->current.enabled ? ext->current.docking ? "dock+" : "mirror+" : "OFF+",
1931              ext->current.rotation * 90,
1932              ext->current.hflip ? "+hflip" : "",
1933              hwc_dev->ext_ovls, num.max_hw_overlays, hwc_dev->last_ext_ovls, hwc_dev->last_int_ovls);
1934     }
1935 
1936     pthread_mutex_unlock(&hwc_dev->lock);
1937     return 0;
1938 }
1939 
omap4_hwc_reset_screen(omap4_hwc_device_t * hwc_dev)1940 static void omap4_hwc_reset_screen(omap4_hwc_device_t *hwc_dev)
1941 {
1942     static int first_set = 1;
1943     int ret;
1944 
1945     if (first_set) {
1946         first_set = 0;
1947         struct dsscomp_setup_dispc_data d = {
1948             .num_mgrs = 1,
1949         };
1950         /* remove bootloader image from the screen as blank/unblank does not change the composition */
1951         ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPC, &d);
1952         if (ret)
1953             ALOGW("failed to remove bootloader image");
1954 
1955         /* blank and unblank fd to make sure display is properly programmed on boot.
1956          * This is needed because the bootloader can not be trusted.
1957          */
1958         ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_POWERDOWN);
1959         if (ret)
1960             ALOGW("failed to blank display");
1961 
1962         ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK);
1963         if (ret)
1964             ALOGW("failed to blank display");
1965     }
1966 }
1967 
omap4_hwc_set(struct hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)1968 static int omap4_hwc_set(struct hwc_composer_device_1 *dev,
1969         size_t numDisplays, hwc_display_contents_1_t** displays)
1970 {
1971     if (!numDisplays || displays == NULL) {
1972         ALOGD("set: empty display list");
1973         return 0;
1974     }
1975     hwc_display_t dpy = NULL;
1976     hwc_surface_t sur = NULL;
1977     hwc_display_contents_1_t* list = displays[0];  // ignore displays beyond the first
1978     if (list != NULL) {
1979         dpy = list->dpy;
1980         sur = list->sur;
1981     }
1982     omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev;
1983     struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
1984     int err = 0;
1985     int invalidate;
1986 
1987     pthread_mutex_lock(&hwc_dev->lock);
1988 
1989     /* disable resetting the screen on the first boot for devices
1990      * with hdmi as primary input.
1991      */
1992     if (!hwc_dev->on_tv)
1993         omap4_hwc_reset_screen(hwc_dev);
1994 
1995     invalidate = hwc_dev->ext_ovls_wanted && (hwc_dev->ext_ovls < hwc_dev->ext_ovls_wanted) &&
1996                                               (hwc_dev->stats.protected || !hwc_dev->ext_ovls);
1997 
1998     if (debug)
1999         dump_set_info(hwc_dev, list);
2000 
2001     if (dpy && sur) {
2002         // list can be NULL which means hwc is temporarily disabled.
2003         // however, if dpy and sur are null it means we're turning the
2004         // screen off. no shall not call eglSwapBuffers() in that case.
2005 
2006         if (hwc_dev->use_sgx) {
2007             if (!eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur)) {
2008                 ALOGE("eglSwapBuffers error");
2009                 err = HWC_EGL_ERROR;
2010                 goto err_out;
2011             }
2012         }
2013 
2014         //dump_dsscomp(dsscomp);
2015 
2016         // signal the event thread that a post has happened
2017         wakeup_hdmi_thread(hwc_dev);
2018         if (hwc_dev->force_sgx > 0)
2019             hwc_dev->force_sgx--;
2020 
2021         hwc_dev->comp_data.blit_data.rgz_flags = hwc_dev->blit_flags;
2022         hwc_dev->comp_data.blit_data.rgz_items = hwc_dev->blit_num;
2023         int omaplfb_comp_data_sz = sizeof(hwc_dev->comp_data) +
2024             (hwc_dev->comp_data.blit_data.rgz_items * sizeof(struct rgz_blt_entry));
2025 
2026 
2027         unsigned int nbufs = hwc_dev->post2_layers;
2028         if (hwc_dev->post2_blit_buffers) {
2029             /*
2030              * We don't want to pass a NULL entry in the Post2, but we need to
2031              * fix up buffer handle array and overlay indexes to account for
2032              * this
2033              */
2034             nbufs += hwc_dev->post2_blit_buffers - 1;
2035 
2036             if (hwc_dev->post2_layers > 1) {
2037                 unsigned int i, j;
2038                 for (i = 0; i < nbufs; i++) {
2039                     hwc_dev->buffers[i] = hwc_dev->buffers[i+1];
2040                 }
2041                 for (i = 1, j= 1; j < hwc_dev->post2_layers; i++, j++) {
2042                     dsscomp->ovls[j].ba = i;
2043                 }
2044             }
2045         }
2046         ALOGI_IF(debugblt && hwc_dev->blt_policy != BLTPOLICY_DISABLED,
2047             "Post2, blits %d, ovl_buffers %d, blit_buffers %d sgx %d",
2048             hwc_dev->blit_num, hwc_dev->post2_layers, hwc_dev->post2_blit_buffers,
2049             hwc_dev->use_sgx);
2050 
2051         debug_post2(hwc_dev, nbufs);
2052         err = hwc_dev->fb_dev->Post2((framebuffer_device_t *)hwc_dev->fb_dev,
2053                                  hwc_dev->buffers,
2054                                  nbufs,
2055                                  dsscomp, omaplfb_comp_data_sz);
2056         showfps();
2057 
2058 #if 0
2059         if (!hwc_dev->use_sgx) {
2060             __u32 crt = 0;
2061             int err2 = ioctl(hwc_dev->fb_fd, FBIO_WAITFORVSYNC, &crt);
2062             if (err2) {
2063                 ALOGE("failed to wait for vsync (%d)", errno);
2064                 err = err ? : -errno;
2065             }
2066         }
2067 #endif
2068     }
2069     hwc_dev->last_ext_ovls = hwc_dev->ext_ovls;
2070     hwc_dev->last_int_ovls = hwc_dev->post2_layers;
2071     if (err)
2072         ALOGE("Post2 error");
2073 
2074     check_sync_fds(numDisplays, displays);
2075 
2076 err_out:
2077     pthread_mutex_unlock(&hwc_dev->lock);
2078 
2079     if (invalidate && hwc_dev->procs && hwc_dev->procs->invalidate)
2080         hwc_dev->procs->invalidate(hwc_dev->procs);
2081 
2082     return err;
2083 }
2084 
omap4_hwc_dump(struct hwc_composer_device_1 * dev,char * buff,int buff_len)2085 static void omap4_hwc_dump(struct hwc_composer_device_1 *dev, char *buff, int buff_len)
2086 {
2087     omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev;
2088     struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->comp_data.dsscomp_data;
2089     struct dump_buf log = {
2090         .buf = buff,
2091         .buf_len = buff_len,
2092     };
2093     int i;
2094 
2095     dump_printf(&log, "omap4_hwc %d:\n", dsscomp->num_ovls);
2096     dump_printf(&log, "  idle timeout: %dms\n", hwc_dev->idle);
2097 
2098     for (i = 0; i < dsscomp->num_ovls; i++) {
2099         struct dss2_ovl_cfg *cfg = &dsscomp->ovls[i].cfg;
2100 
2101         dump_printf(&log, "  layer %d:\n", i);
2102         dump_printf(&log, "     enabled:%s buff:%p %dx%d stride:%d\n",
2103                           cfg->enabled ? "true" : "false", hwc_dev->buffers[i],
2104                           cfg->width, cfg->height, cfg->stride);
2105         dump_printf(&log, "     src:(%d,%d) %dx%d dst:(%d,%d) %dx%d ix:%d zorder:%d\n",
2106                           cfg->crop.x, cfg->crop.y, cfg->crop.w, cfg->crop.h,
2107                           cfg->win.x, cfg->win.y, cfg->win.w, cfg->win.h,
2108                           cfg->ix, cfg->zorder);
2109     }
2110 
2111     if (hwc_dev->blt_policy != BLTPOLICY_DISABLED) {
2112         dump_printf(&log, "  bltpolicy: %s, bltmode: %s\n",
2113             hwc_dev->blt_policy == BLTPOLICY_DEFAULT ? "default" :
2114                 hwc_dev->blt_policy == BLTPOLICY_ALL ? "all" : "unknown",
2115                     hwc_dev->blt_mode == BLTMODE_PAINT ? "paint" : "regionize");
2116     }
2117     dump_printf(&log, "\n");
2118 }
2119 
free_png_image(omap4_hwc_device_t * hwc_dev,struct omap4_hwc_img * img)2120 static void free_png_image(omap4_hwc_device_t *hwc_dev, struct omap4_hwc_img *img)
2121 {
2122     memset(img, 0, sizeof(*img));
2123 }
2124 
load_png_image(omap4_hwc_device_t * hwc_dev,char * path,struct omap4_hwc_img * img)2125 static int load_png_image(omap4_hwc_device_t *hwc_dev, char *path, struct omap4_hwc_img *img)
2126 {
2127     void *ptr = NULL;
2128     png_bytepp row_pointers = NULL;
2129 
2130     FILE *fd = fopen(path, "rb");
2131     if (!fd) {
2132         ALOGE("failed to open PNG file %s: (%d)", path, errno);
2133         return -EINVAL;
2134     }
2135 
2136     const int SIZE_PNG_HEADER = 8;
2137     __u8 header[SIZE_PNG_HEADER];
2138     fread(header, 1, SIZE_PNG_HEADER, fd);
2139     if (png_sig_cmp(header, 0, SIZE_PNG_HEADER)) {
2140         ALOGE("%s is not a PNG file", path);
2141         goto fail;
2142     }
2143 
2144     png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
2145     if (!png_ptr)
2146          goto fail_alloc;
2147     png_infop info_ptr = png_create_info_struct(png_ptr);
2148     if (!info_ptr)
2149          goto fail_alloc;
2150 
2151     if (setjmp(png_jmpbuf(png_ptr)))
2152         goto fail_alloc;
2153 
2154     png_init_io(png_ptr, fd);
2155     png_set_sig_bytes(png_ptr, SIZE_PNG_HEADER);
2156     png_set_user_limits(png_ptr, limits.max_width, limits.max_height);
2157     png_read_info(png_ptr, info_ptr);
2158 
2159     __u8 bit_depth = png_get_bit_depth(png_ptr, info_ptr);
2160     __u32 width = png_get_image_width(png_ptr, info_ptr);
2161     __u32 height = png_get_image_height(png_ptr, info_ptr);
2162     __u8 color_type = png_get_color_type(png_ptr, info_ptr);
2163 
2164     switch (color_type) {
2165     case PNG_COLOR_TYPE_PALETTE:
2166         png_set_palette_to_rgb(png_ptr);
2167         png_set_filler(png_ptr, 128, PNG_FILLER_AFTER);
2168         break;
2169     case PNG_COLOR_TYPE_GRAY:
2170         if (bit_depth < 8) {
2171             png_set_expand_gray_1_2_4_to_8(png_ptr);
2172             if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
2173                 png_set_tRNS_to_alpha(png_ptr);
2174         } else {
2175             png_set_filler(png_ptr, 128, PNG_FILLER_AFTER);
2176         }
2177         /* fall through */
2178     case PNG_COLOR_TYPE_GRAY_ALPHA:
2179         png_set_gray_to_rgb(png_ptr);
2180         break;
2181     case PNG_COLOR_TYPE_RGB:
2182         png_set_filler(png_ptr, 128, PNG_FILLER_AFTER);
2183         /* fall through */
2184     case PNG_COLOR_TYPE_RGB_ALPHA:
2185         png_set_bgr(png_ptr);
2186         break;
2187     default:
2188         ALOGE("unsupported PNG color: %x", color_type);
2189         goto fail_alloc;
2190     }
2191 
2192     if (bit_depth == 16)
2193         png_set_strip_16(png_ptr);
2194 
2195     const int bpp = 4;
2196     img->size = ALIGN(width * height * bpp, 4096);
2197     if (img->size > hwc_dev->img_mem_size) {
2198         ALOGE("image does not fit into framebuffer area (%d > %d)", img->size, hwc_dev->img_mem_size);
2199         goto fail_alloc;
2200     }
2201     img->ptr = hwc_dev->img_mem_ptr;
2202 
2203     row_pointers = calloc(height, sizeof(*row_pointers));
2204     if (!row_pointers) {
2205         ALOGE("failed to allocate row pointers");
2206         goto fail_alloc;
2207     }
2208     __u32 i;
2209     for (i = 0; i < height; i++)
2210         row_pointers[i] = img->ptr + i * width * bpp;
2211     png_set_rows(png_ptr, info_ptr, row_pointers);
2212     png_read_update_info(png_ptr, info_ptr);
2213     img->rowbytes = png_get_rowbytes(png_ptr, info_ptr);
2214 
2215     png_read_image(png_ptr, row_pointers);
2216     png_read_end(png_ptr, NULL);
2217     free(row_pointers);
2218     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2219     fclose(fd);
2220     img->width = width;
2221     img->height = height;
2222     return 0;
2223 
2224 fail_alloc:
2225     free_png_image(hwc_dev, img);
2226     free(row_pointers);
2227     if (!png_ptr || !info_ptr)
2228         ALOGE("failed to allocate PNG structures");
2229     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2230 fail:
2231     fclose(fd);
2232     return -EINVAL;
2233 }
2234 
2235 
omap4_hwc_device_close(hw_device_t * device)2236 static int omap4_hwc_device_close(hw_device_t* device)
2237 {
2238     omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) device;;
2239 
2240     if (hwc_dev) {
2241         if (hwc_dev->dsscomp_fd >= 0)
2242             close(hwc_dev->dsscomp_fd);
2243         if (hwc_dev->hdmi_fb_fd >= 0)
2244             close(hwc_dev->hdmi_fb_fd);
2245         if (hwc_dev->fb_fd >= 0)
2246             close(hwc_dev->fb_fd);
2247         if (hwc_dev->ion_fd >= 0)
2248             ion_close(hwc_dev->ion_fd);
2249 
2250         /* pthread will get killed when parent process exits */
2251         pthread_mutex_destroy(&hwc_dev->lock);
2252         pthread_mutex_destroy(&hwc_dev->vsync_lock);
2253         free(hwc_dev);
2254     }
2255 
2256     return 0;
2257 }
2258 
omap4_hwc_open_fb_hal(IMG_framebuffer_device_public_t ** fb_dev)2259 static int omap4_hwc_open_fb_hal(IMG_framebuffer_device_public_t **fb_dev)
2260 {
2261     const struct hw_module_t *psModule;
2262     IMG_gralloc_module_public_t *psGrallocModule;
2263     int err;
2264 
2265     err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &psModule);
2266     psGrallocModule = (IMG_gralloc_module_public_t *) psModule;
2267 
2268     if(err)
2269         goto err_out;
2270 
2271     if (strcmp(psGrallocModule->base.common.author, "Imagination Technologies")) {
2272         err = -EINVAL;
2273         goto err_out;
2274     }
2275 
2276     *fb_dev = psGrallocModule->psFrameBufferDevice;
2277 
2278     return 0;
2279 
2280 err_out:
2281     ALOGE("Composer HAL failed to load compatible Graphics HAL");
2282     return err;
2283 }
2284 
set_primary_display_transform_matrix(omap4_hwc_device_t * hwc_dev)2285 static void set_primary_display_transform_matrix(omap4_hwc_device_t *hwc_dev)
2286 {
2287     /* create primary display translation matrix */
2288     hwc_dev->fb_dis.ix = 0;/*Default display*/
2289 
2290     int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis);
2291     if (ret)
2292         ALOGE("failed to get display info (%d): %m", errno);
2293 
2294     int lcd_w = hwc_dev->fb_dis.timings.x_res;
2295     int lcd_h = hwc_dev->fb_dis.timings.y_res;
2296     int orig_w = hwc_dev->fb_dev->base.width;
2297     int orig_h = hwc_dev->fb_dev->base.height;
2298     hwc_rect_t region = {.left = 0, .top = 0, .right = orig_w, .bottom = orig_h};
2299     hwc_dev->primary_region = region;
2300     hwc_dev->primary_rotation = ((lcd_w > lcd_h) ^ (orig_w > orig_h)) ? 1 : 0;
2301     hwc_dev->primary_transform = ((lcd_w != orig_w)||(lcd_h != orig_h)) ? 1 : 0;
2302 
2303     ALOGI("transforming FB (%dx%d) => (%dx%d) rot%d", orig_w, orig_h, lcd_w, lcd_h, hwc_dev->primary_rotation);
2304 
2305     /* reorientation matrix is:
2306        m = (center-from-target-center) * (scale-to-target) * (mirror) * (rotate) * (center-to-original-center) */
2307 
2308     memcpy(hwc_dev->primary_m, m_unit, sizeof(m_unit));
2309     m_translate(hwc_dev->primary_m, -(orig_w >> 1), -(orig_h >> 1));
2310     m_rotate(hwc_dev->primary_m, hwc_dev->primary_rotation);
2311     if (hwc_dev->primary_rotation & 1)
2312          swap(orig_w, orig_h);
2313     m_scale(hwc_dev->primary_m, orig_w, lcd_w, orig_h, lcd_h);
2314     m_translate(hwc_dev->primary_m, lcd_w >> 1, lcd_h >> 1);
2315 }
2316 
2317 
handle_hotplug(omap4_hwc_device_t * hwc_dev)2318 static void handle_hotplug(omap4_hwc_device_t *hwc_dev)
2319 {
2320     omap4_hwc_ext_t *ext = &hwc_dev->ext;
2321     __u8 state = ext->hdmi_state;
2322 
2323     /* Ignore external HDMI logic if the primary display is HDMI */
2324     if (hwc_dev->on_tv) {
2325         ALOGI("Primary display is HDMI - skip clone/dock logic");
2326 
2327         if (state) {
2328             __u32 xres = hwc_dev->fb_dev->base.width;
2329             __u32 yres = hwc_dev->fb_dev->base.height;
2330             if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, ext->lcd_xpy)) {
2331                 ALOGE("Failed to set HDMI mode");
2332             }
2333             set_primary_display_transform_matrix(hwc_dev);
2334 
2335             ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK);
2336 
2337             if (hwc_dev->procs && hwc_dev->procs->invalidate) {
2338                 hwc_dev->procs->invalidate(hwc_dev->procs);
2339             }
2340         } else
2341             ext->last_mode = 0;
2342 
2343         return;
2344     }
2345 
2346     pthread_mutex_lock(&hwc_dev->lock);
2347     ext->dock.enabled = ext->mirror.enabled = 0;
2348     if (state) {
2349         /* check whether we can clone and/or dock */
2350         char value[PROPERTY_VALUE_MAX];
2351         property_get("persist.hwc.docking.enabled", value, "1");
2352         ext->dock.enabled = atoi(value) > 0;
2353         property_get("persist.hwc.mirroring.enabled", value, "1");
2354         ext->mirror.enabled = atoi(value) > 0;
2355         property_get("persist.hwc.avoid_mode_change", value, "1");
2356         ext->avoid_mode_change = atoi(value) > 0;
2357 
2358         /* get cloning transformation */
2359         property_get("persist.hwc.docking.transform", value, "0");
2360         ext->dock.rotation = atoi(value) & EXT_ROTATION;
2361         ext->dock.hflip = (atoi(value) & EXT_HFLIP) > 0;
2362         ext->dock.docking = 1;
2363         property_get("persist.hwc.mirroring.transform", value, hwc_dev->fb_dis.timings.y_res > hwc_dev->fb_dis.timings.x_res ? "3" : "0");
2364         ext->mirror.rotation = atoi(value) & EXT_ROTATION;
2365         ext->mirror.hflip = (atoi(value) & EXT_HFLIP) > 0;
2366         ext->mirror.docking = 0;
2367 
2368         if (ext->force_dock) {
2369             /* restrict to docking with no transform */
2370             ext->mirror.enabled = 0;
2371             ext->dock.rotation = 0;
2372             ext->dock.hflip = 0;
2373 
2374             if (!dock_image.rowbytes) {
2375                 property_get("persist.hwc.dock_image", value, "/vendor/res/images/dock/dock.png");
2376                 load_png_image(hwc_dev, value, &dock_image);
2377             }
2378         }
2379 
2380         /* select best mode for mirroring */
2381         if (ext->mirror.enabled) {
2382             ext->current = ext->mirror;
2383             ext->mirror_mode = 0;
2384             if (setup_mirroring(hwc_dev) == 0) {
2385                 ext->mirror_mode = ext->last_mode;
2386                 ioctl(hwc_dev->hdmi_fb_fd, FBIOBLANK, FB_BLANK_UNBLANK);
2387             } else
2388                 ext->mirror.enabled = 0;
2389         }
2390         /* Allocate backup buffers for FB rotation
2391         * This is required only if the FB tranform is different from that
2392         * of the external display and the FB is not in TILER2D space
2393         */
2394         if (ext->mirror.rotation && (limits.fbmem_type != DSSCOMP_FBMEM_TILER2D))
2395             allocate_tiler2d_buffers(hwc_dev);
2396 
2397     } else {
2398         ext->last_mode = 0;
2399         if (ext->mirror.rotation && (limits.fbmem_type != DSSCOMP_FBMEM_TILER2D)) {
2400             /* free tiler 2D buffer on detach */
2401             free_tiler2d_buffers(hwc_dev);
2402         }
2403     }
2404     ALOGI("external display changed (state=%d, mirror={%s tform=%ddeg%s}, dock={%s tform=%ddeg%s%s}, tv=%d", state,
2405          ext->mirror.enabled ? "enabled" : "disabled",
2406          ext->mirror.rotation * 90,
2407          ext->mirror.hflip ? "+hflip" : "",
2408          ext->dock.enabled ? "enabled" : "disabled",
2409          ext->dock.rotation * 90,
2410          ext->dock.hflip ? "+hflip" : "",
2411          ext->force_dock ? " forced" : "",
2412          ext->on_tv);
2413 
2414     pthread_mutex_unlock(&hwc_dev->lock);
2415 
2416     /* hwc_dev->procs is set right after the device is opened, but there is
2417      * still a race condition where a hotplug event might occur after the open
2418      * but before the procs are registered. */
2419     if (hwc_dev->procs && hwc_dev->procs->invalidate)
2420             hwc_dev->procs->invalidate(hwc_dev->procs);
2421 }
2422 
handle_uevents(omap4_hwc_device_t * hwc_dev,const char * buff,int len)2423 static void handle_uevents(omap4_hwc_device_t *hwc_dev, const char *buff, int len)
2424 {
2425     int dock;
2426     int hdmi;
2427     int vsync;
2428     int state = 0;
2429     uint64_t timestamp = 0;
2430     const char *s = buff;
2431 
2432     dock = !strcmp(s, "change@/devices/virtual/switch/dock");
2433     hdmi = !strcmp(s, "change@/devices/virtual/switch/hdmi");
2434     vsync = !strcmp(s, "change@/devices/platform/omapfb") ||
2435         !strcmp(s, "change@/devices/virtual/switch/omapfb-vsync");
2436 
2437     if (!dock && !vsync && !hdmi)
2438        return;
2439 
2440     s += strlen(s) + 1;
2441 
2442     while(*s) {
2443         if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE=")))
2444             state = atoi(s + strlen("SWITCH_STATE="));
2445         else if (!strncmp(s, "SWITCH_TIME=", strlen("SWITCH_TIME=")))
2446             timestamp = strtoull(s + strlen("SWITCH_TIME="), NULL, 0);
2447         else if (!strncmp(s, "VSYNC=", strlen("VSYNC=")))
2448             timestamp = strtoull(s + strlen("VSYNC="), NULL, 0);
2449 
2450         s += strlen(s) + 1;
2451         if (s - buff >= len)
2452             break;
2453     }
2454 
2455     if (vsync) {
2456         fire_vsync_event(hwc_dev, timestamp);
2457     } else {
2458         if (dock) {
2459             hwc_dev->ext.force_dock = state == 1;
2460         } else {
2461             /* If the primary display is HDMI, VSYNC is enabled, and HDMI's plug
2462              * state has just gone from 1->0, then we need to be sure to start
2463              * faking the VSYNC events.
2464              */
2465             if (hwc_dev->on_tv) {
2466                 int new_state, state_change;
2467 
2468                 pthread_mutex_lock(&hwc_dev->vsync_lock);
2469 
2470                 new_state = state == 1;
2471                 state_change = (new_state != hwc_dev->ext.hdmi_state);
2472                 hwc_dev->ext.hdmi_state = new_state;
2473                 if (state_change && !new_state)
2474                     wakeup_hdmi_thread(hwc_dev);
2475 
2476                 pthread_mutex_unlock(&hwc_dev->vsync_lock);
2477             } else {
2478                 hwc_dev->ext.hdmi_state = state == 1;
2479             }
2480         }
2481         handle_hotplug(hwc_dev);
2482     }
2483 }
2484 
omap4_hwc_hdmi_thread(void * data)2485 static void *omap4_hwc_hdmi_thread(void *data)
2486 {
2487     omap4_hwc_device_t *hwc_dev = data;
2488     static char uevent_desc[4096];
2489     struct pollfd fds[2];
2490     int invalidate = 0;
2491     int timeout;
2492     int err;
2493 
2494     setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
2495 
2496     uevent_init();
2497 
2498     fds[0].fd = uevent_get_fd();
2499     fds[0].events = POLLIN;
2500     fds[1].fd = hwc_dev->wakeup_evt;
2501     fds[1].events = POLLIN;
2502 
2503     timeout = hwc_dev->idle ? hwc_dev->idle : -1;
2504 
2505     memset(uevent_desc, 0, sizeof(uevent_desc));
2506 
2507     do {
2508         uint64_t idle_wakeup  = (uint64_t)(-1);
2509         uint64_t vsync_wakeup = (uint64_t)(-1);
2510         uint64_t now = vsync_clock_now();
2511         uint64_t effective_wakeup;
2512         int effective_timeout;
2513 
2514         if (timeout >= 0)
2515             idle_wakeup = now + (((uint64_t)timeout) * 1000000);
2516 
2517         if (hwc_dev->on_tv) {
2518             pthread_mutex_lock(&hwc_dev->vsync_lock);
2519 
2520             if (!hwc_dev->ext.hdmi_state && hwc_dev->vsync_enabled) {
2521                 vsync_wakeup = hwc_dev->last_vsync_time_valid
2522                              ? hwc_dev->last_vsync_time
2523                              : now;
2524 
2525                 vsync_wakeup += hwc_dev->fake_vsync_period;
2526 
2527                 if (vsync_wakeup < now)
2528                     vsync_wakeup = now;
2529             }
2530 
2531             pthread_mutex_unlock(&hwc_dev->vsync_lock);
2532         }
2533 
2534         effective_wakeup = idle_wakeup < vsync_wakeup
2535                          ? idle_wakeup
2536                          : vsync_wakeup;
2537         if (effective_wakeup == (uint64_t)(-1))
2538             effective_timeout = -1;
2539         else if (effective_wakeup <= now)
2540             effective_timeout = 0;
2541         else
2542             effective_timeout = (int)((effective_wakeup - now + 999999) / 1000000);
2543 
2544         if (effective_timeout)
2545             err = poll(fds, 2, effective_timeout);
2546         else
2547             err = 0;
2548 
2549         now = vsync_clock_now();
2550 
2551         if (err == 0) {
2552             int fired = 0;
2553 
2554             if (now >= vsync_wakeup) {
2555                 fire_vsync_event(hwc_dev, vsync_wakeup);
2556                 fired = 1;
2557             }
2558 
2559             if (hwc_dev->idle && (now >= idle_wakeup)) {
2560                 if (hwc_dev->procs) {
2561                     pthread_mutex_lock(&hwc_dev->lock);
2562                     invalidate = hwc_dev->last_int_ovls > 1 && !hwc_dev->force_sgx;
2563                     if (invalidate) {
2564                         hwc_dev->force_sgx = 2;
2565                     }
2566                     pthread_mutex_unlock(&hwc_dev->lock);
2567 
2568                     if (invalidate) {
2569                         hwc_dev->procs->invalidate(hwc_dev->procs);
2570                         timeout = -1;
2571                     }
2572                 }
2573 
2574                 fired = 1;
2575             }
2576 
2577             if (fired)
2578                 continue;
2579         }
2580 
2581         if (err == -1) {
2582             if (errno != EINTR)
2583                 ALOGE("event error: %m");
2584             continue;
2585         }
2586 
2587         if (fds[1].revents & POLLIN) {
2588             uint64_t tmp;
2589 
2590             read(hwc_dev->wakeup_evt, &tmp, sizeof(tmp));
2591 
2592             if (!hwc_dev->force_sgx)
2593                 timeout = hwc_dev->idle ? hwc_dev->idle : -1;
2594         }
2595 
2596         if (fds[0].revents & POLLIN) {
2597             /* keep last 2 zeroes to ensure double 0 termination */
2598             int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2);
2599             handle_uevents(hwc_dev, uevent_desc, len);
2600         }
2601     } while (1);
2602 
2603     return NULL;
2604 }
2605 
omap4_hwc_registerProcs(struct hwc_composer_device_1 * dev,hwc_procs_t const * procs)2606 static void omap4_hwc_registerProcs(struct hwc_composer_device_1* dev,
2607                                     hwc_procs_t const* procs)
2608 {
2609     omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev;
2610 
2611     hwc_dev->procs = (typeof(hwc_dev->procs)) procs;
2612 }
2613 
omap4_hwc_query(struct hwc_composer_device_1 * dev,int what,int * value)2614 static int omap4_hwc_query(struct hwc_composer_device_1* dev,
2615         int what, int* value)
2616 {
2617     omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev;
2618 
2619     switch (what) {
2620     case HWC_BACKGROUND_LAYER_SUPPORTED:
2621         // we don't support the background layer yet
2622         value[0] = 0;
2623         break;
2624     case HWC_VSYNC_PERIOD:
2625         // vsync period in nanosecond
2626         value[0] = 1000000000.0 / hwc_dev->fb_dev->base.fps;
2627         break;
2628     default:
2629         // unsupported query
2630         return -EINVAL;
2631     }
2632     return 0;
2633 }
2634 
omap4_hwc_event_control(struct hwc_composer_device_1 * dev,int dpy,int event,int enabled)2635 static int omap4_hwc_event_control(struct hwc_composer_device_1* dev,
2636         int dpy, int event, int enabled)
2637 {
2638     omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev;
2639 
2640     switch (event) {
2641     case HWC_EVENT_VSYNC:
2642     {
2643         int val = !!enabled;
2644         int err;
2645 
2646         /* If the primary display is HDMI, then we need to be sure to fake a
2647          * stream vsync events if vsync is enabled, but HDMI happens to be
2648          * disconnected.
2649          */
2650         if (hwc_dev->on_tv) {
2651             pthread_mutex_lock(&hwc_dev->vsync_lock);
2652 
2653             if (!val)
2654                 hwc_dev->last_vsync_time_valid = 0;
2655 
2656             /* If VSYNC is enabled, but HDMI is not actually plugged in, we need
2657              * to fake it.  Poke the work thread to make sure it is taking care
2658              * of things.
2659              */
2660             if (!hwc_dev->ext.hdmi_state && !hwc_dev->vsync_enabled && val)
2661                 wakeup_hdmi_thread(hwc_dev);
2662 
2663             hwc_dev->vsync_enabled = val;
2664 
2665             err = ioctl(hwc_dev->fb_fd, OMAPFB_ENABLEVSYNC, &val);
2666             pthread_mutex_unlock(&hwc_dev->vsync_lock);
2667         } else {
2668             err = ioctl(hwc_dev->fb_fd, OMAPFB_ENABLEVSYNC, &val);
2669         }
2670 
2671         if (err < 0)
2672             return -errno;
2673 
2674         return 0;
2675     }
2676     default:
2677         return -EINVAL;
2678     }
2679 }
2680 
omap4_hwc_blank(struct hwc_composer_device_1 * dev,int dpy,int blank)2681 static int omap4_hwc_blank(struct hwc_composer_device_1 *dev, int dpy, int blank)
2682 {
2683     // We're using an older method of screen blanking based on
2684     // early_suspend in the kernel.  No need to do anything here.
2685     return 0;
2686 }
2687 
omap4_hwc_device_open(const hw_module_t * module,const char * name,hw_device_t ** device)2688 static int omap4_hwc_device_open(const hw_module_t* module, const char* name,
2689                 hw_device_t** device)
2690 {
2691     omap4_hwc_module_t *hwc_mod = (omap4_hwc_module_t *)module;
2692     omap4_hwc_device_t *hwc_dev;
2693     int err = 0;
2694 
2695     if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
2696         return -EINVAL;
2697     }
2698 
2699     if (!hwc_mod->fb_dev) {
2700         err = omap4_hwc_open_fb_hal(&hwc_mod->fb_dev);
2701         if (err)
2702             return err;
2703 
2704         if (!hwc_mod->fb_dev) {
2705             ALOGE("Framebuffer HAL not opened before HWC");
2706             return -EFAULT;
2707         }
2708         hwc_mod->fb_dev->bBypassPost = 1;
2709     }
2710 
2711     hwc_dev = (omap4_hwc_device_t *)malloc(sizeof(*hwc_dev));
2712     if (hwc_dev == NULL)
2713         return -ENOMEM;
2714 
2715     memset(hwc_dev, 0, sizeof(*hwc_dev));
2716 
2717     hwc_dev->base.common.tag = HARDWARE_DEVICE_TAG;
2718     hwc_dev->base.common.version = HWC_DEVICE_API_VERSION_1_0;
2719     hwc_dev->base.common.module = (hw_module_t *)module;
2720     hwc_dev->base.common.close = omap4_hwc_device_close;
2721     hwc_dev->base.prepare = omap4_hwc_prepare;
2722     hwc_dev->base.set = omap4_hwc_set;
2723     hwc_dev->base.eventControl = omap4_hwc_event_control;
2724     hwc_dev->base.blank = omap4_hwc_blank;
2725     hwc_dev->base.query = omap4_hwc_query;
2726     hwc_dev->base.registerProcs = omap4_hwc_registerProcs;
2727     hwc_dev->base.dump = omap4_hwc_dump;
2728     hwc_dev->fb_dev = hwc_mod->fb_dev;
2729     hwc_dev->wakeup_evt = -1;
2730     *device = &hwc_dev->base.common;
2731 
2732     hwc_dev->vsync_enabled = 0;
2733     hwc_dev->last_vsync_time_valid = 0;
2734     hwc_dev->fake_vsync_period = 1000000000ull/60;
2735 
2736     hwc_dev->dsscomp_fd = open("/dev/dsscomp", O_RDWR);
2737     if (hwc_dev->dsscomp_fd < 0) {
2738         ALOGE("failed to open dsscomp (%d)", errno);
2739         err = -errno;
2740         goto done;
2741     }
2742 
2743     int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_PLATFORM, &limits);
2744     if (ret) {
2745         ALOGE("failed to get platform limits (%d): %m", errno);
2746         err = -errno;
2747         goto done;
2748     }
2749 
2750     hwc_dev->fb_fd = open("/dev/graphics/fb0", O_RDWR);
2751     if (hwc_dev->fb_fd < 0) {
2752         ALOGE("failed to open fb (%d)", errno);
2753         err = -errno;
2754         goto done;
2755     }
2756 
2757     struct fb_fix_screeninfo fix;
2758     if (ioctl(hwc_dev->fb_fd, FBIOGET_FSCREENINFO, &fix)) {
2759         ALOGE("failed to get fb info (%d)", errno);
2760         err = -errno;
2761         goto done;
2762     }
2763 
2764     hwc_dev->img_mem_size = fix.smem_len;
2765     hwc_dev->img_mem_ptr = mmap(NULL, fix.smem_len, PROT_WRITE, MAP_SHARED, hwc_dev->fb_fd, 0);
2766     if (hwc_dev->img_mem_ptr == MAP_FAILED) {
2767         ALOGE("failed to map fb memory");
2768         err = -errno;
2769         goto done;
2770     }
2771 
2772     /* Allocate the maximum buffers that we can receive from HWC */
2773     hwc_dev->buffers = malloc(sizeof(buffer_handle_t) * MAX_HWC_LAYERS);
2774     if (!hwc_dev->buffers) {
2775         err = -ENOMEM;
2776         goto done;
2777     }
2778 
2779     ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis);
2780     if (ret) {
2781         ALOGE("failed to get display info (%d): %m", errno);
2782         err = -errno;
2783         goto done;
2784     }
2785 
2786     hwc_dev->ion_fd = ion_open();
2787     if (hwc_dev->ion_fd < 0) {
2788         ALOGE("failed to open ion driver (%d)", errno);
2789     }
2790 
2791     int i;
2792     for (i = 0; i < NUM_EXT_DISPLAY_BACK_BUFFERS; i++) {
2793         hwc_dev->ion_handles[i] = NULL;
2794     }
2795 
2796     /* use default value in case some of requested display parameters missing */
2797     hwc_dev->ext.lcd_xpy = 1.0;
2798     if (hwc_dev->fb_dis.timings.x_res && hwc_dev->fb_dis.height_in_mm) {
2799         hwc_dev->ext.lcd_xpy = (float)
2800             hwc_dev->fb_dis.width_in_mm / hwc_dev->fb_dis.timings.x_res /
2801             hwc_dev->fb_dis.height_in_mm * hwc_dev->fb_dis.timings.y_res;
2802     }
2803 
2804     if (hwc_dev->fb_dis.channel == OMAP_DSS_CHANNEL_DIGIT) {
2805         ALOGI("Primary display is HDMI");
2806         hwc_dev->on_tv = 1;
2807     }
2808     else {
2809         hwc_dev->hdmi_fb_fd = open("/dev/graphics/fb1", O_RDWR);
2810         if (hwc_dev->hdmi_fb_fd < 0) {
2811             ALOGE("failed to open hdmi fb (%d)", errno);
2812             err = -errno;
2813             goto done;
2814         }
2815     }
2816     set_primary_display_transform_matrix(hwc_dev);
2817 
2818     if ((hwc_dev->wakeup_evt = eventfd(0, EFD_NONBLOCK)) < 0) {
2819             ALOGE("failed to eventfd (%d): %m", errno);
2820             err = -errno;
2821             goto done;
2822     }
2823 
2824     if (pthread_mutex_init(&hwc_dev->lock, NULL)) {
2825         ALOGE("failed to create mutex (%d): %m", errno);
2826         err = -errno;
2827         goto done;
2828     }
2829 
2830     if (pthread_mutex_init(&hwc_dev->vsync_lock, NULL)) {
2831         ALOGE("failed to create vsync mutex (%d): %m", errno);
2832         err = -errno;
2833         goto done;
2834     }
2835 
2836     if (pthread_create(&hwc_dev->hdmi_thread, NULL, omap4_hwc_hdmi_thread, hwc_dev))
2837     {
2838         ALOGE("failed to create HDMI listening thread (%d): %m", errno);
2839         err = -errno;
2840         goto done;
2841     }
2842 
2843     /* get debug properties */
2844 
2845     /* see if hwc is enabled at all */
2846     char value[PROPERTY_VALUE_MAX];
2847     property_get("debug.hwc.rgb_order", value, "1");
2848     hwc_dev->flags_rgb_order = atoi(value);
2849     property_get("debug.hwc.nv12_only", value, "0");
2850     hwc_dev->flags_nv12_only = atoi(value);
2851     property_get("debug.hwc.idle", value, "250");
2852     hwc_dev->idle = atoi(value);
2853 
2854     /* get the board specific clone properties */
2855     /* 0:0:1280:720 */
2856     if (property_get("persist.hwc.mirroring.region", value, "") <= 0 ||
2857         sscanf(value, "%d:%d:%d:%d",
2858                &hwc_dev->ext.mirror_region.left, &hwc_dev->ext.mirror_region.top,
2859                &hwc_dev->ext.mirror_region.right, &hwc_dev->ext.mirror_region.bottom) != 4 ||
2860         hwc_dev->ext.mirror_region.left >= hwc_dev->ext.mirror_region.right ||
2861         hwc_dev->ext.mirror_region.top >= hwc_dev->ext.mirror_region.bottom) {
2862         struct hwc_rect fb_region = { .right = hwc_dev->fb_dev->base.width, .bottom = hwc_dev->fb_dev->base.height };
2863         hwc_dev->ext.mirror_region = fb_region;
2864     }
2865     ALOGI("clone region is set to (%d,%d) to (%d,%d)",
2866          hwc_dev->ext.mirror_region.left, hwc_dev->ext.mirror_region.top,
2867          hwc_dev->ext.mirror_region.right, hwc_dev->ext.mirror_region.bottom);
2868 
2869     /* read switch state */
2870     int sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY);
2871     if (sw_fd >= 0) {
2872         char value;
2873         if (read(sw_fd, &value, 1) == 1)
2874             hwc_dev->ext.hdmi_state = value == '1';
2875         close(sw_fd);
2876     }
2877     sw_fd = open("/sys/class/switch/dock/state", O_RDONLY);
2878     if (sw_fd >= 0) {
2879         char value;
2880         if (read(sw_fd, &value, 1) == 1)
2881             hwc_dev->ext.force_dock = value == '1';
2882         close(sw_fd);
2883     }
2884     handle_hotplug(hwc_dev);
2885 
2886     ALOGI("omap4_hwc_device_open(rgb_order=%d nv12_only=%d)",
2887         hwc_dev->flags_rgb_order, hwc_dev->flags_nv12_only);
2888 
2889     int gc2d_fd = open("/dev/gcioctl", O_RDWR);
2890     if (gc2d_fd < 0) {
2891         ALOGI("Unable to open gc-core device (%d), blits disabled", errno);
2892         hwc_dev->blt_policy = BLTPOLICY_DISABLED;
2893     } else {
2894         property_get("persist.hwc.bltmode", value, "1");
2895         hwc_dev->blt_mode = atoi(value);
2896         property_get("persist.hwc.bltpolicy", value, "1");
2897         hwc_dev->blt_policy = atoi(value);
2898         ALOGI("blitter present, blits mode %d, blits policy %d", hwc_dev->blt_mode, hwc_dev->blt_policy);
2899         close(gc2d_fd);
2900 
2901         if (rgz_get_screengeometry(hwc_dev->fb_fd, &gscrngeom,
2902                 hwc_dev->fb_dev->base.format) != 0) {
2903             err = -EINVAL;
2904             goto done;
2905         }
2906     }
2907 
2908     property_get("persist.hwc.upscaled_nv12_limit", value, "2.");
2909     sscanf(value, "%f", &hwc_dev->upscaled_nv12_limit);
2910     if (hwc_dev->upscaled_nv12_limit < 0. || hwc_dev->upscaled_nv12_limit > 2048.) {
2911         ALOGW("Invalid upscaled_nv12_limit (%s), setting to 2.", value);
2912         hwc_dev->upscaled_nv12_limit = 2.;
2913     }
2914 
2915 done:
2916     if (err && hwc_dev) {
2917         if (hwc_dev->dsscomp_fd >= 0)
2918             close(hwc_dev->dsscomp_fd);
2919         if (hwc_dev->hdmi_fb_fd >= 0)
2920             close(hwc_dev->hdmi_fb_fd);
2921         if (hwc_dev->fb_fd >= 0)
2922             close(hwc_dev->fb_fd);
2923         if (hwc_dev->wakeup_evt >= 0)
2924             close(hwc_dev->wakeup_evt);
2925         pthread_mutex_destroy(&hwc_dev->lock);
2926         pthread_mutex_destroy(&hwc_dev->vsync_lock);
2927         free(hwc_dev->buffers);
2928         free(hwc_dev);
2929     }
2930 
2931     return err;
2932 }
2933 
2934 static struct hw_module_methods_t omap4_hwc_module_methods = {
2935     .open = omap4_hwc_device_open,
2936 };
2937 
2938 omap4_hwc_module_t HAL_MODULE_INFO_SYM = {
2939     .base = {
2940         .common = {
2941             .tag =                  HARDWARE_MODULE_TAG,
2942             .module_api_version =   HWC_MODULE_API_VERSION_0_1,
2943             .hal_api_version =      HARDWARE_HAL_API_VERSION,
2944             .id =                   HWC_HARDWARE_MODULE_ID,
2945             .name =                 "OMAP 44xx Hardware Composer HAL",
2946             .author =               "Texas Instruments",
2947             .methods =              &omap4_hwc_module_methods,
2948         },
2949     },
2950 };
2951