1b166940edca6e312463461438e2aa66e9852c26aBenoit Goby/* 2b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Copyright (C) 2010 The Android Open Source Project 3b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Copyright (C) 2012-2013, The Linux Foundation All rights reserved. 4b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 5b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Not a Contribution, Apache license notifications and license are retained 6b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * for attribution purposes only. 7b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 8b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Licensed under the Apache License, Version 2.0 (the "License"); 9b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * you may not use this file except in compliance with the License. 10b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * You may obtain a copy of the License at 11b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 12b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * http://www.apache.org/licenses/LICENSE-2.0 13b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * 14b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Unless required by applicable law or agreed to in writing, software 15b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * distributed under the License is distributed on an "AS IS" BASIS, 16b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * See the License for the specific language governing permissions and 18b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * limitations under the License. 19b166940edca6e312463461438e2aa66e9852c26aBenoit Goby */ 20b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#define HWC_UTILS_DEBUG 0 21b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <sys/ioctl.h> 22b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <binder/IServiceManager.h> 23b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <EGL/egl.h> 24b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <cutils/properties.h> 25b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <gralloc_priv.h> 26b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <overlay.h> 27b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include <overlayRotator.h> 28b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "hwc_utils.h" 29b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "hwc_mdpcomp.h" 30b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "hwc_fbupdate.h" 31b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "mdp_version.h" 32b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "hwc_copybit.h" 33b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "external.h" 34b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "hwc_qclient.h" 35b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "QService.h" 36b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#include "comptype.h" 37b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 38b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyusing namespace qClient; 39b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyusing namespace qService; 40b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyusing namespace android; 41b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyusing namespace overlay; 42b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyusing namespace overlay::utils; 43b166940edca6e312463461438e2aa66e9852c26aBenoit Gobynamespace ovutils = overlay::utils; 44b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 45b166940edca6e312463461438e2aa66e9852c26aBenoit Gobynamespace qhwc { 46b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 47b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic int openFramebufferDevice(hwc_context_t *ctx) 48b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 49b166940edca6e312463461438e2aa66e9852c26aBenoit Goby struct fb_fix_screeninfo finfo; 50b166940edca6e312463461438e2aa66e9852c26aBenoit Goby struct fb_var_screeninfo info; 51b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 52b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int fb_fd = openFb(HWC_DISPLAY_PRIMARY); 53b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 54b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &info) == -1) 55b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -errno; 56b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 57b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (int(info.width) <= 0 || int(info.height) <= 0) { 58b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // the driver doesn't return that information 59b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // default to 160 dpi 60b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.width = ((info.xres * 25.4f)/160.0f + 0.5f); 61b166940edca6e312463461438e2aa66e9852c26aBenoit Goby info.height = ((info.yres * 25.4f)/160.0f + 0.5f); 62b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 63b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 64b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float xdpi = (info.xres * 25.4f) / info.width; 65b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float ydpi = (info.yres * 25.4f) / info.height; 66b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 67b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#ifdef MSMFB_METADATA_GET 68b166940edca6e312463461438e2aa66e9852c26aBenoit Goby struct msmfb_metadata metadata; 69b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&metadata, 0 , sizeof(metadata)); 70b166940edca6e312463461438e2aa66e9852c26aBenoit Goby metadata.op = metadata_op_frame_rate; 71b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 72b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) { 73b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("Error retrieving panel frame rate"); 74b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -errno; 75b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 76b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 77b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float fps = metadata.data.panel_frame_rate; 78b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#else 79b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //XXX: Remove reserved field usage on all baselines 80b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //The reserved[3] field is used to store FPS by the driver. 81b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float fps = info.reserved[3] & 0xFF; 82b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#endif 83b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 84b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) == -1) 85b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -errno; 86b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 87b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (finfo.smem_len <= 0) 88b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -errno; 89b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 90b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = fb_fd; 91b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //xres, yres may not be 32 aligned 92b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride = finfo.line_length /(info.xres/8); 93b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = info.xres; 94b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = info.yres; 95b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi; 96b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi; 97b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period = 1000000000l / fps; 98b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 99b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Unblank primary on first boot 100b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ioctl(fb_fd, FBIOBLANK,FB_BLANK_UNBLANK) < 0) { 101b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: Failed to unblank display", __FUNCTION__); 102b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -errno; 103b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 104b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive = true; 105b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 106b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 107b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 108b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 109b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic int ppdComm(const char* cmd, hwc_context_t *ctx) { 110b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int ret = -1; 111b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = write(ctx->mCablProp.daemon_socket, cmd, strlen(cmd)); 112b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ret < 0) { 113b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("Failed to send data over socket: %s", 114b166940edca6e312463461438e2aa66e9852c26aBenoit Goby strerror(errno)); 115b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return ret; 116b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 117b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(HWC_UTILS_DEBUG, "%s: Sent command: %s", __FUNCTION__, cmd); 118b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 119b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 120b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 121b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic void connectPPDaemon(hwc_context_t *ctx) 122b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 123b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int ret = -1; 124b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char property[PROPERTY_VALUE_MAX]; 125b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if ((property_get("ro.qualcomm.cabl", property, NULL) > 0) && 126b166940edca6e312463461438e2aa66e9852c26aBenoit Goby (atoi(property) == 1)) { 127b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("%s: CABL is enabled", __FUNCTION__); 128b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCablProp.enabled = true; 129b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 130b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("%s: CABL is disabled", __FUNCTION__); 131b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCablProp.enabled = false; 132b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 133b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 134b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 135b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if ((property_get("persist.qcom.cabl.video_only", property, NULL) > 0) && 136b166940edca6e312463461438e2aa66e9852c26aBenoit Goby (atoi(property) == 1)) { 137b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD("%s: CABL is in video only mode", __FUNCTION__); 138b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCablProp.videoOnly = true; 139b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 140b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCablProp.videoOnly = false; 141b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 142b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 143b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int daemon_socket = socket_local_client(DAEMON_SOCKET, 144b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ANDROID_SOCKET_NAMESPACE_RESERVED, 145b166940edca6e312463461438e2aa66e9852c26aBenoit Goby SOCK_STREAM); 146b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(!daemon_socket) { 147b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("Connecting to socket failed: %s", strerror(errno)); 148b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCablProp.enabled = false; 149b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 150b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 151b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCablProp.daemon_socket = daemon_socket; 152b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 153b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 154b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid initContext(hwc_context_t *ctx) 155b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 156b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(openFramebufferDevice(ctx) < 0) { 157b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: failed to open framebuffer!!", __FUNCTION__); 158b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 159b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 160b166940edca6e312463461438e2aa66e9852c26aBenoit Goby overlay::Overlay::initOverlay(); 161b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mOverlay = overlay::Overlay::getInstance(); 162b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mRotMgr = new RotMgr(); 163b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion(); 164b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay(); 165b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType(); 166b166940edca6e312463461438e2aa66e9852c26aBenoit Goby overlay::Overlay::initOverlay(); 167b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mOverlay = overlay::Overlay::getInstance(); 168b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mRotMgr = new RotMgr(); 169b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 170b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Is created and destroyed only once for primary 171b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //For external it could get created and destroyed multiple times depending 172b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //on what external we connect to. 173b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mFBUpdate[HWC_DISPLAY_PRIMARY] = 174b166940edca6e312463461438e2aa66e9852c26aBenoit Goby IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres, 175b166940edca6e312463461438e2aa66e9852c26aBenoit Goby HWC_DISPLAY_PRIMARY); 176b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 177b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Check if the target supports copybit compostion (dyn/mdp/c2d) to 178b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // decide if we need to open the copybit module. 179b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int compositionType = 180b166940edca6e312463461438e2aa66e9852c26aBenoit Goby qdutils::QCCompositionType::getInstance().getCompositionType(); 181b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 182b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (compositionType & (qdutils::COMPOSITION_TYPE_DYN | 183b166940edca6e312463461438e2aa66e9852c26aBenoit Goby qdutils::COMPOSITION_TYPE_MDP | 184b166940edca6e312463461438e2aa66e9852c26aBenoit Goby qdutils::COMPOSITION_TYPE_C2D)) { 185b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(); 186b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 187b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 188b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mExtDisplay = new ExternalDisplay(ctx); 189b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 190b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for (uint32_t i = 0; i < MAX_DISPLAYS; i++) { 191b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mLayerRotMap[i] = new LayerRotMap(); 192b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 193b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 194b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mMDPComp[HWC_DISPLAY_PRIMARY] = 195b166940edca6e312463461438e2aa66e9852c26aBenoit Goby MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres, 196b166940edca6e312463461438e2aa66e9852c26aBenoit Goby HWC_DISPLAY_PRIMARY); 197b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 198b166940edca6e312463461438e2aa66e9852c26aBenoit Goby MDPComp::init(ctx); 199b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 200b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->vstate.enable = false; 201b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->vstate.fakevsync = false; 202b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mExtDispConfiguring = false; 203b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mBasePipeSetup = false; 204b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 205b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Right now hwc starts the service but anybody could do it, or it could be 206b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //independent process as well. 207b166940edca6e312463461438e2aa66e9852c26aBenoit Goby QService::init(); 208b166940edca6e312463461438e2aa66e9852c26aBenoit Goby sp<IQClient> client = new QClient(ctx); 209b166940edca6e312463461438e2aa66e9852c26aBenoit Goby interface_cast<IQService>( 210b166940edca6e312463461438e2aa66e9852c26aBenoit Goby defaultServiceManager()->getService( 211b166940edca6e312463461438e2aa66e9852c26aBenoit Goby String16("display.qservice")))->connect(client); 212b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 213b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGI("Initializing Qualcomm Hardware Composer"); 214b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGI("MDP version: %d", ctx->mMDP.version); 215b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 216b166940edca6e312463461438e2aa66e9852c26aBenoit Goby connectPPDaemon(ctx); 217b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 218b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 219b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid closeContext(hwc_context_t *ctx) 220b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 221b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mOverlay) { 222b166940edca6e312463461438e2aa66e9852c26aBenoit Goby delete ctx->mOverlay; 223b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mOverlay = NULL; 224b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 225b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 226b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mRotMgr) { 227b166940edca6e312463461438e2aa66e9852c26aBenoit Goby delete ctx->mRotMgr; 228b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mRotMgr = NULL; 229b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 230b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 231b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(int i = 0; i < MAX_DISPLAYS; i++) { 232b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mCopyBit[i]) { 233b166940edca6e312463461438e2aa66e9852c26aBenoit Goby delete ctx->mCopyBit[i]; 234b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCopyBit[i] = NULL; 235b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 236b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 237b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 238b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd) { 239b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd); 240b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1; 241b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 242b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 243b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mExtDisplay) { 244b166940edca6e312463461438e2aa66e9852c26aBenoit Goby delete ctx->mExtDisplay; 245b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mExtDisplay = NULL; 246b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 247b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 248b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(int i = 0; i < MAX_DISPLAYS; i++) { 249b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mFBUpdate[i]) { 250b166940edca6e312463461438e2aa66e9852c26aBenoit Goby delete ctx->mFBUpdate[i]; 251b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mFBUpdate[i] = NULL; 252b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 253b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mMDPComp[i]) { 254b166940edca6e312463461438e2aa66e9852c26aBenoit Goby delete ctx->mMDPComp[i]; 255b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mMDPComp[i] = NULL; 256b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 257b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mLayerRotMap[i]) { 258b166940edca6e312463461438e2aa66e9852c26aBenoit Goby delete ctx->mLayerRotMap[i]; 259b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mLayerRotMap[i] = NULL; 260b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 261b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 262b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 263b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 264b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 265b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid dumpsys_log(android::String8& buf, const char* fmt, ...) 266b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 267b166940edca6e312463461438e2aa66e9852c26aBenoit Goby va_list varargs; 268b166940edca6e312463461438e2aa66e9852c26aBenoit Goby va_start(varargs, fmt); 269b166940edca6e312463461438e2aa66e9852c26aBenoit Goby buf.appendFormatV(fmt, varargs); 270b166940edca6e312463461438e2aa66e9852c26aBenoit Goby va_end(varargs); 271b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 272b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 273b166940edca6e312463461438e2aa66e9852c26aBenoit Goby/* Calculates the destination position based on the action safe rectangle */ 274b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid getActionSafePosition(hwc_context_t *ctx, int dpy, uint32_t& x, 275b166940edca6e312463461438e2aa66e9852c26aBenoit Goby uint32_t& y, uint32_t& w, uint32_t& h) { 276b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 277b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // if external supports underscan, do nothing 278b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // it will be taken care in the driver 279b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mExtDisplay->isCEUnderscanSupported()) 280b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 281b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 282b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float wRatio = 1.0; 283b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float hRatio = 1.0; 284b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float xRatio = 1.0; 285b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float yRatio = 1.0; 286b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 287b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float fbWidth = ctx->dpyAttr[dpy].xres; 288b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float fbHeight = ctx->dpyAttr[dpy].yres; 289b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 290b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float asX = 0; 291b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float asY = 0; 292b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float asW = fbWidth; 293b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float asH= fbHeight; 294b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char value[PROPERTY_VALUE_MAX]; 295b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 296b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Apply action safe parameters 297b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_get("hw.actionsafe.width", value, "0"); 298b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int asWidthRatio = atoi(value); 299b166940edca6e312463461438e2aa66e9852c26aBenoit Goby property_get("hw.actionsafe.height", value, "0"); 300b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int asHeightRatio = atoi(value); 301b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // based on the action safe ratio, get the Action safe rectangle 302b166940edca6e312463461438e2aa66e9852c26aBenoit Goby asW = fbWidth * (1.0f - asWidthRatio / 100.0f); 303b166940edca6e312463461438e2aa66e9852c26aBenoit Goby asH = fbHeight * (1.0f - asHeightRatio / 100.0f); 304b166940edca6e312463461438e2aa66e9852c26aBenoit Goby asX = (fbWidth - asW) / 2; 305b166940edca6e312463461438e2aa66e9852c26aBenoit Goby asY = (fbHeight - asH) / 2; 306b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 307b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // calculate the position ratio 308b166940edca6e312463461438e2aa66e9852c26aBenoit Goby xRatio = (float)x/fbWidth; 309b166940edca6e312463461438e2aa66e9852c26aBenoit Goby yRatio = (float)y/fbHeight; 310b166940edca6e312463461438e2aa66e9852c26aBenoit Goby wRatio = (float)w/fbWidth; 311b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hRatio = (float)h/fbHeight; 312b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 313b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Calculate the position... 314b166940edca6e312463461438e2aa66e9852c26aBenoit Goby x = (xRatio * asW) + asX; 315b166940edca6e312463461438e2aa66e9852c26aBenoit Goby y = (yRatio * asH) + asY; 316b166940edca6e312463461438e2aa66e9852c26aBenoit Goby w = (wRatio * asW); 317b166940edca6e312463461438e2aa66e9852c26aBenoit Goby h = (hRatio * asH); 318b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 319b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 320b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 321b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 322b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool needsScaling(hwc_layer_1_t const* layer) { 323b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int dst_w, dst_h, src_w, src_h; 324b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 325b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t displayFrame = layer->displayFrame; 326b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t sourceCrop = layer->sourceCrop; 327b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 328b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst_w = displayFrame.right - displayFrame.left; 329b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst_h = displayFrame.bottom - displayFrame.top; 330b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 331b166940edca6e312463461438e2aa66e9852c26aBenoit Goby src_w = sourceCrop.right - sourceCrop.left; 332b166940edca6e312463461438e2aa66e9852c26aBenoit Goby src_h = sourceCrop.bottom - sourceCrop.top; 333b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 334b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(((src_w != dst_w) || (src_h != dst_h))) 335b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return true; 336b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 337b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return false; 338b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 339b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 340b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool isAlphaScaled(hwc_layer_1_t const* layer) { 341b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(needsScaling(layer) && isAlphaPresent(layer)) { 342b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return true; 343b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 344b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return false; 345b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 346b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 347b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool isAlphaPresent(hwc_layer_1_t const* layer) { 348b166940edca6e312463461438e2aa66e9852c26aBenoit Goby private_handle_t *hnd = (private_handle_t *)layer->handle; 349b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(hnd) { 350b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int format = hnd->format; 351b166940edca6e312463461438e2aa66e9852c26aBenoit Goby switch(format) { 352b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case HAL_PIXEL_FORMAT_RGBA_8888: 353b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case HAL_PIXEL_FORMAT_BGRA_8888: 354b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // In any more formats with Alpha go here.. 355b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return true; 356b166940edca6e312463461438e2aa66e9852c26aBenoit Goby default : return false; 357b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 358b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 359b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return false; 360b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 361b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 362b166940edca6e312463461438e2aa66e9852c26aBenoit Goby// Switch ppd on/off for YUV 363b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic void setYUVProp(hwc_context_t *ctx, int yuvCount) { 364b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (!ctx->mCablProp.enabled) 365b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 366b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 367b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (yuvCount > 0 && !ctx->mCablProp.start) { 368b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCablProp.start = true; 369b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mCablProp.videoOnly) 370b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ppdComm("cabl:on", ctx); 371b166940edca6e312463461438e2aa66e9852c26aBenoit Goby else 372b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ppdComm("cabl:yuv_on", ctx); 373b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 374b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else if (yuvCount == 0 && ctx->mCablProp.start) { 375b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCablProp.start = false; 376b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mCablProp.videoOnly) 377b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ppdComm("cabl:off", ctx); 378b166940edca6e312463461438e2aa66e9852c26aBenoit Goby else 379b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ppdComm("cabl:yuv_off", ctx); 380b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return; 381b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 382b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 383b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 384b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid setListStats(hwc_context_t *ctx, 385b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const hwc_display_contents_1_t *list, int dpy) { 386b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 387b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1; 388b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1; 389b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].skipCount = 0; 390b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].needsAlphaScale = false; 391b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].preMultipliedAlpha = false; 392b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].planeAlpha = false; 393b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].yuvCount = 0; 394b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 395b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for (size_t i = 0; i < list->numHwLayers; i++) { 396b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_layer_1_t const* layer = &list->hwLayers[i]; 397b166940edca6e312463461438e2aa66e9852c26aBenoit Goby private_handle_t *hnd = (private_handle_t *)layer->handle; 398b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 399b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //reset stored yuv index 400b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].yuvIndices[i] = -1; 401b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 402b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { 403b166940edca6e312463461438e2aa66e9852c26aBenoit Goby continue; 404b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //We disregard FB being skip for now! so the else if 405b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else if (isSkipLayer(&list->hwLayers[i])) { 406b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].skipCount++; 407b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else if (UNLIKELY(isYuvBuffer(hnd))) { 408b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& yuvCount = ctx->listStats[dpy].yuvCount; 409b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].yuvIndices[yuvCount] = i; 410b166940edca6e312463461438e2aa66e9852c26aBenoit Goby yuvCount++; 411b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 412b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(layer->transform & HWC_TRANSFORM_ROT_90) 413b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mNeedsRotator = true; 414b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 415b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(layer->blending == HWC_BLENDING_PREMULT) 416b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].preMultipliedAlpha = true; 417b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(layer->planeAlpha < 0xFF) 418b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].planeAlpha = true; 419b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(!ctx->listStats[dpy].needsAlphaScale) 420b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer); 421b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 422b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setYUVProp(ctx, ctx->listStats[dpy].yuvCount); 423b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 424b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 425b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 426b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic inline void calc_cut(float& leftCutRatio, float& topCutRatio, 427b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float& rightCutRatio, float& bottomCutRatio, int orient) { 428b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(orient & HAL_TRANSFORM_FLIP_H) { 429b166940edca6e312463461438e2aa66e9852c26aBenoit Goby swap(leftCutRatio, rightCutRatio); 430b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 431b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(orient & HAL_TRANSFORM_FLIP_V) { 432b166940edca6e312463461438e2aa66e9852c26aBenoit Goby swap(topCutRatio, bottomCutRatio); 433b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 434b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(orient & HAL_TRANSFORM_ROT_90) { 435b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Anti clock swapping 436b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float tmpCutRatio = leftCutRatio; 437b166940edca6e312463461438e2aa66e9852c26aBenoit Goby leftCutRatio = topCutRatio; 438b166940edca6e312463461438e2aa66e9852c26aBenoit Goby topCutRatio = rightCutRatio; 439b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rightCutRatio = bottomCutRatio; 440b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bottomCutRatio = tmpCutRatio; 441b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 442b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 443b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 444b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer) { 445b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if((ctx->mMDP.version < qdutils::MDSS_V5) && 446b166940edca6e312463461438e2aa66e9852c26aBenoit Goby (ctx->mMDP.version > qdutils::MDP_V3_0) && 447b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mSecuring) { 448b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return true; 449b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 450b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // On A-Family, Secure policy is applied system wide and not on 451b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // buffers. 452b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (isSecureModePolicy(ctx->mMDP.version)) { 453b166940edca6e312463461438e2aa66e9852c26aBenoit Goby private_handle_t *hnd = (private_handle_t *)layer->handle; 454b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ctx->mSecureMode) { 455b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (! isSecureBuffer(hnd)) { 456b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // This code path executes for the following usecase: 457b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Some Apps in which first few seconds, framework 458b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // sends non-secure buffer and with out destroying 459b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // surfaces, switches to secure buffer thereby exposing 460b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // vulnerability on A-family devices. Catch this situation 461b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // and handle it gracefully by allowing it to be composed by 462b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // GPU. 463b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(HWC_UTILS_DEBUG, "%s: Handle non-secure video layer" 464b166940edca6e312463461438e2aa66e9852c26aBenoit Goby "during secure playback gracefully", __FUNCTION__); 465b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return true; 466b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 467b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 468b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (isSecureBuffer(hnd)) { 469b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // This code path executes for the following usecase: 470b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // For some Apps, when User terminates playback, Framework 471b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // doesnt destroy video surface and video surface still 472b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // comes to Display HAL. This exposes vulnerability on 473b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // A-family. Catch this situation and handle it gracefully 474b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // by allowing it to be composed by GPU. 475b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(HWC_UTILS_DEBUG, "%s: Handle secure video layer" 476b166940edca6e312463461438e2aa66e9852c26aBenoit Goby "during non-secure playback gracefully", __FUNCTION__); 477b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return true; 478b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 479b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 480b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 481b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return false; 482b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 483b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 484b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool isSecureModePolicy(int mdpVersion) { 485b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (mdpVersion < qdutils::MDSS_V5) 486b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return true; 487b166940edca6e312463461438e2aa66e9852c26aBenoit Goby else 488b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return false; 489b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 490b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 491b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint getBlending(int blending) { 492b166940edca6e312463461438e2aa66e9852c26aBenoit Goby switch(blending) { 493b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case HWC_BLENDING_NONE: 494b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return overlay::utils::OVERLAY_BLENDING_OPAQUE; 495b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case HWC_BLENDING_PREMULT: 496b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return overlay::utils::OVERLAY_BLENDING_PREMULT; 497b166940edca6e312463461438e2aa66e9852c26aBenoit Goby case HWC_BLENDING_COVERAGE : 498b166940edca6e312463461438e2aa66e9852c26aBenoit Goby default: 499b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return overlay::utils::OVERLAY_BLENDING_COVERAGE; 500b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 501b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 502b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 503b166940edca6e312463461438e2aa66e9852c26aBenoit Goby//Crops source buffer against destination and FB boundaries 504b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst, 505b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const hwc_rect_t& scissor, int orient) { 506b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 507b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& crop_l = crop.left; 508b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& crop_t = crop.top; 509b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& crop_r = crop.right; 510b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& crop_b = crop.bottom; 511b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int crop_w = crop.right - crop.left; 512b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int crop_h = crop.bottom - crop.top; 513b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 514b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& dst_l = dst.left; 515b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& dst_t = dst.top; 516b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& dst_r = dst.right; 517b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& dst_b = dst.bottom; 518b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int dst_w = abs(dst.right - dst.left); 519b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int dst_h = abs(dst.bottom - dst.top); 520b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 521b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int& sci_l = scissor.left; 522b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int& sci_t = scissor.top; 523b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int& sci_r = scissor.right; 524b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int& sci_b = scissor.bottom; 525b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int sci_w = abs(sci_r - sci_l); 526b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int sci_h = abs(sci_b - sci_t); 527b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 528b166940edca6e312463461438e2aa66e9852c26aBenoit Goby float leftCutRatio = 0.0f, rightCutRatio = 0.0f, topCutRatio = 0.0f, 529b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bottomCutRatio = 0.0f; 530b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 531b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(dst_l < sci_l) { 532b166940edca6e312463461438e2aa66e9852c26aBenoit Goby leftCutRatio = (float)(sci_l - dst_l) / (float)dst_w; 533b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst_l = sci_l; 534b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 535b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 536b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(dst_r > sci_r) { 537b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rightCutRatio = (float)(dst_r - sci_r) / (float)dst_w; 538b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst_r = sci_r; 539b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 540b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 541b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(dst_t < sci_t) { 542b166940edca6e312463461438e2aa66e9852c26aBenoit Goby topCutRatio = (float)(sci_t - dst_t) / (float)dst_h; 543b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst_t = sci_t; 544b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 545b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 546b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(dst_b > sci_b) { 547b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bottomCutRatio = (float)(dst_b - sci_b) / (float)dst_h; 548b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst_b = sci_b; 549b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 550b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 551b166940edca6e312463461438e2aa66e9852c26aBenoit Goby calc_cut(leftCutRatio, topCutRatio, rightCutRatio, bottomCutRatio, orient); 552b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop_l += crop_w * leftCutRatio; 553b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop_t += crop_h * topCutRatio; 554b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop_r -= crop_w * rightCutRatio; 555b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop_b -= crop_h * bottomCutRatio; 556b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 557b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 558b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid getNonWormholeRegion(hwc_display_contents_1_t* list, 559b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t& nwr) 560b166940edca6e312463461438e2aa66e9852c26aBenoit Goby{ 561b166940edca6e312463461438e2aa66e9852c26aBenoit Goby uint32_t last = list->numHwLayers - 1; 562b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t fbDisplayFrame = list->hwLayers[last].displayFrame; 563b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Initiliaze nwr to first frame 564b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.left = list->hwLayers[0].displayFrame.left; 565b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.top = list->hwLayers[0].displayFrame.top; 566b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.right = list->hwLayers[0].displayFrame.right; 567b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.bottom = list->hwLayers[0].displayFrame.bottom; 568b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 569b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for (uint32_t i = 1; i < last; i++) { 570b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t displayFrame = list->hwLayers[i].displayFrame; 571b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.left = min(nwr.left, displayFrame.left); 572b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.top = min(nwr.top, displayFrame.top); 573b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.right = max(nwr.right, displayFrame.right); 574b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.bottom = max(nwr.bottom, displayFrame.bottom); 575b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 576b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 577b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Intersect with the framebuffer 578b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.left = max(nwr.left, fbDisplayFrame.left); 579b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.top = max(nwr.top, fbDisplayFrame.top); 580b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.right = min(nwr.right, fbDisplayFrame.right); 581b166940edca6e312463461438e2aa66e9852c26aBenoit Goby nwr.bottom = min(nwr.bottom, fbDisplayFrame.bottom); 582b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 583b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 584b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 585b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool isExternalActive(hwc_context_t* ctx) { 586b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive; 587b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 588b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 589b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid closeAcquireFds(hwc_display_contents_1_t* list) { 590b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(LIKELY(list)) { 591b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(uint32_t i = 0; i < list->numHwLayers; i++) { 592b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Close the acquireFenceFds 593b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //HWC_FRAMEBUFFER are -1 already by SF, rest we close. 594b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(list->hwLayers[i].acquireFenceFd >= 0) { 595b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(list->hwLayers[i].acquireFenceFd); 596b166940edca6e312463461438e2aa66e9852c26aBenoit Goby list->hwLayers[i].acquireFenceFd = -1; 597b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 598b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 599b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 600b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 601b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 602b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy, 603b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int fd) { 604b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int ret = 0; 605b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 606b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int acquireFd[MAX_NUM_LAYERS]; 607b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int count = 0; 608b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int releaseFd = -1; 609b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int fbFd = -1; 610b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int rotFd = -1; 611b166940edca6e312463461438e2aa66e9852c26aBenoit Goby bool swapzero = false; 612b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); 613b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 614b166940edca6e312463461438e2aa66e9852c26aBenoit Goby struct mdp_buf_sync data; 615b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&data, 0, sizeof(data)); 616b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Until B-family supports sync for rotator 617b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mdpVersion >= qdutils::MDSS_V5) { 618b166940edca6e312463461438e2aa66e9852c26aBenoit Goby data.flags = MDP_BUF_SYNC_FLAG_WAIT; 619b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 620b166940edca6e312463461438e2aa66e9852c26aBenoit Goby data.acq_fen_fd = acquireFd; 621b166940edca6e312463461438e2aa66e9852c26aBenoit Goby data.rel_fen_fd = &releaseFd; 622b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 623b166940edca6e312463461438e2aa66e9852c26aBenoit Goby char property[PROPERTY_VALUE_MAX]; 624b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(property_get("debug.egl.swapinterval", property, "1") > 0) { 625b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(atoi(property) == 0) 626b166940edca6e312463461438e2aa66e9852c26aBenoit Goby swapzero = true; 627b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 628b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 629b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#ifndef MDSS_TARGET 630b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Send acquireFenceFds to rotator 631b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mdpVersion < qdutils::MDSS_V5) { 632b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //A-family 633b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int rotFd = ctx->mRotMgr->getRotDevFd(); 634b166940edca6e312463461438e2aa66e9852c26aBenoit Goby struct msm_rotator_buf_sync rotData; 635b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 636b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(uint32_t i = 0; i < ctx->mLayerRotMap[dpy]->getCount(); i++) { 637b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&rotData, 0, sizeof(rotData)); 638b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int& acquireFenceFd = 639b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd; 640b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rotData.acq_fen_fd = acquireFenceFd; 641b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rotData.session_id = ctx->mLayerRotMap[dpy]->getRot(i)->getSessId(); 642b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ioctl(rotFd, MSM_ROTATOR_IOCTL_BUFFER_SYNC, &rotData); 643b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(acquireFenceFd); 644b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //For MDP to wait on. 645b166940edca6e312463461438e2aa66e9852c26aBenoit Goby acquireFenceFd = dup(rotData.rel_fen_fd); 646b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //A buffer is free to be used by producer as soon as its copied to 647b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //rotator. 648b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mLayerRotMap[dpy]->getLayer(i)->releaseFenceFd = 649b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rotData.rel_fen_fd; 650b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 651b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 652b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //TODO B-family 653b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 654b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 655b166940edca6e312463461438e2aa66e9852c26aBenoit Goby#endif 656b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Accumulate acquireFenceFds for MDP 657b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(uint32_t i = 0; i < list->numHwLayers; i++) { 658b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(list->hwLayers[i].compositionType == HWC_OVERLAY && 659b166940edca6e312463461438e2aa66e9852c26aBenoit Goby list->hwLayers[i].acquireFenceFd >= 0) { 660b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(UNLIKELY(swapzero)) 661b166940edca6e312463461438e2aa66e9852c26aBenoit Goby acquireFd[count++] = -1; 662b166940edca6e312463461438e2aa66e9852c26aBenoit Goby else 663b166940edca6e312463461438e2aa66e9852c26aBenoit Goby acquireFd[count++] = list->hwLayers[i].acquireFenceFd; 664b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 665b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { 666b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(UNLIKELY(swapzero)) 667b166940edca6e312463461438e2aa66e9852c26aBenoit Goby acquireFd[count++] = -1; 668b166940edca6e312463461438e2aa66e9852c26aBenoit Goby else if(fd >= 0) { 669b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //set the acquireFD from fd - which is coming from c2d 670b166940edca6e312463461438e2aa66e9852c26aBenoit Goby acquireFd[count++] = fd; 671b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // Buffer sync IOCTL should be async when using c2d fence is 672b166940edca6e312463461438e2aa66e9852c26aBenoit Goby // used 673b166940edca6e312463461438e2aa66e9852c26aBenoit Goby data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT; 674b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else if(list->hwLayers[i].acquireFenceFd >= 0) 675b166940edca6e312463461438e2aa66e9852c26aBenoit Goby acquireFd[count++] = list->hwLayers[i].acquireFenceFd; 676b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 677b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 678b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 679b166940edca6e312463461438e2aa66e9852c26aBenoit Goby data.acq_fen_fd_cnt = count; 680b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fbFd = ctx->dpyAttr[dpy].fd; 681b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 682b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Waits for acquire fences, returns a release fence 683b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(LIKELY(!swapzero)) { 684b166940edca6e312463461438e2aa66e9852c26aBenoit Goby uint64_t start = systemTime(); 685b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data); 686b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGD_IF(HWC_UTILS_DEBUG, "%s: time taken for MSMFB_BUFFER_SYNC IOCTL = %d", 687b166940edca6e312463461438e2aa66e9852c26aBenoit Goby __FUNCTION__, (size_t) ns2ms(systemTime() - start)); 688b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 689b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 690b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(ret < 0) { 691b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s", 692b166940edca6e312463461438e2aa66e9852c26aBenoit Goby strerror(errno)); 693b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 694b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 695b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(uint32_t i = 0; i < list->numHwLayers; i++) { 696b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(list->hwLayers[i].compositionType == HWC_OVERLAY || 697b166940edca6e312463461438e2aa66e9852c26aBenoit Goby list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) { 698b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Populate releaseFenceFds. 699b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(UNLIKELY(swapzero)) { 700b166940edca6e312463461438e2aa66e9852c26aBenoit Goby list->hwLayers[i].releaseFenceFd = -1; 701b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else if(list->hwLayers[i].releaseFenceFd < 0) { 702b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //If rotator has not already populated this field. 703b166940edca6e312463461438e2aa66e9852c26aBenoit Goby list->hwLayers[i].releaseFenceFd = dup(releaseFd); 704b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 705b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 706b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 707b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 708b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(fd >= 0) { 709b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(fd); 710b166940edca6e312463461438e2aa66e9852c26aBenoit Goby fd = -1; 711b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 712b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 713b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ctx->mCopyBit[dpy]) 714b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mCopyBit[dpy]->setReleaseFd(releaseFd); 715b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 716b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //A-family 717b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mdpVersion < qdutils::MDSS_V5) { 718b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Signals when MDP finishes reading rotator buffers. 719b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mLayerRotMap[dpy]->setReleaseFd(releaseFd); 720b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 721b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 722b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(UNLIKELY(swapzero)){ 723b166940edca6e312463461438e2aa66e9852c26aBenoit Goby list->retireFenceFd = -1; 724b166940edca6e312463461438e2aa66e9852c26aBenoit Goby close(releaseFd); 725b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } else { 726b166940edca6e312463461438e2aa66e9852c26aBenoit Goby list->retireFenceFd = releaseFd; 727b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 728b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 729b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return ret; 730b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 731b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 732b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform, 733b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t& crop, hwc_rect_t& dst) { 734b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int hw_w = ctx->dpyAttr[dpy].xres; 735b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int hw_h = ctx->dpyAttr[dpy].yres; 736b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(dst.left < 0 || dst.top < 0 || 737b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst.right > hw_w || dst.bottom > hw_h) { 738b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t scissor = {0, 0, hw_w, hw_h }; 739b166940edca6e312463461438e2aa66e9852c26aBenoit Goby qhwc::calculate_crop_rects(crop, dst, scissor, transform); 740b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 741b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 742b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 743b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid setMdpFlags(hwc_layer_1_t *layer, 744b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::eMdpFlags &mdpFlags, 745b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int rotDownscale) { 746b166940edca6e312463461438e2aa66e9852c26aBenoit Goby private_handle_t *hnd = (private_handle_t *)layer->handle; 747b166940edca6e312463461438e2aa66e9852c26aBenoit Goby MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 748b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int& transform = layer->transform; 749b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 750b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(layer->blending == HWC_BLENDING_PREMULT) { 751b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::setMdpFlags(mdpFlags, 752b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::OV_MDP_BLEND_FG_PREMULT); 753b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 754b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 755b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(isYuvBuffer(hnd)) { 756b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(isSecureBuffer(hnd)) { 757b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::setMdpFlags(mdpFlags, 758b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::OV_MDP_SECURE_OVERLAY_SESSION); 759b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 760b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(metadata && (metadata->operation & PP_PARAM_INTERLACED) && 761b166940edca6e312463461438e2aa66e9852c26aBenoit Goby metadata->interlaced) { 762b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::setMdpFlags(mdpFlags, 763b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::OV_MDP_DEINTERLACE); 764b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 765b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Pre-rotation will be used using rotator. 766b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(transform & HWC_TRANSFORM_ROT_90) { 767b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::setMdpFlags(mdpFlags, 768b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::OV_MDP_SOURCE_ROTATED_90); 769b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 770b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 771b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 772b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //No 90 component and no rot-downscale then flips done by MDP 773b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //If we use rot then it might as well do flips 774b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(!(layer->transform & HWC_TRANSFORM_ROT_90) && !rotDownscale) { 775b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(layer->transform & HWC_TRANSFORM_FLIP_H) { 776b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H); 777b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 778b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 779b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(layer->transform & HWC_TRANSFORM_FLIP_V) { 780b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V); 781b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 782b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 783b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 784b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(metadata && 785b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ((metadata->operation & PP_PARAM_HSIC) 786b166940edca6e312463461438e2aa66e9852c26aBenoit Goby || (metadata->operation & PP_PARAM_IGC) 787b166940edca6e312463461438e2aa66e9852c26aBenoit Goby || (metadata->operation & PP_PARAM_SHARP2))) { 788b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_PP_EN); 789b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 790b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 791b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 792b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic inline int configRotator(Rotator *rot, const Whf& whf, 793b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const eMdpFlags& mdpFlags, const eTransform& orient, 794b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int& downscale) { 795b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rot->setSource(whf); 796b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rot->setFlags(mdpFlags); 797b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rot->setTransform(orient); 798b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rot->setDownscale(downscale); 799b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(!rot->commit()) return -1; 800b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 801b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 802b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 803b166940edca6e312463461438e2aa66e9852c26aBenoit Goby/* 804b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Sets up BORDERFILL as default base pipe and detaches RGB0. 805b166940edca6e312463461438e2aa66e9852c26aBenoit Goby * Framebuffer is always updated using PLAY ioctl. 806b166940edca6e312463461438e2aa66e9852c26aBenoit Goby */ 807b166940edca6e312463461438e2aa66e9852c26aBenoit Gobybool setupBasePipe(hwc_context_t *ctx) { 808b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int dpy = HWC_DISPLAY_PRIMARY; 809b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int fb_stride = ctx->dpyAttr[dpy].stride; 810b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int fb_width = ctx->dpyAttr[dpy].xres; 811b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int fb_height = ctx->dpyAttr[dpy].yres; 812b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int fb_fd = ctx->dpyAttr[dpy].fd; 813b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 814b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mdp_overlay ovInfo; 815b166940edca6e312463461438e2aa66e9852c26aBenoit Goby msmfb_overlay_data ovData; 816b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&ovInfo, 0, sizeof(mdp_overlay)); 817b166940edca6e312463461438e2aa66e9852c26aBenoit Goby memset(&ovData, 0, sizeof(msmfb_overlay_data)); 818b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 819b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovInfo.src.format = MDP_RGB_BORDERFILL; 820b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovInfo.src.width = fb_width; 821b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovInfo.src.height = fb_height; 822b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovInfo.src_rect.w = fb_width; 823b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovInfo.src_rect.h = fb_height; 824b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovInfo.dst_rect.w = fb_width; 825b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovInfo.dst_rect.h = fb_height; 826b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovInfo.id = MSMFB_NEW_REQUEST; 827b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 828b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) { 829b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s", 830b166940edca6e312463461438e2aa66e9852c26aBenoit Goby strerror(errno)); 831b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return false; 832b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 833b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 834b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ovData.id = ovInfo.id; 835b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) { 836b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s", 837b166940edca6e312463461438e2aa66e9852c26aBenoit Goby strerror(errno)); 838b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return false; 839b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 840b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mBasePipeSetup = true; 841b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return true; 842b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 843b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 844b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 845b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic inline int configMdp(Overlay *ov, const PipeArgs& parg, 846b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const eTransform& orient, const hwc_rect_t& crop, 847b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const hwc_rect_t& pos, const MetaData_t *metadata, 848b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const eDest& dest) { 849b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ov->setSource(parg, dest); 850b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ov->setTransform(orient, dest); 851b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 852b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int crop_w = crop.right - crop.left; 853b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int crop_h = crop.bottom - crop.top; 854b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Dim dcrop(crop.left, crop.top, crop_w, crop_h); 855b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ov->setCrop(dcrop, dest); 856b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 857b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int posW = pos.right - pos.left; 858b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int posH = pos.bottom - pos.top; 859b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Dim position(pos.left, pos.top, posW, posH); 860b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ov->setPosition(position, dest); 861b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 862b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (metadata) 863b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ov->setVisualParams(*metadata, dest); 864b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 865b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if (!ov->commit(dest)) { 866b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 867b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 868b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 869b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 870b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 871b166940edca6e312463461438e2aa66e9852c26aBenoit Gobystatic inline void updateSource(eTransform& orient, Whf& whf, 872b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t& crop) { 873b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Dim srcCrop(crop.left, crop.top, 874b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop.right - crop.left, 875b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop.bottom - crop.top); 876b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //getMdpOrient will switch the flips if the source is 90 rotated. 877b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Clients in Android dont factor in 90 rotation while deciding the flip. 878b166940edca6e312463461438e2aa66e9852c26aBenoit Goby orient = static_cast<eTransform>(ovutils::getMdpOrient(orient)); 879b166940edca6e312463461438e2aa66e9852c26aBenoit Goby preRotateSource(orient, whf, srcCrop); 880b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop.left = srcCrop.x; 881b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop.top = srcCrop.y; 882b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop.right = srcCrop.x + srcCrop.w; 883b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop.bottom = srcCrop.y + srcCrop.h; 884b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 885b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 886b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint configureLowRes(hwc_context_t *ctx, hwc_layer_1_t *layer, 887b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int& dpy, eMdpFlags& mdpFlags, const eZorder& z, 888b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const eIsFg& isFg, const eDest& dest, Rotator **rot) { 889b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 890b166940edca6e312463461438e2aa66e9852c26aBenoit Goby private_handle_t *hnd = (private_handle_t *)layer->handle; 891b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(!hnd) { 892b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: layer handle is NULL", __FUNCTION__); 893b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 894b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 895b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 896b166940edca6e312463461438e2aa66e9852c26aBenoit Goby MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 897b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 898b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t crop = layer->sourceCrop; 899b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t dst = layer->displayFrame; 900b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int transform = layer->transform; 901b166940edca6e312463461438e2aa66e9852c26aBenoit Goby eTransform orient = static_cast<eTransform>(transform); 902b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int downscale = 0; 903b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int rotFlags = ovutils::ROT_FLAGS_NONE; 904b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Whf whf(getWidth(hnd), getHeight(hnd), 905b166940edca6e312463461438e2aa66e9852c26aBenoit Goby getMdpFormat(hnd->format), hnd->size); 906b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 907b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(isYuvBuffer(hnd) && ctx->mMDP.version >= qdutils::MDP_V4_2 && 908b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mMDP.version < qdutils::MDSS_V5) { 909b166940edca6e312463461438e2aa66e9852c26aBenoit Goby downscale = getDownscaleFactor( 910b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop.right - crop.left, 911b166940edca6e312463461438e2aa66e9852c26aBenoit Goby crop.bottom - crop.top, 912b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst.right - dst.left, 913b166940edca6e312463461438e2aa66e9852c26aBenoit Goby dst.bottom - dst.top); 914b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(downscale) { 915b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rotFlags = ROT_DOWNSCALE_ENABLED; 916b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 917b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 918b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 919b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setMdpFlags(layer, mdpFlags, downscale); 920b166940edca6e312463461438e2aa66e9852c26aBenoit Goby trimLayer(ctx, dpy, transform, crop, dst); 921b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 922b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(isYuvBuffer(hnd) && //if 90 component or downscale, use rot 923b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ((transform & HWC_TRANSFORM_ROT_90) || downscale)) { 924b166940edca6e312463461438e2aa66e9852c26aBenoit Goby *rot = ctx->mRotMgr->getNext(); 925b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(*rot == NULL) return -1; 926b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Configure rotator for pre-rotation 927b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(configRotator(*rot, whf, mdpFlags, orient, downscale) < 0) 928b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 929b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mLayerRotMap[dpy]->add(layer, *rot); 930b166940edca6e312463461438e2aa66e9852c26aBenoit Goby whf.format = (*rot)->getDstFormat(); 931b166940edca6e312463461438e2aa66e9852c26aBenoit Goby updateSource(orient, whf, crop); 932b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rotFlags |= ovutils::ROT_PREROTATED; 933b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 934b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 935b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //For the mdp, since either we are pre-rotating or MDP does flips 936b166940edca6e312463461438e2aa66e9852c26aBenoit Goby orient = OVERLAY_TRANSFORM_0; 937b166940edca6e312463461438e2aa66e9852c26aBenoit Goby transform = 0; 938b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 939b166940edca6e312463461438e2aa66e9852c26aBenoit Goby PipeArgs parg(mdpFlags, whf, z, isFg, 940b166940edca6e312463461438e2aa66e9852c26aBenoit Goby static_cast<eRotFlags>(rotFlags), layer->planeAlpha, 941b166940edca6e312463461438e2aa66e9852c26aBenoit Goby (ovutils::eBlending) getBlending(layer->blending)); 942b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 943b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) { 944b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: commit failed for low res panel", __FUNCTION__); 945b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mLayerRotMap[dpy]->reset(); 946b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 947b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 948b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 949b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 950b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 951b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyint configureHighRes(hwc_context_t *ctx, hwc_layer_1_t *layer, 952b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int& dpy, eMdpFlags& mdpFlagsL, const eZorder& z, 953b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const eIsFg& isFg, const eDest& lDest, const eDest& rDest, 954b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Rotator **rot) { 955b166940edca6e312463461438e2aa66e9852c26aBenoit Goby private_handle_t *hnd = (private_handle_t *)layer->handle; 956b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(!hnd) { 957b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: layer handle is NULL", __FUNCTION__); 958b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 959b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 960b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 961b166940edca6e312463461438e2aa66e9852c26aBenoit Goby MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 962b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 963b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int hw_w = ctx->dpyAttr[dpy].xres; 964b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int hw_h = ctx->dpyAttr[dpy].yres; 965b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t crop = layer->sourceCrop; 966b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t dst = layer->displayFrame; 967b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int transform = layer->transform; 968b166940edca6e312463461438e2aa66e9852c26aBenoit Goby eTransform orient = static_cast<eTransform>(transform); 969b166940edca6e312463461438e2aa66e9852c26aBenoit Goby const int downscale = 0; 970b166940edca6e312463461438e2aa66e9852c26aBenoit Goby int rotFlags = ROT_FLAGS_NONE; 971b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 972b166940edca6e312463461438e2aa66e9852c26aBenoit Goby Whf whf(getWidth(hnd), getHeight(hnd), 973b166940edca6e312463461438e2aa66e9852c26aBenoit Goby getMdpFormat(hnd->format), hnd->size); 974b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 975b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setMdpFlags(layer, mdpFlagsL); 976b166940edca6e312463461438e2aa66e9852c26aBenoit Goby trimLayer(ctx, dpy, transform, crop, dst); 977b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 978b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) { 979b166940edca6e312463461438e2aa66e9852c26aBenoit Goby (*rot) = ctx->mRotMgr->getNext(); 980b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if((*rot) == NULL) return -1; 981b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Configure rotator for pre-rotation 982b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(configRotator(*rot, whf, mdpFlagsL, orient, downscale) < 0) 983b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 984b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ctx->mLayerRotMap[dpy]->add(layer, *rot); 985b166940edca6e312463461438e2aa66e9852c26aBenoit Goby whf.format = (*rot)->getDstFormat(); 986b166940edca6e312463461438e2aa66e9852c26aBenoit Goby updateSource(orient, whf, crop); 987b166940edca6e312463461438e2aa66e9852c26aBenoit Goby rotFlags |= ROT_PREROTATED; 988b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 989b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 990b166940edca6e312463461438e2aa66e9852c26aBenoit Goby eMdpFlags mdpFlagsR = mdpFlagsL; 991b166940edca6e312463461438e2aa66e9852c26aBenoit Goby setMdpFlags(mdpFlagsR, OV_MDSS_MDP_RIGHT_MIXER); 992b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 993b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t tmp_cropL, tmp_dstL; 994b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t tmp_cropR, tmp_dstR; 995b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 996b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(lDest != OV_INVALID) { 997b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_cropL = crop; 998b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_dstL = dst; 999b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t scissor = {0, 0, hw_w/2, hw_h }; 1000b166940edca6e312463461438e2aa66e9852c26aBenoit Goby qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0); 1001b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1002b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(rDest != OV_INVALID) { 1003b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_cropR = crop; 1004b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_dstR = dst; 1005b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t scissor = {hw_w/2, 0, hw_w, hw_h }; 1006b166940edca6e312463461438e2aa66e9852c26aBenoit Goby qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0); 1007b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1008b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1009b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //When buffer is flipped, contents of mixer config also needs to swapped. 1010b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //Not needed if the layer is confined to one half of the screen. 1011b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //If rotator has been used then it has also done the flips, so ignore them. 1012b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if((orient & OVERLAY_TRANSFORM_FLIP_V) && lDest != OV_INVALID 1013b166940edca6e312463461438e2aa66e9852c26aBenoit Goby && rDest != OV_INVALID && rot == NULL) { 1014b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t new_cropR; 1015b166940edca6e312463461438e2aa66e9852c26aBenoit Goby new_cropR.left = tmp_cropL.left; 1016b166940edca6e312463461438e2aa66e9852c26aBenoit Goby new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left); 1017b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1018b166940edca6e312463461438e2aa66e9852c26aBenoit Goby hwc_rect_t new_cropL; 1019b166940edca6e312463461438e2aa66e9852c26aBenoit Goby new_cropL.left = new_cropR.right; 1020b166940edca6e312463461438e2aa66e9852c26aBenoit Goby new_cropL.right = tmp_cropR.right; 1021b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1022b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_cropL.left = new_cropL.left; 1023b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_cropL.right = new_cropL.right; 1024b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1025b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_cropR.left = new_cropR.left; 1026b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_cropR.right = new_cropR.right; 1027b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1028b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1029b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1030b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //For the mdp, since either we are pre-rotating or MDP does flips 1031b166940edca6e312463461438e2aa66e9852c26aBenoit Goby orient = OVERLAY_TRANSFORM_0; 1032b166940edca6e312463461438e2aa66e9852c26aBenoit Goby transform = 0; 1033b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1034b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //configure left mixer 1035b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(lDest != OV_INVALID) { 1036b166940edca6e312463461438e2aa66e9852c26aBenoit Goby PipeArgs pargL(mdpFlagsL, whf, z, isFg, 1037b166940edca6e312463461438e2aa66e9852c26aBenoit Goby static_cast<eRotFlags>(rotFlags), layer->planeAlpha, 1038b166940edca6e312463461438e2aa66e9852c26aBenoit Goby (ovutils::eBlending) getBlending(layer->blending)); 1039b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1040b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(configMdp(ctx->mOverlay, pargL, orient, 1041b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_cropL, tmp_dstL, metadata, lDest) < 0) { 1042b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: commit failed for left mixer config", __FUNCTION__); 1043b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 1044b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1045b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1046b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1047b166940edca6e312463461438e2aa66e9852c26aBenoit Goby //configure right mixer 1048b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(rDest != OV_INVALID) { 1049b166940edca6e312463461438e2aa66e9852c26aBenoit Goby PipeArgs pargR(mdpFlagsR, whf, z, isFg, 1050b166940edca6e312463461438e2aa66e9852c26aBenoit Goby static_cast<eRotFlags>(rotFlags), layer->planeAlpha, 1051b166940edca6e312463461438e2aa66e9852c26aBenoit Goby (ovutils::eBlending) getBlending(layer->blending)); 1052b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1053b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_dstR.right = tmp_dstR.right - tmp_dstR.left; 1054b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_dstR.left = 0; 1055b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(configMdp(ctx->mOverlay, pargR, orient, 1056b166940edca6e312463461438e2aa66e9852c26aBenoit Goby tmp_cropR, tmp_dstR, metadata, rDest) < 0) { 1057b166940edca6e312463461438e2aa66e9852c26aBenoit Goby ALOGE("%s: commit failed for right mixer config", __FUNCTION__); 1058b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return -1; 1059b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1060b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1061b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1062b166940edca6e312463461438e2aa66e9852c26aBenoit Goby return 0; 1063b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 1064b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1065b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid LayerRotMap::add(hwc_layer_1_t* layer, Rotator *rot) { 1066b166940edca6e312463461438e2aa66e9852c26aBenoit Goby if(mCount >= MAX_SESS) return; 1067b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mLayer[mCount] = layer; 1068b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mRot[mCount] = rot; 1069b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mCount++; 1070b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 1071b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1072b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid LayerRotMap::reset() { 1073b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for (int i = 0; i < MAX_SESS; i++) { 1074b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mLayer[i] = 0; 1075b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mRot[i] = 0; 1076b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1077b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mCount = 0; 1078b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 1079b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1080b166940edca6e312463461438e2aa66e9852c26aBenoit Gobyvoid LayerRotMap::setReleaseFd(const int& fence) { 1081b166940edca6e312463461438e2aa66e9852c26aBenoit Goby for(uint32_t i = 0; i < mCount; i++) { 1082b166940edca6e312463461438e2aa66e9852c26aBenoit Goby mRot[i]->setReleaseFd(dup(fence)); 1083b166940edca6e312463461438e2aa66e9852c26aBenoit Goby } 1084b166940edca6e312463461438e2aa66e9852c26aBenoit Goby} 1085b166940edca6e312463461438e2aa66e9852c26aBenoit Goby 1086b166940edca6e312463461438e2aa66e9852c26aBenoit Goby};//namespace qhwc 1087