1054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/*
2054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Copyright (C) 2010 The Android Open Source Project
3054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Copyright (C) 2012-2014, The Linux Foundation All rights reserved.
4054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *
5054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Not a Contribution, Apache license notifications and license are retained
6054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * for attribution purposes only.
7054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *
8054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Licensed under the Apache License, Version 2.0 (the "License");
9054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * you may not use this file except in compliance with the License.
10054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * You may obtain a copy of the License at
11054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *
12054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *      http://www.apache.org/licenses/LICENSE-2.0
13054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *
14054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Unless required by applicable law or agreed to in writing, software
15054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * distributed under the License is distributed on an "AS IS" BASIS,
16054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * See the License for the specific language governing permissions and
18054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * limitations under the License.
19054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */
20054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
21054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define HWC_UTILS_DEBUG 0
22054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <math.h>
23054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <sys/ioctl.h>
24054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <linux/fb.h>
25054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <binder/IServiceManager.h>
26054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <EGL/egl.h>
27054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <cutils/properties.h>
28054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <utils/Trace.h>
29054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <gralloc_priv.h>
30054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <overlay.h>
31054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <overlayRotator.h>
32054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <overlayWriteback.h>
33054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_utils.h"
34054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_mdpcomp.h"
35054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_fbupdate.h"
36054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_ad.h"
37054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "mdp_version.h"
38054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_copybit.h"
39054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_dump_layers.h"
40054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hdmi.h"
41054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_qclient.h"
42054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "QService.h"
43054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "comptype.h"
44054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_virtual.h"
45054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "qd_utils.h"
46054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <sys/sysinfo.h>
47cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed#include <dlfcn.h>
48054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
49054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace qClient;
50054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace qService;
51054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace android;
52054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace overlay;
53054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace overlay::utils;
54054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinnamespace ovutils = overlay::utils;
55054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
56054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef QCOM_BSP
57054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef __cplusplus
58054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinextern "C" {
59054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
60054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
61054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinEGLAPI EGLBoolean eglGpuPerfHintQCOM(EGLDisplay dpy, EGLContext ctx,
62054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                           EGLint *attrib_list);
63054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define EGL_GPU_HINT_1        0x32D0
64054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define EGL_GPU_HINT_2        0x32D1
65054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
66054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define EGL_GPU_LEVEL_0       0x0
67054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define EGL_GPU_LEVEL_1       0x1
68054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define EGL_GPU_LEVEL_2       0x2
69054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define EGL_GPU_LEVEL_3       0x3
70054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define EGL_GPU_LEVEL_4       0x4
71054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define EGL_GPU_LEVEL_5       0x5
72054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
73054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef __cplusplus
74054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
75054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
76054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
77054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
78054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define PROP_DEFAULT_APPBUFFER  "ro.sf.default_app_buffer"
79054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define MAX_RAM_SIZE  512*1024*1024
80054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#define qHD_WIDTH 540
81054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
82054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
83054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinnamespace qhwc {
84054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
85054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// Std refresh rates for digital videos- 24p, 30p, 48p and 60p
86054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinuint32_t stdRefreshRates[] = { 30, 24, 48, 60 };
87054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
88054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
89054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
90054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return !((xres > qdutils::MDPVersion::getInstance().getMaxPipeWidth() &&
91054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                !isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY)) ||
92054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (xres < MIN_DISPLAY_XRES || yres < MIN_DISPLAY_YRES));
93054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
94054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
95054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid changeResolution(hwc_context_t *ctx, int xres_orig, int yres_orig,
96054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                      int width, int height) {
97054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Store original display resolution.
98054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_orig;
99054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_orig;
100054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = false;
101054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char property[PROPERTY_VALUE_MAX] = {'\0'};
102054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char *yptr = NULL;
103054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
104054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        yptr = strcasestr(property,"x");
105054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(yptr) {
106054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int xres_new = atoi(property);
107054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int yres_new = atoi(yptr + 1);
108054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (isValidResolution(ctx,xres_new,yres_new) &&
109054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                xres_new != xres_orig && yres_new != yres_orig) {
110054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
111054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
112054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
113054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
114054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                //Caluculate DPI according to changed resolution.
115054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                float xdpi = ((float)xres_new * 25.4f) / (float)width;
116054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                float ydpi = ((float)yres_new * 25.4f) / (float)height;
117054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
118054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
119054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
120054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
121054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
122054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
123054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
124054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// Initialize hdmi display attributes based on
125054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// hdmi display class state
126054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid updateDisplayInfo(hwc_context_t* ctx, int dpy) {
127054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd();
128054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth();
129054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight();
130054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mHDMIDisplay->getMDPScalingMode();
131054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].vsync_period = ctx->mHDMIDisplay->getVsyncPeriod();
132054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //FIXME: for now assume HDMI as secure
133054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Will need to read the HDCP status from the driver
134054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //and update this accordingly
135054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].secure = true;
136054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mViewFrame[dpy].left = 0;
137054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mViewFrame[dpy].top = 0;
138054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mViewFrame[dpy].right = ctx->dpyAttr[dpy].xres;
139054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mViewFrame[dpy].bottom = ctx->dpyAttr[dpy].yres;
140054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
141054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
142054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// Reset hdmi display attributes and list stats structures
143054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid resetDisplayInfo(hwc_context_t* ctx, int dpy) {
144054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&(ctx->dpyAttr[dpy]), 0, sizeof(ctx->dpyAttr[dpy]));
145054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&(ctx->listStats[dpy]), 0, sizeof(ctx->listStats[dpy]));
146054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // We reset the fd to -1 here but External display class is responsible
147054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // for it when the display is disconnected. This is handled as part of
148054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // EXTERNAL_OFFLINE event.
149054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].fd = -1;
150054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
151054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
152054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// Initialize composition resources
153054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid initCompositionResources(hwc_context_t* ctx, int dpy) {
154054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx, dpy);
155054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mMDPComp[dpy] = MDPComp::getObject(ctx, dpy);
156054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
157054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
158054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid destroyCompositionResources(hwc_context_t* ctx, int dpy) {
159054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mFBUpdate[dpy]) {
160054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        delete ctx->mFBUpdate[dpy];
161054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mFBUpdate[dpy] = NULL;
162054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
163054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mMDPComp[dpy]) {
164054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        delete ctx->mMDPComp[dpy];
165054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mMDPComp[dpy] = NULL;
166054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
167054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
168054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
169054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic int openFramebufferDevice(hwc_context_t *ctx)
170054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
171054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct fb_fix_screeninfo finfo;
172054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct fb_var_screeninfo info;
173054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
174054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fb_fd = openFb(HWC_DISPLAY_PRIMARY);
175054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(fb_fd < 0) {
176054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Error Opening FB : %s", __FUNCTION__, strerror(errno));
177054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -errno;
178054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
179054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
180054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &info) == -1) {
181054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s:Error in ioctl FBIOGET_VSCREENINFO: %s", __FUNCTION__,
182054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                                       strerror(errno));
183054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(fb_fd);
184054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -errno;
185054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
186054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
187054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (int(info.width) <= 0 || int(info.height) <= 0) {
188054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // the driver doesn't return that information
189054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // default to 160 dpi
190054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        info.width  = (int)(((float)info.xres * 25.4f)/160.0f + 0.5f);
191054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        info.height = (int)(((float)info.yres * 25.4f)/160.0f + 0.5f);
192054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
193054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
194054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float xdpi = ((float)info.xres * 25.4f) / (float)info.width;
195054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float ydpi = ((float)info.yres * 25.4f) / (float)info.height;
196054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
197054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef MSMFB_METADATA_GET
198054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct msmfb_metadata metadata;
199054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&metadata, 0 , sizeof(metadata));
200054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    metadata.op = metadata_op_frame_rate;
201054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
202054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) {
203054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s:Error retrieving panel frame rate: %s", __FUNCTION__,
204054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                                      strerror(errno));
205054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(fb_fd);
206054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -errno;
207054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
208054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
209054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float fps  = (float)metadata.data.panel_frame_rate;
210054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#else
211054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //XXX: Remove reserved field usage on all baselines
212054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //The reserved[3] field is used to store FPS by the driver.
213054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float fps  = info.reserved[3] & 0xFF;
214054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
215054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
216054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
217054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s:Error in ioctl FBIOGET_FSCREENINFO: %s", __FUNCTION__,
218054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                                       strerror(errno));
219054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(fb_fd);
220054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -errno;
221054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
222054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
223054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = fb_fd;
224054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //xres, yres may not be 32 aligned
225054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride = finfo.line_length /(info.xres/8);
226054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = info.xres;
227054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = info.yres;
228054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
229054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
230054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].refreshRate = (uint32_t)fps;
231054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].dynRefreshRate = (uint32_t)fps;
232054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].secure = true;
233054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period =
234054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (uint32_t)(1000000000l / fps);
235054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
236054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //To change resolution of primary display
237054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    changeResolution(ctx, info.xres, info.yres, info.width, info.height);
238054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
239054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Unblank primary on first boot
240054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ioctl(fb_fd, FBIOBLANK,FB_BLANK_UNBLANK) < 0) {
241054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Failed to unblank display", __FUNCTION__);
242054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -errno;
243054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
244054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive = true;
245054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
246054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
247054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
248054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
249054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void changeDefaultAppBufferCount() {
250054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct sysinfo info;
251054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    unsigned long int ramSize = 0;
252054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (!sysinfo(&info)) {
253054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           ramSize = info.totalram ;
254054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
255054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fb_fd = -1;
256054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct fb_var_screeninfo sInfo ={0};
257054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    fb_fd = open("/dev/graphics/fb0", O_RDONLY);
258054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (fb_fd >=0) {
259054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ioctl(fb_fd, FBIOGET_VSCREENINFO, &sInfo);
260054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(fb_fd);
261054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
262054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if ((ramSize && ramSize < MAX_RAM_SIZE) &&
263054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         (sInfo.xres &&  sInfo.xres <= qHD_WIDTH )) {
264054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  property_set(PROP_DEFAULT_APPBUFFER, "2");
265054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
266054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
267054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
268054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid initContext(hwc_context_t *ctx)
269054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
270054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    overlay::Overlay::initOverlay();
271054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mHDMIDisplay = new HDMIDisplay();
272054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t priW = 0, priH = 0;
273054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // 1. HDMI as Primary
274054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //    -If HDMI cable is connected, read display configs from edid data
275054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //    -If HDMI cable is not connected then use default data in vscreeninfo
276054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // 2. HDMI as External
277054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //    -Initialize HDMI class for use with external display
278054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //    -Use vscreeninfo to populate display configs
279054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
280054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int connected = ctx->mHDMIDisplay->getConnectedState();
281054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(connected == 1) {
282054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mHDMIDisplay->configure();
283054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            updateDisplayInfo(ctx, HWC_DISPLAY_PRIMARY);
284054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
285054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
286054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            openFramebufferDevice(ctx);
287054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = false;
288054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
289054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
290054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        openFramebufferDevice(ctx);
291054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
292054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Send the primary resolution to the hdmi display class
293054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // to be used for MDP scaling functionality
294054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        priW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
295054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        priH = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
296054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mHDMIDisplay->setPrimaryAttributes(priW, priH);
297054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
298054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
299054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char value[PROPERTY_VALUE_MAX];
300054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
301054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
302054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
303054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mOverlay = overlay::Overlay::getInstance();
304054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mRotMgr = RotMgr::getInstance();
305054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mBWCEnabled = qdutils::MDPVersion::getInstance().supportsBWC();
306054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
307054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //default_app_buffer for ferrum
308054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ctx->mMDP.version ==  qdutils::MDP_V3_0_5) {
309054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       changeDefaultAppBufferCount();
310054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
311054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Initialize composition objects for the primary display
312054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    initCompositionResources(ctx, HWC_DISPLAY_PRIMARY);
313054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
314054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Check if the target supports copybit compostion (dyn/mdp) to
315054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // decide if we need to open the copybit module.
316054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int compositionType =
317054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qdutils::QCCompositionType::getInstance().getCompositionType();
318054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
319054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Only MDP copybit is used
320054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
321054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qdutils::COMPOSITION_TYPE_MDP)) &&
322054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ((qdutils::MDPVersion::getInstance().getMDPVersion() ==
323054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qdutils::MDP_V3_0_4) ||
324054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (qdutils::MDPVersion::getInstance().getMDPVersion() ==
325054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qdutils::MDP_V3_0_5))) {
326054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
327054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                                         HWC_DISPLAY_PRIMARY);
328054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
329054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
330054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mHWCVirtual = new HWCVirtualVDS();
331054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
332054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
333054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = false;
334054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected = false;
335054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].mMDPScalingMode= false;
336054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].mMDPScalingMode = false;
337054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].mMDPScalingMode = false;
338054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
339054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Initialize the primary display viewFrame info
340054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mViewFrame[HWC_DISPLAY_PRIMARY].left = 0;
341054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mViewFrame[HWC_DISPLAY_PRIMARY].top = 0;
342054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mViewFrame[HWC_DISPLAY_PRIMARY].right =
343054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (int)ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
344054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mViewFrame[HWC_DISPLAY_PRIMARY].bottom =
345054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         (int)ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
346054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
347054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
348054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mHwcDebug[i] = new HwcDebug(i);
349054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mLayerRotMap[i] = new LayerRotMap();
350054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mAnimationState[i] = ANIMATION_STOPPED;
351054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[i].mActionSafePresent = false;
352054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[i].mAsWidthRatio = 0;
353054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[i].mAsHeightRatio = 0;
354054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
355054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
356054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
357054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mPrevHwLayerCount[i] = 0;
358054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
359054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
360054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MDPComp::init(ctx);
361054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mAD = new AssertiveDisplay(ctx);
362054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
363054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->vstate.enable = false;
364054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->vstate.fakevsync = false;
365054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mExtOrientation = 0;
366054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->numActiveDisplays = 1;
367054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
368054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Right now hwc starts the service but anybody could do it, or it could be
369054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //independent process as well.
370054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    QService::init();
371054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sp<IQClient> client = new QClient(ctx);
372054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    android::sp<qService::IQService> qservice_sp = interface_cast<IQService>(
373054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            defaultServiceManager()->getService(
374054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            String16("display.qservice")));
375054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (qservice_sp.get()) {
376054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      qservice_sp->connect(client);
377054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
378054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
379054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      return ;
380054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
381054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
382054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Initialize device orientation to its default orientation
383054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->deviceOrientation = 0;
384054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mBufferMirrorMode = false;
385054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
386054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    property_get("sys.hwc.windowbox_aspect_ratio_tolerance", value, "0");
387054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mAspectRatioToleranceLevel = (((float)atoi(value)) / 100.0f);
388054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
389054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->enableABC = false;
390054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    property_get("debug.sf.hwc.canUseABC", value, "0");
391054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->enableABC  = atoi(value) ? true : false;
392054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
393cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed    // Initializing boot anim completed check to false
394831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed    ctx->mDefaultModeApplied = false;
395cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed
396f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch    ctx->mCoolColorTemperatureEnabled = false;
397f1812e0b56773537760c9ae8ea45cee5ac902118Steve Pfetsch
398054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Initialize gpu perfomance hint related parameters
399054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    property_get("sys.hwc.gpu_perf_mode", value, "0");
400054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef QCOM_BSP
401054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mGPUHintInfo.mGpuPerfModeEnable = atoi(value)? true : false;
402054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
403054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mGPUHintInfo.mEGLDisplay = NULL;
404054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mGPUHintInfo.mEGLContext = NULL;
405054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
406054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
407054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
408054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Read the system property to determine if windowboxing feature is enabled.
409054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mWindowboxFeature = false;
410054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(property_get("sys.hwc.windowbox_feature", value, "false")
411054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            && !strcmp(value, "true")) {
412054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mWindowboxFeature = true;
413054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
414054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
415054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mUseMetaDataRefreshRate = true;
416054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(property_get("persist.metadata_dynfps.disable", value, "false")
417054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            && !strcmp(value, "true")) {
418054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mUseMetaDataRefreshRate = false;
419054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
420054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
421054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
422054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mHPDEnabled = false;
4236109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    ctx->mColorMode = new ColorMode();
4246109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    ctx->mColorMode->init();
425054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGI("Initializing Qualcomm Hardware Composer");
426054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGI("MDP version: %d", ctx->mMDP.version);
427054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
428054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
429054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid closeContext(hwc_context_t *ctx)
430054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
431054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mOverlay) {
432054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        delete ctx->mOverlay;
433054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mOverlay = NULL;
434054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
435054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
436054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mRotMgr) {
437054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        delete ctx->mRotMgr;
438054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mRotMgr = NULL;
439054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
440054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
441054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
442054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->mCopyBit[i]) {
443054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            delete ctx->mCopyBit[i];
444054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mCopyBit[i] = NULL;
445054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
446054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
447054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
448054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd) {
449054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd);
450054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
451054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
452054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
453054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mHDMIDisplay) {
454054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        delete ctx->mHDMIDisplay;
455054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mHDMIDisplay = NULL;
456054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
457054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
458054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
459054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        destroyCompositionResources(ctx, i);
460054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
461054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->mHwcDebug[i]) {
462054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            delete ctx->mHwcDebug[i];
463054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mHwcDebug[i] = NULL;
464054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
465054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->mLayerRotMap[i]) {
466054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            delete ctx->mLayerRotMap[i];
467054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mLayerRotMap[i] = NULL;
468054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
469054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
470054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mHWCVirtual) {
471054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        delete ctx->mHWCVirtual;
472054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mHWCVirtual = NULL;
473054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
474054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mAD) {
475054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        delete ctx->mAD;
476054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mAD = NULL;
477054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
478054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
4796109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(ctx->mColorMode) {
4806109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        ctx->mColorMode->destroy();
4816109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        delete ctx->mColorMode;
4826109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        ctx->mColorMode = NULL;
4836109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
484054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
485054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
486054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//Helper to roundoff the refreshrates
487054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinuint32_t roundOff(uint32_t refreshRate) {
488054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int count =  (int) (sizeof(stdRefreshRates)/sizeof(stdRefreshRates[0]));
489054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t rate = refreshRate;
490054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i=0; i< count; i++) {
491438a86130d02c5a6fb71367ba8681f36c53531d2Dan Austin      if(abs((int)(stdRefreshRates[i] - refreshRate)) < 2) {
492054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // Most likely used for video, the fps can fluctuate
493054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // Ex: b/w 29 and 30 for 30 fps clip
494054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            rate = stdRefreshRates[i];
495054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            break;
496054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
497054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
498054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return rate;
499054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
500054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
501054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//Helper func to set the dyn fps
502054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid setRefreshRate(hwc_context_t* ctx, int dpy, uint32_t refreshRate) {
503054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Update only if different
504054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx || refreshRate == ctx->dpyAttr[dpy].dynRefreshRate)
505054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
506054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int fbNum = Overlay::getFbForDpy(dpy);
507054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char sysfsPath[qdutils::MAX_SYSFS_FILE_PATH];
508054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    snprintf (sysfsPath, sizeof(sysfsPath),
509054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            "/sys/devices/virtual/graphics/fb%d/dynamic_fps", fbNum);
510054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
511054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fd = open(sysfsPath, O_WRONLY);
512054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(fd >= 0) {
513054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        char str[64];
514054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        snprintf(str, sizeof(str), "%d", refreshRate);
515054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ssize_t ret = write(fd, str, strlen(str));
516054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ret < 0) {
517054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: Failed to write %d with error %s",
518054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    __FUNCTION__, refreshRate, strerror(errno));
519054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
520054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->dpyAttr[dpy].dynRefreshRate = refreshRate;
521054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(HWC_UTILS_DEBUG, "%s: Wrote %d to dynamic_fps",
522054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     __FUNCTION__, refreshRate);
523054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
524054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(fd);
525054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
526054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Failed to open %s with error %s", __FUNCTION__, sysfsPath,
527054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin              strerror(errno));
528054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
529054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
530054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
531054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid dumpsys_log(android::String8& buf, const char* fmt, ...)
532054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
533054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    va_list varargs;
534054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    va_start(varargs, fmt);
535054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    buf.appendFormatV(fmt, varargs);
536054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    va_end(varargs);
537054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
538054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
539054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint getExtOrientation(hwc_context_t* ctx) {
540054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int extOrient = ctx->mExtOrientation;
541054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mBufferMirrorMode)
542054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        extOrient = getMirrorModeOrientation(ctx);
543054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return extOrient;
544054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
545054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
546054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Calculates the destination position based on the action safe rectangle */
547054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& rect) {
548054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Position
549054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int x = rect.left, y = rect.top;
550054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int w = rect.right - rect.left;
551054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int h = rect.bottom - rect.top;
552054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
553054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx->dpyAttr[dpy].mActionSafePresent)
554054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
555054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   // Read action safe properties
556054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int asWidthRatio = ctx->dpyAttr[dpy].mAsWidthRatio;
557054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int asHeightRatio = ctx->dpyAttr[dpy].mAsHeightRatio;
558054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
559054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float wRatio = 1.0;
560054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float hRatio = 1.0;
561054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float xRatio = 1.0;
562054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float yRatio = 1.0;
563054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
564054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t fbWidth = ctx->dpyAttr[dpy].xres;
565054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t fbHeight = ctx->dpyAttr[dpy].yres;
566054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->dpyAttr[dpy].mMDPScalingMode) {
567054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // if MDP scaling mode is enabled for external, need to query
568054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // the actual width and height, as that is the physical w & h
569054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         ctx->mHDMIDisplay->getAttributes(fbWidth, fbHeight);
570054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
571054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
572054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
573054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Since external is rotated 90, need to swap width/height
574054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int extOrient = getExtOrientation(ctx);
575054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
576054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(extOrient & HWC_TRANSFORM_ROT_90)
577054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        swap(fbWidth, fbHeight);
578054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
579054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float asX = 0;
580054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float asY = 0;
581054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float asW = (float)fbWidth;
582054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float asH = (float)fbHeight;
583054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
584054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // based on the action safe ratio, get the Action safe rectangle
585054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    asW = ((float)fbWidth * (1.0f -  (float)asWidthRatio / 100.0f));
586054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    asH = ((float)fbHeight * (1.0f -  (float)asHeightRatio / 100.0f));
587054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    asX = ((float)fbWidth - asW) / 2;
588054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    asY = ((float)fbHeight - asH) / 2;
589054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
590054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // calculate the position ratio
591054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    xRatio = (float)x/(float)fbWidth;
592054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    yRatio = (float)y/(float)fbHeight;
593054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    wRatio = (float)w/(float)fbWidth;
594054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hRatio = (float)h/(float)fbHeight;
595054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
596054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Calculate the position...
597054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    x = int((xRatio * asW) + asX);
598054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    y = int((yRatio * asH) + asY);
599054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    w = int(wRatio * asW);
600054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    h = int(hRatio * asH);
601054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
602054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Convert it back to hwc_rect_t
603054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    rect.left = x;
604054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    rect.top = y;
605054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    rect.right = w + rect.left;
606054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    rect.bottom = h + rect.top;
607054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
608054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return;
609054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
610054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
611054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// This function gets the destination position for Seconday display
612054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// based on the position and aspect ratio with orientation
613054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
614054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            hwc_rect_t& inRect, hwc_rect_t& outRect) {
615054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Physical display resolution
616054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float fbWidth  = (float)ctx->dpyAttr[dpy].xres;
617054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float fbHeight = (float)ctx->dpyAttr[dpy].yres;
618054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //display position(x,y,w,h) in correct aspectratio after rotation
619054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int xPos = 0;
620054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int yPos = 0;
621054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float width = fbWidth;
622054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float height = fbHeight;
623054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Width/Height used for calculation, after rotation
624054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float actualWidth = fbWidth;
625054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float actualHeight = fbHeight;
626054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
627054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float wRatio = 1.0;
628054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float hRatio = 1.0;
629054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float xRatio = 1.0;
630054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float yRatio = 1.0;
631054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t rect = {0, 0, (int)fbWidth, (int)fbHeight};
632054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
633054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Dim inPos(inRect.left, inRect.top, inRect.right - inRect.left,
634054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                inRect.bottom - inRect.top);
635054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Dim outPos(outRect.left, outRect.top, outRect.right - outRect.left,
636054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                outRect.bottom - outRect.top);
637054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
638054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Whf whf((uint32_t)fbWidth, (uint32_t)fbHeight, 0);
639054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eTransform extorient = static_cast<eTransform>(extOrientation);
640054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // To calculate the destination co-ordinates in the new orientation
641054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    preRotateSource(extorient, whf, inPos);
642054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
643054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(extOrientation & HAL_TRANSFORM_ROT_90) {
644054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Swap width/height for input position
645054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        swapWidthHeight(actualWidth, actualHeight);
646054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qdutils::getAspectRatioPosition((int)fbWidth, (int)fbHeight,
647054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                (int)actualWidth, (int)actualHeight, rect);
648054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        xPos = rect.left;
649054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        yPos = rect.top;
650054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        width = float(rect.right - rect.left);
651054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        height = float(rect.bottom - rect.top);
652054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
653054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    xRatio = (float)((float)inPos.x/actualWidth);
654054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    yRatio = (float)((float)inPos.y/actualHeight);
655054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    wRatio = (float)((float)inPos.w/actualWidth);
656054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hRatio = (float)((float)inPos.h/actualHeight);
657054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
658054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Calculate the pos9ition...
659054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    outPos.x = uint32_t((xRatio * width) + (float)xPos);
660054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    outPos.y = uint32_t((yRatio * height) + (float)yPos);
661054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    outPos.w = uint32_t(wRatio * width);
662054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    outPos.h = uint32_t(hRatio * height);
663054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio Position: x = %d,"
664054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 "y = %d w = %d h = %d", __FUNCTION__, outPos.x, outPos.y,
665054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 outPos.w, outPos.h);
666054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
667054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // For sidesync, the dest fb will be in portrait orientation, and the crop
668054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // will be updated to avoid the black side bands, and it will be upscaled
669054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // to fit the dest RB, so recalculate
670054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // the position based on the new width and height
671054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if ((extOrientation & HWC_TRANSFORM_ROT_90) &&
672054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        isOrientationPortrait(ctx)) {
673054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t r = {0, 0, 0, 0};
674054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Calculate the position
675054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        xRatio = (float)(outPos.x - xPos)/width;
676054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // GetaspectRatio -- tricky to get the correct aspect ratio
677054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // But we need to do this.
678054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qdutils::getAspectRatioPosition((int)width, (int)height,
679054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                               (int)width,(int)height, r);
680054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        xPos = r.left;
681054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        yPos = r.top;
682054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        float tempHeight = float(r.bottom - r.top);
683054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        yRatio = (float)yPos/height;
684054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        wRatio = (float)outPos.w/width;
685054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hRatio = tempHeight/height;
686054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
687054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Map the coordinates back to Framebuffer domain
688054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        outPos.x = uint32_t(xRatio * fbWidth);
689054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        outPos.y = uint32_t(yRatio * fbHeight);
690054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        outPos.w = uint32_t(wRatio * fbWidth);
691054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        outPos.h = uint32_t(hRatio * fbHeight);
692054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
693054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio for device in"
694054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 "portrait: x = %d,y = %d w = %d h = %d", __FUNCTION__,
695054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 outPos.x, outPos.y,
696054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 outPos.w, outPos.h);
697054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
698054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->dpyAttr[dpy].mMDPScalingMode) {
699054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        uint32_t extW = 0, extH = 0;
700054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(dpy == HWC_DISPLAY_EXTERNAL) {
701054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mHDMIDisplay->getAttributes(extW, extH);
702054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else if(dpy == HWC_DISPLAY_VIRTUAL) {
703054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            extW = ctx->mHWCVirtual->getScalingWidth();
704054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            extH = ctx->mHWCVirtual->getScalingHeight();
705054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
706054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(HWC_UTILS_DEBUG, "%s: Scaling mode extW=%d extH=%d",
707054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__, extW, extH);
708054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
709054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        fbWidth  = (float)ctx->dpyAttr[dpy].xres;
710054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        fbHeight = (float)ctx->dpyAttr[dpy].yres;
711054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Calculate the position...
712054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        xRatio = (float)outPos.x/fbWidth;
713054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        yRatio = (float)outPos.y/fbHeight;
714054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        wRatio = (float)outPos.w/fbWidth;
715054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hRatio = (float)outPos.h/fbHeight;
716054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
717054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        outPos.x = uint32_t(xRatio * (float)extW);
718054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        outPos.y = uint32_t(yRatio * (float)extH);
719054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        outPos.w = uint32_t(wRatio * (float)extW);
720054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        outPos.h = uint32_t(hRatio * (float)extH);
721054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
722054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Convert Dim to hwc_rect_t
723054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    outRect.left = outPos.x;
724054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    outRect.top = outPos.y;
725054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    outRect.right = outPos.x + outPos.w;
726054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    outRect.bottom = outPos.y + outPos.h;
727054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
728054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return;
729054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
730054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
731054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isPrimaryPortrait(hwc_context_t *ctx) {
732054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fbWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
733054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fbHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
734054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(fbWidth < fbHeight) {
735054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
736054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
737054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
738054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
739054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
740054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isOrientationPortrait(hwc_context_t *ctx) {
741054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isPrimaryPortrait(ctx)) {
742054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return !(ctx->deviceOrientation & 0x1);
743054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
744054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return (ctx->deviceOrientation & 0x1);
745054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
746054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
747054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid calcExtDisplayPosition(hwc_context_t *ctx,
748054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                               private_handle_t *hnd,
749054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                               int dpy,
750054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                               hwc_rect_t& sourceCrop,
751054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                               hwc_rect_t& displayFrame,
752054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                               int& transform,
753054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                               ovutils::eTransform& orient) {
754054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Swap width and height when there is a 90deg transform
755054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int extOrient = getExtOrientation(ctx);
756054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dpy && ctx->mOverlay->isUIScalingOnExternalSupported()) {
757054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!isYuvBuffer(hnd)) {
758054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(extOrient & HWC_TRANSFORM_ROT_90) {
759054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                int dstWidth = ctx->dpyAttr[dpy].xres;
760054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                int dstHeight = ctx->dpyAttr[dpy].yres;;
761054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                int srcWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
762054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                int srcHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
763054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(!isPrimaryPortrait(ctx)) {
764054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    swap(srcWidth, srcHeight);
765054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }                    // Get Aspect Ratio for external
766054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                qdutils::getAspectRatioPosition(dstWidth, dstHeight, srcWidth,
767054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                    srcHeight, displayFrame);
768054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // Crop - this is needed, because for sidesync, the dest fb will
769054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // be in portrait orientation, so update the crop to not show the
770054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // black side bands.
771054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if (isOrientationPortrait(ctx)) {
772054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    sourceCrop = displayFrame;
773054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    displayFrame.left = 0;
774054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    displayFrame.top = 0;
775054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    displayFrame.right = dstWidth;
776054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    displayFrame.bottom = dstHeight;
777054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
778054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
779054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(ctx->dpyAttr[dpy].mMDPScalingMode) {
780054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                uint32_t extW = 0, extH = 0;
781054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // if MDP scaling mode is enabled, map the co-ordinates to new
782054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // domain(downscaled)
783054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                float fbWidth  = (float)ctx->dpyAttr[dpy].xres;
784054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                float fbHeight = (float)ctx->dpyAttr[dpy].yres;
785054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // query MDP configured attributes
786054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(dpy == HWC_DISPLAY_EXTERNAL) {
787054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    ctx->mHDMIDisplay->getAttributes(extW, extH);
788054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                } else if(dpy == HWC_DISPLAY_VIRTUAL) {
789054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    extW = ctx->mHWCVirtual->getScalingWidth();
790054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    extH = ctx->mHWCVirtual->getScalingHeight();
791054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
792054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(HWC_UTILS_DEBUG, "%s: Scaling mode extW=%d extH=%d",
793054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        __FUNCTION__, extW, extH);
794054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
795054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                //Calculate the ratio...
796054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                float wRatio = ((float)extW)/fbWidth;
797054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                float hRatio = ((float)extH)/fbHeight;
798054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
799054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                //convert Dim to hwc_rect_t
800054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                displayFrame.left = int(wRatio*(float)displayFrame.left);
801054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                displayFrame.top = int(hRatio*(float)displayFrame.top);
802054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                displayFrame.right = int(wRatio*(float)displayFrame.right);
803054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                displayFrame.bottom = int(hRatio*(float)displayFrame.bottom);
804054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(DEBUG_MDPDOWNSCALE, "Calculated external display frame"
805054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                         " for MDPDownscale feature [%d %d %d %d]",
806054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                         displayFrame.left, displayFrame.top,
807054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                         displayFrame.right, displayFrame.bottom);
808054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
809054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }else {
810054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(extOrient || ctx->dpyAttr[dpy].mMDPScalingMode) {
811054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                getAspectRatioPosition(ctx, dpy, extOrient,
812054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                       displayFrame, displayFrame);
813054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
814054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
815054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // If there is a external orientation set, use that
816054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(extOrient) {
817054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            transform = extOrient;
818054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            orient = static_cast<ovutils::eTransform >(extOrient);
819054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
820054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Calculate the actionsafe dimensions for External(dpy = 1 or 2)
821054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        getActionSafePosition(ctx, dpy, displayFrame);
822054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
823054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
824054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
825054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Returns the orientation which needs to be set on External for
826054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *  SideSync/Buffer Mirrormode
827054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */
828054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint getMirrorModeOrientation(hwc_context_t *ctx) {
829054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int extOrientation = 0;
830054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int deviceOrientation = ctx->deviceOrientation;
831054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isPrimaryPortrait(ctx))
832054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        deviceOrientation = (deviceOrientation + 1) % 4;
833054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     if (deviceOrientation == 0)
834054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         extOrientation = HWC_TRANSFORM_ROT_270;
835054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     else if (deviceOrientation == 1)//90
836054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         extOrientation = 0;
837054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     else if (deviceOrientation == 2)//180
838054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         extOrientation = HWC_TRANSFORM_ROT_90;
839054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     else if (deviceOrientation == 3)//270
840054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         extOrientation = HWC_TRANSFORM_FLIP_V | HWC_TRANSFORM_FLIP_H;
841054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
842054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return extOrientation;
843054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
844054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
845054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Get External State names */
846054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinconst char* getExternalDisplayState(uint32_t external_state) {
847054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    static const char* externalStates[EXTERNAL_MAXSTATES] = {0};
848054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    externalStates[EXTERNAL_OFFLINE] = STR(EXTERNAL_OFFLINE);
849054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    externalStates[EXTERNAL_ONLINE]  = STR(EXTERNAL_ONLINE);
850054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    externalStates[EXTERNAL_PAUSE]   = STR(EXTERNAL_PAUSE);
851054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    externalStates[EXTERNAL_RESUME]  = STR(EXTERNAL_RESUME);
852054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
853054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(external_state >= EXTERNAL_MAXSTATES) {
854054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return "EXTERNAL_INVALID";
855054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
856054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
857054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return externalStates[external_state];
858054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
859054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
860054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isDownscaleRequired(hwc_layer_1_t const* layer) {
861054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t displayFrame  = layer->displayFrame;
862054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
863054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_w, dst_h, src_w, src_h;
864054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dst_w = displayFrame.right - displayFrame.left;
865054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dst_h = displayFrame.bottom - displayFrame.top;
866054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    src_w = sourceCrop.right - sourceCrop.left;
867054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    src_h = sourceCrop.bottom - sourceCrop.top;
868054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
869054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(((src_w > dst_w) || (src_h > dst_h)))
870054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
871054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
872054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
873054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
874054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool needsScaling(hwc_layer_1_t const* layer) {
875054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_w, dst_h, src_w, src_h;
876054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t displayFrame  = layer->displayFrame;
877054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
878054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
879054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dst_w = displayFrame.right - displayFrame.left;
880054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dst_h = displayFrame.bottom - displayFrame.top;
881054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    src_w = sourceCrop.right - sourceCrop.left;
882054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    src_h = sourceCrop.bottom - sourceCrop.top;
883054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
884054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(layer->transform & HWC_TRANSFORM_ROT_90)
885054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        swap(src_w, src_h);
886054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
887054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(((src_w != dst_w) || (src_h != dst_h)))
888054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
889054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
890054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
891054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
892054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
893054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// Checks if layer needs scaling with split
894054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
895054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int& dpy) {
896054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
897054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int src_width_l, src_height_l;
898054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int src_width_r, src_height_r;
899054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_width_l, dst_height_l;
900054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_width_r, dst_height_r;
901054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int hw_w = ctx->dpyAttr[dpy].xres;
902054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int hw_h = ctx->dpyAttr[dpy].yres;
903054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t cropL, dstL, cropR, dstR;
904054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int lSplit = getLeftSplit(ctx, dpy);
905054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
906054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t displayFrame  = layer->displayFrame;
907054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
908054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
909054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    cropL = sourceCrop;
910054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dstL = displayFrame;
911054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t scissorL = { 0, 0, lSplit, hw_h };
912054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    scissorL = getIntersection(ctx->mViewFrame[dpy], scissorL);
913054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);
914054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
915054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    cropR = sourceCrop;
916054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dstR = displayFrame;
917054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t scissorR = { lSplit, 0, hw_w, hw_h };
918054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    scissorR = getIntersection(ctx->mViewFrame[dpy], scissorR);
919054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);
920054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
921054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Sanitize Crop to stitch
922054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sanitizeSourceCrop(cropL, cropR, hnd);
923054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
924054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Calculate the left dst
925054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dst_width_l = dstL.right - dstL.left;
926054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dst_height_l = dstL.bottom - dstL.top;
927054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    src_width_l = cropL.right - cropL.left;
928054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    src_height_l = cropL.bottom - cropL.top;
929054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
930054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // check if there is any scaling on the left
931054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(((src_width_l != dst_width_l) || (src_height_l != dst_height_l)))
932054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
933054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
934054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Calculate the right dst
935054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dst_width_r = dstR.right - dstR.left;
936054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dst_height_r = dstR.bottom - dstR.top;
937054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    src_width_r = cropR.right - cropR.left;
938054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    src_height_r = cropR.bottom - cropR.top;
939054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
940054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // check if there is any scaling on the right
941054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(((src_width_r != dst_width_r) || (src_height_r != dst_height_r)))
942054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
943054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
944054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
945054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
946054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
947054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isAlphaScaled(hwc_layer_1_t const* layer) {
948054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(needsScaling(layer) && isAlphaPresent(layer)) {
949054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
950054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
951054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
952054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
953054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
954054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isAlphaPresent(hwc_layer_1_t const* layer) {
955054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
956054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(hnd) {
957054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int format = hnd->format;
958054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        switch(format) {
959054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        case HAL_PIXEL_FORMAT_RGBA_8888:
960054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        case HAL_PIXEL_FORMAT_BGRA_8888:
961054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // In any more formats with Alpha go here..
962054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return true;
963054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        default : return false;
964054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
965054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
966054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
967054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
968054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
969054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
970054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t& crop, hwc_rect_t& dst) {
971054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int hw_w = ctx->dpyAttr[dpy].xres;
972054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int hw_h = ctx->dpyAttr[dpy].yres;
973054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dst.left < 0 || dst.top < 0 ||
974054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            dst.right > hw_w || dst.bottom > hw_h) {
975054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t scissor = {0, 0, hw_w, hw_h };
976054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
977054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qhwc::calculate_crop_rects(crop, dst, scissor, transform);
978054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
979054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
980054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
981054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void trimList(hwc_context_t *ctx, hwc_display_contents_1_t *list,
982054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int& dpy) {
983054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(uint32_t i = 0; i < list->numHwLayers - 1; i++) {
984054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t *layer = &list->hwLayers[i];
985054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
986054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int transform = (list->hwLayers[i].flags & HWC_COLOR_FILL) ? 0 :
987054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                list->hwLayers[i].transform;
988054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        trimLayer(ctx, dpy,
989054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                transform,
990054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (hwc_rect_t&)crop,
991054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (hwc_rect_t&)list->hwLayers[i].displayFrame);
992054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.left = (float)crop.left;
993054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.right = (float)crop.right;
994054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.top = (float)crop.top;
995054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.bottom = (float)crop.bottom;
996054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
997054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
998054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
999054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid setListStats(hwc_context_t *ctx,
1000054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t *list, int dpy) {
1001054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int prevYuvCount = ctx->listStats[dpy].yuvCount;
1002054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&ctx->listStats[dpy], 0, sizeof(ListStats));
1003054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].numAppLayers = (int)list->numHwLayers - 1;
1004054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].fbLayerIndex = (int)list->numHwLayers - 1;
1005054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].skipCount = 0;
1006054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].preMultipliedAlpha = false;
1007054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].isSecurePresent = false;
1008054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].yuvCount = 0;
1009054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char property[PROPERTY_VALUE_MAX];
1010054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].isDisplayAnimating = false;
1011054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].secureUI = false;
1012054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].yuv4k2kCount = 0;
1013054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].mActionSafePresent = isActionSafePresent(ctx, dpy);
1014054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].renderBufIndexforABC = -1;
1015054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].secureRGBCount = 0;
1016054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].refreshRateRequest = ctx->dpyAttr[dpy].refreshRate;
1017054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t refreshRate = 0;
1018054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
1019054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1020054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[dpy].mAIVVideoMode = false;
1021054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    resetROI(ctx, dpy);
1022054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1023054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    trimList(ctx, list, dpy);
1024054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    optimizeLayerRects(list);
1025054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (size_t i = 0; i < (size_t)ctx->listStats[dpy].numAppLayers; i++) {
1026054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t const* layer = &list->hwLayers[i];
1027054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
1028054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1029054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef QCOM_BSP
1030054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Window boxing feature is applicable obly for external display, So
1031054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // enable mAIVVideoMode only for external display
1032054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->mWindowboxFeature && dpy && isAIVVideoLayer(layer)) {
1033054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[dpy].mAIVVideoMode = true;
1034054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1035054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
1036054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[dpy].isDisplayAnimating = true;
1037054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1038054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isSecureDisplayBuffer(hnd)) {
1039054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[dpy].secureUI = true;
1040054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1041054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
1042054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // continue if number of app layers exceeds MAX_NUM_APP_LAYERS
1043054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS)
1044054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
1045054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1046054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //reset yuv indices
1047054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->listStats[dpy].yuvIndices[i] = -1;
1048054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->listStats[dpy].yuv4k2kIndices[i] = -1;
1049054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1050054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (isSecureBuffer(hnd)) {
1051054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[dpy].isSecurePresent = true;
1052054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(not isYuvBuffer(hnd)) {
1053054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // cache secureRGB layer parameters like we cache for YUV layers
1054054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                int& secureRGBCount = ctx->listStats[dpy].secureRGBCount;
1055054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[dpy].secureRGBIndices[secureRGBCount] = (int)i;
1056054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                secureRGBCount++;
1057054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1058054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1059054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1060054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (isSkipLayer(&list->hwLayers[i])) {
1061054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[dpy].skipCount++;
1062054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1063054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1064054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (UNLIKELY(isYuvBuffer(hnd))) {
1065054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int& yuvCount = ctx->listStats[dpy].yuvCount;
1066054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[dpy].yuvIndices[yuvCount] = (int)i;
1067054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            yuvCount++;
1068054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1069054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(UNLIKELY(isYUVSplitNeeded(hnd))){
1070054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                int& yuv4k2kCount = ctx->listStats[dpy].yuv4k2kCount;
1071054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[dpy].yuv4k2kIndices[yuv4k2kCount] = (int)i;
1072054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                yuv4k2kCount++;
1073054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1074054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1075054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(layer->blending == HWC_BLENDING_PREMULT)
1076054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[dpy].preMultipliedAlpha = true;
1077054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1078054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef DYNAMIC_FPS
1079054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (!dpy && mdpHw.isDynFpsSupported() && ctx->mUseMetaDataRefreshRate){
1080054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //dyn fps: get refreshrate from metadata
1081054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //Support multiple refresh rates if they are same
1082054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //else set to  default
1083054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            MetaData_t *mdata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
1084054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (mdata && (mdata->operation & UPDATE_REFRESH_RATE)) {
1085054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // Valid refreshRate in metadata and within the range
1086054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                uint32_t rate = roundOff(mdata->refreshrate);
1087054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if((rate >= mdpHw.getMinFpsSupported() &&
1088054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                rate <= mdpHw.getMaxFpsSupported())) {
1089054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    if (!refreshRate) {
1090054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        refreshRate = rate;
1091054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    } else if(refreshRate != rate) {
1092054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        // multiple refreshrate requests, set to default
1093054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        refreshRate = ctx->dpyAttr[dpy].refreshRate;
1094054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    }
1095054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1096054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1097054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1098054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
1099054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1100054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[dpy].yuvCount > 0) {
1101054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (property_get("hw.cabl.yuv", property, NULL) > 0) {
1102054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (atoi(property) != 1) {
1103054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                property_set("hw.cabl.yuv", "1");
1104054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1105054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1106054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
1107054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (property_get("hw.cabl.yuv", property, NULL) > 0) {
1108054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (atoi(property) != 0) {
1109054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                property_set("hw.cabl.yuv", "0");
1110054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1111054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1112054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1113054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1114054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //The marking of video begin/end is useful on some targets where we need
1115054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //to have a padding round to be able to shift pipes across mixers.
1116054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(prevYuvCount != ctx->listStats[dpy].yuvCount) {
1117054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mVideoTransFlag = true;
1118054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1119054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1120054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dpy == HWC_DISPLAY_PRIMARY) {
1121054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mAD->markDoable(ctx, list);
1122054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Store the requested fresh rate
1123054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->listStats[dpy].refreshRateRequest = refreshRate ?
1124054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                refreshRate : ctx->dpyAttr[dpy].refreshRate;
1125054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1126054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1127054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1128054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1129054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinstatic void calc_cut(double& leftCutRatio, double& topCutRatio,
1130054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        double& rightCutRatio, double& bottomCutRatio, int orient) {
1131054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(orient & HAL_TRANSFORM_FLIP_H) {
1132054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        swap(leftCutRatio, rightCutRatio);
1133054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1134054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(orient & HAL_TRANSFORM_FLIP_V) {
1135054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        swap(topCutRatio, bottomCutRatio);
1136054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1137054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(orient & HAL_TRANSFORM_ROT_90) {
1138054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Anti clock swapping
1139054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        double tmpCutRatio = leftCutRatio;
1140054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        leftCutRatio = topCutRatio;
1141054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        topCutRatio = rightCutRatio;
1142054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rightCutRatio = bottomCutRatio;
1143054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bottomCutRatio = tmpCutRatio;
1144054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1145054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1146054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1147054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer) {
1148054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((ctx->mMDP.version < qdutils::MDSS_V5) &&
1149054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       (ctx->mMDP.version > qdutils::MDP_V3_0) &&
1150054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mSecuring) {
1151054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
1152054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1153054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (isSecureModePolicy(ctx->mMDP.version)) {
1154054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
1155054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->mSecureMode) {
1156054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (! isSecureBuffer(hnd)) {
1157054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning ON ...",
1158054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                         __FUNCTION__);
1159054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return true;
1160054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1161054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
1162054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (isSecureBuffer(hnd)) {
1163054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning OFF ...",
1164054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                         __FUNCTION__);
1165054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return true;
1166054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1167054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1168054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1169054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
1170054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1171054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1172054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isSecureModePolicy(int mdpVersion) {
1173054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (mdpVersion < qdutils::MDSS_V5)
1174054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
1175054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    else
1176054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1177054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1178054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1179054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isRotatorSupportedFormat(private_handle_t *hnd) {
1180054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Following rotator src formats are supported by mdp driver
1181054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // TODO: Add more formats in future, if mdp driver adds support
1182054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(hnd != NULL) {
1183054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        switch(hnd->format) {
1184054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            case HAL_PIXEL_FORMAT_RGBA_8888:
1185054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            case HAL_PIXEL_FORMAT_RGBA_5551:
1186054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            case HAL_PIXEL_FORMAT_RGBA_4444:
1187054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            case HAL_PIXEL_FORMAT_RGB_565:
1188054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            case HAL_PIXEL_FORMAT_RGB_888:
1189054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            case HAL_PIXEL_FORMAT_BGRA_8888:
1190054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return true;
1191054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            default:
1192054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
1193054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1194054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1195054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
1196054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1197054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1198054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd) {
1199054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Rotate layers, if it is not secure display buffer and not
1200054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // for the MDP versions below MDP5
1201054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((!isSecureDisplayBuffer(hnd) && isRotatorSupportedFormat(hnd) &&
1202054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        !ctx->mMDP.version < qdutils::MDSS_V5)
1203054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                   || isYuvBuffer(hnd)) {
1204054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
1205054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1206054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
1207054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1208054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1209054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// returns true if Action safe dimensions are set and target supports Actionsafe
1210054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isActionSafePresent(hwc_context_t *ctx, int dpy) {
1211054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // if external supports underscan, do nothing
1212054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // it will be taken care in the driver
1213054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Disable Action safe for 8974 due to HW limitation for downscaling
1214054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // layers with overlapped region
1215054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Disable Actionsafe for non HDMI displays.
1216054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!(dpy == HWC_DISPLAY_EXTERNAL) ||
1217054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qdutils::MDPVersion::getInstance().is8x74v2() ||
1218054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mHDMIDisplay->isCEUnderscanSupported()) {
1219054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1220054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1221054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1222054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char value[PROPERTY_VALUE_MAX];
1223054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Read action safe properties
1224054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    property_get("persist.sys.actionsafe.width", value, "0");
1225054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].mAsWidthRatio = atoi(value);
1226054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    property_get("persist.sys.actionsafe.height", value, "0");
1227054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].mAsHeightRatio = atoi(value);
1228054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1229054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx->dpyAttr[dpy].mAsWidthRatio && !ctx->dpyAttr[dpy].mAsHeightRatio) {
1230054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //No action safe ratio set, return
1231054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1232054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1233054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1234054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1235054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1236054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint getBlending(int blending) {
1237054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    switch(blending) {
1238054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    case HWC_BLENDING_NONE:
1239054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return overlay::utils::OVERLAY_BLENDING_OPAQUE;
1240054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    case HWC_BLENDING_PREMULT:
1241054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return overlay::utils::OVERLAY_BLENDING_PREMULT;
1242054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    case HWC_BLENDING_COVERAGE :
1243054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    default:
1244054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return overlay::utils::OVERLAY_BLENDING_COVERAGE;
1245054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1246054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1247054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1248054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//Crops source buffer against destination and FB boundaries
1249054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
1250054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                          const hwc_rect_t& scissor, int orient) {
1251054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1252054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int& crop_l = crop.left;
1253054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int& crop_t = crop.top;
1254054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int& crop_r = crop.right;
1255054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int& crop_b = crop.bottom;
1256054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int crop_w = crop.right - crop.left;
1257054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int crop_h = crop.bottom - crop.top;
1258054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1259054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int& dst_l = dst.left;
1260054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int& dst_t = dst.top;
1261054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int& dst_r = dst.right;
1262054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int& dst_b = dst.bottom;
1263054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_w = abs(dst.right - dst.left);
1264054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_h = abs(dst.bottom - dst.top);
1265054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1266054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int& sci_l = scissor.left;
1267054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int& sci_t = scissor.top;
1268054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int& sci_r = scissor.right;
1269054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int& sci_b = scissor.bottom;
1270054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1271054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    double leftCutRatio = 0.0, rightCutRatio = 0.0, topCutRatio = 0.0,
1272054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            bottomCutRatio = 0.0;
1273054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1274054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dst_l < sci_l) {
1275054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        leftCutRatio = (double)(sci_l - dst_l) / (double)dst_w;
1276054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dst_l = sci_l;
1277054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1278054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1279054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dst_r > sci_r) {
1280054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rightCutRatio = (double)(dst_r - sci_r) / (double)dst_w;
1281054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dst_r = sci_r;
1282054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1283054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1284054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dst_t < sci_t) {
1285054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        topCutRatio = (double)(sci_t - dst_t) / (double)dst_h;
1286054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dst_t = sci_t;
1287054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1288054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1289054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dst_b > sci_b) {
1290054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bottomCutRatio = (double)(dst_b - sci_b) / (double)dst_h;
1291054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dst_b = sci_b;
1292054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1293054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1294054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    calc_cut(leftCutRatio, topCutRatio, rightCutRatio, bottomCutRatio, orient);
1295054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    crop_l += (int)round((double)crop_w * leftCutRatio);
1296054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    crop_t += (int)round((double)crop_h * topCutRatio);
1297054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    crop_r -= (int)round((double)crop_w * rightCutRatio);
1298054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    crop_b -= (int)round((double)crop_h * bottomCutRatio);
1299054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1300054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1301054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool areLayersIntersecting(const hwc_layer_1_t* layer1,
1302054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const hwc_layer_1_t* layer2) {
1303054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t irect = getIntersection(layer1->displayFrame,
1304054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layer2->displayFrame);
1305054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return isValidRect(irect);
1306054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1307054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1308054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isSameRect(const hwc_rect& rect1, const hwc_rect& rect2)
1309054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
1310054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   return ((rect1.left == rect2.left) && (rect1.top == rect2.top) &&
1311054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           (rect1.right == rect2.right) && (rect1.bottom == rect2.bottom));
1312054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1313054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1314054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isValidRect(const hwc_rect& rect)
1315054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
1316054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   return ((rect.bottom > rect.top) && (rect.right > rect.left)) ;
1317054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1318054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1319054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool operator ==(const hwc_rect_t& lhs, const hwc_rect_t& rhs) {
1320054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(lhs.left == rhs.left && lhs.top == rhs.top &&
1321054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       lhs.right == rhs.right &&  lhs.bottom == rhs.bottom )
1322054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin          return true ;
1323054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
1324054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1325054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
132672aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.Rbool layerUpdating(const hwc_layer_1_t* layer) {
132772aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R    hwc_region_t surfDamage = layer->surfaceDamage;
132872aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R    return ((surfDamage.numRects == 0) ||
132972aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R            isValidRect(layer->surfaceDamage.rects[0]));
133072aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R}
133172aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R
1332054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinhwc_rect_t moveRect(const hwc_rect_t& rect, const int& x_off, const int& y_off)
1333054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
1334054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t res;
1335054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1336054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isValidRect(rect))
1337054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return (hwc_rect_t){0, 0, 0, 0};
1338054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1339054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    res.left = rect.left + x_off;
1340054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    res.top = rect.top + y_off;
1341054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    res.right = rect.right + x_off;
1342054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    res.bottom = rect.bottom + y_off;
1343054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1344054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return res;
1345054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1346054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1347054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* computes the intersection of two rects */
1348054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinhwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2)
1349054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
1350054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   hwc_rect_t res;
1351054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1352054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(!isValidRect(rect1) || !isValidRect(rect2)){
1353054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      return (hwc_rect_t){0, 0, 0, 0};
1354054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
1355054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1356054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1357054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   res.left = max(rect1.left, rect2.left);
1358054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   res.top = max(rect1.top, rect2.top);
1359054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   res.right = min(rect1.right, rect2.right);
1360054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   res.bottom = min(rect1.bottom, rect2.bottom);
1361054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1362054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(!isValidRect(res))
1363054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      return (hwc_rect_t){0, 0, 0, 0};
1364054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1365054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   return res;
1366054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1367054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1368054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* computes the union of two rects */
1369054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinhwc_rect_t getUnion(const hwc_rect &rect1, const hwc_rect &rect2)
1370054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
1371054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   hwc_rect_t res;
1372054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1373054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(!isValidRect(rect1)){
1374054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      return rect2;
1375054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
1376054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1377054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(!isValidRect(rect2)){
1378054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      return rect1;
1379054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
1380054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1381054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   res.left = min(rect1.left, rect2.left);
1382054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   res.top = min(rect1.top, rect2.top);
1383054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   res.right =  max(rect1.right, rect2.right);
1384054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   res.bottom =  max(rect1.bottom, rect2.bottom);
1385054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1386054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   return res;
1387054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1388054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1389054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results
1390054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * a single rect */
1391054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinhwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
1392054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1393054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   hwc_rect_t res = rect1;
1394054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1395054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
1396054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      if((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom))
1397054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         res.top = rect2.bottom;
1398054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      else if((rect1.bottom == rect2.bottom)&& (rect2.top >= rect1.top))
1399054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         res.bottom = rect2.top;
1400054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
1401054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   else if((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
1402054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      if((rect1.left == rect2.left) && (rect2.right <= rect1.right))
1403054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         res.left = rect2.right;
1404054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      else if((rect1.right == rect2.right)&& (rect2.left >= rect1.left))
1405054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         res.right = rect2.left;
1406054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
1407054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   return res;
1408054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1409054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1410054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid optimizeLayerRects(const hwc_display_contents_1_t *list) {
1411054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int i= (int)list->numHwLayers-2;
1412054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    while(i > 0) {
1413054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //see if there is no blending required.
1414054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //If it is opaque see if we can substract this region from below
1415054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //layers.
1416054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(list->hwLayers[i].blending == HWC_BLENDING_NONE &&
1417054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                list->hwLayers[i].planeAlpha == 0xFF) {
1418054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int j= i-1;
1419054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_rect_t& topframe =
1420054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (hwc_rect_t&)list->hwLayers[i].displayFrame;
1421054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            while(j >= 0) {
1422054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               if(!needsScaling(&list->hwLayers[j])) {
1423054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  hwc_layer_1_t* layer = (hwc_layer_1_t*)&list->hwLayers[j];
1424054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  hwc_rect_t& bottomframe = layer->displayFrame;
1425054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  hwc_rect_t bottomCrop =
1426054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                      integerizeSourceCrop(layer->sourceCropf);
1427054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  int transform = (layer->flags & HWC_COLOR_FILL) ? 0 :
1428054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                      layer->transform;
1429054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1430054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  hwc_rect_t irect = getIntersection(bottomframe, topframe);
1431054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  if(isValidRect(irect)) {
1432054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     hwc_rect_t dest_rect;
1433054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     //if intersection is valid rect, deduct it
1434054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     dest_rect  = deductRect(bottomframe, irect);
1435054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     qhwc::calculate_crop_rects(bottomCrop, bottomframe,
1436054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                                dest_rect, transform);
1437054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     //Update layer sourceCropf
1438054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     layer->sourceCropf.left =(float)bottomCrop.left;
1439054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     layer->sourceCropf.top = (float)bottomCrop.top;
1440054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     layer->sourceCropf.right = (float)bottomCrop.right;
1441054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     layer->sourceCropf.bottom = (float)bottomCrop.bottom;
1442054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef QCOM_BSP
1443054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     //Update layer dirtyRect
1444054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     layer->dirtyRect = getIntersection(bottomCrop,
1445054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                            layer->dirtyRect);
1446054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
1447054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  }
1448054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               }
1449054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               j--;
1450054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1451054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1452054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        i--;
1453054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1454054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1455054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1456054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid getNonWormholeRegion(hwc_display_contents_1_t* list,
1457054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                              hwc_rect_t& nwr)
1458054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
1459054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    size_t last = list->numHwLayers - 1;
1460054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t fbDisplayFrame = list->hwLayers[last].displayFrame;
1461054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Initiliaze nwr to first frame
1462054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    nwr.left =  list->hwLayers[0].displayFrame.left;
1463054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    nwr.top =  list->hwLayers[0].displayFrame.top;
1464054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    nwr.right =  list->hwLayers[0].displayFrame.right;
1465054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    nwr.bottom =  list->hwLayers[0].displayFrame.bottom;
1466054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1467054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (size_t i = 1; i < last; i++) {
1468054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
1469054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        nwr = getUnion(nwr, displayFrame);
1470054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1471054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1472054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Intersect with the framebuffer
1473054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    nwr = getIntersection(nwr, fbDisplayFrame);
1474054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1475054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1476054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isExternalActive(hwc_context_t* ctx) {
1477054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive;
1478054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1479054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1480054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid closeAcquireFds(hwc_display_contents_1_t* list) {
1481054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(LIKELY(list)) {
1482054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        for(uint32_t i = 0; i < list->numHwLayers; i++) {
1483054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //Close the acquireFenceFds
1484054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //HWC_FRAMEBUFFER are -1 already by SF, rest we close.
1485054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(list->hwLayers[i].acquireFenceFd >= 0) {
1486054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                close(list->hwLayers[i].acquireFenceFd);
1487054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                list->hwLayers[i].acquireFenceFd = -1;
1488054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1489054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1490054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Writeback
1491054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(list->outbufAcquireFenceFd >= 0) {
1492054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            close(list->outbufAcquireFenceFd);
1493054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            list->outbufAcquireFenceFd = -1;
1494054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1495054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1496054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1497054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1498054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
1499054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int fd) {
1500054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ATRACE_CALL();
1501054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int ret = 0;
1502054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int acquireFd[MAX_NUM_APP_LAYERS];
1503054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int count = 0;
1504054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int releaseFd = -1;
1505054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int retireFd = -1;
1506054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fbFd = -1;
1507054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool swapzero = false;
1508054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1509054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct mdp_buf_sync data;
1510054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&data, 0, sizeof(data));
1511054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    data.acq_fen_fd = acquireFd;
1512054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    data.rel_fen_fd = &releaseFd;
1513054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    data.retire_fen_fd = &retireFd;
1514054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    data.flags = MDP_BUF_SYNC_FLAG_RETIRE_FENCE;
1515054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
15165936d78c2a15671de2a803e3beffdcb5079041b3Alex Naidis#ifdef DEBUG_SWAPINTERVAL
1517054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char property[PROPERTY_VALUE_MAX];
1518054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(property_get("debug.egl.swapinterval", property, "1") > 0) {
1519054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(atoi(property) == 0)
1520054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            swapzero = true;
1521054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
15225936d78c2a15671de2a803e3beffdcb5079041b3Alex Naidis#endif
1523054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1524054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool isExtAnimating = false;
1525054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dpy)
1526054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       isExtAnimating = ctx->listStats[dpy].isDisplayAnimating;
1527054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1528054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Send acquireFenceFds to rotator
1529054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(uint32_t i = 0; i < ctx->mLayerRotMap[dpy]->getCount(); i++) {
1530054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int rotFd = ctx->mRotMgr->getRotDevFd();
1531054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int rotReleaseFd = -1;
1532054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        overlay::Rotator* currRot = ctx->mLayerRotMap[dpy]->getRot(i);
1533054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* currLayer = ctx->mLayerRotMap[dpy]->getLayer(i);
1534054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((currRot == NULL) || (currLayer == NULL)) {
1535054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
1536054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1537054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        struct mdp_buf_sync rotData;
1538054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        memset(&rotData, 0, sizeof(rotData));
1539054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rotData.acq_fen_fd =
1540054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                &currLayer->acquireFenceFd;
1541054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rotData.rel_fen_fd = &rotReleaseFd; //driver to populate this
1542054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rotData.session_id = currRot->getSessId();
1543054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(currLayer->acquireFenceFd >= 0) {
1544054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            rotData.acq_fen_fd_cnt = 1; //1 ioctl call per rot session
1545054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1546054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int ret = 0;
1547054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(LIKELY(!swapzero) and (not ctx->mLayerRotMap[dpy]->isRotCached(i)))
1548054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ret = ioctl(rotFd, MSMFB_BUFFER_SYNC, &rotData);
1549054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1550054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ret < 0) {
1551054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed for rot sync, err=%s",
1552054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    __FUNCTION__, strerror(errno));
1553054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            close(rotReleaseFd);
1554054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
1555054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            close(currLayer->acquireFenceFd);
1556054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //For MDP to wait on.
1557054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            currLayer->acquireFenceFd =
1558054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    dup(rotReleaseFd);
1559054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //A buffer is free to be used by producer as soon as its copied to
1560054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //rotator
1561054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            currLayer->releaseFenceFd =
1562054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    rotReleaseFd;
1563054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1564054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1565054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1566054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Accumulate acquireFenceFds for MDP Overlays
1567054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(list->outbufAcquireFenceFd >= 0) {
1568054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Writeback output buffer
1569054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(LIKELY(!swapzero) )
1570054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            acquireFd[count++] = list->outbufAcquireFenceFd;
1571054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1572054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1573054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(uint32_t i = 0; i < list->numHwLayers; i++) {
1574054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(((isAbcInUse(ctx)== true ) ||
1575054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin          (list->hwLayers[i].compositionType == HWC_OVERLAY)) &&
1576054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        list->hwLayers[i].acquireFenceFd >= 0) {
1577054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(LIKELY(!swapzero) ) {
1578054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // if ABC is enabled for more than one layer.
1579054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // renderBufIndexforABC will work as FB.Hence
1580054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // set the acquireFD from fd - which is coming from copybit
1581054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(fd >= 0 && (isAbcInUse(ctx) == true)) {
1582054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    if(ctx->listStats[dpy].renderBufIndexforABC ==(int32_t)i)
1583054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        acquireFd[count++] = fd;
1584054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    else
1585054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        continue;
1586054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                } else
1587054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
1588054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1589054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1590054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
1591054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(LIKELY(!swapzero) ) {
1592054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(fd >= 0) {
1593054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    //set the acquireFD from fd - which is coming from c2d
1594054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    acquireFd[count++] = fd;
1595054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    // Buffer sync IOCTL should be async when using c2d fence is
1596054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    // used
1597054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
1598054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                } else if(list->hwLayers[i].acquireFenceFd >= 0)
1599054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
1600054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1601054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1602054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1603054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1604054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if ((fd >= 0) && !dpy && ctx->mPtorInfo.isActive()) {
1605054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Acquire c2d fence of Overlap render buffer
1606054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(LIKELY(!swapzero) )
1607054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            acquireFd[count++] = fd;
1608054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1609054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1610054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    data.acq_fen_fd_cnt = count;
1611054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    fbFd = ctx->dpyAttr[dpy].fd;
1612054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1613054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Waits for acquire fences, returns a release fence
1614054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(LIKELY(!swapzero)) {
1615054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
1616054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1617054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1618054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ret < 0) {
1619054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed, err=%s",
1620054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  __FUNCTION__, strerror(errno));
1621054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: acq_fen_fd_cnt=%d flags=%d fd=%d dpy=%d numHwLayers=%zu",
1622054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin              __FUNCTION__, data.acq_fen_fd_cnt, data.flags, fbFd,
1623054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin              dpy, list->numHwLayers);
1624054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(releaseFd);
1625054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        releaseFd = -1;
1626054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(retireFd);
1627054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        retireFd = -1;
1628054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1629054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1630054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(uint32_t i = 0; i < list->numHwLayers; i++) {
1631054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
1632054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef QCOM_BSP
1633054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           list->hwLayers[i].compositionType == HWC_BLIT ||
1634054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
1635054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
1636054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //Populate releaseFenceFds.
1637054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(UNLIKELY(swapzero)) {
1638054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                list->hwLayers[i].releaseFenceFd = -1;
1639054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            } else if(isExtAnimating) {
1640054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // Release all the app layer fds immediately,
1641054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // if animation is in progress.
1642054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                list->hwLayers[i].releaseFenceFd = -1;
1643054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            } else if(list->hwLayers[i].releaseFenceFd < 0 ) {
1644054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef QCOM_BSP
1645054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                //If rotator has not already populated this field
1646054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // & if it's a not VPU layer
1647054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1648054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // if ABC is enabled for more than one layer
1649054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(fd >= 0 && (isAbcInUse(ctx) == true) &&
1650054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  ctx->listStats[dpy].renderBufIndexforABC !=(int32_t)i){
1651054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    list->hwLayers[i].releaseFenceFd = dup(fd);
1652054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                } else if((list->hwLayers[i].compositionType == HWC_BLIT)&&
1653054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                               (isAbcInUse(ctx) == false)){
1654054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    //For Blit, the app layers should be released when the Blit
1655054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    //is complete. This fd was passed from copybit->draw
1656054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    list->hwLayers[i].releaseFenceFd = dup(fd);
1657054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                } else
1658054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
1659054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                {
1660054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    list->hwLayers[i].releaseFenceFd = dup(releaseFd);
1661054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1662054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1663054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1664054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1665054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1666054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(fd >= 0) {
1667054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(fd);
1668054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        fd = -1;
1669054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1670054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1671054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ctx->mCopyBit[dpy]) {
1672054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (!dpy && ctx->mPtorInfo.isActive())
1673054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mCopyBit[dpy]->setReleaseFdSync(releaseFd);
1674054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        else
1675054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
1676054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1677054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1678054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Signals when MDP finishes reading rotator buffers.
1679054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mLayerRotMap[dpy]->setReleaseFd(releaseFd);
1680054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    close(releaseFd);
1681054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    releaseFd = -1;
1682054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1683054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(UNLIKELY(swapzero)) {
1684054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        list->retireFenceFd = -1;
1685054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
1686054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        list->retireFenceFd = retireFd;
1687054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1688054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return ret;
1689054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1690054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1691054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
1692054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::eMdpFlags &mdpFlags,
1693054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int rotDownscale, int transform) {
1694054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
1695054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MetaData_t *metadata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
1696054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1697054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(layer->blending == HWC_BLENDING_PREMULT) {
1698054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags,
1699054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::OV_MDP_BLEND_FG_PREMULT);
1700054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1701054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1702054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
1703054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            metadata->interlaced) {
1704054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags,
1705054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::OV_MDP_DEINTERLACE);
1706054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1707054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1708054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Mark MDP flags with SECURE_OVERLAY_SESSION for driver
1709054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isSecureBuffer(hnd)) {
1710054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags,
1711054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
1712054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags,
1713054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::OV_MDP_SMP_FORCE_ALLOC);
1714054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1715054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1716054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isProtectedBuffer(hnd)) {
1717054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags,
1718054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::OV_MDP_SMP_FORCE_ALLOC);
1719054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1720054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1721054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isSecureDisplayBuffer(hnd)) {
1722054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Mark MDP flags with SECURE_DISPLAY_OVERLAY_SESSION for driver
1723054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags,
1724054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                             ovutils::OV_MDP_SECURE_DISPLAY_OVERLAY_SESSION);
1725054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1726054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1727054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Pre-rotation will be used using rotator.
1728054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1729054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags,
1730054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::OV_MDP_SOURCE_ROTATED_90);
1731054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1732054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //No 90 component and no rot-downscale then flips done by MDP
1733054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If we use rot then it might as well do flips
1734054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!(transform & HWC_TRANSFORM_ROT_90) && !rotDownscale) {
1735054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(transform & HWC_TRANSFORM_FLIP_H) {
1736054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
1737054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1738054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1739054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(transform & HWC_TRANSFORM_FLIP_V) {
1740054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::setMdpFlags(mdpFlags,  ovutils::OV_MDP_FLIP_V);
1741054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1742054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1743054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1744054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(metadata &&
1745054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ((metadata->operation & PP_PARAM_HSIC)
1746054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        || (metadata->operation & PP_PARAM_IGC)
1747054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        || (metadata->operation & PP_PARAM_SHARP2))) {
1748054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_PP_EN);
1749054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1750054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1751054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1752054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint configRotator(Rotator *rot, Whf& whf,
1753054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t& crop, const eMdpFlags& mdpFlags,
1754054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const eTransform& orient, const int& downscale) {
1755054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1756054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Fix alignments for TILED format
1757054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
1758054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            whf.format == MDP_Y_CBCR_H2V2_TILE) {
1759054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        whf.w =  utils::alignup(whf.w, 64);
1760054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        whf.h = utils::alignup(whf.h, 32);
1761054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1762054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    rot->setSource(whf);
1763054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1764054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
1765054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qdutils::MDSS_V5) {
1766054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         Dim rotCrop(crop.left, crop.top, crop.right - crop.left,
1767054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                crop.bottom - crop.top);
1768054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rot->setCrop(rotCrop);
1769054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1770054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1771054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    rot->setFlags(mdpFlags);
1772054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    rot->setTransform(orient);
1773054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    rot->setDownscale(downscale);
1774054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!rot->commit()) return -1;
1775054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
1776054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1777054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1778054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint configMdp(Overlay *ov, const PipeArgs& parg,
1779054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const eTransform& orient, const hwc_rect_t& crop,
1780054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const hwc_rect_t& pos, const MetaData_t *metadata,
1781054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const eDest& dest) {
1782054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ov->setSource(parg, dest);
1783054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ov->setTransform(orient, dest);
1784054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1785054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int crop_w = crop.right - crop.left;
1786054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int crop_h = crop.bottom - crop.top;
1787054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Dim dcrop(crop.left, crop.top, crop_w, crop_h);
1788054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ov->setCrop(dcrop, dest);
1789054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1790054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int posW = pos.right - pos.left;
1791054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int posH = pos.bottom - pos.top;
1792054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Dim position(pos.left, pos.top, posW, posH);
1793054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ov->setPosition(position, dest);
1794054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1795054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (metadata)
1796054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ov->setVisualParams(*metadata, dest);
1797054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1798054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (!ov->commit(dest)) {
1799054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
1800054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1801054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
1802054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1803054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1804054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer,
1805054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
1806054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const eDest& dest) {
1807054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1808054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
1809054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    trimLayer(ctx, dpy, 0, dst, dst);
1810054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1811054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int w = ctx->dpyAttr[dpy].xres;
1812054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int h = ctx->dpyAttr[dpy].yres;
1813054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_w = dst.right - dst.left;
1814054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_h = dst.bottom - dst.top;
1815054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t color = layer->transform;
1816054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888));
1817054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1818054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SOLID_FILL);
1819054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (layer->blending == HWC_BLENDING_PREMULT)
1820054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_BLEND_FG_PREMULT);
1821054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1822054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    PipeArgs parg(mdpFlags, whf, z, static_cast<eRotFlags>(0),
1823054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  layer->planeAlpha,
1824054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  (ovutils::eBlending) getBlending(layer->blending));
1825054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1826054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Configure MDP pipe for Color layer
1827054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Dim pos(dst.left, dst.top, dst_w, dst_h);
1828054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mOverlay->setSource(parg, dest);
1829054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mOverlay->setColor(color, dest);
1830054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mOverlay->setTransform(0, dest);
1831054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mOverlay->setCrop(pos, dest);
1832054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mOverlay->setPosition(pos, dest);
1833054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1834054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (!ctx->mOverlay->commit(dest)) {
1835054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Configure color layer failed!", __FUNCTION__);
1836054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
1837054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1838054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
1839054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1840054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1841054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid updateSource(eTransform& orient, Whf& whf,
1842054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t& crop, Rotator *rot) {
1843054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Dim transformedCrop(crop.left, crop.top,
1844054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.right - crop.left,
1845054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.bottom - crop.top);
1846054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
1847054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qdutils::MDSS_V5) {
1848054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //B-family rotator internally could modify destination dimensions if
1849054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //downscaling is supported
1850054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        whf = rot->getDstWhf();
1851054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        transformedCrop = rot->getDstDimensions();
1852054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
1853054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //A-family rotator rotates entire buffer irrespective of crop, forcing
1854054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //us to recompute the crop based on transform
1855054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
1856054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        preRotateSource(orient, whf, transformedCrop);
1857054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1858054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1859054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    crop.left = transformedCrop.x;
1860054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    crop.top = transformedCrop.y;
1861054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    crop.right = transformedCrop.x + transformedCrop.w;
1862054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    crop.bottom = transformedCrop.y + transformedCrop.h;
1863054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1864054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1865054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint getRotDownscale(hwc_context_t *ctx, const hwc_layer_1_t *layer) {
1866054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(not qdutils::MDPVersion::getInstance().isRotDownscaleEnabled()) {
1867054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return 0;
1868054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1869054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1870054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int downscale = 0;
1871054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
1872054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
1873054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
1874054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1875054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(not hnd) {
1876054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return 0;
1877054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1878054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1879054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
1880054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool isInterlaced = metadata && (metadata->operation & PP_PARAM_INTERLACED)
1881054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                && metadata->interlaced;
1882054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int transform = layer->transform;
1883054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
1884054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1885054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isYuvBuffer(hnd)) {
1886054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->mMDP.version >= qdutils::MDP_V4_2 &&
1887054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->mMDP.version < qdutils::MDSS_V5) {
1888054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            downscale = Rotator::getDownscaleFactor(crop.right - crop.left,
1889054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    crop.bottom - crop.top, dst.right - dst.left,
1890054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    dst.bottom - dst.top, format, isInterlaced);
1891054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
1892054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            Dim adjCrop(crop.left, crop.top, crop.right - crop.left,
1893054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    crop.bottom - crop.top);
1894054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            Dim pos(dst.left, dst.top, dst.right - dst.left,
1895054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    dst.bottom - dst.top);
1896054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(transform & HAL_TRANSFORM_ROT_90) {
1897054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                swap(adjCrop.w, adjCrop.h);
1898054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1899054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            downscale = Rotator::getDownscaleFactor(adjCrop.w, adjCrop.h, pos.w,
1900054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    pos.h, format, isInterlaced);
1901054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1902054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1903054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return downscale;
1904054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1905054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1906054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isZoomModeEnabled(hwc_rect_t crop) {
1907054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // This does not work for zooming in top left corner of the image
1908054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return(crop.top > 0 || crop.left > 0);
1909054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1910054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1911054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy) {
1912054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Source crop [%d %d %d %d]", dpy,
1913054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             crop.left, crop.top, crop.right, crop.bottom);
1914054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isZoomModeEnabled(crop)) {
1915054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        Dim srcCrop(crop.left, crop.top,
1916054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                crop.right - crop.left,
1917054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                crop.bottom - crop.top);
1918054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int extW = ctx->dpyAttr[dpy].xres;
1919054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int extH = ctx->dpyAttr[dpy].yres;
1920054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Crop the original video in order to fit external display aspect ratio
1921054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(srcCrop.w * extH < extW * srcCrop.h) {
1922054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int offset = (srcCrop.h - ((srcCrop.w * extH) / extW)) / 2;
1923054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.top += offset;
1924054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.bottom -= offset;
1925054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
1926054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int offset = (srcCrop.w - ((extW * srcCrop.h) / extH)) / 2;
1927054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.left += offset;
1928054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.right -= offset;
1929054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1930054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
1931054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 " source crop [%d %d %d %d]", extW, extH, dpy,
1932054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 crop.left, crop.top, crop.right, crop.bottom);
1933054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1934054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1935054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1936054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t crop,
1937054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                           hwc_rect_t& dst, int dpy) {
1938054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Destination position [%d %d %d %d]", dpy,
1939054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             dst.left, dst.top, dst.right, dst.bottom);
1940054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Dim srcCrop(crop.left, crop.top,
1941054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.right - crop.left,
1942054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.bottom - crop.top);
1943054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int extW = ctx->dpyAttr[dpy].xres;
1944054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int extH = ctx->dpyAttr[dpy].yres;
1945054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Set the destination coordinates of external display to full screen,
1946054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // when zoom in mode is enabled or the ratio between video aspect ratio
1947054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // and external display aspect ratio is below the minimum tolerance level
1948054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // and above maximum tolerance level
1949054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float videoAspectRatio = ((float)srcCrop.w / (float)srcCrop.h);
1950054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float extDisplayAspectRatio = ((float)extW / (float)extH);
1951054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float videoToExternalRatio = videoAspectRatio / extDisplayAspectRatio;
1952054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((fabs(1.0f - videoToExternalRatio) <= ctx->mAspectRatioToleranceLevel) ||
1953054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (isZoomModeEnabled(crop))) {
1954054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dst.left = 0;
1955054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dst.top = 0;
1956054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dst.right = extW;
1957054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dst.bottom = extH;
1958054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1959054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
1960054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             " Destination position [%d %d %d %d] Source crop [%d %d %d %d]",
1961054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             extW, extH, dpy, dst.left, dst.top, dst.right, dst.bottom,
1962054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             crop.left, crop.top, crop.right, crop.bottom);
1963054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1964054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1965054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
1966054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                           hwc_rect_t& dst, int dpy) {
1967054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateCropAIVVideoMode(ctx, crop, dpy);
1968054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateDestAIVVideoMode(ctx, crop, dst, dpy);
1969054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1970054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1971054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
1972054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
1973054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const eDest& dest, Rotator **rot) {
1974054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1975054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
1976054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1977054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!hnd) {
1978054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (layer->flags & HWC_COLOR_FILL) {
1979054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // Configure Color layer
1980054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return configColorLayer(ctx, layer, dpy, mdpFlags, z, dest);
1981054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1982054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: layer handle is NULL", __FUNCTION__);
1983054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
1984054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1985054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1986054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
1987054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1988054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
1989054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
1990054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int transform = layer->transform;
1991054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eTransform orient = static_cast<eTransform>(transform);
1992054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int rotFlags = ovutils::ROT_FLAGS_NONE;
1993054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
1994054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
1995054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1996054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Handle R/B swap
1997054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (layer->flags & HWC_FORMAT_RB_SWAP) {
1998054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
1999054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2000054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2001054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2002054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2003054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // update source crop and destination position of AIV video layer.
2004054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2005054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        updateCoordinates(ctx, crop, dst, dpy);
2006054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2007054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
2008054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int downscale = getRotDownscale(ctx, layer);
2009054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
2010054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2011054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //if 90 component or downscale, use rot
2012054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
2013054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        *rot = ctx->mRotMgr->getNext();
2014054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(*rot == NULL) return -1;
2015054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mLayerRotMap[dpy]->add(layer, *rot);
2016054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        BwcPM::setBwc(ctx, dpy, hnd, crop, dst, transform, downscale,
2017054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mdpFlags);
2018054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Configure rotator for pre-rotation
2019054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
2020054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: configRotator failed!", __FUNCTION__);
2021054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2022054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2023054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        updateSource(orient, whf, crop, *rot);
2024054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rotFlags |= ROT_PREROTATED;
2025054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2026054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2027054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //For the mdp, since either we are pre-rotating or MDP does flips
2028054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    orient = OVERLAY_TRANSFORM_0;
2029054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    transform = 0;
2030054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    PipeArgs parg(mdpFlags, whf, z,
2031054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2032054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  (ovutils::eBlending) getBlending(layer->blending));
2033054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2034054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) {
2035054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: commit failed for low res panel", __FUNCTION__);
2036054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
2037054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2038054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
2039054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2040054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2041054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//Helper to 1) Ensure crops dont have gaps 2) Ensure L and W are even
2042054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
2043054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd) {
2044054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(cropL.right - cropL.left) {
2045054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isYuvBuffer(hnd)) {
2046054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //Always safe to even down left
2047054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::even_floor(cropL.left);
2048054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //If right is even, automatically width is even, since left is
2049054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //already even
2050054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::even_floor(cropL.right);
2051054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2052054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Make sure there are no gaps between left and right splits if the layer
2053054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //is spread across BOTH halves
2054054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(cropR.right - cropR.left) {
2055054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            cropR.left = cropL.right;
2056054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2057054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2058054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2059054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(cropR.right - cropR.left) {
2060054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isYuvBuffer(hnd)) {
2061054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //Always safe to even down left
2062054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::even_floor(cropR.left);
2063054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //If right is even, automatically width is even, since left is
2064054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //already even
2065054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::even_floor(cropR.right);
2066054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2067054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2068054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2069054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2070054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
2071054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
2072054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const eDest& lDest, const eDest& rDest,
2073054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        Rotator **rot) {
2074054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
2075054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!hnd) {
2076054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: layer handle is NULL", __FUNCTION__);
2077054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
2078054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2079054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2080054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2081054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2082054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int hw_w = ctx->dpyAttr[dpy].xres;
2083054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int hw_h = ctx->dpyAttr[dpy].yres;
2084054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2085054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
2086054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int transform = layer->transform;
2087054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eTransform orient = static_cast<eTransform>(transform);
2088054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int rotFlags = ROT_FLAGS_NONE;
2089054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
2090054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
2091054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2092054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Handle R/B swap
2093054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (layer->flags & HWC_FORMAT_RB_SWAP) {
2094054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2095054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2096054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2097054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2098054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2099054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2100054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // update source crop and destination position of AIV video layer.
2101054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2102054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        updateCoordinates(ctx, crop, dst, dpy);
2103054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2104054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2105054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Calculate the external display position based on MDP downscale,
2106054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       ActionSafe, and extorientation features. */
2107054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
2108054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int downscale = getRotDownscale(ctx, layer);
2109054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    setMdpFlags(ctx, layer, mdpFlagsL, downscale, transform);
2110054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2111054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(lDest != OV_INVALID && rDest != OV_INVALID) {
2112054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Enable overfetch
2113054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        setMdpFlags(mdpFlagsL, OV_MDSS_MDP_DUAL_PIPE);
2114054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2115054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2116054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Will do something only if feature enabled and conditions suitable
2117054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //hollow call otherwise
2118054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mAD->prepare(ctx, crop, whf, hnd)) {
2119054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        overlay::Writeback *wb = overlay::Writeback::getInstance();
2120054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        whf.format = wb->getOutputFormat();
2121054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2122054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2123054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
2124054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (*rot) = ctx->mRotMgr->getNext();
2125054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((*rot) == NULL) return -1;
2126054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mLayerRotMap[dpy]->add(layer, *rot);
2127054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Configure rotator for pre-rotation
2128054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
2129054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: configRotator failed!", __FUNCTION__);
2130054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2131054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2132054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        updateSource(orient, whf, crop, *rot);
2133054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rotFlags |= ROT_PREROTATED;
2134054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2135054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2136054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eMdpFlags mdpFlagsR = mdpFlagsL;
2137054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    setMdpFlags(mdpFlagsR, OV_MDSS_MDP_RIGHT_MIXER);
2138054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2139054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t tmp_cropL = {0}, tmp_dstL = {0};
2140054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t tmp_cropR = {0}, tmp_dstR = {0};
2141054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2142054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int lSplit = getLeftSplit(ctx, dpy);
2143054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2144054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Calculate Left rects
2145054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dst.left < lSplit) {
2146054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropL = crop;
2147054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_dstL = dst;
2148054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t scissor = {0, 0, lSplit, hw_h };
2149054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
2150054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
2151054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2152054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2153054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Calculate Right rects
2154054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dst.right > lSplit) {
2155054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropR = crop;
2156054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_dstR = dst;
2157054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t scissor = {lSplit, 0, hw_w, hw_h };
2158054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
2159054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
2160054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2161054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2162054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sanitizeSourceCrop(tmp_cropL, tmp_cropR, hnd);
2163054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2164054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //When buffer is H-flipped, contents of mixer config also needs to swapped
2165054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Not needed if the layer is confined to one half of the screen.
2166054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If rotator has been used then it has also done the flips, so ignore them.
2167054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((orient & OVERLAY_TRANSFORM_FLIP_H) && (dst.left < lSplit) &&
2168054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (dst.right > lSplit) && (*rot) == NULL) {
2169054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t new_cropR;
2170054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        new_cropR.left = tmp_cropL.left;
2171054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);
2172054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2173054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t new_cropL;
2174054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        new_cropL.left  = new_cropR.right;
2175054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        new_cropL.right = tmp_cropR.right;
2176054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2177054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropL.left =  new_cropL.left;
2178054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropL.right =  new_cropL.right;
2179054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2180054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropR.left = new_cropR.left;
2181054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropR.right =  new_cropR.right;
2182054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2183054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2184054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2185054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //For the mdp, since either we are pre-rotating or MDP does flips
2186054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    orient = OVERLAY_TRANSFORM_0;
2187054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    transform = 0;
2188054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2189054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //configure left mixer
2190054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(lDest != OV_INVALID) {
2191054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeArgs pargL(mdpFlagsL, whf, z,
2192054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                       static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2193054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                       (ovutils::eBlending) getBlending(layer->blending));
2194054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2195054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configMdp(ctx->mOverlay, pargL, orient,
2196054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
2197054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2198054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2199054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2200054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2201054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2202054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //configure right mixer
2203054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(rDest != OV_INVALID) {
2204054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeArgs pargR(mdpFlagsR, whf, z,
2205054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                       static_cast<eRotFlags>(rotFlags),
2206054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                       layer->planeAlpha,
2207054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                       (ovutils::eBlending) getBlending(layer->blending));
2208054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_dstR.right = tmp_dstR.right - lSplit;
2209054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_dstR.left = tmp_dstR.left - lSplit;
2210054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configMdp(ctx->mOverlay, pargR, orient,
2211054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
2212054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2213054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2214054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2215054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2216054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2217054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
2218054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2219054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2220054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
2221054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
2222054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const eDest& lDest, const eDest& rDest,
2223054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        Rotator **rot) {
2224054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
2225054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!hnd) {
2226054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: layer handle is NULL", __FUNCTION__);
2227054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
2228054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2229054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2230054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2231054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2232054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);;
2233054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
2234054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int transform = layer->transform;
2235054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eTransform orient = static_cast<eTransform>(transform);
2236054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int downscale = 0;
2237054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int rotFlags = ROT_FLAGS_NONE;
2238054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Splitting only YUV layer on primary panel needs different zorders
2239054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //for both layers as both the layers are configured to single mixer
2240054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eZorder lz = z;
2241054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eZorder rz = (eZorder)(z + 1);
2242054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2243054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Whf whf(getWidth(hnd), getHeight(hnd),
2244054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            getMdpFormat(hnd->format), (uint32_t)hnd->size);
2245054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2246054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // update source crop and destination position of AIV video layer.
2247054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2248054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        updateCoordinates(ctx, crop, dst, dpy);
2249054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2250054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2251054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Calculate the external display position based on MDP downscale,
2252054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       ActionSafe, and extorientation features. */
2253054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
2254054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2255054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    setMdpFlags(ctx, layer, mdpFlagsL, 0, transform);
2256054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    trimLayer(ctx, dpy, transform, crop, dst);
2257054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2258054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
2259054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (*rot) = ctx->mRotMgr->getNext();
2260054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((*rot) == NULL) return -1;
2261054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mLayerRotMap[dpy]->add(layer, *rot);
2262054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Configure rotator for pre-rotation
2263054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
2264054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: configRotator failed!", __FUNCTION__);
2265054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2266054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2267054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        updateSource(orient, whf, crop, *rot);
2268054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rotFlags |= ROT_PREROTATED;
2269054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2270054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2271054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eMdpFlags mdpFlagsR = mdpFlagsL;
2272054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int lSplit = dst.left + (dst.right - dst.left)/2;
2273054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2274054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t tmp_cropL = {0}, tmp_dstL = {0};
2275054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t tmp_cropR = {0}, tmp_dstR = {0};
2276054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2277054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(lDest != OV_INVALID) {
2278054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropL = crop;
2279054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_dstL = dst;
2280054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t scissor = {dst.left, dst.top, lSplit, dst.bottom };
2281054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
2282054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2283054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(rDest != OV_INVALID) {
2284054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropR = crop;
2285054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_dstR = dst;
2286054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t scissor = {lSplit, dst.top, dst.right, dst.bottom };
2287054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
2288054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2289054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2290054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sanitizeSourceCrop(tmp_cropL, tmp_cropR, hnd);
2291054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2292054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //When buffer is H-flipped, contents of mixer config also needs to swapped
2293054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Not needed if the layer is confined to one half of the screen.
2294054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If rotator has been used then it has also done the flips, so ignore them.
2295054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((orient & OVERLAY_TRANSFORM_FLIP_H) && lDest != OV_INVALID
2296054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            && rDest != OV_INVALID && (*rot) == NULL) {
2297054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t new_cropR;
2298054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        new_cropR.left = tmp_cropL.left;
2299054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);
2300054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2301054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t new_cropL;
2302054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        new_cropL.left  = new_cropR.right;
2303054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        new_cropL.right = tmp_cropR.right;
2304054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2305054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropL.left =  new_cropL.left;
2306054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropL.right =  new_cropL.right;
2307054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2308054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropR.left = new_cropR.left;
2309054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        tmp_cropR.right =  new_cropR.right;
2310054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2311054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2312054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2313054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //For the mdp, since either we are pre-rotating or MDP does flips
2314054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    orient = OVERLAY_TRANSFORM_0;
2315054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    transform = 0;
2316054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2317054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //configure left half
2318054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(lDest != OV_INVALID) {
2319054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeArgs pargL(mdpFlagsL, whf, lz,
2320054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2321054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (ovutils::eBlending) getBlending(layer->blending));
2322054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2323054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configMdp(ctx->mOverlay, pargL, orient,
2324054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
2325054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: commit failed for left half config", __FUNCTION__);
2326054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2327054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2328054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2329054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2330054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //configure right half
2331054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(rDest != OV_INVALID) {
2332054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeArgs pargR(mdpFlagsR, whf, rz,
2333054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                static_cast<eRotFlags>(rotFlags),
2334054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                layer->planeAlpha,
2335054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (ovutils::eBlending) getBlending(layer->blending));
2336054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configMdp(ctx->mOverlay, pargR, orient,
2337054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
2338054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: commit failed for right half config", __FUNCTION__);
2339054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2340054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2341054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2342054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2343054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
2344054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2345054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2346054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool canUseRotator(hwc_context_t *ctx, int dpy) {
2347054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mOverlay->isDMAMultiplexingSupported() &&
2348054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            isSecondaryConnected(ctx) &&
2349054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            !ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause) {
2350054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        /* mdss driver on certain targets support multiplexing of DMA pipe
2351054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         * in LINE and BLOCK modes for writeback panels.
2352054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         */
2353054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(dpy == HWC_DISPLAY_PRIMARY)
2354054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
2355054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2356054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((ctx->mMDP.version == qdutils::MDP_V3_0_4)
2357054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin          ||(ctx->mMDP.version == qdutils::MDP_V3_0_5))
2358054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
2359054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
2360054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2361054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2362054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint getLeftSplit(hwc_context_t *ctx, const int& dpy) {
2363054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Default even split for all displays with high res
2364054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int lSplit = ctx->dpyAttr[dpy].xres / 2;
2365054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dpy == HWC_DISPLAY_PRIMARY &&
2366054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qdutils::MDPVersion::getInstance().getLeftSplit()) {
2367054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Override if split published by driver for primary
2368054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        lSplit = qdutils::MDPVersion::getInstance().getLeftSplit();
2369054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2370054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return lSplit;
2371054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2372054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2373054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isDisplaySplit(hwc_context_t* ctx, int dpy) {
2374054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
2375054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->dpyAttr[dpy].xres > mdpHw.getMaxPipeWidth()) {
2376054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
2377054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2378054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //For testing we could split primary via device tree values
2379054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dpy == HWC_DISPLAY_PRIMARY && mdpHw.getRightSplit()) {
2380054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
2381054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2382054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
2383054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2384054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2385054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//clear prev layer prop flags and realloc for current frame
2386054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
2387054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->layerProp[dpy]) {
2388054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       delete[] ctx->layerProp[dpy];
2389054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       ctx->layerProp[dpy] = NULL;
2390054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2391054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->layerProp[dpy] = new LayerProp[numAppLayers];
2392054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2393054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2394054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isAbcInUse(hwc_context_t *ctx){
2395054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin  return (ctx->enableABC && ctx->listStats[0].renderBufIndexforABC == 0);
2396054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2397054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2398054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid dumpBuffer(private_handle_t *ohnd, char *bufferName) {
2399054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ohnd != NULL && ohnd->base) {
2400054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        char dumpFilename[PATH_MAX];
2401054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bool bResult = false;
2402054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int width = getWidth(ohnd);
2403054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int height = getHeight(ohnd);
2404054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int format = ohnd->format;
2405054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //dummy aligned w & h.
2406054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int alW = 0, alH = 0;
2407054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int size = getBufferSizeAndDimensions(width, height, format, alW, alH);
2408054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        snprintf(dumpFilename, sizeof(dumpFilename), "/data/%s.%s.%dx%d.raw",
2409054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            bufferName,
2410054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            overlay::utils::getFormatString(utils::getMdpFormat(format)),
2411054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            width, height);
2412054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        FILE* fp = fopen(dumpFilename, "w+");
2413054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (NULL != fp) {
2414054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            bResult = (bool) fwrite((void*)ohnd->base, size, 1, fp);
2415054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            fclose(fp);
2416054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2417054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD("Buffer[%s] Dump to %s: %s",
2418054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bufferName, dumpFilename, bResult ? "Success" : "Fail");
2419054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2420054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2421054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2422054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isGLESComp(hwc_context_t *ctx,
2423054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     hwc_display_contents_1_t* list) {
2424054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
2425054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0; index < numAppLayers; index++) {
2426054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &(list->hwLayers[index]);
2427054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(layer->compositionType == HWC_FRAMEBUFFER)
2428054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return true;
2429054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2430054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
2431054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2432054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2433054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
2434054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct gpu_hint_info *gpuHint = &ctx->mGPUHintInfo;
2435054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!gpuHint->mGpuPerfModeEnable || !ctx || !list)
2436054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
2437054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2438054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef QCOM_BSP
2439054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Set the GPU hint flag to high for MIXED/GPU composition only for
2440054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       first frame after MDP -> GPU/MIXED mode transition. Set the GPU
2441054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       hint to default if the previous composition is GPU or current GPU
2442054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       composition is due to idle fallback */
2443054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!gpuHint->mEGLDisplay || !gpuHint->mEGLContext) {
2444054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        gpuHint->mEGLDisplay = eglGetCurrentDisplay();
2445054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!gpuHint->mEGLDisplay) {
2446054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGW("%s Warning: EGL current display is NULL", __FUNCTION__);
2447054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return;
2448054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2449054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        gpuHint->mEGLContext = eglGetCurrentContext();
2450054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!gpuHint->mEGLContext) {
2451054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGW("%s Warning: EGL current context is NULL", __FUNCTION__);
2452054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return;
2453054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2454054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2455054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isGLESComp(ctx, list)) {
2456054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(gpuHint->mCompositionState != COMPOSITION_STATE_GPU
2457054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            && !MDPComp::isIdleFallback()) {
2458054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            EGLint attr_list[] = {EGL_GPU_HINT_1,
2459054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                  EGL_GPU_LEVEL_3,
2460054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                  EGL_NONE };
2461054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_3) &&
2462054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
2463054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                    gpuHint->mEGLContext, attr_list)) {
2464054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGW("eglGpuPerfHintQCOM failed for Built in display");
2465054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            } else {
2466054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_3;
2467054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                gpuHint->mCompositionState = COMPOSITION_STATE_GPU;
2468054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2469054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
2470054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            EGLint attr_list[] = {EGL_GPU_HINT_1,
2471054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                  EGL_GPU_LEVEL_0,
2472054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                  EGL_NONE };
2473054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
2474054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
2475054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                    gpuHint->mEGLContext, attr_list)) {
2476054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGW("eglGpuPerfHintQCOM failed for Built in display");
2477054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            } else {
2478054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
2479054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2480054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(MDPComp::isIdleFallback()) {
2481054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                gpuHint->mCompositionState = COMPOSITION_STATE_IDLE_FALLBACK;
2482054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2483054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2484054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
2485054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        /* set the GPU hint flag to default for MDP composition */
2486054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        EGLint attr_list[] = {EGL_GPU_HINT_1,
2487054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                              EGL_GPU_LEVEL_0,
2488054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                              EGL_NONE };
2489054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
2490054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
2491054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                    gpuHint->mEGLContext, attr_list)) {
2492054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGW("eglGpuPerfHintQCOM failed for Built in display");
2493054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
2494054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
2495054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2496054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        gpuHint->mCompositionState = COMPOSITION_STATE_MDP;
2497054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2498054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
2499054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2500054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2501054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool isPeripheral(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
2502054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // To be peripheral, 3 boundaries should match.
2503054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint8_t eqBounds = 0;
2504054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (rect1.left == rect2.left)
2505054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        eqBounds++;
2506054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (rect1.top == rect2.top)
2507054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        eqBounds++;
2508054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (rect1.right == rect2.right)
2509054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        eqBounds++;
2510054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (rect1.bottom == rect2.bottom)
2511054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        eqBounds++;
2512054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return (eqBounds == 3);
2513054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2514054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2515831babe5975a052c87de04db7a6acf006b031380Naseer Ahmedvoid applyDefaultMode(hwc_context_t *ctx) {
2516cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed    char value[PROPERTY_VALUE_MAX];
2517831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed    int boot_finished = 0;
2518831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed    static int ret = ctx->mColorMode->applyDefaultMode();
2519831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed    if(!ret) {
2520831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed        ctx->mDefaultModeApplied = true;
2521831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed        return;
2522831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed    }
2523cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed
2524cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed    // Reading property set on boot finish in SF
2525cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed    property_get("service.bootanim.exit", value, "0");
2526cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed    boot_finished = atoi(value);
2527cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed    if (!boot_finished)
2528cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed        return;
2529cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed
25306109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    ret = ctx->mColorMode->applyDefaultMode();
25316109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if (ret)
25326109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        ALOGD("%s: Not able to apply default mode", __FUNCTION__);
2533831babe5975a052c87de04db7a6acf006b031380Naseer Ahmed    ctx->mDefaultModeApplied = true;
2534cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed}
2535cfacc80f236685f3c3c9f556cf9fae81fbf8a37aNaseer Ahmed
2536054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid BwcPM::setBwc(const hwc_context_t *ctx, const int& dpy,
2537054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const private_handle_t *hnd,
2538054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const hwc_rect_t& crop, const hwc_rect_t& dst,
2539054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int& transform,const int& downscale,
2540054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::eMdpFlags& mdpFlags) {
2541054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Target doesnt support Bwc
2542054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
2543054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(not mdpHw.supportsBWC()) {
2544054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
2545054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2546054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Disabled at runtime
2547054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(not ctx->mBWCEnabled) return;
2548054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //BWC not supported with rot-downscale
2549054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(downscale) return;
2550054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Not enabled for secondary displays
2551054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dpy) return;
2552054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Not enabled for non-video buffers
2553054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(not isYuvBuffer(hnd)) return;
2554054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2555054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int src_w = crop.right - crop.left;
2556054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int src_h = crop.bottom - crop.top;
2557054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_w = dst.right - dst.left;
2558054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_h = dst.bottom - dst.top;
2559054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(transform & HAL_TRANSFORM_ROT_90) {
2560054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        swap(src_w, src_h);
2561054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2562054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //src width > MAX mixer supported dim
2563054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(src_w > (int) qdutils::MDPVersion::getInstance().getMaxPipeWidth()) {
2564054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
2565054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2566a670ba4e8a6fb6c72b285ed54d66be1e965a4eb1Arun Kumar K.R    //H/w requirement for BWC only. Pipe can still support 4096
2567a670ba4e8a6fb6c72b285ed54d66be1e965a4eb1Arun Kumar K.R    if(src_h > 4092) {
2568a670ba4e8a6fb6c72b285ed54d66be1e965a4eb1Arun Kumar K.R        return;
2569a670ba4e8a6fb6c72b285ed54d66be1e965a4eb1Arun Kumar K.R    }
2570054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Decimation necessary, cannot use BWC. H/W requirement.
2571054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(qdutils::MDPVersion::getInstance().supportsDecimation()) {
2572054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        uint8_t horzDeci = 0;
2573054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        uint8_t vertDeci = 0;
2574054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ovutils::getDecimationFactor(src_w, src_h, dst_w, dst_h, horzDeci,
2575054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                vertDeci);
2576054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(horzDeci || vertDeci) return;
2577054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2578054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2579054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDSS_MDP_BWC_EN);
2580054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2581054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2582054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid LayerRotMap::add(hwc_layer_1_t* layer, Rotator *rot) {
2583054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCount >= RotMgr::MAX_ROT_SESS) return;
2584054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mLayer[mCount] = layer;
2585054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mRot[mCount] = rot;
2586054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCount++;
2587054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2588054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2589054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid LayerRotMap::reset() {
2590054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (int i = 0; i < RotMgr::MAX_ROT_SESS; i++) {
2591054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mLayer[i] = 0;
2592054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mRot[i] = 0;
2593054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2594054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCount = 0;
2595054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2596054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2597054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid LayerRotMap::clear() {
2598054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    RotMgr::getInstance()->markUnusedTop(mCount);
2599054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    reset();
2600054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2601054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2602054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool LayerRotMap::isRotCached(uint32_t index) const {
2603054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    overlay::Rotator* rot = getRot(index);
2604054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_layer_1_t* layer =  getLayer(index);
2605054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2606054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(rot and layer and layer->handle) {
2607054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)(layer->handle);
2608054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return (rot->isRotCached(hnd->fd,(uint32_t)(hnd->offset)));
2609054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2610054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
2611054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2612054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2613054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid LayerRotMap::setReleaseFd(const int& fence) {
2614054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(uint32_t i = 0; i < mCount; i++) {
2615054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mRot[i] and mLayer[i] and mLayer[i]->handle) {
2616054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            /* Ensure that none of the above (Rotator-instance,
2617054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             * layer and layer-handle) are NULL*/
2618054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(isRotCached(i))
2619054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mRot[i]->setPrevBufReleaseFd(dup(fence));
2620054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            else
2621054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mRot[i]->setCurrBufReleaseFd(dup(fence));
2622054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2623054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2624054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2625054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
26269f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.Rhwc_rect expandROIFromMidPoint(hwc_rect roi, hwc_rect fullFrame) {
26279f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    int lRoiWidth = 0, rRoiWidth = 0;
26289f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    int half_frame_width = fullFrame.right/2;
26299f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26309f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    hwc_rect lFrame = fullFrame;
26319f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    hwc_rect rFrame = fullFrame;
26329f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    lFrame.right = (lFrame.right - lFrame.left)/2;
26339f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    rFrame.left = lFrame.right;
26349f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26359f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    hwc_rect lRoi = getIntersection(roi, lFrame);
26369f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    hwc_rect rRoi = getIntersection(roi, rFrame);
26379f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26389f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    lRoiWidth = lRoi.right - lRoi.left;
26399f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    rRoiWidth = rRoi.right - rRoi.left;
26409f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26419f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    if(lRoiWidth && rRoiWidth) {
26429f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        if(lRoiWidth < rRoiWidth)
26439f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            roi.left = half_frame_width - rRoiWidth;
26449f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        else
26459f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            roi.right = half_frame_width + lRoiWidth;
26469f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    }
26479f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    return roi;
26489f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R}
26499f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2650054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid resetROI(hwc_context_t *ctx, const int dpy) {
2651054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int fbXRes = (int)ctx->dpyAttr[dpy].xres;
2652054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int fbYRes = (int)ctx->dpyAttr[dpy].yres;
265307bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R
265407bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R    /* When source split is enabled, both the panels are calibrated
265507bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R     * in a single coordinate system. So only one ROI is generated
265607bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R     * for the whole panel extending equally from the midpoint and
265707bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R     * populated for the left side. */
265807bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R    if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
265907bb927c66c474b9f0aff9677f848d3d8d543b8fArun Kumar K.R            isDisplaySplit(ctx, dpy)) {
2660054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int lSplit = getLeftSplit(ctx, dpy);
2661054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->listStats[dpy].lRoi = (struct hwc_rect){0, 0, lSplit, fbYRes};
2662054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->listStats[dpy].rRoi = (struct hwc_rect){lSplit, 0, fbXRes, fbYRes};
2663054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else  {
2664054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->listStats[dpy].lRoi = (struct hwc_rect){0, 0,fbXRes, fbYRes};
2665054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->listStats[dpy].rRoi = (struct hwc_rect){0, 0, 0, 0};
2666054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2667054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2668054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2669054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinhwc_rect_t getSanitizeROI(struct hwc_rect roi, hwc_rect boundary)
2670054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
2671054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(!isValidRect(roi))
2672054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin      return roi;
2673054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2674054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   struct hwc_rect t_roi = roi;
2675054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2676054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   const int LEFT_ALIGN = qdutils::MDPVersion::getInstance().getLeftAlign();
2677054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   const int WIDTH_ALIGN = qdutils::MDPVersion::getInstance().getWidthAlign();
2678054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   const int TOP_ALIGN = qdutils::MDPVersion::getInstance().getTopAlign();
2679054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   const int HEIGHT_ALIGN = qdutils::MDPVersion::getInstance().getHeightAlign();
2680054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   const int MIN_WIDTH = qdutils::MDPVersion::getInstance().getMinROIWidth();
2681054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   const int MIN_HEIGHT = qdutils::MDPVersion::getInstance().getMinROIHeight();
2682054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2683054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   /* Align to minimum width recommended by the panel */
2684054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if((t_roi.right - t_roi.left) < MIN_WIDTH) {
2685c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R       if(MIN_WIDTH == boundary.right - boundary.left) {
2686c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R           t_roi.left = 0;
2687c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R           t_roi.right = MIN_WIDTH;
2688c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R       } else {
2689c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R           if((t_roi.left + MIN_WIDTH) > boundary.right)
2690c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R               t_roi.left = t_roi.right - MIN_WIDTH;
2691c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R           else
2692c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R               t_roi.right = t_roi.left + MIN_WIDTH;
26938982d8b9241f4ac3fd5a35a5016289f25981a729Arun Kumar K.R       }
2694054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
2695054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2696054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin  /* Align to minimum height recommended by the panel */
2697054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if((t_roi.bottom - t_roi.top) < MIN_HEIGHT) {
2698c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R       if(MIN_HEIGHT == boundary.bottom - boundary.top) {
2699c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R           t_roi.top = 0;
2700c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R           t_roi.bottom = MIN_HEIGHT;
2701c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R       } else {
2702c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R           if((t_roi.top + MIN_HEIGHT) > boundary.bottom)
2703c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R               t_roi.top = t_roi.bottom - MIN_HEIGHT;
2704c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R           else
2705c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R               t_roi.bottom = t_roi.top + MIN_HEIGHT;
27068982d8b9241f4ac3fd5a35a5016289f25981a729Arun Kumar K.R       }
2707054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
2708054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2709054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   /* Align left and width to meet panel restrictions */
2710054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(LEFT_ALIGN)
2711054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       t_roi.left = t_roi.left - (t_roi.left % LEFT_ALIGN);
2712054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2713054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(WIDTH_ALIGN) {
2714054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       int width = t_roi.right - t_roi.left;
2715c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R       width = WIDTH_ALIGN * ((width + (WIDTH_ALIGN - 1)) / WIDTH_ALIGN);
2716c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R       t_roi.right = t_roi.left + width;
2717c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R
2718054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       if(t_roi.right > boundary.right) {
2719054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           t_roi.right = boundary.right;
2720054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           t_roi.left = t_roi.right - width;
2721054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2722054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           if(LEFT_ALIGN)
2723054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               t_roi.left = t_roi.left - (t_roi.left % LEFT_ALIGN);
2724054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       }
2725054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
2726054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2727054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   /* Align top and height to meet panel restrictions */
2728054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(TOP_ALIGN)
2729054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       t_roi.top = t_roi.top - (t_roi.top % TOP_ALIGN);
2730054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2731054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   if(HEIGHT_ALIGN) {
2732054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       int height = t_roi.bottom - t_roi.top;
2733c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R       height = HEIGHT_ALIGN *  ((height + (HEIGHT_ALIGN - 1)) / HEIGHT_ALIGN);
2734c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R       t_roi.bottom = t_roi.top  + height;
2735c30c577b5318940126005724c097fd452b903e62Arun Kumar K.R
2736054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       if(t_roi.bottom > boundary.bottom) {
2737054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           t_roi.bottom = boundary.bottom;
2738054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           t_roi.top = t_roi.bottom - height;
2739054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2740054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           if(TOP_ALIGN)
2741054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               t_roi.top = t_roi.top - (t_roi.top % TOP_ALIGN);
2742054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       }
2743054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   }
2744054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2745054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin   return t_roi;
2746054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2747054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2748054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid handle_pause(hwc_context_t* ctx, int dpy) {
2749054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->dpyAttr[dpy].connected) {
2750054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.lock();
2751054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[dpy].isActive = true;
2752054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[dpy].isPause = true;
2753054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.unlock();
2754054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->proc->invalidate(ctx->proc);
2755054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2756054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
2757054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               * 2 / 1000);
2758054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2759054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // At this point all the pipes used by External have been
2760054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // marked as UNSET.
2761054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.lock();
2762054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Perform commit to unstage the pipes.
2763054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
2764054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: display commit fail! for %d dpy",
2765054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  __FUNCTION__, dpy);
2766054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2767054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.unlock();
2768054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->proc->invalidate(ctx->proc);
2769054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2770054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return;
2771054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2772054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2773054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid handle_resume(hwc_context_t* ctx, int dpy) {
2774054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->dpyAttr[dpy].connected) {
2775054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.lock();
2776054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[dpy].isConfiguring = true;
2777054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[dpy].isActive = true;
2778054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.unlock();
2779054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->proc->invalidate(ctx->proc);
2780054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2781054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
2782054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               * 2 / 1000);
2783054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2784054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //At this point external has all the pipes it would need.
2785054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.lock();
2786054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[dpy].isPause = false;
2787054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.unlock();
2788054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->proc->invalidate(ctx->proc);
2789054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2790054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return;
2791054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2792054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2793054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid clearPipeResources(hwc_context_t* ctx, int dpy) {
2794054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mOverlay) {
2795054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mOverlay->configBegin();
2796054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mOverlay->configDone();
2797054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2798054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mRotMgr) {
2799054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mRotMgr->clear();
2800054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2801054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Call a display commit to ensure that pipes and associated
2802054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // fd's are cleaned up.
2803054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
2804054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: display commit failed for  %d", __FUNCTION__, dpy);
2805054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2806054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2807054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2808054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// Handles online events when HDMI is the primary display. In particular,
2809054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// online events for hdmi connected before AND after boot up and HWC init.
2810054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid handle_online(hwc_context_t* ctx, int dpy) {
2811054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //On 8994 due to hardware limitations, we disable bwc completely when HDMI
2812054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //intf is active
2813054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(qdutils::MDPVersion::getInstance().is8994() and
2814054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qdutils::MDPVersion::getInstance().supportsBWC()) {
2815054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mBWCEnabled = false;
2816054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2817054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Close the current fd if it was opened earlier on when HWC
2818054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // was initialized.
2819054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ctx->dpyAttr[dpy].fd >= 0) {
2820054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(ctx->dpyAttr[dpy].fd);
2821054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->dpyAttr[dpy].fd = -1;
2822054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2823054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // TODO: If HDMI is connected after the display has booted up,
2824054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // and the best configuration is different from the default
2825054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // then we need to deal with this appropriately.
2826054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mHDMIDisplay->configure();
2827054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateDisplayInfo(ctx, dpy);
2828054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    initCompositionResources(ctx, dpy);
2829054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].connected = true;
2830054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2831054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2832054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// Handles offline events for HDMI. This can be used for offline events
2833054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// initiated by the HDMI driver and the CEC framework.
2834054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid handle_offline(hwc_context_t* ctx, int dpy) {
2835054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    destroyCompositionResources(ctx, dpy);
2836054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Clear all pipe resources and call a display commit to ensure
2837054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // that all the fd's are closed. This will ensure that the HDMI
2838054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // core turns off and that we receive an event the next time the
2839054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // cable is connected.
2840054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
2841054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        clearPipeResources(ctx, dpy);
2842054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2843054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mHDMIDisplay->teardown();
2844054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    resetDisplayInfo(ctx, dpy);
2845054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].connected = false;
2846054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->dpyAttr[dpy].isActive = false;
2847054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //On 8994 due to hardware limitations, we enable bwc only when HDMI
2848054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //intf is inactive
2849054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(qdutils::MDPVersion::getInstance().is8994() and
2850054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qdutils::MDPVersion::getInstance().supportsBWC()) {
2851054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mBWCEnabled = true;
2852054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2853054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2854054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
28556109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmedvoid ColorMode::init() {
28566109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    //Map symbols from libmm-qdcm and get list of modes
28576109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    mModeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
28586109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if (mModeHandle) {
28596109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        *(void **)& fnApplyDefaultMode = dlsym(mModeHandle, "applyDefaults");
28606109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        *(void **)& fnApplyModeById = dlsym(mModeHandle, "applyModeById");
28616109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        *(void **)& fnGetNumModes = dlsym(mModeHandle, "getNumDisplayModes");
28623bbf145177e8bccb8cf5f817dfd7751a712cfdfaNaseer Ahmed        *(void **)& fnGetCurrentMode = dlsym(mModeHandle, "getCurrentMode");
28636109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        *(void **)& fnGetModeList = dlsym(mModeHandle, "getDisplayModeIdList");
28646109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        *(void **)& fnSetDefaultMode = dlsym(mModeHandle, "setDefaultMode");
2865bc094c7aa4c1ba978c1dd0e228dc5373a184a407Arun Kumar K.R        *(void **)& fnDeleteInstance = dlsym(mModeHandle, "deleteInstance");
28666109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    } else {
28676109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        ALOGW("Unable to load libmm-qdcm");
28686109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
28696109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
28706109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(fnGetNumModes) {
28716109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        mNumModes = fnGetNumModes(HWC_DISPLAY_PRIMARY);
28726109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        if(mNumModes > MAX_NUM_COLOR_MODES) {
28736109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed            ALOGE("Number of modes is above the limit: %d", mNumModes);
28746109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed            mNumModes = 0;
28756109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed            return;
28766109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        }
28776109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        if(fnGetModeList) {
28786109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed            fnGetModeList(mModeList, &mCurMode, HWC_DISPLAY_PRIMARY);
28796109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed            mCurModeIndex = getIndexForMode(mCurMode);
28806109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed            ALOGI("ColorMode: current mode: %d current mode index: %d number of modes: %d",
28816109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed                    mCurMode, mCurModeIndex, mNumModes);
28826109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        }
28836109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
28846109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed}
28856109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
28866109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed//Legacy API
28876109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmedint ColorMode::applyDefaultMode() {
28883bbf145177e8bccb8cf5f817dfd7751a712cfdfaNaseer Ahmed    int ret = 0;
28896109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(fnApplyDefaultMode) {
28903bbf145177e8bccb8cf5f817dfd7751a712cfdfaNaseer Ahmed        ret = fnApplyDefaultMode(HWC_DISPLAY_PRIMARY);
28913bbf145177e8bccb8cf5f817dfd7751a712cfdfaNaseer Ahmed        if(!ret) {
28923bbf145177e8bccb8cf5f817dfd7751a712cfdfaNaseer Ahmed            mCurModeIndex = getIndexForMode(fnGetCurrentMode(HWC_DISPLAY_PRIMARY));
28933bbf145177e8bccb8cf5f817dfd7751a712cfdfaNaseer Ahmed        }
28943bbf145177e8bccb8cf5f817dfd7751a712cfdfaNaseer Ahmed        return ret;
28956109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    } else {
28966109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        return -EINVAL;
28976109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
28986109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed}
28996109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
29006109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmedint ColorMode::applyModeByID(int modeID) {
29016109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(fnApplyModeById) {
29026109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        int ret = fnApplyModeById(modeID, HWC_DISPLAY_PRIMARY);
29036109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        if (!ret)
29046109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed            ret = setDefaultMode(modeID);
29056109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        return ret;
29066109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    } else {
29076109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        return -EINVAL;
29086109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
29096109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed}
29106109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
29116109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed//This API is called from setActiveConfig
29126109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed//The value here must be set as default
29136109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmedint ColorMode::applyModeByIndex(int index) {
29146109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    int ret = 0;
29156109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    int mode  = getModeForIndex(index);
29166109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(mode < 0) {
29176109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        ALOGE("Invalid mode for index: %d", index);
29186109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        return -EINVAL;
29196109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
29206109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    ALOGD("%s: Applying mode index: %d modeID: %d", __FUNCTION__, index, mode);
29216109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    ret = applyModeByID(mode);
29226109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(!ret) {
29236109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        mCurModeIndex = index;
29246109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
29256109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    return ret;
29266109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed}
29276109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
29286109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmedint ColorMode::setDefaultMode(int modeID) {
29296109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(fnSetDefaultMode) {
29306109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        ALOGD("Setting default color mode to %d", modeID);
29316109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        return fnSetDefaultMode(modeID, HWC_DISPLAY_PRIMARY);
29326109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    } else {
29336109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        return -EINVAL;
29346109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
29356109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed}
29366109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
29376109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmedint ColorMode::getModeForIndex(int index) {
29386109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(index < mNumModes) {
29396109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        return mModeList[index];
29406109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    } else {
29416109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        return -EINVAL;
29426109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
29436109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed}
29446109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
29456109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmedint ColorMode::getIndexForMode(int mode) {
29466109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(mModeList) {
29476109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        for(int32_t i = 0; i < mNumModes; i++)
29486109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed            if(mModeList[i] == mode)
29496109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed                return i;
29506109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
29516109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    return -EINVAL;
29526109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed}
29536109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
29546109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmedvoid ColorMode::destroy() {
29556109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    if(mModeHandle) {
2956bc094c7aa4c1ba978c1dd0e228dc5373a184a407Arun Kumar K.R        if (fnDeleteInstance) {
2957bc094c7aa4c1ba978c1dd0e228dc5373a184a407Arun Kumar K.R            fnDeleteInstance();
2958bc094c7aa4c1ba978c1dd0e228dc5373a184a407Arun Kumar K.R        }
29596109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        dlclose(mModeHandle);
29606109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed        mModeHandle = NULL;
29616109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed    }
29626109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed}
29636109f69d576a9692126ebf8c8d6391fd92aa8e5aNaseer Ahmed
2964054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin};//namespace qhwc
2965