hwc.cpp revision a00c043512babb1d6f48a0a505f30b906fac8066
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <errno.h>
17#include <fcntl.h>
18#include <poll.h>
19#include <pthread.h>
20#include <stdio.h>
21#include <stdlib.h>
22
23#include <sys/ioctl.h>
24#include <sys/mman.h>
25#include <sys/time.h>
26#include <sys/resource.h>
27
28#include <s3c-fb.h>
29
30#include <EGL/egl.h>
31
32#define HWC_REMOVE_DEPRECATED_VERSIONS 1
33
34#include <cutils/log.h>
35#include <hardware/gralloc.h>
36#include <hardware/hardware.h>
37#include <hardware/hwcomposer.h>
38#include <hardware_legacy/uevent.h>
39#include <utils/Vector.h>
40
41#include <sync/sync.h>
42
43#include "ion.h"
44#include "gralloc_priv.h"
45#include "exynos_gscaler.h"
46#include "exynos_format.h"
47
48struct hwc_callback_entry {
49    void (*callback)(void *, private_handle_t *);
50    void *data;
51};
52typedef android::Vector<struct hwc_callback_entry> hwc_callback_queue_t;
53
54const size_t NUM_HW_WINDOWS = 5;
55const size_t NO_FB_NEEDED = NUM_HW_WINDOWS + 1;
56const size_t MAX_PIXELS = 2560 * 1600 * 2;
57const size_t NUM_GSC_UNITS = 3;
58const size_t GSC_W_ALIGNMENT = 16;
59const size_t GSC_H_ALIGNMENT = 16;
60const int CAMERA_GSC_IDX = 2;
61
62struct exynos5_hwc_composer_device_1_t;
63
64struct exynos5_gsc_map_t {
65    enum {
66        GSC_NONE = 0,
67        GSC_M2M,
68        // TODO: GSC_LOCAL_PATH
69    } mode;
70    int idx;
71};
72
73struct exynos5_hwc_post_data_t {
74    exynos5_hwc_composer_device_1_t *pdev;
75    int                             overlay_map[NUM_HW_WINDOWS];
76    exynos5_gsc_map_t               gsc_map[NUM_HW_WINDOWS];
77    hwc_layer_1_t                   overlays[NUM_HW_WINDOWS];
78    int                             num_overlays;
79    size_t                          fb_window;
80    int                             fence;
81    pthread_mutex_t                 completion_lock;
82    pthread_cond_t                  completion;
83};
84
85const size_t NUM_GSC_DST_BUFS = 2;
86struct exynos5_gsc_data_t {
87    void            *gsc;
88    exynos_gsc_img  src_cfg;
89    exynos_gsc_img  dst_cfg;
90    buffer_handle_t dst_buf[NUM_GSC_DST_BUFS];
91    size_t          current_buf;
92};
93
94struct exynos5_hwc_composer_device_1_t {
95    hwc_composer_device_1_t base;
96
97    int                     fd;
98    int                     vsync_fd;
99    exynos5_hwc_post_data_t bufs;
100
101    const private_module_t  *gralloc_module;
102    alloc_device_t          *alloc_device;
103    hwc_procs_t             *procs;
104    pthread_t               vsync_thread;
105
106    bool hdmi_hpd;
107    bool hdmi_mirroring;
108    void *hdmi_gsc;
109
110    exynos5_gsc_data_t      gsc[NUM_GSC_UNITS];
111};
112
113static void dump_handle(private_handle_t *h)
114{
115    ALOGV("\t\tformat = %d, width = %u, height = %u, stride = %u",
116            h->format, h->width, h->height, h->stride);
117}
118
119static void dump_layer(hwc_layer_1_t const *l)
120{
121    ALOGV("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, "
122            "{%d,%d,%d,%d}, {%d,%d,%d,%d}",
123            l->compositionType, l->flags, l->handle, l->transform,
124            l->blending,
125            l->sourceCrop.left,
126            l->sourceCrop.top,
127            l->sourceCrop.right,
128            l->sourceCrop.bottom,
129            l->displayFrame.left,
130            l->displayFrame.top,
131            l->displayFrame.right,
132            l->displayFrame.bottom);
133
134    if(l->handle && !(l->flags & HWC_SKIP_LAYER))
135        dump_handle(private_handle_t::dynamicCast(l->handle));
136}
137
138static void dump_config(s3c_fb_win_config &c)
139{
140    ALOGV("\tstate = %u", c.state);
141    if (c.state == c.S3C_FB_WIN_STATE_BUFFER) {
142        ALOGV("\t\tfd = %d, offset = %u, stride = %u, "
143                "x = %d, y = %d, w = %u, h = %u, "
144                "format = %u",
145                c.fd, c.offset, c.stride,
146                c.x, c.y, c.w, c.h,
147                c.format);
148    }
149    else if (c.state == c.S3C_FB_WIN_STATE_COLOR) {
150        ALOGV("\t\tcolor = %u", c.color);
151    }
152}
153
154static void dump_gsc_img(exynos_gsc_img &c)
155{
156    ALOGV("\tx = %u, y = %u, w = %u, h = %u, fw = %u, fh = %u",
157            c.x, c.y, c.w, c.h, c.fw, c.fh);
158    ALOGV("\taddr = {%u, %u, %u}, rot = %u, cacheable = %u, drmMode = %u",
159            c.yaddr, c.uaddr, c.vaddr, c.rot, c.cacheable, c.drmMode);
160}
161
162inline int WIDTH(const hwc_rect &rect) { return rect.right - rect.left; }
163inline int HEIGHT(const hwc_rect &rect) { return rect.bottom - rect.top; }
164template<typename T> inline T max(T a, T b) { return (a > b) ? a : b; }
165template<typename T> inline T min(T a, T b) { return (a < b) ? a : b; }
166
167static bool is_transformed(const hwc_layer_1_t &layer)
168{
169    return layer.transform != 0;
170}
171
172static bool is_rotated(const hwc_layer_1_t &layer)
173{
174    return (layer.transform & HAL_TRANSFORM_ROT_90) ||
175            (layer.transform & HAL_TRANSFORM_ROT_180);
176}
177
178static bool is_scaled(const hwc_layer_1_t &layer)
179{
180    return WIDTH(layer.displayFrame) != WIDTH(layer.sourceCrop) ||
181            HEIGHT(layer.displayFrame) != HEIGHT(layer.sourceCrop);
182}
183
184static enum s3c_fb_pixel_format exynos5_format_to_s3c_format(int format)
185{
186    switch (format) {
187    case HAL_PIXEL_FORMAT_RGBA_8888:
188        return S3C_FB_PIXEL_FORMAT_RGBA_8888;
189    case HAL_PIXEL_FORMAT_RGBX_8888:
190        return S3C_FB_PIXEL_FORMAT_RGBX_8888;
191    case HAL_PIXEL_FORMAT_RGBA_5551:
192        return S3C_FB_PIXEL_FORMAT_RGBA_5551;
193    case HAL_PIXEL_FORMAT_RGBA_4444:
194        return S3C_FB_PIXEL_FORMAT_RGBA_4444;
195
196    default:
197        return S3C_FB_PIXEL_FORMAT_MAX;
198    }
199}
200
201static bool exynos5_format_is_supported(int format)
202{
203    return exynos5_format_to_s3c_format(format) < S3C_FB_PIXEL_FORMAT_MAX;
204}
205
206static bool exynos5_format_is_supported_by_gscaler(int format)
207{
208    switch (format) {
209    case HAL_PIXEL_FORMAT_RGBX_8888:
210    case HAL_PIXEL_FORMAT_RGB_565:
211    case HAL_PIXEL_FORMAT_YV12:
212    case HAL_PIXEL_FORMAT_YCbCr_420_P:
213    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
214    case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP:
215    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
216    case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP:
217    case HAL_PIXEL_FORMAT_YCbCr_422_I:
218    case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I:
219    case HAL_PIXEL_FORMAT_YCbCr_422_P:
220    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
221    case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I:
222    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
223    case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP:
224    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
225    case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP:
226    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
227    case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED:
228    case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I:
229    case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I:
230        return true;
231
232    default:
233        return false;
234    }
235}
236
237static bool exynos5_format_requires_gscaler(int format)
238{
239    return exynos5_format_is_supported_by_gscaler(format) &&
240            format != HAL_PIXEL_FORMAT_RGBX_8888;
241}
242
243static uint8_t exynos5_format_to_bpp(int format)
244{
245    switch (format) {
246    case HAL_PIXEL_FORMAT_RGBA_8888:
247    case HAL_PIXEL_FORMAT_RGBX_8888:
248        return 32;
249
250    case HAL_PIXEL_FORMAT_RGBA_5551:
251    case HAL_PIXEL_FORMAT_RGBA_4444:
252        return 16;
253
254    default:
255        ALOGW("unrecognized pixel format %u", format);
256        return 0;
257    }
258}
259
260static bool exynos5_supports_gscaler(hwc_layer_1_t &layer, int format)
261{
262    private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
263
264    int max_w = is_rotated(layer) ? 2048 : 4800;
265    int max_h = is_rotated(layer) ? 2048 : 3344;
266
267    bool rot90or270 = !!(layer.transform & HAL_TRANSFORM_ROT_90);
268    // n.b.: HAL_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_90 |
269    //                               HAL_TRANSFORM_ROT_180
270
271    return exynos5_format_is_supported_by_gscaler(format) &&
272            handle->stride <= max_w &&
273            handle->stride % GSC_W_ALIGNMENT == 0 &&
274            handle->height <= max_h &&
275            handle->height % GSC_H_ALIGNMENT == 0 &&
276            // per 46.2
277            (!rot90or270 || layer.sourceCrop.top % 2 == 0) &&
278            (!rot90or270 || layer.sourceCrop.left % 2 == 0);
279            // per 46.3.1.6
280}
281
282static int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev)
283{
284    if (dev->hdmi_mirroring)
285        return 0;
286
287    exynos_gsc_img src_info;
288    exynos_gsc_img dst_info;
289
290    // TODO: Don't hardcode
291    int src_w = 2560;
292    int src_h = 1600;
293    int dst_w = 1920;
294    int dst_h = 1080;
295
296    dev->hdmi_gsc = exynos_gsc_create_exclusive(3, GSC_OUTPUT_MODE, GSC_OUT_TV);
297    if (!dev->hdmi_gsc) {
298        ALOGE("%s: exynos_gsc_create_exclusive failed", __func__);
299        return -ENODEV;
300    }
301
302    memset(&src_info, 0, sizeof(src_info));
303    memset(&dst_info, 0, sizeof(dst_info));
304
305    src_info.w = src_w;
306    src_info.h = src_h;
307    src_info.fw = src_w;
308    src_info.fh = src_h;
309    src_info.format = HAL_PIXEL_FORMAT_BGRA_8888;
310
311    dst_info.w = dst_w;
312    dst_info.h = dst_h;
313    dst_info.fw = dst_w;
314    dst_info.fh = dst_h;
315    dst_info.format = HAL_PIXEL_FORMAT_YV12;
316
317    int ret = exynos_gsc_config_exclusive(dev->hdmi_gsc, &src_info, &dst_info);
318    if (ret < 0) {
319        ALOGE("%s: exynos_gsc_config_exclusive failed %d", __func__, ret);
320        exynos_gsc_destroy(dev->hdmi_gsc);
321        dev->hdmi_gsc = NULL;
322        return ret;
323    }
324
325    dev->hdmi_mirroring = true;
326    return 0;
327}
328
329static void hdmi_disable(struct exynos5_hwc_composer_device_1_t *dev)
330{
331    if (!dev->hdmi_mirroring)
332        return;
333    exynos_gsc_destroy(dev->hdmi_gsc);
334    dev->hdmi_gsc = NULL;
335    dev->hdmi_mirroring = false;
336}
337
338static int hdmi_output(struct exynos5_hwc_composer_device_1_t *dev, private_handle_t *fb)
339{
340    exynos_gsc_img src_info;
341    exynos_gsc_img dst_info;
342
343    memset(&src_info, 0, sizeof(src_info));
344    memset(&dst_info, 0, sizeof(dst_info));
345
346    src_info.yaddr = fb->fd;
347
348    int ret = exynos_gsc_run_exclusive(dev->hdmi_gsc, &src_info, &dst_info);
349    if (ret < 0) {
350        ALOGE("%s: exynos_gsc_run_exclusive failed %d", __func__, ret);
351        return ret;
352    }
353
354    return 0;
355}
356
357bool exynos5_supports_overlay(hwc_layer_1_t &layer, size_t i)
358{
359    if (layer.flags & HWC_SKIP_LAYER) {
360        ALOGV("\tlayer %u: skipping", i);
361        return false;
362    }
363
364    private_handle_t *handle = private_handle_t::dynamicCast(layer.handle);
365
366    if (!handle) {
367        ALOGV("\tlayer %u: handle is NULL", i);
368        return false;
369    }
370    if (exynos5_format_requires_gscaler(handle->format)) {
371        if (!exynos5_supports_gscaler(layer, handle->format)) {
372            ALOGV("\tlayer %u: gscaler required but not supported", i);
373            return false;
374        }
375    } else {
376        if (!exynos5_format_is_supported(handle->format)) {
377            ALOGV("\tlayer %u: pixel format %u not supported", i, handle->format);
378            return false;
379        }
380        if (is_scaled(layer)) {
381            ALOGV("\tlayer %u: scaling not supported", i);
382            return false;
383        }
384        if (is_transformed(layer)) {
385            ALOGV("\tlayer %u: transformations not supported", i);
386            return false;
387        }
388    }
389    if (layer.blending != HWC_BLENDING_NONE) {
390        // TODO: support this
391        ALOGV("\tlayer %u: blending not supported", i);
392        return false;
393    }
394
395    return true;
396}
397
398inline bool intersect(const hwc_rect &r1, const hwc_rect &r2)
399{
400    return !(r1.left > r2.right ||
401        r1.right < r2.left ||
402        r1.top > r2.bottom ||
403        r1.bottom < r2.top);
404}
405
406inline hwc_rect intersection(const hwc_rect &r1, const hwc_rect &r2)
407{
408    hwc_rect i;
409    i.top = max(r1.top, r2.top);
410    i.bottom = min(r1.bottom, r2.bottom);
411    i.left = max(r1.left, r2.left);
412    i.right = min(r1.right, r2.right);
413    return i;
414}
415
416static int exynos5_prepare(hwc_composer_device_1_t *dev, hwc_layer_list_1_t* list)
417{
418    if (!list)
419        return 0;
420
421    ALOGV("preparing %u layers", list->numHwLayers);
422
423    exynos5_hwc_composer_device_1_t *pdev =
424            (exynos5_hwc_composer_device_1_t *)dev;
425    memset(pdev->bufs.overlays, 0, sizeof(pdev->bufs.overlays));
426    memset(pdev->bufs.gsc_map, 0, sizeof(pdev->bufs.gsc_map));
427
428    bool force_fb = false;
429    if (pdev->hdmi_hpd) {
430        hdmi_enable(pdev);
431        force_fb = true;
432    } else {
433        hdmi_disable(pdev);
434    }
435
436    for (size_t i = 0; i < NUM_HW_WINDOWS; i++)
437        pdev->bufs.overlay_map[i] = -1;
438
439    bool fb_needed = false;
440    size_t first_fb = 0, last_fb = 0;
441
442    // find unsupported overlays
443    for (size_t i = 0; i < list->numHwLayers; i++) {
444        hwc_layer_1_t &layer = list->hwLayers[i];
445
446        if (layer.compositionType == HWC_BACKGROUND && !force_fb) {
447            ALOGV("\tlayer %u: background supported", i);
448            dump_layer(&list->hwLayers[i]);
449            continue;
450        }
451
452        if (exynos5_supports_overlay(list->hwLayers[i], i) && !force_fb) {
453            ALOGV("\tlayer %u: overlay supported", i);
454            layer.compositionType = HWC_OVERLAY;
455            dump_layer(&list->hwLayers[i]);
456            continue;
457        }
458
459        if (!fb_needed) {
460            first_fb = i;
461            fb_needed = true;
462        }
463        last_fb = i;
464        layer.compositionType = HWC_FRAMEBUFFER;
465
466        dump_layer(&list->hwLayers[i]);
467    }
468
469    // can't composite overlays sandwiched between framebuffers
470    if (fb_needed)
471        for (size_t i = first_fb; i < last_fb; i++)
472            list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
473
474    // Incrementally try to add our supported layers to hardware windows.
475    // If adding a layer would violate a hardware constraint, force it
476    // into the framebuffer and try again.  (Revisiting the entire list is
477    // necessary because adding a layer to the framebuffer can cause other
478    // windows to retroactively violate constraints.)
479    bool changed;
480    do {
481        android::Vector<hwc_rect> rects;
482        android::Vector<hwc_rect> overlaps;
483        size_t pixels_left, windows_left, gsc_left = NUM_GSC_UNITS;
484
485        if (fb_needed) {
486            hwc_rect_t fb_rect;
487            fb_rect.top = fb_rect.left = 0;
488            fb_rect.right = pdev->gralloc_module->xres - 1;
489            fb_rect.bottom = pdev->gralloc_module->yres - 1;
490            pixels_left = MAX_PIXELS - pdev->gralloc_module->xres *
491                    pdev->gralloc_module->yres;
492            windows_left = NUM_HW_WINDOWS - 1;
493            rects.push_back(fb_rect);
494        }
495        else {
496            pixels_left = MAX_PIXELS;
497            windows_left = NUM_HW_WINDOWS;
498        }
499        if (pdev->hdmi_mirroring)
500            gsc_left--;
501
502        changed = false;
503
504        for (size_t i = 0; i < list->numHwLayers; i++) {
505            hwc_layer_1_t &layer = list->hwLayers[i];
506            if (layer.flags & HWC_SKIP_LAYER)
507                continue;
508
509            private_handle_t *handle = private_handle_t::dynamicCast(
510                    layer.handle);
511
512            // we've already accounted for the framebuffer above
513            if (layer.compositionType == HWC_FRAMEBUFFER)
514                continue;
515
516            // only layer 0 can be HWC_BACKGROUND, so we can
517            // unconditionally allow it without extra checks
518            if (layer.compositionType == HWC_BACKGROUND) {
519                windows_left--;
520                continue;
521            }
522
523            size_t pixels_needed = WIDTH(layer.displayFrame) *
524                    HEIGHT(layer.displayFrame);
525            bool can_compose = windows_left && pixels_needed <= pixels_left;
526            bool gsc_required = exynos5_format_requires_gscaler(handle->format);
527            if (gsc_required)
528                can_compose = can_compose && gsc_left;
529
530            // hwc_rect_t right and bottom values are normally exclusive;
531            // the intersection logic is simpler if we make them inclusive
532            hwc_rect_t visible_rect = layer.displayFrame;
533            visible_rect.right--; visible_rect.bottom--;
534
535            // no more than 2 layers can overlap on a given pixel
536            for (size_t j = 0; can_compose && j < overlaps.size(); j++) {
537                if (intersect(visible_rect, overlaps.itemAt(j)))
538                    can_compose = false;
539            }
540
541            if (!can_compose) {
542                layer.compositionType = HWC_FRAMEBUFFER;
543                if (!fb_needed) {
544                    first_fb = last_fb = i;
545                    fb_needed = true;
546                }
547                else {
548                    first_fb = min(i, first_fb);
549                    last_fb = max(i, last_fb);
550                }
551                changed = true;
552                break;
553            }
554
555            for (size_t j = 0; j < rects.size(); j++) {
556                const hwc_rect_t &other_rect = rects.itemAt(j);
557                if (intersect(visible_rect, other_rect))
558                    overlaps.push_back(intersection(visible_rect, other_rect));
559            }
560            rects.push_back(visible_rect);
561            pixels_left -= pixels_needed;
562            windows_left--;
563            if (gsc_required)
564                gsc_left--;
565        }
566
567        if (changed)
568            for (size_t i = first_fb; i < last_fb; i++)
569                list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
570    } while(changed);
571
572    unsigned int nextWindow = 0;
573    int nextGsc = 0;
574
575    for (size_t i = 0; i < list->numHwLayers; i++) {
576        hwc_layer_1_t &layer = list->hwLayers[i];
577        if (layer.flags & HWC_SKIP_LAYER)
578            continue;
579
580        if (fb_needed && i == first_fb) {
581            ALOGV("assigning framebuffer to window %u\n",
582                    nextWindow);
583            nextWindow++;
584            continue;
585        }
586
587        if (layer.compositionType != HWC_FRAMEBUFFER) {
588            ALOGV("assigning layer %u to window %u", i, nextWindow);
589            pdev->bufs.overlay_map[nextWindow] = i;
590            if (layer.compositionType == HWC_OVERLAY) {
591                private_handle_t *handle =
592                        private_handle_t::dynamicCast(layer.handle);
593                if (exynos5_format_requires_gscaler(handle->format)) {
594                    ALOGV("\tusing gscaler %u", nextGsc);
595                    pdev->bufs.gsc_map[i].mode =
596                            exynos5_gsc_map_t::GSC_M2M;
597                    pdev->bufs.gsc_map[i].idx = nextGsc++;
598                    if (nextGsc == CAMERA_GSC_IDX)
599                        nextGsc++;
600                }
601            }
602            nextWindow++;
603        }
604    }
605
606    for (size_t i = nextGsc; i < NUM_GSC_UNITS; i++) {
607        for (size_t j = 0; j < NUM_GSC_DST_BUFS; j++)
608            if (pdev->gsc[i].dst_buf[j])
609                pdev->alloc_device->free(pdev->alloc_device,
610                        pdev->gsc[i].dst_buf[j]);
611        memset(&pdev->gsc[i], 0, sizeof(pdev->gsc[i]));
612    }
613
614    if (fb_needed)
615        pdev->bufs.fb_window = first_fb;
616    else
617        pdev->bufs.fb_window = NO_FB_NEEDED;
618
619    return 0;
620}
621
622static inline bool gsc_dst_cfg_changed(exynos_gsc_img &c1, exynos_gsc_img &c2)
623{
624    return c1.x != c2.x ||
625            c1.y != c2.y ||
626            c1.w != c2.w ||
627            c1.h != c2.h ||
628            c1.format != c2.format ||
629            c1.rot != c2.rot ||
630            c1.cacheable != c2.cacheable ||
631            c1.drmMode != c2.drmMode;
632}
633
634static inline bool gsc_src_cfg_changed(exynos_gsc_img &c1, exynos_gsc_img &c2)
635{
636    return gsc_dst_cfg_changed(c1, c2) ||
637            c1.fw != c2.fw ||
638            c1.fh != c2.fh;
639}
640
641static int exynos5_config_gsc_m2m(hwc_layer_1_t &layer,
642        alloc_device_t* alloc_device, exynos5_gsc_data_t *gsc_data,
643        int gsc_idx)
644{
645    ALOGV("configuring gscaler %u for memory-to-memory", gsc_idx);
646
647    private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle);
648    buffer_handle_t dst_buf;
649    private_handle_t *dst_handle;
650    int ret = 0;
651
652    exynos_gsc_img src_cfg, dst_cfg;
653    memset(&src_cfg, 0, sizeof(src_cfg));
654    memset(&dst_cfg, 0, sizeof(dst_cfg));
655
656    src_cfg.x = layer.sourceCrop.left;
657    src_cfg.y = layer.sourceCrop.top;
658    src_cfg.w = WIDTH(layer.sourceCrop);
659    src_cfg.fw = src_handle->stride;
660    src_cfg.h = HEIGHT(layer.sourceCrop);
661    src_cfg.fh = src_handle->height;
662    src_cfg.yaddr = src_handle->fd;
663    src_cfg.uaddr = src_handle->fd1;
664    src_cfg.vaddr = src_handle->fd2;
665    src_cfg.format = src_handle->format;
666
667    dst_cfg.x = 0;
668    dst_cfg.y = 0;
669    dst_cfg.w = WIDTH(layer.displayFrame);
670    dst_cfg.h = HEIGHT(layer.displayFrame);
671    dst_cfg.format = HAL_PIXEL_FORMAT_BGRA_8888;
672    dst_cfg.rot = layer.transform;
673
674    ALOGV("source configuration:");
675    dump_gsc_img(src_cfg);
676
677    if (gsc_src_cfg_changed(src_cfg, gsc_data->src_cfg) ||
678            gsc_dst_cfg_changed(dst_cfg, gsc_data->dst_cfg)) {
679        int dst_stride;
680        int usage = GRALLOC_USAGE_SW_READ_NEVER |
681                GRALLOC_USAGE_SW_WRITE_NEVER |
682                GRALLOC_USAGE_HW_COMPOSER;
683        // TODO: add GRALLOC_USAGE_PROTECTED if source buffer is also protected
684
685        int w = ALIGN(WIDTH(layer.displayFrame), GSC_W_ALIGNMENT);
686        int h = ALIGN(HEIGHT(layer.displayFrame), GSC_H_ALIGNMENT);
687
688        for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
689            if (gsc_data->dst_buf[i]) {
690                alloc_device->free(alloc_device, gsc_data->dst_buf[i]);
691                gsc_data->dst_buf[i] = NULL;
692            }
693
694            int ret = alloc_device->alloc(alloc_device, w, h,
695                    HAL_PIXEL_FORMAT_RGBX_8888, usage, &gsc_data->dst_buf[i],
696                    &dst_stride);
697            if (ret < 0) {
698                ALOGE("failed to allocate destination buffer: %s",
699                        strerror(-ret));
700                goto err_alloc;
701            }
702        }
703
704        gsc_data->current_buf = 0;
705    }
706
707    dst_buf = gsc_data->dst_buf[gsc_data->current_buf];
708    dst_handle = private_handle_t::dynamicCast(dst_buf);
709
710    dst_cfg.fw = dst_handle->stride;
711    dst_cfg.fh = dst_handle->height;
712    dst_cfg.yaddr = dst_handle->fd;
713
714    ALOGV("destination configuration:");
715    dump_gsc_img(dst_cfg);
716
717    gsc_data->gsc = exynos_gsc_create_exclusive(gsc_idx, GSC_M2M_MODE,
718            GSC_DUMMY);
719    if (!gsc_data->gsc) {
720        ALOGE("failed to create gscaler handle");
721        ret = -1;
722        goto err_alloc;
723    }
724
725    ret = exynos_gsc_config_exclusive(gsc_data->gsc, &src_cfg, &dst_cfg);
726    if (ret < 0) {
727        ALOGE("failed to configure gscaler %u", gsc_idx);
728        goto err_gsc_config;
729    }
730
731    ret = exynos_gsc_run_exclusive(gsc_data->gsc, &src_cfg, &dst_cfg);
732    if (ret < 0) {
733        ALOGE("failed to run gscaler %u", gsc_idx);
734        goto err_gsc_config;
735    }
736
737    gsc_data->src_cfg = src_cfg;
738    gsc_data->dst_cfg = dst_cfg;
739
740    return 0;
741
742err_gsc_config:
743    exynos_gsc_destroy(gsc_data->gsc);
744    gsc_data->gsc = NULL;
745err_alloc:
746    for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) {
747        if (gsc_data->dst_buf[i]) {
748           alloc_device->free(alloc_device, gsc_data->dst_buf[i]);
749           gsc_data->dst_buf[i] = NULL;
750       }
751    }
752    return ret;
753}
754
755static void exynos5_config_handle(private_handle_t *handle,
756        hwc_rect_t &sourceCrop, hwc_rect_t &displayFrame,
757        s3c_fb_win_config &cfg)
758{
759    cfg.state = cfg.S3C_FB_WIN_STATE_BUFFER;
760    cfg.fd = handle->fd;
761    cfg.x = displayFrame.left;
762    cfg.y = displayFrame.top;
763    cfg.w = WIDTH(displayFrame);
764    cfg.h = HEIGHT(displayFrame);
765    cfg.format = exynos5_format_to_s3c_format(handle->format);
766    uint8_t bpp = exynos5_format_to_bpp(handle->format);
767    cfg.offset = (sourceCrop.top * handle->stride + sourceCrop.left) * bpp / 8;
768    cfg.stride = handle->stride * bpp / 8;
769}
770
771static void exynos5_config_overlay(hwc_layer_1_t *layer, s3c_fb_win_config &cfg,
772        const private_module_t *gralloc_module)
773{
774    if (layer->compositionType == HWC_BACKGROUND) {
775        hwc_color_t color = layer->backgroundColor;
776        cfg.state = cfg.S3C_FB_WIN_STATE_COLOR;
777        cfg.color = (color.r << 16) | (color.g << 8) | color.b;
778        cfg.x = 0;
779        cfg.y = 0;
780        cfg.w = gralloc_module->xres;
781        cfg.h = gralloc_module->yres;
782        return;
783    }
784
785    private_handle_t *handle = private_handle_t::dynamicCast(layer->handle);
786    exynos5_config_handle(handle, layer->sourceCrop, layer->displayFrame, cfg);
787}
788
789static void exynos5_post_callback(void *data, private_handle_t *fb)
790{
791    exynos5_hwc_post_data_t *pdata = (exynos5_hwc_post_data_t *)data;
792
793    struct s3c_fb_win_config_data win_data;
794    struct s3c_fb_win_config *config = win_data.config;
795    memset(config, 0, sizeof(win_data.config));
796
797    for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
798        if ( pdata->overlay_map[i] != -1) {
799            hwc_layer_1_t &layer = pdata->overlays[i];
800            private_handle_t *handle =
801                    private_handle_t::dynamicCast(layer.handle);
802
803            if (layer.acquireFenceFd != -1) {
804                int err = sync_wait(layer.acquireFenceFd, 100);
805                if (err != 0)
806                    ALOGW("fence for layer %zu didn't signal in 100 ms: %s",
807                          i, strerror(errno));
808                close(layer.acquireFenceFd);
809            }
810
811            if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) {
812                int gsc_idx = pdata->gsc_map[i].idx;
813                exynos5_config_gsc_m2m(layer, pdata->pdev->alloc_device,
814                        &pdata->pdev->gsc[gsc_idx], gsc_idx);
815            }
816        }
817    }
818
819    for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
820        if (i == pdata->fb_window) {
821            hwc_rect_t rect = { 0, 0, fb->width, fb->height };
822            exynos5_config_handle(fb, rect, rect, config[i]);
823        } else if ( pdata->overlay_map[i] != -1) {
824            hwc_layer_1_t &layer = pdata->overlays[i];
825            private_handle_t *handle =
826                    private_handle_t::dynamicCast(layer.handle);
827
828            if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) {
829                int gsc_idx = pdata->gsc_map[i].idx;
830                exynos5_gsc_data_t &gsc = pdata->pdev->gsc[gsc_idx];
831
832                if (!gsc.gsc) {
833                    ALOGE("failed to queue gscaler %u input for layer %u",
834                            gsc_idx, i);
835                    continue;
836                }
837
838                int err = exynos_gsc_stop_exclusive(gsc.gsc);
839                exynos_gsc_destroy(gsc.gsc);
840                gsc.gsc = NULL;
841                if (err < 0) {
842                    ALOGE("failed to dequeue gscaler output for layer %u", i);
843                    continue;
844                }
845
846                buffer_handle_t dst_buf = gsc.dst_buf[gsc.current_buf];
847                gsc.current_buf = (gsc.current_buf + 1) % NUM_GSC_DST_BUFS;
848                private_handle_t *dst_handle =
849                        private_handle_t::dynamicCast(dst_buf);
850                exynos5_config_handle(dst_handle, layer.sourceCrop,
851                        layer.displayFrame, config[i]);
852            }
853            else {
854                exynos5_config_overlay(&layer, config[i],
855                        pdata->pdev->gralloc_module);
856            }
857        }
858        ALOGV("window %u configuration:", i);
859        dump_config(config[i]);
860    }
861
862    int ret = ioctl(pdata->pdev->fd, S3CFB_WIN_CONFIG, &win_data);
863    if (ret < 0)
864        ALOGE("ioctl S3CFB_WIN_CONFIG failed: %d", errno);
865
866    if (pdata->pdev->hdmi_mirroring)
867        hdmi_output(pdata->pdev, fb);
868
869    pthread_mutex_lock(&pdata->completion_lock);
870    pdata->fence = win_data.fence;
871    pthread_cond_signal(&pdata->completion);
872    pthread_mutex_unlock(&pdata->completion_lock);
873}
874
875static int exynos5_set(struct hwc_composer_device_1 *dev, hwc_display_t dpy,
876        hwc_surface_t sur, hwc_layer_list_1_t* list)
877{
878    exynos5_hwc_composer_device_1_t *pdev =
879            (exynos5_hwc_composer_device_1_t *)dev;
880
881    if (!dpy || !sur)
882        return 0;
883
884    hwc_callback_queue_t *queue = NULL;
885    pthread_mutex_t *lock = NULL;
886    exynos5_hwc_post_data_t *data = NULL;
887
888    if (list) {
889        for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
890            if (pdev->bufs.overlay_map[i] != -1) {
891                pdev->bufs.overlays[i] =
892                    list->hwLayers[pdev->bufs.overlay_map[i]];
893            }
894        }
895
896        data = (exynos5_hwc_post_data_t *)
897                malloc(sizeof(exynos5_hwc_post_data_t));
898        memcpy(data, &pdev->bufs, sizeof(pdev->bufs));
899
900        data->fence = -1;
901        pthread_mutex_init(&data->completion_lock, NULL);
902        pthread_cond_init(&data->completion, NULL);
903
904        if (pdev->bufs.fb_window == NO_FB_NEEDED) {
905            exynos5_post_callback(data, NULL);
906        } else {
907
908            struct hwc_callback_entry entry;
909            entry.callback = exynos5_post_callback;
910            entry.data = data;
911
912            queue = reinterpret_cast<hwc_callback_queue_t *>(
913                pdev->gralloc_module->queue);
914            lock = const_cast<pthread_mutex_t *>(
915                &pdev->gralloc_module->queue_lock);
916
917            pthread_mutex_lock(lock);
918            queue->push_front(entry);
919            pthread_mutex_unlock(lock);
920
921            EGLBoolean success = eglSwapBuffers((EGLDisplay)dpy,
922                    (EGLSurface)sur);
923            if (!success) {
924                ALOGE("HWC_EGL_ERROR");
925                if (list) {
926                    pthread_mutex_lock(lock);
927                    queue->removeAt(0);
928                    pthread_mutex_unlock(lock);
929                    free(data);
930                }
931                return HWC_EGL_ERROR;
932            }
933        }
934    }
935
936
937    pthread_mutex_lock(&data->completion_lock);
938    while (data->fence == -1)
939        pthread_cond_wait(&data->completion, &data->completion_lock);
940    pthread_mutex_unlock(&data->completion_lock);
941
942    for (size_t i = 0; i < NUM_HW_WINDOWS; i++) {
943        if (pdev->bufs.overlay_map[i] != -1) {
944            int dup_fd = dup(data->fence);
945            if (dup_fd < 0)
946                ALOGW("release fence dup failed: %s", strerror(errno));
947            list->hwLayers[pdev->bufs.overlay_map[i]].releaseFenceFd = dup_fd;
948        }
949    }
950    close(data->fence);
951    free(data);
952    return 0;
953}
954
955static void exynos5_registerProcs(struct hwc_composer_device_1* dev,
956        hwc_procs_t const* procs)
957{
958    struct exynos5_hwc_composer_device_1_t* pdev =
959            (struct exynos5_hwc_composer_device_1_t*)dev;
960    pdev->procs = const_cast<hwc_procs_t *>(procs);
961}
962
963static int exynos5_query(struct hwc_composer_device_1* dev, int what, int *value)
964{
965    struct exynos5_hwc_composer_device_1_t *pdev =
966            (struct exynos5_hwc_composer_device_1_t *)dev;
967
968    switch (what) {
969    case HWC_BACKGROUND_LAYER_SUPPORTED:
970        // we support the background layer
971        value[0] = 1;
972        break;
973    case HWC_VSYNC_PERIOD:
974        // vsync period in nanosecond
975        value[0] = 1000000000.0 / pdev->gralloc_module->fps;
976        break;
977    default:
978        // unsupported query
979        return -EINVAL;
980    }
981    return 0;
982}
983
984static int exynos5_eventControl(struct hwc_composer_device_1 *dev, int event,
985        int enabled)
986{
987    struct exynos5_hwc_composer_device_1_t *pdev =
988            (struct exynos5_hwc_composer_device_1_t *)dev;
989
990    switch (event) {
991    case HWC_EVENT_VSYNC:
992        __u32 val = !!enabled;
993        int err = ioctl(pdev->fd, S3CFB_SET_VSYNC_INT, &val);
994        if (err < 0) {
995            ALOGE("vsync ioctl failed");
996            return -errno;
997        }
998
999        return 0;
1000    }
1001
1002    return -EINVAL;
1003}
1004
1005static void handle_hdmi_uevent(struct exynos5_hwc_composer_device_1_t *pdev,
1006        const char *buff, int len)
1007{
1008    const char *s = buff;
1009    s += strlen(s) + 1;
1010
1011    while (*s) {
1012        if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE=")))
1013            pdev->hdmi_hpd = atoi(s + strlen("SWITCH_STATE=")) == 1;
1014
1015        s += strlen(s) + 1;
1016        if (s - buff >= len)
1017            break;
1018    }
1019
1020    ALOGV("HDMI HPD changed to %s", pdev->hdmi_hpd ? "enabled" : "disabled");
1021
1022    if (pdev->procs && pdev->procs->invalidate)
1023        pdev->procs->invalidate(pdev->procs);
1024}
1025
1026static void handle_vsync_event(struct exynos5_hwc_composer_device_1_t *pdev)
1027{
1028    if (!pdev->procs || !pdev->procs->vsync)
1029        return;
1030
1031    int err = lseek(pdev->vsync_fd, 0, SEEK_SET);
1032    if (err < 0) {
1033        ALOGE("error seeking to vsync timestamp: %s", strerror(errno));
1034        return;
1035    }
1036
1037    char buf[4096];
1038    err = read(pdev->vsync_fd, buf, sizeof(buf));
1039    if (err < 0) {
1040        ALOGE("error reading vsync timestamp: %s", strerror(errno));
1041        return;
1042    }
1043    buf[sizeof(buf) - 1] = '\0';
1044
1045    errno = 0;
1046    uint64_t timestamp = strtoull(buf, NULL, 0);
1047    if (!errno)
1048        pdev->procs->vsync(pdev->procs, 0, timestamp);
1049}
1050
1051static void *hwc_vsync_thread(void *data)
1052{
1053    struct exynos5_hwc_composer_device_1_t *pdev =
1054            (struct exynos5_hwc_composer_device_1_t *)data;
1055    char uevent_desc[4096];
1056    memset(uevent_desc, 0, sizeof(uevent_desc));
1057
1058    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
1059
1060    uevent_init();
1061
1062    char temp[4096];
1063    int err = read(pdev->vsync_fd, temp, sizeof(temp));
1064    if (err < 0) {
1065        ALOGE("error reading vsync timestamp: %s", strerror(errno));
1066        return NULL;
1067    }
1068
1069    struct pollfd fds[2];
1070    fds[0].fd = pdev->vsync_fd;
1071    fds[0].events = POLLPRI;
1072    fds[1].fd = uevent_get_fd();
1073    fds[1].events = POLLIN;
1074
1075    while (true) {
1076        int err = poll(fds, 2, -1);
1077
1078        if (err > 0) {
1079            if (fds[0].revents & POLLPRI) {
1080                handle_vsync_event(pdev);
1081            }
1082            else if (fds[1].revents & POLLIN) {
1083                int len = uevent_next_event(uevent_desc,
1084                        sizeof(uevent_desc) - 2);
1085
1086                bool hdmi = !strcmp(uevent_desc,
1087                        "change@/devices/virtual/switch/hdmi");
1088                if (hdmi)
1089                    handle_hdmi_uevent(pdev, uevent_desc, len);
1090            }
1091        }
1092        else if (err == -1) {
1093            if (errno == EINTR)
1094                break;
1095            ALOGE("error in vsync thread: %s", strerror(errno));
1096        }
1097    }
1098
1099    return NULL;
1100}
1101
1102static int exynos5_blank(struct hwc_composer_device_1 *dev, int blank)
1103{
1104    struct exynos5_hwc_composer_device_1_t *pdev =
1105            (struct exynos5_hwc_composer_device_1_t *)dev;
1106
1107    int fb_blank = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK;
1108    int err = ioctl(pdev->fd, FBIOBLANK, fb_blank);
1109    if (err < 0) {
1110        ALOGE("%sblank ioctl failed", blank ? "" : "un");
1111        return -errno;
1112    }
1113
1114    return 0;
1115}
1116
1117struct hwc_methods_1 exynos5_methods = {
1118    eventControl: exynos5_eventControl,
1119    blank: exynos5_blank,
1120};
1121
1122static int exynos5_close(hw_device_t* device);
1123
1124static int exynos5_open(const struct hw_module_t *module, const char *name,
1125        struct hw_device_t **device)
1126{
1127    int ret;
1128    int sw_fd;
1129
1130    if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
1131        return -EINVAL;
1132    }
1133
1134    struct exynos5_hwc_composer_device_1_t *dev;
1135    dev = (struct exynos5_hwc_composer_device_1_t *)malloc(sizeof(*dev));
1136    memset(dev, 0, sizeof(*dev));
1137
1138    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
1139            (const struct hw_module_t **)&dev->gralloc_module)) {
1140        ALOGE("failed to get gralloc hw module");
1141        ret = -EINVAL;
1142        goto err_get_module;
1143    }
1144
1145    if (gralloc_open((const hw_module_t *)dev->gralloc_module,
1146            &dev->alloc_device)) {
1147        ALOGE("failed to open gralloc");
1148        ret = -EINVAL;
1149        goto err_get_module;
1150    }
1151
1152    dev->fd = open("/dev/graphics/fb0", O_RDWR);
1153    if (dev->fd < 0) {
1154        ALOGE("failed to open framebuffer");
1155        ret = dev->fd;
1156        goto err_open_fb;
1157    }
1158
1159    dev->vsync_fd = open("/sys/devices/platform/exynos5-fb.1/vsync", O_RDONLY);
1160    if (dev->vsync_fd < 0) {
1161        ALOGE("failed to open vsync attribute");
1162        ret = dev->vsync_fd;
1163        goto err_ioctl;
1164    }
1165
1166    sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY);
1167    if (sw_fd) {
1168        char val;
1169        if (read(sw_fd, &val, 1) == 1 && val == '1')
1170            dev->hdmi_hpd = true;
1171    }
1172
1173    dev->base.common.tag = HARDWARE_DEVICE_TAG;
1174    dev->base.common.version = HWC_DEVICE_API_VERSION_1_0;
1175    dev->base.common.module = const_cast<hw_module_t *>(module);
1176    dev->base.common.close = exynos5_close;
1177
1178    dev->base.prepare = exynos5_prepare;
1179    dev->base.set = exynos5_set;
1180    dev->base.registerProcs = exynos5_registerProcs;
1181    dev->base.query = exynos5_query;
1182    dev->base.methods = &exynos5_methods;
1183
1184    dev->bufs.pdev = dev;
1185
1186    *device = &dev->base.common;
1187
1188    ret = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev);
1189    if (ret) {
1190        ALOGE("failed to start vsync thread: %s", strerror(ret));
1191        ret = -ret;
1192        goto err_vsync;
1193    }
1194
1195    return 0;
1196
1197err_vsync:
1198    close(dev->vsync_fd);
1199err_ioctl:
1200    close(dev->fd);
1201err_open_fb:
1202    gralloc_close(dev->alloc_device);
1203err_get_module:
1204    free(dev);
1205    return ret;
1206}
1207
1208static int exynos5_close(hw_device_t *device)
1209{
1210    struct exynos5_hwc_composer_device_1_t *dev =
1211            (struct exynos5_hwc_composer_device_1_t *)device;
1212    pthread_kill(dev->vsync_thread, SIGTERM);
1213    pthread_join(dev->vsync_thread, NULL);
1214    for (size_t i = 0; i < NUM_GSC_UNITS; i++) {
1215        if (dev->gsc[i].gsc)
1216            exynos_gsc_destroy(dev->gsc[i].gsc);
1217        for (size_t j = 0; i < NUM_GSC_DST_BUFS; j++)
1218            if (dev->gsc[i].dst_buf[j])
1219                dev->alloc_device->free(dev->alloc_device, dev->gsc[i].dst_buf[j]);
1220    }
1221    gralloc_close(dev->alloc_device);
1222    close(dev->vsync_fd);
1223    close(dev->fd);
1224    return 0;
1225}
1226
1227static struct hw_module_methods_t exynos5_hwc_module_methods = {
1228    open: exynos5_open,
1229};
1230
1231hwc_module_t HAL_MODULE_INFO_SYM = {
1232    common: {
1233        tag: HARDWARE_MODULE_TAG,
1234        module_api_version: HWC_MODULE_API_VERSION_0_1,
1235        hal_api_version: HARDWARE_HAL_API_VERSION,
1236        id: HWC_HARDWARE_MODULE_ID,
1237        name: "Samsung exynos5 hwcomposer module",
1238        author: "Google",
1239        methods: &exynos5_hwc_module_methods,
1240    }
1241};
1242