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