hwc.cpp revision 4e0f168e3d62fd6d594c4015f2f3da4449fcbf19
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> 39600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann#include <utils/String8.h> 4086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include <utils/Vector.h> 4186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 42f4cc0c30da5158aba393c5b3b566ad6f210072fcGreg Hackmann#include <sync/sync.h> 43f4cc0c30da5158aba393c5b3b566ad6f210072fcGreg Hackmann 4486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include "ion.h" 4586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann#include "gralloc_priv.h" 46cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby#include "exynos_gscaler.h" 479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann#include "exynos_format.h" 488bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby#include "exynos_v4l2.h" 498bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby#include "s5p_tvout_v4l2.h" 5086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 51f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmannstruct hwc_callback_entry { 52f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann void (*callback)(void *, private_handle_t *); 53f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann void *data; 5486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 5586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmanntypedef android::Vector<struct hwc_callback_entry> hwc_callback_queue_t; 5686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 5731991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmannconst size_t NUM_HW_WINDOWS = 5; 5886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannconst size_t NO_FB_NEEDED = NUM_HW_WINDOWS + 1; 5931991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmannconst size_t MAX_PIXELS = 2560 * 1600 * 2; 609130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannconst size_t GSC_W_ALIGNMENT = 16; 619130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannconst size_t GSC_H_ALIGNMENT = 16; 622ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmannconst int AVAILABLE_GSC_UNITS[] = { 0, 3 }; 632ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmannconst size_t NUM_GSC_UNITS = sizeof(AVAILABLE_GSC_UNITS) / 642ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmann sizeof(AVAILABLE_GSC_UNITS[0]); 6586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 6687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstruct exynos5_hwc_composer_device_1_t; 6786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 689130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstruct exynos5_gsc_map_t { 699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann enum { 709130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann GSC_NONE = 0, 719130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann GSC_M2M, 729130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // TODO: GSC_LOCAL_PATH 739130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } mode; 749130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int idx; 759130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann}; 769130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 7786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstruct exynos5_hwc_post_data_t { 78f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_composer_device_1_t *pdev; 79f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int overlay_map[NUM_HW_WINDOWS]; 809130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_gsc_map_t gsc_map[NUM_HW_WINDOWS]; 81f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_layer_1_t overlays[NUM_HW_WINDOWS]; 82f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int num_overlays; 83f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann size_t fb_window; 84f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int fence; 85f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pthread_mutex_t completion_lock; 86f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pthread_cond_t completion; 8786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 8886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 899130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannconst size_t NUM_GSC_DST_BUFS = 2; 909130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstruct exynos5_gsc_data_t { 919130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann void *gsc; 929130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_img src_cfg; 939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_img dst_cfg; 949130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann buffer_handle_t dst_buf[NUM_GSC_DST_BUFS]; 959130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann size_t current_buf; 969130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann}; 979130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstruct exynos5_hwc_composer_device_1_t { 99f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_composer_device_1_t base; 10086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 101f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int fd; 1022972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann int vsync_fd; 103f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_post_data_t bufs; 10486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 105f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const private_module_t *gralloc_module; 1069130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann alloc_device_t *alloc_device; 107da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall const hwc_procs_t *procs; 108f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pthread_t vsync_thread; 109cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1108bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby int hdmi_mixer0; 1118bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby int hdmi_layer0; 1128bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby int hdmi_layer1; 113f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool hdmi_hpd; 1148bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby bool hdmi_enabled; 115ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby bool hdmi_blanked; 116f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann void *hdmi_gsc; 1178bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby int hdmi_w; 1188bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby int hdmi_h; 1198bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby exynos_gsc_img hdmi_src; 1208bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby exynos_gsc_img hdmi_dst; 1219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 1229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_gsc_data_t gsc[NUM_GSC_UNITS]; 123600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 124600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann struct s3c_fb_win_config last_config[NUM_HW_WINDOWS]; 125600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann const void *last_handles[NUM_HW_WINDOWS]; 126600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann exynos5_gsc_map_t last_gsc_map[NUM_HW_WINDOWS]; 12786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 12886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1299130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic void dump_handle(private_handle_t *h) 1309130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 131eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann ALOGV("\t\tformat = %d, width = %u, height = %u, stride = %u, vstride = %u", 132eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann h->format, h->width, h->height, h->stride, h->vstride); 1339130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 1349130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 13587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic void dump_layer(hwc_layer_1_t const *l) 13686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 137f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, " 138f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann "{%d,%d,%d,%d}, {%d,%d,%d,%d}", 139f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->compositionType, l->flags, l->handle, l->transform, 140f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->blending, 141f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->sourceCrop.left, 142f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->sourceCrop.top, 143f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->sourceCrop.right, 144f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->sourceCrop.bottom, 145f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->displayFrame.left, 146f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->displayFrame.top, 147f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->displayFrame.right, 148f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann l->displayFrame.bottom); 14986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1509130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if(l->handle && !(l->flags & HWC_SKIP_LAYER)) 1519130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dump_handle(private_handle_t::dynamicCast(l->handle)); 15286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 15386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 15486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic void dump_config(s3c_fb_win_config &c) 15586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 156f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\tstate = %u", c.state); 157f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (c.state == c.S3C_FB_WIN_STATE_BUFFER) { 158f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\t\tfd = %d, offset = %u, stride = %u, " 159f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann "x = %d, y = %d, w = %u, h = %u, " 16093cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann "format = %u, blending = %u", 161f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann c.fd, c.offset, c.stride, 162f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann c.x, c.y, c.w, c.h, 16393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann c.format, c.blending); 164f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 165f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann else if (c.state == c.S3C_FB_WIN_STATE_COLOR) { 166f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\t\tcolor = %u", c.color); 167f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 16886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 16986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1709130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic void dump_gsc_img(exynos_gsc_img &c) 1719130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 1729130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tx = %u, y = %u, w = %u, h = %u, fw = %u, fh = %u", 1739130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c.x, c.y, c.w, c.h, c.fw, c.fh); 1749130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\taddr = {%u, %u, %u}, rot = %u, cacheable = %u, drmMode = %u", 1759130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann c.yaddr, c.uaddr, c.vaddr, c.rot, c.cacheable, c.drmMode); 1769130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 1779130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 17886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmanninline int WIDTH(const hwc_rect &rect) { return rect.right - rect.left; } 17986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmanninline int HEIGHT(const hwc_rect &rect) { return rect.bottom - rect.top; } 18031991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmanntemplate<typename T> inline T max(T a, T b) { return (a > b) ? a : b; } 18131991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmanntemplate<typename T> inline T min(T a, T b) { return (a < b) ? a : b; } 18231991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann 18331991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmannstatic bool is_transformed(const hwc_layer_1_t &layer) 18431991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann{ 185f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return layer.transform != 0; 18631991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann} 18786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1889130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic bool is_rotated(const hwc_layer_1_t &layer) 1899130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 1909130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return (layer.transform & HAL_TRANSFORM_ROT_90) || 1919130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann (layer.transform & HAL_TRANSFORM_ROT_180); 1929130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 1939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 19487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic bool is_scaled(const hwc_layer_1_t &layer) 19586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 196f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return WIDTH(layer.displayFrame) != WIDTH(layer.sourceCrop) || 197f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann HEIGHT(layer.displayFrame) != HEIGHT(layer.sourceCrop); 19886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 19986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 2008bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobystatic inline bool gsc_dst_cfg_changed(exynos_gsc_img &c1, exynos_gsc_img &c2) 2018bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby{ 2028bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return c1.x != c2.x || 2038bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.y != c2.y || 2048bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.w != c2.w || 2058bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.h != c2.h || 2068bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.format != c2.format || 2078bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.rot != c2.rot || 2088bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.cacheable != c2.cacheable || 2098bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.drmMode != c2.drmMode; 2108bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby} 2118bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 2128bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobystatic inline bool gsc_src_cfg_changed(exynos_gsc_img &c1, exynos_gsc_img &c2) 2138bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby{ 2148bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return gsc_dst_cfg_changed(c1, c2) || 2158bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.fw != c2.fw || 2168bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby c1.fh != c2.fh; 2178bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby} 2188bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 21986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic enum s3c_fb_pixel_format exynos5_format_to_s3c_format(int format) 22086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 221f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann switch (format) { 222f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_8888: 223f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return S3C_FB_PIXEL_FORMAT_RGBA_8888; 224f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBX_8888: 225f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return S3C_FB_PIXEL_FORMAT_RGBX_8888; 226f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_5551: 227f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return S3C_FB_PIXEL_FORMAT_RGBA_5551; 228f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 229f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann default: 230f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return S3C_FB_PIXEL_FORMAT_MAX; 231f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 23286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 23386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 23486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic bool exynos5_format_is_supported(int format) 23586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 236f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return exynos5_format_to_s3c_format(format) < S3C_FB_PIXEL_FORMAT_MAX; 23786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 23886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 23986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic bool exynos5_format_is_supported_by_gscaler(int format) 24086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 2419130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann switch (format) { 242f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBX_8888: 243f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGB_565: 244c853be7b9977a6a0402bd5a65c0c32ac9e2fde1dRebecca Schultz Zavin case HAL_PIXEL_FORMAT_EXYNOS_YV12: 2459130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_420_P: 2469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_422_SP: 2479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_SP: 2489130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_420_SP: 2499130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP: 2509130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_422_I: 2519130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_422_I: 2529130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_422_P: 2539130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CbYCrY_422_I: 2549130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_CbYCrY_422_I: 2559130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCrCb_422_SP: 2569130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_SP: 257c853be7b9977a6a0402bd5a65c0c32ac9e2fde1dRebecca Schultz Zavin case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP: 2589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_420_SP: 2599130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 2609130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCbCr_420_SP_TILED: 2619130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_YCrCb_422_I: 2629130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann case HAL_PIXEL_FORMAT_CUSTOM_CrYCbY_422_I: 263f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return true; 264f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 265f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann default: 266f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return false; 267f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 26886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 26986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 270296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmannstatic bool exynos5_format_is_ycrcb(int format) 271296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann{ 272c853be7b9977a6a0402bd5a65c0c32ac9e2fde1dRebecca Schultz Zavin return format == HAL_PIXEL_FORMAT_EXYNOS_YV12; 273296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann} 274296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann 2759130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic bool exynos5_format_requires_gscaler(int format) 2769130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 2779130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return exynos5_format_is_supported_by_gscaler(format) && 2789130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann format != HAL_PIXEL_FORMAT_RGBX_8888; 2799130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 2809130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 28186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic uint8_t exynos5_format_to_bpp(int format) 28286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 283f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann switch (format) { 284f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_8888: 285f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBX_8888: 286f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 32; 287f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 288f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_5551: 289f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HAL_PIXEL_FORMAT_RGBA_4444: 290f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 16; 291f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 292f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann default: 293f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGW("unrecognized pixel format %u", format); 294f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 295f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 29686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 29786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 298227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmannstatic bool exynos5_supports_gscaler(hwc_layer_1_t &layer, int format, 299227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann bool local_path) 3009130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 3019130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = private_handle_t::dynamicCast(layer.handle); 3029130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 3039130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int max_w = is_rotated(layer) ? 2048 : 4800; 3049130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int max_h = is_rotated(layer) ? 2048 : 3344; 3059130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 3069130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann bool rot90or270 = !!(layer.transform & HAL_TRANSFORM_ROT_90); 3079130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // n.b.: HAL_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_90 | 3089130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // HAL_TRANSFORM_ROT_180 3099130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 310227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann int src_w = WIDTH(layer.sourceCrop), src_h = HEIGHT(layer.sourceCrop); 311227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann int dest_w, dest_h; 312227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann if (rot90or270) { 313227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_w = HEIGHT(layer.displayFrame); 314227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_h = WIDTH(layer.displayFrame); 315227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann } else { 316227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_w = WIDTH(layer.displayFrame); 317227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_h = HEIGHT(layer.displayFrame); 318227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann } 319227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann int max_downscale = local_path ? 4 : 16; 320227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann const int max_upscale = 8; 321227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann 3229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return exynos5_format_is_supported_by_gscaler(format) && 3239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann handle->stride <= max_w && 3249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann handle->stride % GSC_W_ALIGNMENT == 0 && 325227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann src_w <= dest_w * max_downscale && 326227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_w <= src_w * max_upscale && 327eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann handle->vstride <= max_h && 328eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann handle->vstride % GSC_H_ALIGNMENT == 0 && 329227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann src_h <= dest_h * max_downscale && 330227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann dest_h <= src_h * max_upscale && 3319130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // per 46.2 3329130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann (!rot90or270 || layer.sourceCrop.top % 2 == 0) && 3339130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann (!rot90or270 || layer.sourceCrop.left % 2 == 0); 3349130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann // per 46.3.1.6 3359130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 3369130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 337d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Gobyint hdmi_get_config(struct exynos5_hwc_composer_device_1_t *dev) 338d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby{ 339d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby struct v4l2_dv_preset preset; 340d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby struct v4l2_dv_enum_preset enum_preset; 341d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby int index = 0; 342d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby bool found = false; 343d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby int ret; 344d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 3458bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (ioctl(dev->hdmi_layer0, VIDIOC_G_DV_PRESET, &preset) < 0) { 346d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGE("%s: g_dv_preset error, %d", __func__, errno); 347d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby return -1; 348d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 349d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 350d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby while (true) { 351d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby enum_preset.index = index++; 3528bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ret = ioctl(dev->hdmi_layer0, VIDIOC_ENUM_DV_PRESETS, &enum_preset); 353d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 354d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (ret < 0) { 355d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (errno == EINVAL) 356d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby break; 357d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGE("%s: enum_dv_presets error, %d", __func__, errno); 358d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby return -1; 359d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 360d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 361d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGV("%s: %d preset=%02d width=%d height=%d name=%s", 362d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby __func__, enum_preset.index, enum_preset.preset, 363d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby enum_preset.width, enum_preset.height, enum_preset.name); 364d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 365d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (preset.preset == enum_preset.preset) { 3668bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_w = enum_preset.width; 3678bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_h = enum_preset.height; 368d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby found = true; 369d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 370d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 371d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 372d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby return found ? 0 : -1; 373d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby} 374d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 37593cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmannstatic enum s3c_fb_blending exynos5_blending_to_s3c_blending(int32_t blending) 37693cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann{ 37793cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann switch (blending) { 37893cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann case HWC_BLENDING_NONE: 37993cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return S3C_FB_BLENDING_NONE; 38093cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann case HWC_BLENDING_PREMULT: 38193cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return S3C_FB_BLENDING_PREMULT; 38293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann case HWC_BLENDING_COVERAGE: 38393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return S3C_FB_BLENDING_COVERAGE; 38493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann 38593cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann default: 38693cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return S3C_FB_BLENDING_MAX; 38793cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann } 38893cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann} 38993cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann 39093cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmannstatic bool exynos5_blending_is_supported(int32_t blending) 39193cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann{ 39293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann return exynos5_blending_to_s3c_blending(blending) < S3C_FB_BLENDING_MAX; 39393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann} 39493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann 3958bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobystatic int hdmi_start_background(struct exynos5_hwc_composer_device_1_t *dev) 3968bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby{ 3978bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby struct v4l2_requestbuffers reqbuf; 3988bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby struct v4l2_subdev_format sd_fmt; 3998bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby struct v4l2_subdev_crop sd_crop; 4008bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby struct v4l2_format fmt; 4018bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby struct v4l2_buffer buffer; 4028bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby struct v4l2_plane planes[1]; 4038bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4048bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&reqbuf, 0, sizeof(reqbuf)); 4058bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&sd_fmt, 0, sizeof(sd_fmt)); 4068bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&sd_crop, 0, sizeof(sd_crop)); 4078bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&fmt, 0, sizeof(fmt)); 4088bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&buffer, 0, sizeof(buffer)); 4098bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(planes, 0, sizeof(planes)); 4108bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4118bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.pad = MIXER_G1_SUBDEV_PAD_SINK; 4128bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 4138bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.format.width = 1; 4148bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.format.height = 1; 4158bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE; 4168bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_subdev_s_fmt(dev->hdmi_mixer0, &sd_fmt) < 0) { 4178bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: s_fmt failed pad=%d", __func__, sd_fmt.pad); 4188bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4198bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4208bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4218bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.pad = MIXER_G1_SUBDEV_PAD_SINK; 4228bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 4238bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.rect.left = 0; 4248bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.rect.top = 0; 4258bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.rect.width = 1; 4268bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.rect.height = 1; 4278bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_subdev_s_crop(dev->hdmi_mixer0, &sd_crop) < 0) { 4288bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: set_crop failed pad=%d", __func__, sd_crop.pad); 4298bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4308bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4318bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4328bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.pad = MIXER_G1_SUBDEV_PAD_SOURCE; 4338bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; 4348bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.format.width = dev->hdmi_w; 4358bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.format.height = dev->hdmi_h; 4368bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_fmt.format.code = V4L2_MBUS_FMT_XRGB8888_4X8_LE; 4378bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_subdev_s_fmt(dev->hdmi_mixer0, &sd_fmt) < 0) { 4388bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: s_fmt failed pad=%d", __func__, sd_fmt.pad); 4398bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4408bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4418bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4428bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.pad = MIXER_G1_SUBDEV_PAD_SOURCE; 4438bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE; 4448bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.rect.left = 0; 4458bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.rect.top = 0; 4468bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.rect.width = 1; 4478bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby sd_crop.rect.height = 1; 4488bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_subdev_s_crop(dev->hdmi_mixer0, &sd_crop) < 0) { 4498bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: s_crop failed pad=%d", __func__, sd_crop.pad); 4508bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4518bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4528bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4538bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4548bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby fmt.fmt.pix_mp.width = 1; 4558bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby fmt.fmt.pix_mp.height = 1; 4568bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_BGR32; 4578bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby fmt.fmt.pix_mp.field = V4L2_FIELD_ANY; 4588bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby fmt.fmt.pix_mp.num_planes = 1; 4598bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_v4l2_s_fmt(dev->hdmi_layer1, &fmt) < 0) { 4608bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s::videodev set format failed", __func__); 4618bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4628bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4638bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4648bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby reqbuf.count = 1; 4658bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 4668bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby reqbuf.memory = V4L2_MEMORY_MMAP; 4678bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4688bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_v4l2_reqbufs(dev->hdmi_layer1, &reqbuf) < 0) { 4698bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: exynos_v4l2_reqbufs failed %d", __func__, errno); 4708bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4718bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4728bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4738bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (reqbuf.count != 1) { 4748bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: didn't get buffer", __func__); 4758bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4768bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4778bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4788bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&buffer, 0, sizeof(buffer)); 4798bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby buffer.type = reqbuf.type; 4808bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby buffer.memory = V4L2_MEMORY_MMAP; 4818bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby buffer.length = 1; 4828bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby buffer.m.planes = planes; 4838bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_v4l2_querybuf(dev->hdmi_layer1, &buffer) < 0) { 4848bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: exynos_v4l2_querybuf failed %d", __func__, errno); 4858bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4868bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4878bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4888bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby void *start = mmap(NULL, planes[0].length, PROT_READ | PROT_WRITE, 4898bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby MAP_SHARED, dev->hdmi_layer1, planes[0].m.mem_offset); 4908bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (start == MAP_FAILED) { 4918bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: mmap failed %d", __func__, errno); 4928bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 4938bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 4948bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4958bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(start, 0, planes[0].length); 4968bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4978bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby munmap(start, planes[0].length); 4988bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 4998bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_v4l2_qbuf(dev->hdmi_layer1, &buffer) < 0) { 5008bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: exynos_v4l2_qbuf failed %d", __func__, errno); 5018bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 5028bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 5038bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5048bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_v4l2_streamon(dev->hdmi_layer1, buffer.type) < 0) { 5058bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s:stream on failed", __func__); 5068bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 5078bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 5088bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5098bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_v4l2_s_ctrl(dev->hdmi_layer1, V4L2_CID_TV_LAYER_PRIO, 0) < 0) { 5108bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: s_ctrl LAYER_PRIO failed", __func__); 5118bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 5128bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 5138bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5148bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return 0; 5158bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby} 5168bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5178bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobystatic int hdmi_stop_background(struct exynos5_hwc_composer_device_1_t *dev) 5188bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby{ 5198bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby struct v4l2_requestbuffers reqbuf; 5208bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5218bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_v4l2_streamoff(dev->hdmi_layer1, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) { 5228bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s:stream off failed", __func__); 5238bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 5248bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 5258bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5268bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&reqbuf, 0, sizeof(reqbuf)); 5278bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby reqbuf.count = 0; 5288bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; 5298bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby reqbuf.memory = V4L2_MEMORY_MMAP; 5308bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos_v4l2_reqbufs(dev->hdmi_layer1, &reqbuf) < 0) { 5318bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: exynos_v4l2_reqbufs failed %d", __func__, errno); 5328bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 5338bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 5348bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5358bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return 0; 5368bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby} 5378bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 538cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Gobystatic int hdmi_enable(struct exynos5_hwc_composer_device_1_t *dev) 539cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby{ 5408bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (dev->hdmi_enabled) 541f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 542f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 543ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby if (dev->hdmi_blanked) 544ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby return 0; 545ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby 546f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_gsc = exynos_gsc_create_exclusive(3, GSC_OUTPUT_MODE, GSC_OUT_TV); 547f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!dev->hdmi_gsc) { 548f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("%s: exynos_gsc_create_exclusive failed", __func__); 549f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -ENODEV; 550f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 551f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 5528bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&dev->hdmi_src, 0, sizeof(dev->hdmi_src)); 553f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 5548bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (hdmi_start_background(dev) < 0) { 5558bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: hdmi_start_background failed", __func__); 5568bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return -1; 557f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 558f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 5598bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_enabled = true; 560f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 561cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby} 562cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 563cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Gobystatic void hdmi_disable(struct exynos5_hwc_composer_device_1_t *dev) 564cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby{ 5658bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (!dev->hdmi_enabled) 566f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return; 567f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos_gsc_destroy(dev->hdmi_gsc); 568ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby hdmi_stop_background(dev); 569f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_gsc = NULL; 5708bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_enabled = false; 571cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby} 572cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 5738bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobystatic int hdmi_configure(struct exynos5_hwc_composer_device_1_t *dev, 5748bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby exynos_gsc_img &src_cfg, 5758bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby exynos_gsc_img &dst_cfg) 5768bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby{ 5778bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (!gsc_src_cfg_changed(src_cfg, dev->hdmi_src) 5788bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby && !gsc_dst_cfg_changed(dst_cfg, dev->hdmi_dst)) 5798bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return 0; 5808bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5818bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGV("HDMI source config:"); 5828bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dump_gsc_img(src_cfg); 5838bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGV("HDMI dest config:"); 5848bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dump_gsc_img(dst_cfg); 5858bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5868bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby exynos_gsc_stop_exclusive(dev->hdmi_gsc); 5878bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5888bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby int ret = exynos_gsc_config_exclusive(dev->hdmi_gsc, &src_cfg, &dst_cfg); 5898bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (ret < 0) { 5908bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("%s: exynos_gsc_config_exclusive failed %d", __func__, ret); 5918bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return ret; 5928bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 5938bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5948bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_src = src_cfg; 5958bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_dst = dst_cfg; 5968bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return ret; 5978bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby} 5988bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 5998bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobystatic int hdmi_configure_handle(struct exynos5_hwc_composer_device_1_t *dev, private_handle_t *h) 6008bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby{ 6018bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby exynos_gsc_img src_cfg, dst_cfg; 6028bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&src_cfg, 0, sizeof(src_cfg)); 6038bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&dst_cfg, 0, sizeof(dst_cfg)); 6048bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 6058bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.w = src_cfg.fw = h->width; 6068bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.h = src_cfg.fh = h->height; 6078bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.format = HAL_PIXEL_FORMAT_BGRA_8888; 6088bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 6098bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.w = dst_cfg.fw = dev->hdmi_w; 6108bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.h = dst_cfg.fh = dev->hdmi_h; 6118bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.format = HAL_PIXEL_FORMAT_EXYNOS_YV12; 6128bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 6138bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return hdmi_configure(dev, src_cfg, dst_cfg); 6148bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby} 6158bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 6168bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobystatic int hdmi_configure_layer(struct exynos5_hwc_composer_device_1_t *dev, hwc_layer_1_t &layer) 6178bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby{ 6188bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby exynos_gsc_img src_cfg, dst_cfg; 6198bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&src_cfg, 0, sizeof(src_cfg)); 6208bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby memset(&dst_cfg, 0, sizeof(dst_cfg)); 6218bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle); 6228bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 6238bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.x = layer.sourceCrop.left; 6248bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.y = layer.sourceCrop.top; 6258bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.w = WIDTH(layer.sourceCrop); 6268bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.fw = src_handle->stride; 6278bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.h = HEIGHT(layer.sourceCrop); 6288bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.fh = src_handle->vstride; 6298bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_cfg.format = src_handle->format; 6308bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 6318bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (dev->hdmi_w * src_cfg.h < dev->hdmi_h * src_cfg.w) { 6328bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.w = dev->hdmi_w; 6338bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.fw = dev->hdmi_w; 6348bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.fh = dev->hdmi_h; 6358bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.h = dev->hdmi_w * src_cfg.h / src_cfg.w; 6368bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.y = (dev->hdmi_h - dst_cfg.h) / 2; 6378bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 6388bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby else { 6398bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.w = dev->hdmi_h * src_cfg.w / src_cfg.h; 6408bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.fw = dev->hdmi_w; 6418bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.h = dev->hdmi_h; 6428bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.fh = dev->hdmi_h; 6438bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.x = (dev->hdmi_w - dst_cfg.w) / 2; 6448bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 6458bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.format = HAL_PIXEL_FORMAT_EXYNOS_YV12; 6468bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dst_cfg.rot = layer.transform; 6478bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 6488bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby return hdmi_configure(dev, src_cfg, dst_cfg); 6498bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby} 6508bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 6518bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobystatic int hdmi_output(struct exynos5_hwc_composer_device_1_t *dev, private_handle_t *h) 652cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby{ 653f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos_gsc_img src_info; 654f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos_gsc_img dst_info; 655cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 656f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(&src_info, 0, sizeof(src_info)); 657f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(&dst_info, 0, sizeof(dst_info)); 658cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 6598bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_info.yaddr = h->fd; 6608bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (exynos5_format_is_ycrcb(h->format)) { 6618bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_info.uaddr = h->fd2; 6628bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_info.vaddr = h->fd1; 6638bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } else { 6648bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_info.uaddr = h->fd1; 6658bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby src_info.vaddr = h->fd2; 6668bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 667cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 668f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int ret = exynos_gsc_run_exclusive(dev->hdmi_gsc, &src_info, &dst_info); 669f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (ret < 0) { 670f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("%s: exynos_gsc_run_exclusive failed %d", __func__, ret); 671f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return ret; 672f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 673cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 674f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 675cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby} 676cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 677f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmannbool exynos5_supports_overlay(hwc_layer_1_t &layer, size_t i) 678f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann{ 679d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann if (layer.flags & HWC_SKIP_LAYER) { 680d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann ALOGV("\tlayer %u: skipping", i); 681d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann return false; 682d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann } 683d82ad20ecb7f5873d2e743faac5211b953ed77c4Greg Hackmann 684f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann private_handle_t *handle = private_handle_t::dynamicCast(layer.handle); 685f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 686f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!handle) { 687f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\tlayer %u: handle is NULL", i); 688f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return false; 689f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 6909130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (exynos5_format_requires_gscaler(handle->format)) { 691227ae8aef6c88f5321dad4aeed230c43a39594caGreg Hackmann if (!exynos5_supports_gscaler(layer, handle->format, false)) { 6929130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tlayer %u: gscaler required but not supported", i); 6939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return false; 6949130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 6959130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } else { 6969130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (!exynos5_format_is_supported(handle->format)) { 6979130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tlayer %u: pixel format %u not supported", i, handle->format); 6989130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return false; 6999130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 7009130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (is_scaled(layer)) { 7019130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tlayer %u: scaling not supported", i); 7029130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return false; 7039130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 7049130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (is_transformed(layer)) { 7059130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("\tlayer %u: transformations not supported", i); 7069130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return false; 7079130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 708f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 70993cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann if (!exynos5_blending_is_supported(layer.blending)) { 71093cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann ALOGV("\tlayer %u: blending %d not supported", i, layer.blending); 711f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return false; 712f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 713f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 714f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return true; 71586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 71686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 71731991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmanninline bool intersect(const hwc_rect &r1, const hwc_rect &r2) 71831991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann{ 719f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return !(r1.left > r2.right || 720f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann r1.right < r2.left || 721f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann r1.top > r2.bottom || 722f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann r1.bottom < r2.top); 72331991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann} 72431991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann 72531991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmanninline hwc_rect intersection(const hwc_rect &r1, const hwc_rect &r2) 72631991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann{ 727f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect i; 728f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann i.top = max(r1.top, r2.top); 729f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann i.bottom = min(r1.bottom, r2.bottom); 730f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann i.left = max(r1.left, r2.left); 731f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann i.right = min(r1.right, r2.right); 732f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return i; 73331991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann} 73431991d5b23d9099b66a73fea7fc5cc9b05ff26a6Greg Hackmann 735e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hallstatic int exynos5_prepare(hwc_composer_device_1_t *dev, 736e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall size_t numDisplays, hwc_display_contents_1_t** displays) 73786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 738e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall if (!numDisplays || !displays) 739f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 74086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 741e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall ALOGV("preparing %u layers", displays[0]->numHwLayers); 74286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 743f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_composer_device_1_t *pdev = 744f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (exynos5_hwc_composer_device_1_t *)dev; 745f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(pdev->bufs.overlays, 0, sizeof(pdev->bufs.overlays)); 7469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann memset(pdev->bufs.gsc_map, 0, sizeof(pdev->bufs.gsc_map)); 74786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 748f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool force_fb = false; 749f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (pdev->hdmi_hpd) { 750f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hdmi_enable(pdev); 751f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann force_fb = true; 7528bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 7538bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 7548bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (layer.flags & HWC_SKIP_LAYER) 7558bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby continue; 7568bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby private_handle_t *handle = private_handle_t::dynamicCast(layer.handle); 7578bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (handle->flags & GRALLOC_USAGE_EXTERNAL_DISP) { 7588bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby force_fb = false; 7598bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby break; 7608bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 7618bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 762f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } else { 763f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hdmi_disable(pdev); 764f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 765cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 76687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling for (size_t i = 0; i < NUM_HW_WINDOWS; i++) 76787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pdev->bufs.overlay_map[i] = -1; 76887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 769f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool fb_needed = false; 770f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann size_t first_fb = 0, last_fb = 0; 771f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 772f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // find unsupported overlays 773e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 774e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 775f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 776f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer.compositionType == HWC_BACKGROUND && !force_fb) { 777f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\tlayer %u: background supported", i); 778e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall dump_layer(&displays[0]->hwLayers[i]); 779f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 780f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 781f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 782e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall if (exynos5_supports_overlay(displays[0]->hwLayers[i], i) && !force_fb) { 783f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("\tlayer %u: overlay supported", i); 784f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann layer.compositionType = HWC_OVERLAY; 785e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall dump_layer(&displays[0]->hwLayers[i]); 786f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 787f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 788f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 789f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!fb_needed) { 790f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann first_fb = i; 791f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_needed = true; 792f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 793f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann last_fb = i; 794f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann layer.compositionType = HWC_FRAMEBUFFER; 7959130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 796e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall dump_layer(&displays[0]->hwLayers[i]); 797f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 798f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 799f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // can't composite overlays sandwiched between framebuffers 800f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (fb_needed) 801f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t i = first_fb; i < last_fb; i++) 802e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall displays[0]->hwLayers[i].compositionType = HWC_FRAMEBUFFER; 803f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 804f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // Incrementally try to add our supported layers to hardware windows. 805f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // If adding a layer would violate a hardware constraint, force it 806f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // into the framebuffer and try again. (Revisiting the entire list is 807f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // necessary because adding a layer to the framebuffer can cause other 808f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // windows to retroactively violate constraints.) 809f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool changed; 810f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann do { 811f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann android::Vector<hwc_rect> rects; 812f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann android::Vector<hwc_rect> overlaps; 8139130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann size_t pixels_left, windows_left, gsc_left = NUM_GSC_UNITS; 814f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 815f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (fb_needed) { 816f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect_t fb_rect; 817f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_rect.top = fb_rect.left = 0; 818f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_rect.right = pdev->gralloc_module->xres - 1; 819f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_rect.bottom = pdev->gralloc_module->yres - 1; 820f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pixels_left = MAX_PIXELS - pdev->gralloc_module->xres * 821f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->gralloc_module->yres; 822f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann windows_left = NUM_HW_WINDOWS - 1; 823f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann rects.push_back(fb_rect); 824f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 825f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann else { 826f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pixels_left = MAX_PIXELS; 827f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann windows_left = NUM_HW_WINDOWS; 828f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 8298bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (pdev->hdmi_enabled) 8309130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_left--; 8319130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 832f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann changed = false; 833f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 834e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 835e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 8369130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (layer.flags & HWC_SKIP_LAYER) 8379130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann continue; 8389130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 8399130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = private_handle_t::dynamicCast( 8409130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann layer.handle); 841f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 842f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // we've already accounted for the framebuffer above 843f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer.compositionType == HWC_FRAMEBUFFER) 844f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 845f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 846f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // only layer 0 can be HWC_BACKGROUND, so we can 847f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // unconditionally allow it without extra checks 848f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer.compositionType == HWC_BACKGROUND) { 849f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann windows_left--; 850f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 851f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 852f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 853f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann size_t pixels_needed = WIDTH(layer.displayFrame) * 854f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann HEIGHT(layer.displayFrame); 855f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann bool can_compose = windows_left && pixels_needed <= pixels_left; 8569130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann bool gsc_required = exynos5_format_requires_gscaler(handle->format); 8579130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_required) 8589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann can_compose = can_compose && gsc_left; 859f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 860f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // hwc_rect_t right and bottom values are normally exclusive; 861f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // the intersection logic is simpler if we make them inclusive 862f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect_t visible_rect = layer.displayFrame; 863f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann visible_rect.right--; visible_rect.bottom--; 864f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 865f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // no more than 2 layers can overlap on a given pixel 866f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t j = 0; can_compose && j < overlaps.size(); j++) { 867f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (intersect(visible_rect, overlaps.itemAt(j))) 868f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann can_compose = false; 869f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 870f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 871f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!can_compose) { 872f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann layer.compositionType = HWC_FRAMEBUFFER; 873f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!fb_needed) { 874f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann first_fb = last_fb = i; 875f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann fb_needed = true; 876f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 877f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann else { 878f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann first_fb = min(i, first_fb); 879f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann last_fb = max(i, last_fb); 880f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 881f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann changed = true; 882f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann break; 883f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 884f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 885f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t j = 0; j < rects.size(); j++) { 886f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const hwc_rect_t &other_rect = rects.itemAt(j); 887f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (intersect(visible_rect, other_rect)) 888f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann overlaps.push_back(intersection(visible_rect, other_rect)); 889f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 890f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann rects.push_back(visible_rect); 891f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pixels_left -= pixels_needed; 892f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann windows_left--; 8939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_required) 8949130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_left--; 895f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 896f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 897f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (changed) 898f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t i = first_fb; i < last_fb; i++) 899e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall displays[0]->hwLayers[i].compositionType = HWC_FRAMEBUFFER; 900f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } while(changed); 901f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 902f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann unsigned int nextWindow = 0; 9039130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int nextGsc = 0; 904f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 905e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall for (size_t i = 0; i < displays[0]->numHwLayers; i++) { 906e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall hwc_layer_1_t &layer = displays[0]->hwLayers[i]; 907f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 908f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (fb_needed && i == first_fb) { 909f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("assigning framebuffer to window %u\n", 910f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann nextWindow); 911f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann nextWindow++; 912f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann continue; 913f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 914f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 915f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer.compositionType != HWC_FRAMEBUFFER) { 916f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("assigning layer %u to window %u", i, nextWindow); 917f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->bufs.overlay_map[nextWindow] = i; 9189130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (layer.compositionType == HWC_OVERLAY) { 9199130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = 9209130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t::dynamicCast(layer.handle); 9219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (exynos5_format_requires_gscaler(handle->format)) { 9222ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmann ALOGV("\tusing gscaler %u", AVAILABLE_GSC_UNITS[nextGsc]); 9239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdev->bufs.gsc_map[i].mode = 9249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_gsc_map_t::GSC_M2M; 9259130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdev->bufs.gsc_map[i].idx = nextGsc++; 9269130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 9279130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 928f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann nextWindow++; 929f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 930f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 931f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 9329130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = nextGsc; i < NUM_GSC_UNITS; i++) { 9339130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t j = 0; j < NUM_GSC_DST_BUFS; j++) 9349130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (pdev->gsc[i].dst_buf[j]) 9359130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdev->alloc_device->free(pdev->alloc_device, 9369130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdev->gsc[i].dst_buf[j]); 9379130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann memset(&pdev->gsc[i], 0, sizeof(pdev->gsc[i])); 9389130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 9399130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 940f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (fb_needed) 941f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->bufs.fb_window = first_fb; 942f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann else 943f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->bufs.fb_window = NO_FB_NEEDED; 944f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 9459130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return 0; 9469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann} 9479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9489130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannstatic int exynos5_config_gsc_m2m(hwc_layer_1_t &layer, 9499130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann alloc_device_t* alloc_device, exynos5_gsc_data_t *gsc_data, 9509130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int gsc_idx) 9519130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann{ 9529130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("configuring gscaler %u for memory-to-memory", gsc_idx); 9539130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9549130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *src_handle = private_handle_t::dynamicCast(layer.handle); 9559130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann buffer_handle_t dst_buf; 9569130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *dst_handle; 9579130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int ret = 0; 9589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9599130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_img src_cfg, dst_cfg; 9609130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann memset(&src_cfg, 0, sizeof(src_cfg)); 9619130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann memset(&dst_cfg, 0, sizeof(dst_cfg)); 9629130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9639130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.x = layer.sourceCrop.left; 9649130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.y = layer.sourceCrop.top; 9659130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.w = WIDTH(layer.sourceCrop); 9669130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.fw = src_handle->stride; 9679130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.h = HEIGHT(layer.sourceCrop); 968eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann src_cfg.fh = src_handle->vstride; 9699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.yaddr = src_handle->fd; 970296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann if (exynos5_format_is_ycrcb(src_handle->format)) { 971296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann src_cfg.uaddr = src_handle->fd2; 972296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann src_cfg.vaddr = src_handle->fd1; 973296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann } else { 974296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann src_cfg.uaddr = src_handle->fd1; 975296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann src_cfg.vaddr = src_handle->fd2; 976296668ec39f8e30a0aa652f6a99ebfd522fda864Greg Hackmann } 9779130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann src_cfg.format = src_handle->format; 9787bd58627f6422d26e4a1d053a84aba8835bff359Sanghee Kim src_cfg.drmMode = !!(src_handle->flags & GRALLOC_USAGE_PROTECTED); 9799130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9809130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.x = 0; 9819130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.y = 0; 9829130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.w = WIDTH(layer.displayFrame); 9839130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.h = HEIGHT(layer.displayFrame); 984a00c043512babb1d6f48a0a505f30b906fac8066Greg Hackmann dst_cfg.format = HAL_PIXEL_FORMAT_BGRA_8888; 9859130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.rot = layer.transform; 9869130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9879130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("source configuration:"); 9889130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dump_gsc_img(src_cfg); 9899130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 9909130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_src_cfg_changed(src_cfg, gsc_data->src_cfg) || 9919130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_dst_cfg_changed(dst_cfg, gsc_data->dst_cfg)) { 9929130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int dst_stride; 9939130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int usage = GRALLOC_USAGE_SW_READ_NEVER | 9949130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann GRALLOC_USAGE_SW_WRITE_NEVER | 9959130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann GRALLOC_USAGE_HW_COMPOSER; 9967bd58627f6422d26e4a1d053a84aba8835bff359Sanghee Kim 9977bd58627f6422d26e4a1d053a84aba8835bff359Sanghee Kim if (src_handle->flags & GRALLOC_USAGE_PROTECTED) 9987bd58627f6422d26e4a1d053a84aba8835bff359Sanghee Kim usage |= GRALLOC_USAGE_PROTECTED; 9999130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10009130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int w = ALIGN(WIDTH(layer.displayFrame), GSC_W_ALIGNMENT); 10019130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int h = ALIGN(HEIGHT(layer.displayFrame), GSC_H_ALIGNMENT); 10029130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10039130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) { 10049130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_data->dst_buf[i]) { 10059130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann alloc_device->free(alloc_device, gsc_data->dst_buf[i]); 10069130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->dst_buf[i] = NULL; 10079130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 10089130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10099130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int ret = alloc_device->alloc(alloc_device, w, h, 10109130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann HAL_PIXEL_FORMAT_RGBX_8888, usage, &gsc_data->dst_buf[i], 10119130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann &dst_stride); 10129130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (ret < 0) { 10139130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to allocate destination buffer: %s", 10149130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann strerror(-ret)); 10159130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_alloc; 10169130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 10179130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 10189130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10199130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->current_buf = 0; 1020f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1021f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 10229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_buf = gsc_data->dst_buf[gsc_data->current_buf]; 10239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_handle = private_handle_t::dynamicCast(dst_buf); 10249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10259130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.fw = dst_handle->stride; 1026eba34a93004e81973d22d7523a0edf3eb79b8445Greg Hackmann dst_cfg.fh = dst_handle->vstride; 10279130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dst_cfg.yaddr = dst_handle->fd; 10287bd58627f6422d26e4a1d053a84aba8835bff359Sanghee Kim dst_cfg.drmMode = !!(dst_handle->flags & GRALLOC_USAGE_PROTECTED); 10299130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10309130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("destination configuration:"); 10319130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dump_gsc_img(dst_cfg); 10329130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10332ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmann gsc_data->gsc = exynos_gsc_create_exclusive(AVAILABLE_GSC_UNITS[gsc_idx], 10342ddbc743328b3f4367599e8802934efcaa5e265dGreg Hackmann GSC_M2M_MODE, GSC_DUMMY); 10359130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (!gsc_data->gsc) { 10369130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to create gscaler handle"); 10379130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ret = -1; 10389130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_alloc; 10399130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 10409130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10419130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ret = exynos_gsc_config_exclusive(gsc_data->gsc, &src_cfg, &dst_cfg); 10429130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (ret < 0) { 10439130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to configure gscaler %u", gsc_idx); 10449130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_gsc_config; 10459130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 10469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ret = exynos_gsc_run_exclusive(gsc_data->gsc, &src_cfg, &dst_cfg); 10489130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (ret < 0) { 10499130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to run gscaler %u", gsc_idx); 10509130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_gsc_config; 10519130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 10529130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10539130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->src_cfg = src_cfg; 10549130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->dst_cfg = dst_cfg; 10559130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 1056f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 10579130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 10589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannerr_gsc_config: 10599130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_destroy(gsc_data->gsc); 10609130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->gsc = NULL; 10619130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannerr_alloc: 10629130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = 0; i < NUM_GSC_DST_BUFS; i++) { 10639130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gsc_data->dst_buf[i]) { 10649130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann alloc_device->free(alloc_device, gsc_data->dst_buf[i]); 10659130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_data->dst_buf[i] = NULL; 10669130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 10679130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 10689130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann return ret; 106986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 107086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 107186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic void exynos5_config_handle(private_handle_t *handle, 1072f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect_t &sourceCrop, hwc_rect_t &displayFrame, 107393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann int32_t blending, s3c_fb_win_config &cfg) 1074f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann{ 1075f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.state = cfg.S3C_FB_WIN_STATE_BUFFER; 1076f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.fd = handle->fd; 1077f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.x = displayFrame.left; 1078f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.y = displayFrame.top; 1079f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.w = WIDTH(displayFrame); 1080f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.h = HEIGHT(displayFrame); 1081f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.format = exynos5_format_to_s3c_format(handle->format); 1082f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann uint8_t bpp = exynos5_format_to_bpp(handle->format); 1083f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.offset = (sourceCrop.top * handle->stride + sourceCrop.left) * bpp / 8; 1084f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.stride = handle->stride * bpp / 8; 108593cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann cfg.blending = exynos5_blending_to_s3c_blending(blending); 108686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 108786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 108887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic void exynos5_config_overlay(hwc_layer_1_t *layer, s3c_fb_win_config &cfg, 1089f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const private_module_t *gralloc_module) 109086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1091f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (layer->compositionType == HWC_BACKGROUND) { 1092f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_color_t color = layer->backgroundColor; 1093f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.state = cfg.S3C_FB_WIN_STATE_COLOR; 1094f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.color = (color.r << 16) | (color.g << 8) | color.b; 1095f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.x = 0; 1096f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.y = 0; 1097f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.w = gralloc_module->xres; 1098f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann cfg.h = gralloc_module->yres; 1099f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return; 1100f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1101f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1102f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann private_handle_t *handle = private_handle_t::dynamicCast(layer->handle); 110393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann exynos5_config_handle(handle, layer->sourceCrop, layer->displayFrame, 110493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann layer->blending, cfg); 110586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 110686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 110786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic void exynos5_post_callback(void *data, private_handle_t *fb) 110886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 11098bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby hwc_layer_1_t *hdmi_layer = NULL; 1110f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_post_data_t *pdata = (exynos5_hwc_post_data_t *)data; 1111f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1112f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct s3c_fb_win_config_data win_data; 1113f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct s3c_fb_win_config *config = win_data.config; 1114f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(config, 0, sizeof(win_data.config)); 11159130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 11169130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 11179130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if ( pdata->overlay_map[i] != -1) { 11189130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann hwc_layer_1_t &layer = pdata->overlays[i]; 11199130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = 11209130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t::dynamicCast(layer.handle); 11219130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 11229130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (layer.acquireFenceFd != -1) { 11239130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int err = sync_wait(layer.acquireFenceFd, 100); 11249130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (err != 0) 11259130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGW("fence for layer %zu didn't signal in 100 ms: %s", 11269130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann i, strerror(errno)); 11279130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann close(layer.acquireFenceFd); 11289130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 11299130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 11309130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) { 11319130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int gsc_idx = pdata->gsc_map[i].idx; 11329130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_config_gsc_m2m(layer, pdata->pdev->alloc_device, 11339130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann &pdata->pdev->gsc[gsc_idx], gsc_idx); 11349130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 11359130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 11369130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 11379130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 1138f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1139f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (i == pdata->fb_window) { 1140f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_rect_t rect = { 0, 0, fb->width, fb->height }; 114193cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann int32_t blending = (i == 0) ? HWC_BLENDING_NONE : 114293cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann HWC_BLENDING_PREMULT; 114393cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann exynos5_config_handle(fb, rect, rect, blending, config[i]); 1144f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } else if ( pdata->overlay_map[i] != -1) { 11459130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann hwc_layer_1_t &layer = pdata->overlays[i]; 11469130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *handle = 11479130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t::dynamicCast(layer.handle); 11489130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 11499130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (pdata->gsc_map[i].mode == exynos5_gsc_map_t::GSC_M2M) { 11509130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int gsc_idx = pdata->gsc_map[i].idx; 11519130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_gsc_data_t &gsc = pdata->pdev->gsc[gsc_idx]; 11529130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 11539130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (!gsc.gsc) { 11549130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to queue gscaler %u input for layer %u", 11559130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc_idx, i); 11569130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann continue; 11579130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 11589130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 11599130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann int err = exynos_gsc_stop_exclusive(gsc.gsc); 11609130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_destroy(gsc.gsc); 11619130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc.gsc = NULL; 11629130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (err < 0) { 11639130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to dequeue gscaler output for layer %u", i); 11649130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann continue; 11659130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 11669130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 11679130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann buffer_handle_t dst_buf = gsc.dst_buf[gsc.current_buf]; 11689130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gsc.current_buf = (gsc.current_buf + 1) % NUM_GSC_DST_BUFS; 11699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t *dst_handle = 11709130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann private_handle_t::dynamicCast(dst_buf); 117190219f32a19cfaa1c24673452e9f33cccc092e21Greg Hackmann hwc_rect_t sourceCrop = { 0, 0, 117290219f32a19cfaa1c24673452e9f33cccc092e21Greg Hackmann WIDTH(layer.displayFrame), HEIGHT(layer.displayFrame) }; 117390219f32a19cfaa1c24673452e9f33cccc092e21Greg Hackmann exynos5_config_handle(dst_handle, sourceCrop, 117493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann layer.displayFrame, layer.blending, config[i]); 11758bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 11768bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (handle->flags & GRALLOC_USAGE_EXTERNAL_DISP) 11778bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby hdmi_layer = &layer; 11789130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 11799130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann else { 11809130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos5_config_overlay(&layer, config[i], 11819130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann pdata->pdev->gralloc_module); 118287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 118387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 118493cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann if (i == 0 && config[i].blending != S3C_FB_BLENDING_NONE) { 118593cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann ALOGV("blending not supported on window 0; forcing BLENDING_NONE"); 118693cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann config[i].blending = S3C_FB_BLENDING_NONE; 118793cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann } 118893cc5e7a6186155981ac10e8809de957d2fc1595Greg Hackmann 11899130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGV("window %u configuration:", i); 1190f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dump_config(config[i]); 1191f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 119286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1193f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int ret = ioctl(pdata->pdev->fd, S3CFB_WIN_CONFIG, &win_data); 1194f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (ret < 0) 1195f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("ioctl S3CFB_WIN_CONFIG failed: %d", errno); 1196600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann else { 1197600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann memcpy(pdata->pdev->last_config, &win_data.config, 1198600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann sizeof(win_data.config)); 1199600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann memcpy(pdata->pdev->last_gsc_map, pdata->gsc_map, 1200600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann sizeof(pdata->gsc_map)); 1201600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1202600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann if (i == pdata->fb_window) { 1203600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann pdata->pdev->last_handles[i] = NULL; 1204600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann } else if (pdata->overlay_map[i] != -1) { 1205600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann hwc_layer_1_t &layer = pdata->overlays[i]; 1206600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann pdata->pdev->last_handles[i] = layer.handle; 1207600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann } 1208600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann } 1209600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann } 121086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 12118bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (pdata->pdev->hdmi_enabled) { 12128bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (hdmi_layer) { 12138bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby private_handle_t *handle = 12148bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby private_handle_t::dynamicCast(hdmi_layer->handle); 12158bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby hdmi_configure_layer(pdata->pdev, *hdmi_layer); 12168bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby hdmi_output(pdata->pdev, handle); 12178bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } else { 12188bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby hdmi_configure_handle(pdata->pdev, fb); 12198bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby hdmi_output(pdata->pdev, fb); 12208bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 12218bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 1222cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 122387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_lock(&pdata->completion_lock); 122487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pdata->fence = win_data.fence; 122587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_cond_signal(&pdata->completion); 122687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_unlock(&pdata->completion_lock); 122786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 122886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1229e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hallstatic int exynos5_set(struct hwc_composer_device_1 *dev, 1230e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall size_t numDisplays, hwc_display_contents_1_t** displays) 123186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1232f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_composer_device_1_t *pdev = 1233f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (exynos5_hwc_composer_device_1_t *)dev; 123486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1235e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall if (!numDisplays || !displays || !displays[0] || !displays[0]->dpy || !displays[0]->sur) 1236f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 123786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1238f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_callback_queue_t *queue = NULL; 1239f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pthread_mutex_t *lock = NULL; 1240f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann exynos5_hwc_post_data_t *data = NULL; 124186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 12420fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 12430fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann if (pdev->bufs.overlay_map[i] != -1) { 12440fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann pdev->bufs.overlays[i] = 12450fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann displays[0]->hwLayers[pdev->bufs.overlay_map[i]]; 124687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 12470fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann } 124887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 12490fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann data = (exynos5_hwc_post_data_t *) 12500fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann malloc(sizeof(exynos5_hwc_post_data_t)); 12510fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann memcpy(data, &pdev->bufs, sizeof(pdev->bufs)); 12520fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann 12530fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann data->fence = -1; 12540fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann pthread_mutex_init(&data->completion_lock, NULL); 12550fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann pthread_cond_init(&data->completion, NULL); 12560fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann 12570fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann if (displays[0]->numHwLayers && pdev->bufs.fb_window == NO_FB_NEEDED) { 12580fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann exynos5_post_callback(data, NULL); 12590fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann } else { 12600fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann 12610fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann struct hwc_callback_entry entry; 12620fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann entry.callback = exynos5_post_callback; 12630fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann entry.data = data; 12640fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann 12650fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann queue = reinterpret_cast<hwc_callback_queue_t *>( 12660fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann pdev->gralloc_module->queue); 12670fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann lock = const_cast<pthread_mutex_t *>( 12680fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann &pdev->gralloc_module->queue_lock); 12690fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann 12700fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann pthread_mutex_lock(lock); 12710fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann queue->push_front(entry); 12720fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann pthread_mutex_unlock(lock); 12730fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann 12740fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann EGLBoolean success = eglSwapBuffers((EGLDisplay)displays[0]->dpy, 12750fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann (EGLSurface)displays[0]->sur); 12760fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann if (!success) { 12770fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann ALOGE("HWC_EGL_ERROR"); 12780fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann if (displays[0]) { 12790fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann pthread_mutex_lock(lock); 12800fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann queue->removeAt(0); 12810fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann pthread_mutex_unlock(lock); 12820fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann free(data); 128387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 12840fbe1706499c5d1c48b3c97669be79c5e6213cefGreg Hackmann return HWC_EGL_ERROR; 128587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 1286f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 128786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 128886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 128987e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_lock(&data->completion_lock); 129087e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling while (data->fence == -1) 129187e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_cond_wait(&data->completion, &data->completion_lock); 129287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling pthread_mutex_unlock(&data->completion_lock); 129387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling 129487e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 129587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling if (pdev->bufs.overlay_map[i] != -1) { 129687e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling int dup_fd = dup(data->fence); 129787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling if (dup_fd < 0) 129887e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling ALOGW("release fence dup failed: %s", strerror(errno)); 1299e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall displays[0]->hwLayers[pdev->bufs.overlay_map[i]].releaseFenceFd = dup_fd; 130087e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 130187e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling } 130287e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling close(data->fence); 130387e707ef7564de37b526a13f030e3c41673dd9c9Erik Gilling free(data); 1304f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 130586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 130686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 130787e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic void exynos5_registerProcs(struct hwc_composer_device_1* dev, 1308f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hwc_procs_t const* procs) 130986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1310f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t* pdev = 1311f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t*)dev; 1312da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall pdev->procs = procs; 131386eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 131486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 131587e707ef7564de37b526a13f030e3c41673dd9c9Erik Gillingstatic int exynos5_query(struct hwc_composer_device_1* dev, int what, int *value) 131686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1317f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *pdev = 1318f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t *)dev; 1319f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1320f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann switch (what) { 1321f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HWC_BACKGROUND_LAYER_SUPPORTED: 1322f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // we support the background layer 1323f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann value[0] = 1; 1324f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann break; 1325f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HWC_VSYNC_PERIOD: 1326f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // vsync period in nanosecond 1327f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann value[0] = 1000000000.0 / pdev->gralloc_module->fps; 1328f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann break; 1329f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann default: 1330f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann // unsupported query 1331f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -EINVAL; 1332f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1333f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 133486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 133586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1336e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hallstatic int exynos5_eventControl(struct hwc_composer_device_1 *dev, int dpy, 1337e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hall int event, int enabled) 133886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1339f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *pdev = 1340f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t *)dev; 1341f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1342f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann switch (event) { 1343f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann case HWC_EVENT_VSYNC: 1344f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann __u32 val = !!enabled; 1345f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int err = ioctl(pdev->fd, S3CFB_SET_VSYNC_INT, &val); 1346f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (err < 0) { 1347f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("vsync ioctl failed"); 1348f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -errno; 1349f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1350f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1351f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 1352f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1353f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1354f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -EINVAL; 135586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 135686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1357cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Gobystatic void handle_hdmi_uevent(struct exynos5_hwc_composer_device_1_t *pdev, 1358f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const char *buff, int len) 1359cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby{ 1360f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann const char *s = buff; 1361f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann s += strlen(s) + 1; 1362cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1363f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann while (*s) { 1364f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE="))) 1365f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->hdmi_hpd = atoi(s + strlen("SWITCH_STATE=")) == 1; 1366cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1367f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann s += strlen(s) + 1; 1368f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (s - buff >= len) 1369f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann break; 1370f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1371cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1372d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (pdev->hdmi_hpd) { 1373d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (hdmi_get_config(pdev)) { 1374d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby ALOGE("Error reading HDMI configuration"); 1375d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby pdev->hdmi_hpd = false; 1376d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby return; 1377d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 1378d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 1379d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 1380f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGV("HDMI HPD changed to %s", pdev->hdmi_hpd ? "enabled" : "disabled"); 1381d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby if (pdev->hdmi_hpd) 13828bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGI("HDMI Resolution changed to %dx%d", pdev->hdmi_h, pdev->hdmi_w); 1383cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 1384da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall /* hwc_dev->procs is set right after the device is opened, but there is 1385da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall * still a race condition where a hotplug event might occur after the open 1386da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall * but before the procs are registered. */ 1387da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall if (pdev->procs) 1388f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann pdev->procs->invalidate(pdev->procs); 1389cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby} 1390cdd61b35ae02e1fe761815ad9bd166db4098ece2Benoit Goby 13912972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmannstatic void handle_vsync_event(struct exynos5_hwc_composer_device_1_t *pdev) 139286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1393da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall if (!pdev->procs) 1394f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return; 139586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1396fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann int err = lseek(pdev->vsync_fd, 0, SEEK_SET); 1397fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann if (err < 0) { 1398fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann ALOGE("error seeking to vsync timestamp: %s", strerror(errno)); 1399fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann return; 1400fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann } 1401fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann 14022972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann char buf[4096]; 1403fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann err = read(pdev->vsync_fd, buf, sizeof(buf)); 14042972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (err < 0) { 14052972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann ALOGE("error reading vsync timestamp: %s", strerror(errno)); 14062972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann return; 1407f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 14082972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann buf[sizeof(buf) - 1] = '\0'; 140986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 14102972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann errno = 0; 14112972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann uint64_t timestamp = strtoull(buf, NULL, 0); 14122972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (!errno) 14132972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann pdev->procs->vsync(pdev->procs, 0, timestamp); 141486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 141586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 141686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic void *hwc_vsync_thread(void *data) 141786eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1418f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *pdev = 1419f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t *)data; 1420f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann char uevent_desc[4096]; 1421f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(uevent_desc, 0, sizeof(uevent_desc)); 1422f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1423f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 1424f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1425f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann uevent_init(); 1426f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1427fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann char temp[4096]; 1428fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann int err = read(pdev->vsync_fd, temp, sizeof(temp)); 1429fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann if (err < 0) { 1430fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann ALOGE("error reading vsync timestamp: %s", strerror(errno)); 1431fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann return NULL; 1432fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann } 1433fbeb8534d8bbb60d39f9e62e3876c4b2da810972Greg Hackmann 14342972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann struct pollfd fds[2]; 14352972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann fds[0].fd = pdev->vsync_fd; 14362972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann fds[0].events = POLLPRI; 14372972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann fds[1].fd = uevent_get_fd(); 14382972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann fds[1].events = POLLIN; 14392972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann 14402972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann while (true) { 14412972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann int err = poll(fds, 2, -1); 14423464b1dd35ad9c49f797e069922f22a788a8b440Greg Hackmann 14432972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (err > 0) { 14442972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (fds[0].revents & POLLPRI) { 14452972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann handle_vsync_event(pdev); 14462972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 14472972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann else if (fds[1].revents & POLLIN) { 14482972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann int len = uevent_next_event(uevent_desc, 14492972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann sizeof(uevent_desc) - 2); 14502972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann 14512972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann bool hdmi = !strcmp(uevent_desc, 14522972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann "change@/devices/virtual/switch/hdmi"); 14532972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (hdmi) 14542972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann handle_hdmi_uevent(pdev, uevent_desc, len); 14552972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 14562972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 14572972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann else if (err == -1) { 14582972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (errno == EINTR) 14592972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann break; 14602972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann ALOGE("error in vsync thread: %s", strerror(errno)); 14612972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 1462f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1463f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1464f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return NULL; 146586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 146686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 1467e94046d91136bbb2654ae197dc1782b7f11275d0Jesse Hallstatic int exynos5_blank(struct hwc_composer_device_1 *dev, int dpy, int blank) 146800359a8853031c94e4f7d5c8d79a44917de9842fColin Cross{ 146900359a8853031c94e4f7d5c8d79a44917de9842fColin Cross struct exynos5_hwc_composer_device_1_t *pdev = 147000359a8853031c94e4f7d5c8d79a44917de9842fColin Cross (struct exynos5_hwc_composer_device_1_t *)dev; 147100359a8853031c94e4f7d5c8d79a44917de9842fColin Cross 147200359a8853031c94e4f7d5c8d79a44917de9842fColin Cross int fb_blank = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK; 147300359a8853031c94e4f7d5c8d79a44917de9842fColin Cross int err = ioctl(pdev->fd, FBIOBLANK, fb_blank); 147400359a8853031c94e4f7d5c8d79a44917de9842fColin Cross if (err < 0) { 147500359a8853031c94e4f7d5c8d79a44917de9842fColin Cross ALOGE("%sblank ioctl failed", blank ? "" : "un"); 147600359a8853031c94e4f7d5c8d79a44917de9842fColin Cross return -errno; 147700359a8853031c94e4f7d5c8d79a44917de9842fColin Cross } 147800359a8853031c94e4f7d5c8d79a44917de9842fColin Cross 1479ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby if (pdev->hdmi_hpd) { 1480ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby if (blank && !pdev->hdmi_blanked) 1481ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby hdmi_disable(pdev); 1482ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby pdev->hdmi_blanked = !!blank; 1483ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby } 1484ad4e3589e43660981c09755f0535c393e31cef35Benoit Goby 148500359a8853031c94e4f7d5c8d79a44917de9842fColin Cross return 0; 148600359a8853031c94e4f7d5c8d79a44917de9842fColin Cross} 148700359a8853031c94e4f7d5c8d79a44917de9842fColin Cross 1488600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmannstatic void exynos5_dump(hwc_composer_device_1* dev, char *buff, int buff_len) 1489600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann{ 1490600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann if (buff_len <= 0) 1491600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann return; 1492600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 1493600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann struct exynos5_hwc_composer_device_1_t *pdev = 1494600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann (struct exynos5_hwc_composer_device_1_t *)dev; 1495600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 1496600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann android::String8 result; 1497600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 14988bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby result.appendFormat(" hdmi_enabled=%u\n", pdev->hdmi_enabled); 14998bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (pdev->hdmi_enabled) 15008bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby result.appendFormat(" w=%u, h=%u\n", pdev->hdmi_w, pdev->hdmi_h); 1501600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.append( 1502600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann " type | handle | color | blend | format | position | size | gsc \n" 1503600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann "----------+----------|----------+-------+--------+---------------+---------------------\n"); 1504600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann // 8_______ | 8_______ | 8_______ | 5____ | 6_____ | [5____,5____] | [5____,5____] | 3__ \n" 1505600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 1506600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann for (size_t i = 0; i < NUM_HW_WINDOWS; i++) { 1507600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann struct s3c_fb_win_config &config = pdev->last_config[i]; 1508600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann if (config.state == config.S3C_FB_WIN_STATE_DISABLED) { 1509600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.appendFormat(" %8s | %8s | %8s | %5s | %6s | %13s | %13s", 1510600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann "DISABLED", "-", "-", "-", "-", "-", "-"); 1511600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann } 1512600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann else { 1513600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann if (config.state == config.S3C_FB_WIN_STATE_COLOR) 1514600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.appendFormat(" %8s | %8s | %8x | %5s | %6s", "COLOR", 1515600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann "-", config.color, "-", "-"); 1516600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann else { 1517600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann if (pdev->last_handles[i]) 1518600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.appendFormat(" %8s | %8x", "OVERLAY", intptr_t(pdev->last_handles[i])); 1519600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann else 1520600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.appendFormat(" %8s | %8s", "FB", "-"); 1521600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 1522600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.appendFormat(" | %8s | %5x | %6x", "-", config.blending, 1523600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann config.format); 1524600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann } 1525600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 1526600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.appendFormat(" | [%5d,%5d] | [%5u,%5u]", config.x, config.y, 1527600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann config.w, config.h); 1528600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann } 1529600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann if (pdev->last_gsc_map[i].mode == exynos5_gsc_map_t::GSC_NONE) 1530600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.appendFormat(" | %3s", "-"); 1531600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann else 1532600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.appendFormat(" | %3d", 1533600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann AVAILABLE_GSC_UNITS[pdev->last_gsc_map[i].idx]); 1534600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann result.append("\n"); 1535600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann } 1536600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 1537600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann strlcpy(buff, result.string(), buff_len); 1538600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann} 1539600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann 154086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic int exynos5_close(hw_device_t* device); 154186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 154286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic int exynos5_open(const struct hw_module_t *module, const char *name, 1543f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct hw_device_t **device) 154486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1545f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int ret; 1546f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann int sw_fd; 1547f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1548f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 1549f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return -EINVAL; 1550f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1551f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1552f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *dev; 1553f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev = (struct exynos5_hwc_composer_device_1_t *)malloc(sizeof(*dev)); 1554f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann memset(dev, 0, sizeof(*dev)); 1555f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1556f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, 1557f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (const struct hw_module_t **)&dev->gralloc_module)) { 1558f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("failed to get gralloc hw module"); 1559f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ret = -EINVAL; 1560f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann goto err_get_module; 1561f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1562f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 15639130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (gralloc_open((const hw_module_t *)dev->gralloc_module, 15649130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann &dev->alloc_device)) { 15659130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ALOGE("failed to open gralloc"); 15669130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann ret = -EINVAL; 15679130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_get_module; 15689130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 15699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann 1570f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->fd = open("/dev/graphics/fb0", O_RDWR); 1571f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (dev->fd < 0) { 1572f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("failed to open framebuffer"); 1573f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ret = dev->fd; 15749130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann goto err_open_fb; 1575f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1576f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 15778bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_mixer0 = open("/dev/v4l-subdev7", O_RDWR); 15788bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (dev->hdmi_layer0 < 0) { 15798bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("failed to open hdmi mixer0 subdev"); 15808bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ret = dev->hdmi_layer0; 1581d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby goto err_ioctl; 1582d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby } 1583d6bb7cef6f2325e7703704b3acbec99df2b6d381Benoit Goby 15848bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_layer0 = open("/dev/video16", O_RDWR); 15858bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (dev->hdmi_layer0 < 0) { 15868bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("failed to open hdmi layer0 device"); 15878bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ret = dev->hdmi_layer0; 15888bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby goto err_mixer0; 15898bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 15908bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 15918bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby dev->hdmi_layer1 = open("/dev/video17", O_RDWR); 15928bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby if (dev->hdmi_layer1 < 0) { 15938bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ALOGE("failed to open hdmi layer1 device"); 15948bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby ret = dev->hdmi_layer1; 15958bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby goto err_hdmi0; 15968bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby } 15978bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby 15982972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann dev->vsync_fd = open("/sys/devices/platform/exynos5-fb.1/vsync", O_RDONLY); 15992972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann if (dev->vsync_fd < 0) { 16002972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann ALOGE("failed to open vsync attribute"); 16012972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann ret = dev->vsync_fd; 16028bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby goto err_hdmi1; 16032972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann } 16042972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann 1605f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY); 1606f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (sw_fd) { 1607f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann char val; 16084e0f168e3d62fd6d594c4015f2f3da4449fcbf19Benoit Goby if (read(sw_fd, &val, 1) == 1 && val == '1') { 1609f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->hdmi_hpd = true; 16104e0f168e3d62fd6d594c4015f2f3da4449fcbf19Benoit Goby if (hdmi_get_config(dev)) { 16114e0f168e3d62fd6d594c4015f2f3da4449fcbf19Benoit Goby ALOGE("Error reading HDMI configuration"); 16124e0f168e3d62fd6d594c4015f2f3da4449fcbf19Benoit Goby dev->hdmi_hpd = false; 16134e0f168e3d62fd6d594c4015f2f3da4449fcbf19Benoit Goby } 16144e0f168e3d62fd6d594c4015f2f3da4449fcbf19Benoit Goby } 1615f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1616f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1617f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.common.tag = HARDWARE_DEVICE_TAG; 1618f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.common.version = HWC_DEVICE_API_VERSION_1_0; 1619f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.common.module = const_cast<hw_module_t *>(module); 1620f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.common.close = exynos5_close; 1621f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1622f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.prepare = exynos5_prepare; 1623f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.set = exynos5_set; 1624da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall dev->base.eventControl = exynos5_eventControl; 1625da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall dev->base.blank = exynos5_blank; 1626f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->base.query = exynos5_query; 1627da5a71d42af7add8e6ab5c56cf31e5dc89a80f6cJesse Hall dev->base.registerProcs = exynos5_registerProcs; 1628600867e7481266f7e3f227da275f544d3ff7d72aGreg Hackmann dev->base.dump = exynos5_dump; 1629f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1630f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann dev->bufs.pdev = dev; 1631f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1632f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann *device = &dev->base.common; 1633f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1634f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ret = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev); 1635f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann if (ret) { 1636f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ALOGE("failed to start vsync thread: %s", strerror(ret)); 1637f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann ret = -ret; 16382972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann goto err_vsync; 1639f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 1640f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann 1641f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 164286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 16432972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmannerr_vsync: 16442972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann close(dev->vsync_fd); 16458bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobyerr_mixer0: 16468bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby close(dev->hdmi_mixer0); 16478bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobyerr_hdmi1: 16488bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby close(dev->hdmi_layer0); 16498bad7e324e05d7246e3ed4c331060628fe753392Benoit Gobyerr_hdmi0: 16508bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby close(dev->hdmi_layer1); 165186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannerr_ioctl: 1652f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann close(dev->fd); 16539130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmannerr_open_fb: 16549130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gralloc_close(dev->alloc_device); 165586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannerr_get_module: 1656f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann free(dev); 1657f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return ret; 165886eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 165986eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 166086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic int exynos5_close(hw_device_t *device) 166186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann{ 1662f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann struct exynos5_hwc_composer_device_1_t *dev = 1663f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann (struct exynos5_hwc_composer_device_1_t *)device; 16642972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann pthread_kill(dev->vsync_thread, SIGTERM); 16652972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann pthread_join(dev->vsync_thread, NULL); 16669130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t i = 0; i < NUM_GSC_UNITS; i++) { 16679130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (dev->gsc[i].gsc) 16689130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann exynos_gsc_destroy(dev->gsc[i].gsc); 16699130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann for (size_t j = 0; i < NUM_GSC_DST_BUFS; j++) 16709130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann if (dev->gsc[i].dst_buf[j]) 16719130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann dev->alloc_device->free(dev->alloc_device, dev->gsc[i].dst_buf[j]); 16729130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann } 16739130e706ff8bf69346d557aabc48080bee4be5cbGreg Hackmann gralloc_close(dev->alloc_device); 16742972485a91007a12d3ad1c6057601ccbf15f01efGreg Hackmann close(dev->vsync_fd); 16758bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby close(dev->hdmi_mixer0); 16768bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby close(dev->hdmi_layer0); 16778bad7e324e05d7246e3ed4c331060628fe753392Benoit Goby close(dev->hdmi_layer1); 1678f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann close(dev->fd); 1679f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann return 0; 168086eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann} 168186eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 168286eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannstatic struct hw_module_methods_t exynos5_hwc_module_methods = { 1683f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann open: exynos5_open, 168486eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 168586eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann 168686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmannhwc_module_t HAL_MODULE_INFO_SYM = { 1687f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann common: { 1688f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann tag: HARDWARE_MODULE_TAG, 1689f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann module_api_version: HWC_MODULE_API_VERSION_0_1, 1690f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann hal_api_version: HARDWARE_HAL_API_VERSION, 1691f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann id: HWC_HARDWARE_MODULE_ID, 1692f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann name: "Samsung exynos5 hwcomposer module", 1693f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann author: "Google", 1694f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann methods: &exynos5_hwc_module_methods, 1695f6f2e546404d3fe17781ef7a13b29691f3025f42Greg Hackmann } 169686eb1c67dc9654aed754b3a74a0839a2a7c2f939Greg Hackmann}; 1697