hwc.cpp revision eba34a93004e81973d22d7523a0edf3eb79b8445
186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann/* 286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * Copyright (C) 2012 The Android Open Source Project 386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * 486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * Licensed under the Apache License, Version 2.0 (the "License"); 586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * you may not use this file except in compliance with the License. 686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * You may obtain a copy of the License at 786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * 886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * http://www.apache.org/licenses/LICENSE-2.0 986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * 1086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * Unless required by applicable law or agreed to in writing, software 1186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * distributed under the License is distributed on an "AS IS" BASIS, 1286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * See the License for the specific language governing permissions and 1486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann * limitations under the License. 1586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann */ 1686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <errno.h> 1786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <fcntl.h> 182972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann#include <poll.h> 1986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <pthread.h> 2086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <stdio.h> 2186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <stdlib.h> 2286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 2386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <sys/ioctl.h> 2486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <sys/mman.h> 2586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <sys/time.h> 2686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <sys/resource.h> 2786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 2886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <s3c-fb.h> 2986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 3086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <EGL/egl.h> 3186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 3287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling#define HWC_REMOVE_DEPRECATED_VERSIONS 1 3387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 3486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <cutils/log.h> 3586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <hardware/gralloc.h> 3686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <hardware/hardware.h> 3786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <hardware/hwcomposer.h> 3886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <hardware_legacy/uevent.h> 3986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <utils/Vector.h> 4086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 41f4cc0c30da5158aba393c5b3b566ad6f210072fcGreg Hackmann#include <sync/sync.h> 42f4cc0c30da5158aba393c5b3b566ad6f210072fcGreg Hackmann 4386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include "ion.h" 4486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include "gralloc_priv.h" 45cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby#include "exynos_gscaler.h" 469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann#include "exynos_format.h" 47d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby#include "videodev2.h" 4886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 49f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmannstruct hwc_callback_entry { 50f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann void (*callback)(void *, private_handle_t *); 51f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann void *data; 5286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 5386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmanntypedef android::Vector<struct hwc_callback_entry> hwc_callback_queue_t; 5486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 5531991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmannconst size_t NUM_HW_WINDOWS = 5; 5686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannconst size_t NO_FB_NEEDED = NUM_HW_WINDOWS + 1; 5731991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmannconst size_t MAX_PIXELS = 2560 * 1600 * 2; 589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannconst size_t GSC_W_ALIGNMENT = 16; 599130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannconst size_t GSC_H_ALIGNMENT = 16; 602ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmannconst int AVAILABLE_GSC_UNITS[] = { 0, 3 }; 612ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmannconst size_t NUM_GSC_UNITS = sizeof(AVAILABLE_GSC_UNITS) / 622ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmann sizeof(AVAILABLE_GSC_UNITS[0]); 6386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 6487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstruct exynos5_hwc_composer_device_1_t; 6586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 669130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstruct exynos5_gsc_map_t { 679130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann enum { 689130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann GSC_NONE = 0, 699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann GSC_M2M, 709130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // TODO: GSC_LOCAL_PATH 719130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } mode; 729130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int idx; 739130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann}; 749130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstruct exynos5_hwc_post_data_t { 76f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_composer_device_1_t *pdev; 77f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int overlay_map[NUM_HW_WINDOWS]; 789130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_gsc_map_t gsc_map[NUM_HW_WINDOWS]; 79f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_layer_1_t overlays[NUM_HW_WINDOWS]; 80f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int num_overlays; 81f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann size_t fb_window; 82f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int fence; 83f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pthread_mutex_t completion_lock; 84f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pthread_cond_t completion; 8586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 8686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 879130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannconst size_t NUM_GSC_DST_BUFS = 2; 889130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstruct exynos5_gsc_data_t { 899130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann void *gsc; 909130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_img src_cfg; 919130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_img dst_cfg; 929130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann buffer_handle_t dst_buf[NUM_GSC_DST_BUFS]; 939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann size_t current_buf; 949130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann}; 959130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstruct exynos5_hwc_composer_device_1_t { 97f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_composer_device_1_t base; 9886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 99f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int fd; 1002972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann int vsync_fd; 101f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_post_data_t bufs; 10286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 103f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const private_module_t *gralloc_module; 1049130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann alloc_device_t *alloc_device; 105f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_procs_t *procs; 106f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pthread_t vsync_thread; 107cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 108d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby int hdmi_fd; 109f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool hdmi_hpd; 110f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool hdmi_mirroring; 111f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann void *hdmi_gsc; 112d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby exynos_gsc_img hdmi_cfg; 1139130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 1149130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_gsc_data_t gsc[NUM_GSC_UNITS]; 11586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 11686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1179130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic void dump_handle(private_handle_t *h) 1189130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 119eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann ALOGV("\t\tformat = %d, width = %u, height = %u, stride = %u, vstride = %u", 120eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann h->format, h->width, h->height, h->stride, h->vstride); 1219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 1229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 12387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic void dump_layer(hwc_layer_1_t const *l) 12486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 125f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, " 126f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann "{%d,%d,%d,%d}, {%d,%d,%d,%d}", 127f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->compositionType, l->flags, l->handle, l->transform, 128f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->blending, 129f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->sourceCrop.left, 130f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->sourceCrop.top, 131f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->sourceCrop.right, 132f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->sourceCrop.bottom, 133f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->displayFrame.left, 134f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->displayFrame.top, 135f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->displayFrame.right, 136f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->displayFrame.bottom); 13786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1389130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if(l->handle && !(l->flags & HWC_SKIP_LAYER)) 1399130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dump_handle(private_handle_t::dynamicCast(l->handle)); 14086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 14186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 14286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic void dump_config(s3c_fb_win_config &c) 14386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 144f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\tstate = %u", c.state); 145f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (c.state == c.S3C_FB_WIN_STATE_BUFFER) { 146f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\t\tfd = %d, offset = %u, stride = %u, " 147f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann "x = %d, y = %d, w = %u, h = %u, " 14893cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann "format = %u, blending = %u", 149f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann c.fd, c.offset, c.stride, 150f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann c.x, c.y, c.w, c.h, 15193cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann c.format, c.blending); 152f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 153f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann else if (c.state == c.S3C_FB_WIN_STATE_COLOR) { 154f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\t\tcolor = %u", c.color); 155f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 15686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 15786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic void dump_gsc_img(exynos_gsc_img &c) 1599130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 1609130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tx = %u, y = %u, w = %u, h = %u, fw = %u, fh = %u", 1619130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c.x, c.y, c.w, c.h, c.fw, c.fh); 1629130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\taddr = {%u, %u, %u}, rot = %u, cacheable = %u, drmMode = %u", 1639130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c.yaddr, c.uaddr, c.vaddr, c.rot, c.cacheable, c.drmMode); 1649130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 1659130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 16686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmanninline int WIDTH(const hwc_rect &rect) { return rect.right - rect.left; } 16786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmanninline int HEIGHT(const hwc_rect &rect) { return rect.bottom - rect.top; } 16831991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmanntemplate<typename T> inline T max(T a, T b) { return (a > b) ? a : b; } 16931991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmanntemplate<typename T> inline T min(T a, T b) { return (a < b) ? a : b; } 17031991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann 17131991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmannstatic bool is_transformed(const hwc_layer_1_t &layer) 17231991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann{ 173f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return layer.transform != 0; 17431991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann} 17586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1769130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic bool is_rotated(const hwc_layer_1_t &layer) 1779130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 1789130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return (layer.transform & HAL_TRANSFORM_ROT_90) || 1799130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann (layer.transform & HAL_TRANSFORM_ROT_180); 1809130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 1819130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 18287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic bool is_scaled(const hwc_layer_1_t &layer) 18386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 184f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return WIDTH(layer.displayFrame) != WIDTH(layer.sourceCrop) || 185f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann HEIGHT(layer.displayFrame) != HEIGHT(layer.sourceCrop); 18686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 18786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 18886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic enum s3c_fb_pixel_format exynos5_format_to_s3c_format(int format) 18986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 190f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann switch (format) { 191f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_8888: 192f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return S3C_FB_PIXEL_FORMAT_RGBA_8888; 193f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBX_8888: 194f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return S3C_FB_PIXEL_FORMAT_RGBX_8888; 195f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_5551: 196f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return S3C_FB_PIXEL_FORMAT_RGBA_5551; 197f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 198f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann default: 199f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return S3C_FB_PIXEL_FORMAT_MAX; 200f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 20186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 20286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 20386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic bool exynos5_format_is_supported(int format) 20486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 205f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return exynos5_format_to_s3c_format(format) < S3C_FB_PIXEL_FORMAT_MAX; 20686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 20786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 20886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic bool exynos5_format_is_supported_by_gscaler(int format) 20986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 2109130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann switch (format) { 211f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBX_8888: 212f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGB_565: 213f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_YV12: 2149130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_420_P: 2159130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_422_SP: 2169130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: 2179130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_420_SP: 2189130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: 2199130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_422_I: 2209130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: 2219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_422_P: 2229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CbYCrY_422_I: 2239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: 2249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCrCb_422_SP: 2259130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: 2269130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCrCb_420_SP: 2279130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: 2289130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 2299130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: 2309130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: 2319130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: 232f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return true; 233f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 234f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann default: 235f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return false; 236f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 23786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 23886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 239296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmannstatic bool exynos5_format_is_ycrcb(int format) 240296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann{ 241296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann return format == HAL_PIXEL_FORMAT_YV12; 242296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann} 243296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann 2449130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic bool exynos5_format_requires_gscaler(int format) 2459130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 2469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return exynos5_format_is_supported_by_gscaler(format) && 2479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann format != HAL_PIXEL_FORMAT_RGBX_8888; 2489130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 2499130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 25086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic uint8_t exynos5_format_to_bpp(int format) 25186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 252f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann switch (format) { 253f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_8888: 254f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBX_8888: 255f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 32; 256f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 257f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_5551: 258f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_4444: 259f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 16; 260f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 261f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann default: 262f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGW("unrecognized pixel format %u", format); 263f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 264f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 26586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 26686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 267227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmannstatic bool exynos5_supports_gscaler(hwc_layer_1_t &layer, int format, 268227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann bool local_path) 2699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 2709130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = private_handle_t::dynamicCast(layer.handle); 2719130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 2729130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int max_w = is_rotated(layer) ? 2048 : 4800; 2739130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int max_h = is_rotated(layer) ? 2048 : 3344; 2749130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 2759130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann bool rot90or270 = !!(layer.transform & HAL_TRANSFORM_ROT_90); 2769130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // n.b.: HAL_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_90 | 2779130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // HAL_TRANSFORM_ROT_180 2789130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 279227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann int src_w = WIDTH(layer.sourceCrop), src_h = HEIGHT(layer.sourceCrop); 280227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann int dest_w, dest_h; 281227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann if (rot90or270) { 282227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_w = HEIGHT(layer.displayFrame); 283227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_h = WIDTH(layer.displayFrame); 284227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann } else { 285227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_w = WIDTH(layer.displayFrame); 286227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_h = HEIGHT(layer.displayFrame); 287227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann } 288227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann int max_downscale = local_path ? 4 : 16; 289227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann const int max_upscale = 8; 290227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann 2919130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return exynos5_format_is_supported_by_gscaler(format) && 2929130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann handle->stride <= max_w && 2939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann handle->stride % GSC_W_ALIGNMENT == 0 && 294227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann src_w <= dest_w * max_downscale && 295227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_w <= src_w * max_upscale && 296eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann handle->vstride <= max_h && 297eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann handle->vstride % GSC_H_ALIGNMENT == 0 && 298227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann src_h <= dest_h * max_downscale && 299227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_h <= src_h * max_upscale && 3009130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // per 46.2 3019130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann (!rot90or270 || layer.sourceCrop.top % 2 == 0) && 3029130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann (!rot90or270 || layer.sourceCrop.left % 2 == 0); 3039130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // per 46.3.1.6 3049130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 3059130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 306d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Gobyint hdmi_get_config(struct exynos5_hwc_composer_device_1_t *dev) 307d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby{ 308d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby struct v4l2_dv_preset preset; 309d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby struct v4l2_dv_enum_preset enum_preset; 310d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby exynos_gsc_img *info = &dev->hdmi_cfg; 311d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby int index = 0; 312d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby bool found = false; 313d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby int ret; 314d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 315d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (ioctl(dev->hdmi_fd, VIDIOC_G_DV_PRESET, &preset) < 0) { 316d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGE("%s: g_dv_preset error, %d", __func__, errno); 317d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby return -1; 318d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 319d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 320d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby while (true) { 321d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby enum_preset.index = index++; 322d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ret = ioctl(dev->hdmi_fd, VIDIOC_ENUM_DV_PRESETS, &enum_preset); 323d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 324d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (ret < 0) { 325d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (errno == EINVAL) 326d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby break; 327d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGE("%s: enum_dv_presets error, %d", __func__, errno); 328d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby return -1; 329d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 330d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 331d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGV("%s: %d preset=%02d width=%d height=%d name=%s", 332d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby __func__, enum_preset.index, enum_preset.preset, 333d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby enum_preset.width, enum_preset.height, enum_preset.name); 334d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 335d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (preset.preset == enum_preset.preset) { 336d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby info->w = enum_preset.width; 337d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby info->h = enum_preset.height; 338d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby info->fw = enum_preset.width; 339d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby info->fh = enum_preset.height; 340d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby info->format = HAL_PIXEL_FORMAT_YV12; 341d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby found = true; 342d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 343d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 344d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 345d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby return found ? 0 : -1; 346d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby} 347d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 34893cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmannstatic enum s3c_fb_blending exynos5_blending_to_s3c_blending(int32_t blending) 34993cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann{ 35093cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann switch (blending) { 35193cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann case HWC_BLENDING_NONE: 35293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return S3C_FB_BLENDING_NONE; 35393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann case HWC_BLENDING_PREMULT: 35493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return S3C_FB_BLENDING_PREMULT; 35593cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann case HWC_BLENDING_COVERAGE: 35693cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return S3C_FB_BLENDING_COVERAGE; 35793cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann 35893cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann default: 35993cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return S3C_FB_BLENDING_MAX; 36093cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann } 36193cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann} 36293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann 36393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmannstatic bool exynos5_blending_is_supported(int32_t blending) 36493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann{ 36593cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return exynos5_blending_to_s3c_blending(blending) < S3C_FB_BLENDING_MAX; 36693cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann} 36793cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann 368cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Gobystatic int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev) 369cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby{ 370f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (dev->hdmi_mirroring) 371f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 372f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 373f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos_gsc_img src_info; 374f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int src_w = 2560; 375f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int src_h = 1600; 376f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 377f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_gsc = exynos_gsc_create_exclusive(3, GSC_OUTPUT_MODE, GSC_OUT_TV); 378f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!dev->hdmi_gsc) { 379f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("%s: exynos_gsc_create_exclusive failed", __func__); 380f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -ENODEV; 381f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 382f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 383f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(&src_info, 0, sizeof(src_info)); 384f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 385f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann src_info.w = src_w; 386f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann src_info.h = src_h; 387f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann src_info.fw = src_w; 388f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann src_info.fh = src_h; 389f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann src_info.format = HAL_PIXEL_FORMAT_BGRA_8888; 390f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 391d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby int ret = exynos_gsc_config_exclusive(dev->hdmi_gsc, &src_info, &dev->hdmi_cfg); 392f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (ret < 0) { 393f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("%s: exynos_gsc_config_exclusive failed %d", __func__, ret); 394f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos_gsc_destroy(dev->hdmi_gsc); 395f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_gsc = NULL; 396f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return ret; 397f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 398f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 399f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_mirroring = true; 400f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 401cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby} 402cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 403cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Gobystatic void hdmi_disable(struct exynos5_hwc_composer_device_1_t *dev) 404cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby{ 405f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!dev->hdmi_mirroring) 406f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return; 407f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos_gsc_destroy(dev->hdmi_gsc); 408f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_gsc = NULL; 409f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_mirroring = false; 410cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby} 411cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 412cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Gobystatic int hdmi_output(struct exynos5_hwc_composer_device_1_t *dev, private_handle_t *fb) 413cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby{ 414f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos_gsc_img src_info; 415f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos_gsc_img dst_info; 416cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 417f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(&src_info, 0, sizeof(src_info)); 418f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(&dst_info, 0, sizeof(dst_info)); 419cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 420f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann src_info.yaddr = fb->fd; 421cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 422f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int ret = exynos_gsc_run_exclusive(dev->hdmi_gsc, &src_info, &dst_info); 423f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (ret < 0) { 424f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("%s: exynos_gsc_run_exclusive failed %d", __func__, ret); 425f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return ret; 426f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 427cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 428f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 429cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby} 430cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 431f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmannbool exynos5_supports_overlay(hwc_layer_1_t &layer, size_t i) 432f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann{ 433d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann if (layer.flags & HWC_SKIP_LAYER) { 434d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann ALOGV("\tlayer %u: skipping", i); 435d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann return false; 436d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann } 437d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann 438f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann private_handle_t *handle = private_handle_t::dynamicCast(layer.handle); 439f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 440f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!handle) { 441f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\tlayer %u: handle is NULL", i); 442f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return false; 443f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 4449130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (exynos5_format_requires_gscaler(handle->format)) { 445227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann if (!exynos5_supports_gscaler(layer, handle->format, false)) { 4469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tlayer %u: gscaler required but not supported", i); 4479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return false; 4489130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 4499130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } else { 4509130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (!exynos5_format_is_supported(handle->format)) { 4519130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tlayer %u: pixel format %u not supported", i, handle->format); 4529130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return false; 4539130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 4549130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (is_scaled(layer)) { 4559130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tlayer %u: scaling not supported", i); 4569130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return false; 4579130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 4589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (is_transformed(layer)) { 4599130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tlayer %u: transformations not supported", i); 4609130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return false; 4619130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 462f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 46393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann if (!exynos5_blending_is_supported(layer.blending)) { 46493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann ALOGV("\tlayer %u: blending %d not supported", i, layer.blending); 465f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return false; 466f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 467f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 468f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return true; 46986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 47086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 47131991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmanninline bool intersect(const hwc_rect &r1, const hwc_rect &r2) 47231991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann{ 473f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return !(r1.left > r2.right || 474f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann r1.right < r2.left || 475f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann r1.top > r2.bottom || 476f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann r1.bottom < r2.top); 47731991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann} 47831991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann 47931991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmanninline hwc_rect intersection(const hwc_rect &r1, const hwc_rect &r2) 48031991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann{ 481f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect i; 482f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann i.top = max(r1.top, r2.top); 483f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann i.bottom = min(r1.bottom, r2.bottom); 484f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann i.left = max(r1.left, r2.left); 485f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann i.right = min(r1.right, r2.right); 486f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return i; 48731991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann} 48831991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann 489e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hallstatic int exynos5_prepare(hwc_composer_device_1_t *dev, 490e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall size_t numDisplays, hwc_display_contents_1_t** displays) 49186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 492e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall if (!numDisplays || !displays) 493f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 49486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 495e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall ALOGV("preparing %u layers", displays[0]->numHwLayers); 49686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 497f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_composer_device_1_t *pdev = 498f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (exynos5_hwc_composer_device_1_t *)dev; 499f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(pdev->bufs.overlays, 0, sizeof(pdev->bufs.overlays)); 5009130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann memset(pdev->bufs.gsc_map, 0, sizeof(pdev->bufs.gsc_map)); 50186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 502f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool force_fb = false; 503f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (pdev->hdmi_hpd) { 504f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hdmi_enable(pdev); 505f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann force_fb = true; 506f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } else { 507f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hdmi_disable(pdev); 508f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 509cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 51087e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling for (size_t i = 0; i < NUM_HW_WINDOWS; i++) 51187e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pdev->bufs.overlay_map[i] = -1; 51287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 513f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool fb_needed = false; 514f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann size_t first_fb = 0, last_fb = 0; 515f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 516f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // find unsupported overlays 517e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 518e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 519f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 520f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer.compositionType == HWC_BACKGROUND && !force_fb) { 521f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\tlayer %u: background supported", i); 522e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall dump_layer(&displays[0]->hwLayers[i]); 523f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 524f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 525f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 526e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall if (exynos5_supports_overlay(displays[0]->hwLayers[i], i) && !force_fb) { 527f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\tlayer %u: overlay supported", i); 528f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann layer.compositionType = HWC_OVERLAY; 529e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall dump_layer(&displays[0]->hwLayers[i]); 530f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 531f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 532f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 533f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!fb_needed) { 534f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann first_fb = i; 535f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_needed = true; 536f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 537f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann last_fb = i; 538f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann layer.compositionType = HWC_FRAMEBUFFER; 5399130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 540e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall dump_layer(&displays[0]->hwLayers[i]); 541f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 542f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 543f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // can't composite overlays sandwiched between framebuffers 544f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (fb_needed) 545f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t i = first_fb; i < last_fb; i++) 546e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall displays[0]->hwLayers[i].compositionType = HWC_FRAMEBUFFER; 547f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 548f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // Incrementally try to add our supported layers to hardware windows. 549f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // If adding a layer would violate a hardware constraint, force it 550f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // into the framebuffer and try again. (Revisiting the entire list is 551f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // necessary because adding a layer to the framebuffer can cause other 552f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // windows to retroactively violate constraints.) 553f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool changed; 554f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann do { 555f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann android::Vector<hwc_rect> rects; 556f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann android::Vector<hwc_rect> overlaps; 5579130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann size_t pixels_left, windows_left, gsc_left = NUM_GSC_UNITS; 558f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 559f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (fb_needed) { 560f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect_t fb_rect; 561f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_rect.top = fb_rect.left = 0; 562f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_rect.right = pdev->gralloc_module->xres - 1; 563f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_rect.bottom = pdev->gralloc_module->yres - 1; 564f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pixels_left = MAX_PIXELS - pdev->gralloc_module->xres * 565f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->gralloc_module->yres; 566f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann windows_left = NUM_HW_WINDOWS - 1; 567f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann rects.push_back(fb_rect); 568f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 569f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann else { 570f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pixels_left = MAX_PIXELS; 571f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann windows_left = NUM_HW_WINDOWS; 572f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 5739130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (pdev->hdmi_mirroring) 5749130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_left--; 5759130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 576f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann changed = false; 577f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 578e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 579e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 5809130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (layer.flags & HWC_SKIP_LAYER) 5819130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann continue; 5829130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 5839130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = private_handle_t::dynamicCast( 5849130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann layer.handle); 585f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 586f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // we've already accounted for the framebuffer above 587f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer.compositionType == HWC_FRAMEBUFFER) 588f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 589f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 590f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // only layer 0 can be HWC_BACKGROUND, so we can 591f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // unconditionally allow it without extra checks 592f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer.compositionType == HWC_BACKGROUND) { 593f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann windows_left--; 594f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 595f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 596f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 597f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann size_t pixels_needed = WIDTH(layer.displayFrame) * 598f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann HEIGHT(layer.displayFrame); 599f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool can_compose = windows_left && pixels_needed <= pixels_left; 6009130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann bool gsc_required = exynos5_format_requires_gscaler(handle->format); 6019130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_required) 6029130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann can_compose = can_compose && gsc_left; 603f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 604f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // hwc_rect_t right and bottom values are normally exclusive; 605f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // the intersection logic is simpler if we make them inclusive 606f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect_t visible_rect = layer.displayFrame; 607f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann visible_rect.right--; visible_rect.bottom--; 608f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 609f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // no more than 2 layers can overlap on a given pixel 610f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t j = 0; can_compose && j < overlaps.size(); j++) { 611f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (intersect(visible_rect, overlaps.itemAt(j))) 612f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann can_compose = false; 613f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 614f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 615f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!can_compose) { 616f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann layer.compositionType = HWC_FRAMEBUFFER; 617f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!fb_needed) { 618f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann first_fb = last_fb = i; 619f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_needed = true; 620f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 621f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann else { 622f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann first_fb = min(i, first_fb); 623f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann last_fb = max(i, last_fb); 624f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 625f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann changed = true; 626f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann break; 627f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 628f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 629f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t j = 0; j < rects.size(); j++) { 630f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const hwc_rect_t &other_rect = rects.itemAt(j); 631f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (intersect(visible_rect, other_rect)) 632f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann overlaps.push_back(intersection(visible_rect, other_rect)); 633f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 634f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann rects.push_back(visible_rect); 635f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pixels_left -= pixels_needed; 636f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann windows_left--; 6379130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_required) 6389130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_left--; 639f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 640f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 641f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (changed) 642f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t i = first_fb; i < last_fb; i++) 643e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall displays[0]->hwLayers[i].compositionType = HWC_FRAMEBUFFER; 644f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } while(changed); 645f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 646f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann unsigned int nextWindow = 0; 6479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int nextGsc = 0; 648f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 649e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 650e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 651f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 652f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (fb_needed && i == first_fb) { 653f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("assigning framebuffer to window %u\n", 654f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann nextWindow); 655f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann nextWindow++; 656f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 657f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 658f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 659f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer.compositionType != HWC_FRAMEBUFFER) { 660f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("assigning layer %u to window %u", i, nextWindow); 661f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->bufs.overlay_map[nextWindow] = i; 6629130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (layer.compositionType == HWC_OVERLAY) { 6639130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = 6649130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t::dynamicCast(layer.handle); 6659130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (exynos5_format_requires_gscaler(handle->format)) { 6662ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmann ALOGV("\tusing gscaler %u", AVAILABLE_GSC_UNITS[nextGsc]); 6679130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdev->bufs.gsc_map[i].mode = 6689130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_gsc_map_t::GSC_M2M; 6699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdev->bufs.gsc_map[i].idx = nextGsc++; 6709130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 6719130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 672f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann nextWindow++; 673f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 674f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 675f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 6769130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = nextGsc; i < NUM_GSC_UNITS; i++) { 6779130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t j = 0; j < NUM_GSC_DST_BUFS; j++) 6789130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (pdev->gsc[i].dst_buf[j]) 6799130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdev->alloc_device->free(pdev->alloc_device, 6809130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdev->gsc[i].dst_buf[j]); 6819130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann memset(&pdev->gsc[i], 0, sizeof(pdev->gsc[i])); 6829130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 6839130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 684f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (fb_needed) 685f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->bufs.fb_window = first_fb; 686f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann else 687f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->bufs.fb_window = NO_FB_NEEDED; 688f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 6899130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return 0; 6909130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 6919130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 6929130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic inline bool gsc_dst_cfg_changed(exynos_gsc_img &c1, exynos_gsc_img &c2) 6939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 6949130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return c1.x != c2.x || 6959130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.y != c2.y || 6969130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.w != c2.w || 6979130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.h != c2.h || 6989130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.format != c2.format || 6999130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.rot != c2.rot || 7009130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.cacheable != c2.cacheable || 7019130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.drmMode != c2.drmMode; 7029130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 7039130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7049130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic inline bool gsc_src_cfg_changed(exynos_gsc_img &c1, exynos_gsc_img &c2) 7059130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 7069130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return gsc_dst_cfg_changed(c1, c2) || 7079130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.fw != c2.fw || 7089130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c1.fh != c2.fh; 7099130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 7109130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7119130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic int exynos5_config_gsc_m2m(hwc_layer_1_t &layer, 7129130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann alloc_device_t* alloc_device, exynos5_gsc_data_t *gsc_data, 7139130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int gsc_idx) 7149130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 7159130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("configuring gscaler %u for memory-to-memory", gsc_idx); 7169130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7179130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle); 7189130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann buffer_handle_t dst_buf; 7199130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *dst_handle; 7209130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int ret = 0; 7219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_img src_cfg, dst_cfg; 7239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann memset(&src_cfg, 0, sizeof(src_cfg)); 7249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann memset(&dst_cfg, 0, sizeof(dst_cfg)); 7259130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7269130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.x = layer.sourceCrop.left; 7279130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.y = layer.sourceCrop.top; 7289130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.w = WIDTH(layer.sourceCrop); 7299130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.fw = src_handle->stride; 7309130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.h = HEIGHT(layer.sourceCrop); 731eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann src_cfg.fh = src_handle->vstride; 7329130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.yaddr = src_handle->fd; 733296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann if (exynos5_format_is_ycrcb(src_handle->format)) { 734296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann src_cfg.uaddr = src_handle->fd2; 735296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann src_cfg.vaddr = src_handle->fd1; 736296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann } else { 737296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann src_cfg.uaddr = src_handle->fd1; 738296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann src_cfg.vaddr = src_handle->fd2; 739296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann } 7409130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.format = src_handle->format; 7419130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7429130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.x = 0; 7439130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.y = 0; 7449130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.w = WIDTH(layer.displayFrame); 7459130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.h = HEIGHT(layer.displayFrame); 746a00c043512babb1d6f48a0a505f30b906fac8066Greg Hackmann dst_cfg.format = HAL_PIXEL_FORMAT_BGRA_8888; 7479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.rot = layer.transform; 7489130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7499130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("source configuration:"); 7509130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dump_gsc_img(src_cfg); 7519130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7529130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_src_cfg_changed(src_cfg, gsc_data->src_cfg) || 7539130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_dst_cfg_changed(dst_cfg, gsc_data->dst_cfg)) { 7549130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int dst_stride; 7559130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int usage = GRALLOC_USAGE_SW_READ_NEVER | 7569130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann GRALLOC_USAGE_SW_WRITE_NEVER | 7579130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann GRALLOC_USAGE_HW_COMPOSER; 7589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // TODO: add GRALLOC_USAGE_PROTECTED if source buffer is also protected 7599130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7609130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int w = ALIGN(WIDTH(layer.displayFrame), GSC_W_ALIGNMENT); 7619130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int h = ALIGN(HEIGHT(layer.displayFrame), GSC_H_ALIGNMENT); 7629130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7639130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) { 7649130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_data->dst_buf[i]) { 7659130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann alloc_device->free(alloc_device, gsc_data->dst_buf[i]); 7669130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->dst_buf[i] = NULL; 7679130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 7689130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int ret = alloc_device->alloc(alloc_device, w, h, 7709130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann HAL_PIXEL_FORMAT_RGBX_8888, usage, &gsc_data->dst_buf[i], 7719130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann &dst_stride); 7729130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (ret < 0) { 7739130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to allocate destination buffer: %s", 7749130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann strerror(-ret)); 7759130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_alloc; 7769130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 7779130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 7789130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7799130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->current_buf = 0; 780f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 781f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 7829130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_buf = gsc_data->dst_buf[gsc_data->current_buf]; 7839130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_handle = private_handle_t::dynamicCast(dst_buf); 7849130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7859130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.fw = dst_handle->stride; 786eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann dst_cfg.fh = dst_handle->vstride; 7879130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.yaddr = dst_handle->fd; 7889130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7899130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("destination configuration:"); 7909130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dump_gsc_img(dst_cfg); 7919130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7922ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmann gsc_data->gsc = exynos_gsc_create_exclusive(AVAILABLE_GSC_UNITS[gsc_idx], 7932ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmann GSC_M2M_MODE, GSC_DUMMY); 7949130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (!gsc_data->gsc) { 7959130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to create gscaler handle"); 7969130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ret = -1; 7979130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_alloc; 7989130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 7999130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 8009130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ret = exynos_gsc_config_exclusive(gsc_data->gsc, &src_cfg, &dst_cfg); 8019130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (ret < 0) { 8029130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to configure gscaler %u", gsc_idx); 8039130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_gsc_config; 8049130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 8059130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 8069130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ret = exynos_gsc_run_exclusive(gsc_data->gsc, &src_cfg, &dst_cfg); 8079130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (ret < 0) { 8089130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to run gscaler %u", gsc_idx); 8099130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_gsc_config; 8109130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 8119130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 8129130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->src_cfg = src_cfg; 8139130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->dst_cfg = dst_cfg; 8149130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 815f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 8169130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 8179130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannerr_gsc_config: 8189130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_destroy(gsc_data->gsc); 8199130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->gsc = NULL; 8209130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannerr_alloc: 8219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) { 8229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_data->dst_buf[i]) { 8239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann alloc_device->free(alloc_device, gsc_data->dst_buf[i]); 8249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->dst_buf[i] = NULL; 8259130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 8269130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 8279130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return ret; 82886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 82986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 83086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic void exynos5_config_handle(private_handle_t *handle, 831f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect_t &sourceCrop, hwc_rect_t &displayFrame, 83293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann int32_t blending, s3c_fb_win_config &cfg) 833f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann{ 834f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.state = cfg.S3C_FB_WIN_STATE_BUFFER; 835f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.fd = handle->fd; 836f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.x = displayFrame.left; 837f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.y = displayFrame.top; 838f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.w = WIDTH(displayFrame); 839f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.h = HEIGHT(displayFrame); 840f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.format = exynos5_format_to_s3c_format(handle->format); 841f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann uint8_t bpp = exynos5_format_to_bpp(handle->format); 842f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.offset = (sourceCrop.top * handle->stride + sourceCrop.left) * bpp / 8; 843f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.stride = handle->stride * bpp / 8; 84493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann cfg.blending = exynos5_blending_to_s3c_blending(blending); 84586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 84686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 84787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic void exynos5_config_overlay(hwc_layer_1_t *layer, s3c_fb_win_config &cfg, 848f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const private_module_t *gralloc_module) 84986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 850f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer->compositionType == HWC_BACKGROUND) { 851f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_color_t color = layer->backgroundColor; 852f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.state = cfg.S3C_FB_WIN_STATE_COLOR; 853f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.color = (color.r << 16) | (color.g << 8) | color.b; 854f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.x = 0; 855f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.y = 0; 856f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.w = gralloc_module->xres; 857f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.h = gralloc_module->yres; 858f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return; 859f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 860f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 861f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann private_handle_t *handle = private_handle_t::dynamicCast(layer->handle); 86293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann exynos5_config_handle(handle, layer->sourceCrop, layer->displayFrame, 86393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann layer->blending, cfg); 86486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 86586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 86686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic void exynos5_post_callback(void *data, private_handle_t *fb) 86786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 868f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_post_data_t *pdata = (exynos5_hwc_post_data_t *)data; 869f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 870f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct s3c_fb_win_config_data win_data; 871f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct s3c_fb_win_config *config = win_data.config; 872f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(config, 0, sizeof(win_data.config)); 8739130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 8749130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 8759130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if ( pdata->overlay_map[i] != -1) { 8769130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann hwc_layer_1_t &layer = pdata->overlays[i]; 8779130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = 8789130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t::dynamicCast(layer.handle); 8799130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 8809130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (layer.acquireFenceFd != -1) { 8819130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int err = sync_wait(layer.acquireFenceFd, 100); 8829130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (err != 0) 8839130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGW("fence for layer %zu didn't signal in 100 ms: %s", 8849130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann i, strerror(errno)); 8859130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann close(layer.acquireFenceFd); 8869130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 8879130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 8889130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) { 8899130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int gsc_idx = pdata->gsc_map[i].idx; 8909130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_config_gsc_m2m(layer, pdata->pdev->alloc_device, 8919130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann &pdata->pdev->gsc[gsc_idx], gsc_idx); 8929130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 8939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 8949130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 8959130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 896f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 897f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (i == pdata->fb_window) { 898f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect_t rect = { 0, 0, fb->width, fb->height }; 89993cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann int32_t blending = (i == 0) ? HWC_BLENDING_NONE : 90093cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann HWC_BLENDING_PREMULT; 90193cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann exynos5_config_handle(fb, rect, rect, blending, config[i]); 902f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } else if ( pdata->overlay_map[i] != -1) { 9039130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann hwc_layer_1_t &layer = pdata->overlays[i]; 9049130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = 9059130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t::dynamicCast(layer.handle); 9069130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9079130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) { 9089130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int gsc_idx = pdata->gsc_map[i].idx; 9099130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_gsc_data_t &gsc = pdata->pdev->gsc[gsc_idx]; 9109130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9119130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (!gsc.gsc) { 9129130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to queue gscaler %u input for layer %u", 9139130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_idx, i); 9149130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann continue; 9159130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 9169130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9179130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int err = exynos_gsc_stop_exclusive(gsc.gsc); 9189130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_destroy(gsc.gsc); 9199130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc.gsc = NULL; 9209130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (err < 0) { 9219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to dequeue gscaler output for layer %u", i); 9229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann continue; 9239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 9249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9259130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann buffer_handle_t dst_buf = gsc.dst_buf[gsc.current_buf]; 9269130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc.current_buf = (gsc.current_buf + 1) % NUM_GSC_DST_BUFS; 9279130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *dst_handle = 9289130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t::dynamicCast(dst_buf); 92990219f32a19cfaa1c24673452e9f33cccc092e21Greg Hackmann hwc_rect_t sourceCrop = { 0, 0, 93090219f32a19cfaa1c24673452e9f33cccc092e21Greg Hackmann WIDTH(layer.displayFrame), HEIGHT(layer.displayFrame) }; 93190219f32a19cfaa1c24673452e9f33cccc092e21Greg Hackmann exynos5_config_handle(dst_handle, sourceCrop, 93293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann layer.displayFrame, layer.blending, config[i]); 9339130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 9349130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann else { 9359130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_config_overlay(&layer, config[i], 9369130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdata->pdev->gralloc_module); 93787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 93887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 93993cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann if (i == 0 && config[i].blending != S3C_FB_BLENDING_NONE) { 94093cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann ALOGV("blending not supported on window 0; forcing BLENDING_NONE"); 94193cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann config[i].blending = S3C_FB_BLENDING_NONE; 94293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann } 94393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann 9449130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("window %u configuration:", i); 945f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dump_config(config[i]); 946f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 94786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 948f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int ret = ioctl(pdata->pdev->fd, S3CFB_WIN_CONFIG, &win_data); 949f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (ret < 0) 950f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("ioctl S3CFB_WIN_CONFIG failed: %d", errno); 95186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 952f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (pdata->pdev->hdmi_mirroring) 953f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hdmi_output(pdata->pdev, fb); 954cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 95587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_lock(&pdata->completion_lock); 95687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pdata->fence = win_data.fence; 95787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_cond_signal(&pdata->completion); 95887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_unlock(&pdata->completion_lock); 95986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 96086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 961e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hallstatic int exynos5_set(struct hwc_composer_device_1 *dev, 962e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall size_t numDisplays, hwc_display_contents_1_t** displays) 96386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 964f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_composer_device_1_t *pdev = 965f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (exynos5_hwc_composer_device_1_t *)dev; 96686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 967e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall if (!numDisplays || !displays || !displays[0] || !displays[0]->dpy || !displays[0]->sur) 968f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 96986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 970f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_callback_queue_t *queue = NULL; 971f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pthread_mutex_t *lock = NULL; 972f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_post_data_t *data = NULL; 97386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 974e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall if (displays[0]->numHwLayers) { 97587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 97687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling if (pdev->bufs.overlay_map[i] != -1) { 97787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pdev->bufs.overlays[i] = 978e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall displays[0]->hwLayers[pdev->bufs.overlay_map[i]]; 97987e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 98087e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 98187e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 982f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann data = (exynos5_hwc_post_data_t *) 983f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann malloc(sizeof(exynos5_hwc_post_data_t)); 984f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memcpy(data, &pdev->bufs, sizeof(pdev->bufs)); 98586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 98687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling data->fence = -1; 98787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_init(&data->completion_lock, NULL); 98887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_cond_init(&data->completion, NULL); 98987e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 990f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (pdev->bufs.fb_window == NO_FB_NEEDED) { 991f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_post_callback(data, NULL); 992f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } else { 99387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 99487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling struct hwc_callback_entry entry; 99587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling entry.callback = exynos5_post_callback; 99687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling entry.data = data; 99787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 99887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling queue = reinterpret_cast<hwc_callback_queue_t *>( 99987e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pdev->gralloc_module->queue); 100087e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling lock = const_cast<pthread_mutex_t *>( 100187e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling &pdev->gralloc_module->queue_lock); 100287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 100387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_lock(lock); 100487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling queue->push_front(entry); 100587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_unlock(lock); 100687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 1007e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall EGLBoolean success = eglSwapBuffers((EGLDisplay)displays[0]->dpy, 1008e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall (EGLSurface)displays[0]->sur); 100987e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling if (!success) { 101087e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling ALOGE("HWC_EGL_ERROR"); 1011e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall if (displays[0]) { 101287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_lock(lock); 101387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling queue->removeAt(0); 101487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_unlock(lock); 101587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling free(data); 101687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 101787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling return HWC_EGL_ERROR; 101887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 101987e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 1020f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 102186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 102286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 102387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_lock(&data->completion_lock); 102487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling while (data->fence == -1) 102587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_cond_wait(&data->completion, &data->completion_lock); 102687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_unlock(&data->completion_lock); 102787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 102887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 102987e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling if (pdev->bufs.overlay_map[i] != -1) { 103087e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling int dup_fd = dup(data->fence); 103187e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling if (dup_fd < 0) 103287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling ALOGW("release fence dup failed: %s", strerror(errno)); 1033e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall displays[0]->hwLayers[pdev->bufs.overlay_map[i]].releaseFenceFd = dup_fd; 103487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 103587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 103687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling close(data->fence); 103787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling free(data); 1038f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 103986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 104086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 104187e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic void exynos5_registerProcs(struct hwc_composer_device_1* dev, 1042f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_procs_t const* procs) 104386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1044f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t* pdev = 1045f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t*)dev; 1046f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->procs = const_cast<hwc_procs_t *>(procs); 104786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 104886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 104987e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic int exynos5_query(struct hwc_composer_device_1* dev, int what, int *value) 105086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1051f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *pdev = 1052f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t *)dev; 1053f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1054f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann switch (what) { 1055f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HWC_BACKGROUND_LAYER_SUPPORTED: 1056f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // we support the background layer 1057f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann value[0] = 1; 1058f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann break; 1059f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HWC_VSYNC_PERIOD: 1060f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // vsync period in nanosecond 1061f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann value[0] = 1000000000.0 / pdev->gralloc_module->fps; 1062f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann break; 1063f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann default: 1064f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // unsupported query 1065f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -EINVAL; 1066f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1067f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 106886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 106986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1070e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hallstatic int exynos5_eventControl(struct hwc_composer_device_1 *dev, int dpy, 1071e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall int event, int enabled) 107286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1073f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *pdev = 1074f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t *)dev; 1075f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1076f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann switch (event) { 1077f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HWC_EVENT_VSYNC: 1078f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann __u32 val = !!enabled; 1079f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int err = ioctl(pdev->fd, S3CFB_SET_VSYNC_INT, &val); 1080f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (err < 0) { 1081f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("vsync ioctl failed"); 1082f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -errno; 1083f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1084f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1085f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 1086f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1087f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1088f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -EINVAL; 108986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 109086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1091cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Gobystatic void handle_hdmi_uevent(struct exynos5_hwc_composer_device_1_t *pdev, 1092f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const char *buff, int len) 1093cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby{ 1094f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const char *s = buff; 1095f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann s += strlen(s) + 1; 1096cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1097f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann while (*s) { 1098f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE="))) 1099f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->hdmi_hpd = atoi(s + strlen("SWITCH_STATE=")) == 1; 1100cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1101f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann s += strlen(s) + 1; 1102f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (s - buff >= len) 1103f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann break; 1104f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1105cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1106d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (pdev->hdmi_hpd) { 1107d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (hdmi_get_config(pdev)) { 1108d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGE("Error reading HDMI configuration"); 1109d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby pdev->hdmi_hpd = false; 1110d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby return; 1111d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 1112d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 1113d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 1114f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("HDMI HPD changed to %s", pdev->hdmi_hpd ? "enabled" : "disabled"); 1115d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (pdev->hdmi_hpd) 1116d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGI("HDMI Resolution changed to %dx%d", pdev->hdmi_cfg.h, pdev->hdmi_cfg.w); 1117cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1118f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (pdev->procs && pdev->procs->invalidate) 1119f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->procs->invalidate(pdev->procs); 1120cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby} 1121cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 11222972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmannstatic void handle_vsync_event(struct exynos5_hwc_composer_device_1_t *pdev) 112386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1124f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!pdev->procs || !pdev->procs->vsync) 1125f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return; 112686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1127fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann int err = lseek(pdev->vsync_fd, 0, SEEK_SET); 1128fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann if (err < 0) { 1129fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann ALOGE("error seeking to vsync timestamp: %s", strerror(errno)); 1130fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann return; 1131fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann } 1132fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann 11332972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann char buf[4096]; 1134fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann err = read(pdev->vsync_fd, buf, sizeof(buf)); 11352972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (err < 0) { 11362972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann ALOGE("error reading vsync timestamp: %s", strerror(errno)); 11372972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann return; 1138f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 11392972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann buf[sizeof(buf) - 1] = '\0'; 114086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 11412972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann errno = 0; 11422972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann uint64_t timestamp = strtoull(buf, NULL, 0); 11432972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (!errno) 11442972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann pdev->procs->vsync(pdev->procs, 0, timestamp); 114586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 114686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 114786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic void *hwc_vsync_thread(void *data) 114886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1149f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *pdev = 1150f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t *)data; 1151f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann char uevent_desc[4096]; 1152f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(uevent_desc, 0, sizeof(uevent_desc)); 1153f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1154f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 1155f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1156f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann uevent_init(); 1157f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1158fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann char temp[4096]; 1159fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann int err = read(pdev->vsync_fd, temp, sizeof(temp)); 1160fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann if (err < 0) { 1161fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann ALOGE("error reading vsync timestamp: %s", strerror(errno)); 1162fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann return NULL; 1163fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann } 1164fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann 11652972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann struct pollfd fds[2]; 11662972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann fds[0].fd = pdev->vsync_fd; 11672972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann fds[0].events = POLLPRI; 11682972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann fds[1].fd = uevent_get_fd(); 11692972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann fds[1].events = POLLIN; 11702972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann 11712972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann while (true) { 11722972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann int err = poll(fds, 2, -1); 11733464b1dd35ad9c49f797e069922f22a788a8b440Greg Hackmann 11742972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (err > 0) { 11752972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (fds[0].revents & POLLPRI) { 11762972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann handle_vsync_event(pdev); 11772972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 11782972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann else if (fds[1].revents & POLLIN) { 11792972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann int len = uevent_next_event(uevent_desc, 11802972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann sizeof(uevent_desc) - 2); 11812972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann 11822972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann bool hdmi = !strcmp(uevent_desc, 11832972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann "change@/devices/virtual/switch/hdmi"); 11842972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (hdmi) 11852972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann handle_hdmi_uevent(pdev, uevent_desc, len); 11862972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 11872972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 11882972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann else if (err == -1) { 11892972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (errno == EINTR) 11902972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann break; 11912972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann ALOGE("error in vsync thread: %s", strerror(errno)); 11922972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 1193f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1194f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1195f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return NULL; 119686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 119786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1198e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hallstatic int exynos5_blank(struct hwc_composer_device_1 *dev, int dpy, int blank) 119900359a8853031c94e4f7d5c8d79a44917de9842fColin Cross{ 120000359a8853031c94e4f7d5c8d79a44917de9842fColin Cross struct exynos5_hwc_composer_device_1_t *pdev = 120100359a8853031c94e4f7d5c8d79a44917de9842fColin Cross (struct exynos5_hwc_composer_device_1_t *)dev; 120200359a8853031c94e4f7d5c8d79a44917de9842fColin Cross 120300359a8853031c94e4f7d5c8d79a44917de9842fColin Cross int fb_blank = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK; 120400359a8853031c94e4f7d5c8d79a44917de9842fColin Cross int err = ioctl(pdev->fd, FBIOBLANK, fb_blank); 120500359a8853031c94e4f7d5c8d79a44917de9842fColin Cross if (err < 0) { 120600359a8853031c94e4f7d5c8d79a44917de9842fColin Cross ALOGE("%sblank ioctl failed", blank ? "" : "un"); 120700359a8853031c94e4f7d5c8d79a44917de9842fColin Cross return -errno; 120800359a8853031c94e4f7d5c8d79a44917de9842fColin Cross } 120900359a8853031c94e4f7d5c8d79a44917de9842fColin Cross 121000359a8853031c94e4f7d5c8d79a44917de9842fColin Cross return 0; 121100359a8853031c94e4f7d5c8d79a44917de9842fColin Cross} 121200359a8853031c94e4f7d5c8d79a44917de9842fColin Cross 121387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstruct hwc_methods_1 exynos5_methods = { 1214f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann eventControl: exynos5_eventControl, 121500359a8853031c94e4f7d5c8d79a44917de9842fColin Cross blank: exynos5_blank, 121686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 121786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 121886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic int exynos5_close(hw_device_t* device); 121986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 122086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic int exynos5_open(const struct hw_module_t *module, const char *name, 1221f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct hw_device_t **device) 122286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1223f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int ret; 1224f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int sw_fd; 1225f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1226f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 1227f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -EINVAL; 1228f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1229f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1230f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *dev; 1231f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev = (struct exynos5_hwc_composer_device_1_t *)malloc(sizeof(*dev)); 1232f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(dev, 0, sizeof(*dev)); 1233f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1234f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, 1235f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (const struct hw_module_t **)&dev->gralloc_module)) { 1236f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("failed to get gralloc hw module"); 1237f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ret = -EINVAL; 1238f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann goto err_get_module; 1239f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1240f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 12419130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gralloc_open((const hw_module_t *)dev->gralloc_module, 12429130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann &dev->alloc_device)) { 12439130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to open gralloc"); 12449130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ret = -EINVAL; 12459130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_get_module; 12469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 12479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 1248f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->fd = open("/dev/graphics/fb0", O_RDWR); 1249f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (dev->fd < 0) { 1250f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("failed to open framebuffer"); 1251f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ret = dev->fd; 12529130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_open_fb; 1253f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1254f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1255d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby dev->hdmi_fd = open("/dev/video16", O_RDWR); 1256d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (dev->hdmi_fd < 0) { 1257d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGE("failed to open hdmi device"); 1258d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ret = dev->hdmi_fd; 1259d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby goto err_ioctl; 1260d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 1261d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 12622972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann dev->vsync_fd = open("/sys/devices/platform/exynos5-fb.1/vsync", O_RDONLY); 12632972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (dev->vsync_fd < 0) { 12642972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann ALOGE("failed to open vsync attribute"); 12652972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann ret = dev->vsync_fd; 1266d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby goto err_hdmi; 12672972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 12682972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann 1269f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY); 1270f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (sw_fd) { 1271f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann char val; 1272f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (read(sw_fd, &val, 1) == 1 && val == '1') 1273f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_hpd = true; 1274f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1275f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1276f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.common.tag = HARDWARE_DEVICE_TAG; 1277f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.common.version = HWC_DEVICE_API_VERSION_1_0; 1278f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.common.module = const_cast<hw_module_t *>(module); 1279f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.common.close = exynos5_close; 1280f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1281f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.prepare = exynos5_prepare; 1282f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.set = exynos5_set; 1283f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.registerProcs = exynos5_registerProcs; 1284f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.query = exynos5_query; 1285f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.methods = &exynos5_methods; 1286f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1287f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->bufs.pdev = dev; 1288f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1289f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann *device = &dev->base.common; 1290f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1291f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ret = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev); 1292f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (ret) { 1293f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("failed to start vsync thread: %s", strerror(ret)); 1294f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ret = -ret; 12952972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann goto err_vsync; 1296f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1297f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1298f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 129986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 13002972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmannerr_vsync: 13012972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann close(dev->vsync_fd); 1302d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Gobyerr_hdmi: 1303d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby close(dev->hdmi_fd); 130486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannerr_ioctl: 1305f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann close(dev->fd); 13069130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannerr_open_fb: 13079130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gralloc_close(dev->alloc_device); 130886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannerr_get_module: 1309f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann free(dev); 1310f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return ret; 131186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 131286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 131386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic int exynos5_close(hw_device_t *device) 131486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1315f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *dev = 1316f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t *)device; 13172972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann pthread_kill(dev->vsync_thread, SIGTERM); 13182972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann pthread_join(dev->vsync_thread, NULL); 13199130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = 0; i < NUM_GSC_UNITS; i++) { 13209130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (dev->gsc[i].gsc) 13219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_destroy(dev->gsc[i].gsc); 13229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t j = 0; i < NUM_GSC_DST_BUFS; j++) 13239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (dev->gsc[i].dst_buf[j]) 13249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dev->alloc_device->free(dev->alloc_device, dev->gsc[i].dst_buf[j]); 13259130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 13269130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gralloc_close(dev->alloc_device); 13272972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann close(dev->vsync_fd); 1328d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby close(dev->hdmi_fd); 1329f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann close(dev->fd); 1330f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 133186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 133286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 133386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic struct hw_module_methods_t exynos5_hwc_module_methods = { 1334f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann open: exynos5_open, 133586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 133686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 133786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannhwc_module_t HAL_MODULE_INFO_SYM = { 1338f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann common: { 1339f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann tag: HARDWARE_MODULE_TAG, 1340f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann module_api_version: HWC_MODULE_API_VERSION_0_1, 1341f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hal_api_version: HARDWARE_HAL_API_VERSION, 1342f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann id: HWC_HARDWARE_MODULE_ID, 1343f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann name: "Samsung exynos5 hwcomposer module", 1344f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann author: "Google", 1345f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann methods: &exynos5_hwc_module_methods, 1346f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 134786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 1348