1054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/*
2054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
3054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Not a Contribution, Apache license notifications and license are retained
4054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * for attribution purposes only.
5054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *
6054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Licensed under the Apache License, Version 2.0 (the "License");
7054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * you may not use this file except in compliance with the License.
8054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * You may obtain a copy of the License at
9054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *
10054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *      http://www.apache.org/licenses/LICENSE-2.0
11054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *
12054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Unless required by applicable law or agreed to in writing, software
13054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * distributed under the License is distributed on an "AS IS" BASIS,
14054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * See the License for the specific language governing permissions and
16054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * limitations under the License.
17054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */
18054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
19054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <math.h>
20054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_mdpcomp.h"
21054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <sys/ioctl.h>
22054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <dlfcn.h>
23054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hdmi.h"
24054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "qdMetaData.h"
25054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "mdp_version.h"
26054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_fbupdate.h"
27054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_ad.h"
28054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include <overlayRotator.h>
29054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "hwc_copybit.h"
30054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "qd_utils.h"
31054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
32054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace overlay;
33054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace qdutils;
34054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinusing namespace overlay::utils;
35054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinnamespace ovutils = overlay::utils;
36054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
37054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinnamespace qhwc {
38054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
39054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//==============MDPComp========================================================
40054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
41054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinIdleInvalidator *MDPComp::sIdleInvalidator = NULL;
42054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::sIdleFallBack = false;
43054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::sHandleTimeout = false;
44054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::sDebugLogs = false;
45054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::sEnabled = false;
46054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::sEnableMixedMode = true;
47054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::sSimulationFlags = 0;
48054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::sMaxPipesPerMixer = 0;
49054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::sEnableYUVsplit = false;
50054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::sSrcSplitEnabled = false;
51054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::sMaxSecLayers = 1;
52054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::enablePartialUpdateForMDP3 = false;
53054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::sIsPartialUpdateActive = true;
54a2f8c1e71fe985a5306dd303850e9862d422249cNaseer Ahmedbool MDPComp::sIsSingleFullScreenUpdate = false;
55054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid *MDPComp::sLibPerfHint = NULL;
56054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::sPerfLockHandle = 0;
57054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
58054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint (*MDPComp::sPerfLockRelease)(int value) = NULL;
59054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::sPerfHintWindow = -1;
60054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
61054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinMDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) {
62054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
63054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sSrcSplitEnabled = true;
64054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return new MDPCompSrcSplit(dpy);
65054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else if(isDisplaySplit(ctx, dpy)) {
66054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return new MDPCompSplit(dpy);
67054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
68054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return new MDPCompNonSplit(dpy);
69054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
70054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
71054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinMDPComp::MDPComp(int dpy):mDpy(dpy){};
72054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
73054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::dump(android::String8& buf, hwc_context_t *ctx)
74054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
75054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS)
76054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
77054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
78054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dumpsys_log(buf,"HWC Map for Dpy: %s \n",
79054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (mDpy == 0) ? "\"PRIMARY\"" :
80054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\"");
81054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d "
82054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                "fbCount:%2d \n", mCurrentFrame.layerCount,
83054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
84054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dumpsys_log(buf,"needsFBRedraw:%3s  pipesUsed:%2d  MaxPipesPerMixer: %d \n",
85054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (mCurrentFrame.needsRedraw? "YES" : "NO"),
86054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.mdpCount, sMaxPipesPerMixer);
87054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isDisplaySplit(ctx, mDpy)) {
88054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] "
89054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                "Right: [%d, %d, %d, %d] \n",
90054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
91054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].lRoi.right,
92054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].lRoi.bottom,
93054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top,
94054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].rRoi.right,
95054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].rRoi.bottom);
96054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
97054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n",
98054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top,
99054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].lRoi.right,
100054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->listStats[mDpy].lRoi.bottom);
101054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
102054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dumpsys_log(buf," ---------------------------------------------  \n");
103054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype  |  Z  \n");
104054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dumpsys_log(buf," ---------------------------------------------  \n");
105054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0; index < mCurrentFrame.layerCount; index++ )
106054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
107054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    index,
108054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
109054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     mCurrentFrame.layerToMDP[index],
110054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    (mCurrentFrame.isFBComposed[index] ?
111054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    (mCurrentFrame.drop[index] ? "DROP" :
112054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"),
113054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
114054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
115054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    dumpsys_log(buf,"\n");
116054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
117054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
118054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::init(hwc_context_t *ctx) {
119054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
120054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx) {
121054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
122054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
123054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
124054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
125054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char property[PROPERTY_VALUE_MAX] = {0};
126054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
127054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sEnabled = false;
128054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((ctx->mMDP.version >= qdutils::MDP_V4_0) &&
129054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       (property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
130054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
131054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
132054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sEnabled = true;
133054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
134054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
135054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sEnableMixedMode = true;
136054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) &&
137054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
138054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
139054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sEnableMixedMode = false;
140054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
141054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
142054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
143054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
144054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sMaxPipesPerMixer = (int)mdpVersion.getBlendStages();
145054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(property_get("persist.hwc.mdpcomp.maxpermixer", property, "-1") > 0) {
146054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int val = atoi(property);
147054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(val >= 0)
148054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            sMaxPipesPerMixer = min(val, sMaxPipesPerMixer);
149054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
150054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
151054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Maximum layers allowed to use MDP on secondary panels. If property
152054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * doesn't exist, default to 1. Using the property it can be set to 0 or
153054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * more.
154054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     */
155054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(property_get("persist.hwc.maxseclayers", property, "1") > 0) {
156054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int val = atoi(property);
157054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sMaxSecLayers = (val >= 0) ? val : 1;
158054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sMaxSecLayers = min(sMaxSecLayers, sMaxPipesPerMixer);
159054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
160054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
161054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mMDP.panel != MIPI_CMD_PANEL) {
162054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sIdleInvalidator = IdleInvalidator::getInstance();
163054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(sIdleInvalidator->init(timeout_handler, ctx) < 0) {
164054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            delete sIdleInvalidator;
165054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            sIdleInvalidator = NULL;
166054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
167054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
168054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
169054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!qdutils::MDPVersion::getInstance().isSrcSplit() &&
170054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() &&
171054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 &&
172054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
173054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) {
174054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sEnableYUVsplit = true;
175054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
176054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
177054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool defaultPTOR = false;
178054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Enable PTOR when "persist.hwc.ptor.enable" is not defined for
179054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //8x16 and 8x39 targets by default
180054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((property_get("persist.hwc.ptor.enable", property, NULL) <= 0) &&
181054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (qdutils::MDPVersion::getInstance().is8x16() ||
182054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                qdutils::MDPVersion::getInstance().is8x39())) {
183054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        defaultPTOR = true;
184054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
185054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
186054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (defaultPTOR || (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)) ||
187054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (!strncmp(property, "1", PROPERTY_VALUE_MAX ))) {
188054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
189054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                                    HWC_DISPLAY_PRIMARY);
190054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
191054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
192054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((property_get("persist.mdp3.partialUpdate", property, NULL) <= 0) &&
193054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin          (ctx->mMDP.version == qdutils::MDP_V3_0_5)) {
194054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       enablePartialUpdateForMDP3 = true;
195054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
196054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
197054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!enablePartialUpdateForMDP3 &&
198054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin          (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
199054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
200054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       enablePartialUpdateForMDP3 = true;
201054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
202054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
203054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sIsPartialUpdateActive = getPartialUpdatePref(ctx);
204054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
205054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(property_get("persist.mdpcomp_perfhint", property, "-1") > 0) {
206054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int val = atoi(property);
207054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(val > 0 && loadPerfLib()) {
208054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            sPerfHintWindow = val;
209054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGI("PerfHintWindow = %d", sPerfHintWindow);
210054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
211054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
212054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
213054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
214054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
215054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
216054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::reset(hwc_context_t *ctx) {
217054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int numLayers = ctx->listStats[mDpy].numAppLayers;
218054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.reset(numLayers);
219054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mOverlay->clear(mDpy);
220054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mLayerRotMap[mDpy]->clear();
221054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
222054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
223054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::reset() {
224054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sHandleTimeout = false;
225054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mModeOn = false;
226054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
227054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
228054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::timeout_handler(void *udata) {
229054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
230054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
231054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx) {
232054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: received empty data in timer callback", __FUNCTION__);
233054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
234054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
235054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
236054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mDrawLock.lock();
237054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Handle timeout event only if the previous composition is MDP or MIXED.
238054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!sHandleTimeout) {
239054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__);
240054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.unlock();
241054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
242054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
243054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx->proc) {
244054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: HWC proc not registered", __FUNCTION__);
245054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mDrawLock.unlock();
246054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
247054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
248054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sIdleFallBack = true;
249054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mDrawLock.unlock();
250054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Trigger SF to redraw the current frame */
251054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->proc->invalidate(ctx->proc);
252054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
253054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
254054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::setMaxPipesPerMixer(const uint32_t value) {
255054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    qdutils::MDPVersion &mdpVersion = qdutils::MDPVersion::getInstance();
256054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t maxSupported = (int)mdpVersion.getBlendStages();
257054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(value > maxSupported) {
258054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGW("%s: Input exceeds max value supported. Setting to"
259054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                "max value: %d", __FUNCTION__, maxSupported);
260054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
261054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sMaxPipesPerMixer = min(value, maxSupported);
262054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
263054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
264054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::setIdleTimeout(const uint32_t& timeout) {
265054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    enum { ONE_REFRESH_PERIOD_MS = 17, ONE_BILLION_MS = 1000000000 };
266054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
267054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sIdleInvalidator) {
268054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(timeout <= ONE_REFRESH_PERIOD_MS) {
269054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //If the specified timeout is < 1 draw cycle worth, "virtually"
270054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //disable idle timeout. The ideal way for clients to disable
271054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //timeout is to set it to 0
272054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            sIdleInvalidator->setIdleTimeout(ONE_BILLION_MS);
273054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGI("Disabled idle timeout");
274054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return;
275054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
276054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sIdleInvalidator->setIdleTimeout(timeout);
277054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGI("Idle timeout set to %u", timeout);
278054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
279054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGW("Cannot set idle timeout, IdleInvalidator not enabled");
280054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
281054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
282054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
283054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
284054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                   hwc_display_contents_1_t* list) {
285054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    LayerProp *layerProp = ctx->layerProp[mDpy];
286054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
287054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
288054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &(list->hwLayers[index]);
289054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!mCurrentFrame.isFBComposed[index]) {
290054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layerProp[index].mFlags |= HWC_MDPCOMP;
291054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layer->compositionType = HWC_OVERLAY;
292054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layer->hints |= HWC_HINT_CLEAR_FB;
293054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
294054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            /* Drop the layer when its already present in FB OR when it lies
295054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             * outside frame's ROI */
296054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) {
297054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                layer->compositionType = HWC_OVERLAY;
298054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
299054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
300054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
301054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
302054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
303054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::setRedraw(hwc_context_t *ctx,
304054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
305054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.needsRedraw = false;
306054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!mCachedFrame.isSameFrame(mCurrentFrame, list) ||
307054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (list->flags & HWC_GEOMETRY_CHANGED) ||
308054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            isSkipPresent(ctx, mDpy)) {
309054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCurrentFrame.needsRedraw = true;
310054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
311054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
312054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
313054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinMDPComp::FrameInfo::FrameInfo() {
314054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&mdpToLayer, 0, sizeof(mdpToLayer));
315054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    reset(0);
316054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
317054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
318054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::FrameInfo::reset(const int& numLayers) {
319054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0 ; i < MAX_NUM_BLEND_STAGES; i++ ) {
320054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mdpToLayer[i].pipeInfo) {
321054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            delete mdpToLayer[i].pipeInfo;
322054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mdpToLayer[i].pipeInfo = NULL;
323054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //We dont own the rotator
324054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mdpToLayer[i].rot = NULL;
325054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
326054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
327054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
328054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&mdpToLayer, 0, sizeof(mdpToLayer));
329054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&layerToMDP, -1, sizeof(layerToMDP));
330054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&isFBComposed, 1, sizeof(isFBComposed));
331054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
332054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    layerCount = numLayers;
333054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    fbCount = numLayers;
334054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mdpCount = 0;
335054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    needsRedraw = true;
336054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    fbZ = -1;
337054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
338054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
339054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::FrameInfo::map() {
340054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // populate layer and MDP maps
341054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int mdpIdx = 0;
342054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int idx = 0; idx < layerCount; idx++) {
343054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!isFBComposed[idx]) {
344054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mdpToLayer[mdpIdx].listIndex = idx;
345054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layerToMDP[idx] = mdpIdx++;
346054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
347054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
348054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
349054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
350054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinMDPComp::LayerCache::LayerCache() {
351054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    reset();
352054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
353054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
354054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::LayerCache::reset() {
355054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&isFBComposed, true, sizeof(isFBComposed));
356054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&drop, false, sizeof(drop));
357054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    layerCount = 0;
358054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
359054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
360054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
361054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    layerCount = curFrame.layerCount;
362054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed));
363054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memcpy(&drop, &curFrame.drop, sizeof(drop));
364054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
365054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
366054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame,
367054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                      hwc_display_contents_1_t* list) {
368054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(layerCount != curFrame.layerCount)
369054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
370054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < curFrame.layerCount; i++) {
371054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((curFrame.isFBComposed[i] != isFBComposed[i]) ||
372054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (curFrame.drop[i] != drop[i])) {
373054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
374054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
37572aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R        hwc_layer_1_t const* layer = &list->hwLayers[i];
37672aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R        if(curFrame.isFBComposed[i] && layerUpdating(layer)){
377054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
378054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
379054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
380054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
381054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
382054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
383054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
384054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
385054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) ||
386054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (not isValidDimension(ctx,layer))
387054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //More conditions here, SKIP, sRGB+Blend etc
388054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ) {
389054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
390054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
391054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
392054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
393054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
394054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
395054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
396054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
397054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!hnd) {
398054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (layer->flags & HWC_COLOR_FILL) {
399054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // Color layer
400054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return true;
401054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
402054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: layer handle is NULL", __FUNCTION__);
403054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
404054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
405054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
406054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //XXX: Investigate doing this with pixel phase on MDSS
407054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf))
408054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
409054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
410054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
411054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
412054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90);
413054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left;
414054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top;
415054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_w = dst.right - dst.left;
416054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dst_h = dst.bottom - dst.top;
417054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float w_scale = ((float)crop_w / (float)dst_w);
418054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    float h_scale = ((float)crop_h / (float)dst_h);
419054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MDPVersion& mdpHw = MDPVersion::getInstance();
420054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
421054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Workaround for MDP HW limitation in DSI command mode panels where
422054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
423054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * less than 5 pixels
424054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * There also is a HW limilation in MDP, minimum block size is 2x2
425054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * Fallback to GPU if height is less than 2.
426054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     */
427054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
428054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
429054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
430054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((w_scale > 1.0f) || (h_scale > 1.0f)) {
431054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
432054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const float w_dscale = w_scale;
433054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const float h_dscale = h_scale;
434054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
435054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->mMDP.version >= qdutils::MDSS_V5) {
436054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
437054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mdpHw.supportsDecimation()) {
438054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                /* On targets that doesnt support Decimation (eg.,8x26)
439054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 * maximum downscale support is overlay pipe downscale.
440054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 */
441054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(crop_w > (int) mdpHw.getMaxPipeWidth() ||
442054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        w_dscale > maxMDPDownscale ||
443054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        h_dscale > maxMDPDownscale)
444054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
445054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            } else {
446054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                // Decimation on macrotile format layers is not supported.
447054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(isTileRendered(hnd)) {
448054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    /* Bail out if
449054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     *      1. Src crop > Mixer limit on nonsplit MDPComp
450054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     *      2. exceeds maximum downscale limit
451054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     */
452054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    if(((crop_w > (int) mdpHw.getMaxPipeWidth()) &&
453054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                !sSrcSplitEnabled) ||
454054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            w_dscale > maxMDPDownscale ||
455054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            h_dscale > maxMDPDownscale) {
456054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        return false;
457054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    }
458054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                } else if(w_dscale > 64 || h_dscale > 64)
459054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
460054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
461054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else { //A-family
462054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale)
463054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
464054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
465054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
466054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
467054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((w_scale < 1.0f) || (h_scale < 1.0f)) {
468054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const uint32_t upscale = mdpHw.getMaxMDPUpscale();
469054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const float w_uscale = 1.0f / w_scale;
470054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const float h_uscale = 1.0f / h_scale;
471054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
472054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(w_uscale > upscale || h_uscale > upscale)
473054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
474054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
475054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
476054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
477054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
478054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
479054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::isFrameDoable(hwc_context_t *ctx) {
480054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool ret = true;
481054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
482054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isEnabled()) {
483054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
484054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret = false;
485054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else if((qdutils::MDPVersion::getInstance().is8x26() ||
486054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               qdutils::MDPVersion::getInstance().is8x16() ||
487054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin               qdutils::MDPVersion::getInstance().is8x39()) &&
488054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mVideoTransFlag &&
489054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            isSecondaryConnected(ctx)) {
490054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //1 Padding round to shift pipes across mixers
491054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
492054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__);
493054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret = false;
494054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
495054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       /* TODO: freeing up all the resources only for the targets having total
496054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                number of pipes < 8. Need to analyze number of VIG pipes used
497054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                for primary in previous draw cycle and accordingly decide
498054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                whether to fall back to full GPU comp or video only comp
499054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        */
500054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isSecondaryConfiguring(ctx)) {
501054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF( isDebug(),"%s: External Display connection is pending",
502054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                      __FUNCTION__);
503054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ret = false;
504054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else if(ctx->isPaddingRound) {
505054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
506054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     __FUNCTION__,mDpy);
507054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ret = false;
508054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
509054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else if (ctx->isDMAStateChanging) {
510054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Bail out if a padding round has been invoked in order to switch DMA
511054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // state to block mode. We need this to cater for the case when a layer
512054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // requires rotation in the current frame.
513054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: padding round invoked to switch DMA state",
514054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__);
515054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
516054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
517054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
518054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return ret;
519054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
520054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
52172aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.Rhwc_rect_t MDPComp::calculateDirtyRect(const hwc_layer_1_t* layer,
52272aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R                    hwc_rect_t& scissor) {
52372aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  hwc_region_t surfDamage = layer->surfaceDamage;
52472aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf);
52572aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  hwc_rect_t dst = layer->displayFrame;
52672aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  int x_off = dst.left - src.left;
52772aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  int y_off = dst.top - src.top;
52872aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  hwc_rect dirtyRect = (hwc_rect){0, 0, 0, 0};
52972aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  hwc_rect_t updatingRect = dst;
53072aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R
53172aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  if (surfDamage.numRects == 0) {
53272aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R      // full layer updating, dirty rect is full frame
53372aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R      dirtyRect = getIntersection(layer->displayFrame, scissor);
53472aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  } else {
53572aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R      for(uint32_t i = 0; i < surfDamage.numRects; i++) {
53672aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R          updatingRect = moveRect(surfDamage.rects[i], x_off, y_off);
53772aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R          hwc_rect_t intersect = getIntersection(updatingRect, scissor);
53872aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R          if(isValidRect(intersect)) {
53972aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R              dirtyRect = getUnion(intersect, dirtyRect);
54072aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R          }
54172aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R      }
54272aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  }
54372aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R
54472aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R  return dirtyRect;
54572aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R}
54672aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R
5479f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.Rvoid MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
5489f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        hwc_rect &dst) {
549054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t roi = ctx->listStats[mDpy].lRoi;
5509f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    dst = getIntersection(dst, roi);
5519f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    crop = dst;
552054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
553054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
554054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* 1) Identify layers that are not visible or lying outside the updating ROI and
555054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *    drop them from composition.
556054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 2) If we have a scaling layer which needs cropping against generated
557054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *    ROI, reset ROI to full resolution. */
558054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx,
559054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
560054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
561054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
562054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
563054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = numAppLayers - 1; i >= 0; i--){
564054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!isValidRect(visibleRect)) {
565054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.drop[i] = true;
566054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.dropCount++;
567054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
568054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
569054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
570054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const hwc_layer_1_t* layer =  &list->hwLayers[i];
571054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t dstRect = layer->displayFrame;
572054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t res  = getIntersection(visibleRect, dstRect);
573054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
574054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!isValidRect(res)) {
575054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.drop[i] = true;
576054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.dropCount++;
577054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
578054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            /* Reset frame ROI when any layer which needs scaling also needs ROI
579054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             * cropping */
580054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!isSameRect(res, dstRect) && needsScaling (layer)) {
581054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
582054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
583054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.dropCount = 0;
584054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
585054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
586054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
587054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            /* deduct any opaque region from visibleRect */
588054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (layer->blending == HWC_BLENDING_NONE &&
589054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    layer->planeAlpha == 0xFF)
590054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                visibleRect = deductRect(visibleRect, res);
591054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
592054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
593054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
594054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
595054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
596054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
597054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * are updating. If DirtyRegion is applicable, calculate it by accounting all
598054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * the changing layer's dirtyRegion. */
599054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPCompNonSplit::generateROI(hwc_context_t *ctx,
600054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
601054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
602054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!canPartialUpdate(ctx, list))
603054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
604054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
605054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
606054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
607054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (int)ctx->dpyAttr[mDpy].yres};
608054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
609054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0; index < numAppLayers; index++ ) {
610054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[index];
61172aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R        if (layerUpdating(layer) ||
612054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                isYuvBuffer((private_handle_t *)layer->handle)) {
61341ac35e73491eb7e3337abe257c042dac4ad2e1fArun Kumar K.R            hwc_rect_t dirtyRect = getIntersection(layer->displayFrame,
61441ac35e73491eb7e3337abe257c042dac4ad2e1fArun Kumar K.R                                                    fullFrame);
61572aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R            if(!needsScaling(layer) && !layer->transform) {
61672aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R                dirtyRect = calculateDirtyRect(layer, fullFrame);
617054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
618054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
61972aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R            roi = getUnion(roi, dirtyRect);
620054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
621054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
622054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
623054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* No layer is updating. Still SF wants a refresh.*/
624054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isValidRect(roi))
625054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
626054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
627054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Align ROI coordinates to panel restrictions
628054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    roi = getSanitizeROI(roi, fullFrame);
629054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
630054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[mDpy].lRoi = roi;
631054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!validateAndApplyROI(ctx, list))
632054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        resetROI(ctx, mDpy);
633054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
634054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__,
635054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
636054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom);
637054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
638054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
6399f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.Rvoid MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect &crop,
6409f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        hwc_rect &dst) {
6419f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    hwc_rect roi = getUnion(ctx->listStats[mDpy].lRoi,
6429f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            ctx->listStats[mDpy].rRoi);
6439f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    hwc_rect tmpDst = getIntersection(dst, roi);
6449f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    if(!isSameRect(dst, tmpDst)) {
6459f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        crop.left = crop.left + (tmpDst.left - dst.left);
6469f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        crop.top = crop.top + (tmpDst.top - dst.top);
6479f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        crop.right = crop.left + (tmpDst.right - tmpDst.left);
6489f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        crop.bottom = crop.top + (tmpDst.bottom - tmpDst.top);
6499f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        dst = tmpDst;
6509f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    }
651054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
6529f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
653054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* 1) Identify layers that are not visible or lying outside BOTH the updating
654054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *    ROI's and drop them from composition. If a layer is spanning across both
655054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *    the halves of the screen but needed by only ROI, the non-contributing
656054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *    half will not be programmed for MDP.
657054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 2) If we have a scaling layer which needs cropping against generated
658054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin *    ROI, reset ROI to full resolution. */
659054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx,
660054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
661054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
662054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
663054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
664054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi;
665054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi;
666054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
667054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = numAppLayers - 1; i >= 0; i--){
668054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR))
669054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        {
670054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.drop[i] = true;
671054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.dropCount++;
672054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
673054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
674054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
675054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const hwc_layer_1_t* layer =  &list->hwLayers[i];
676054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t dstRect = layer->displayFrame;
677054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
678054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t l_res  = getIntersection(visibleRectL, dstRect);
679054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t r_res  = getIntersection(visibleRectR, dstRect);
680054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t res = getUnion(l_res, r_res);
681054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
682054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!isValidRect(l_res) && !isValidRect(r_res)) {
683054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.drop[i] = true;
684054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.dropCount++;
685054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
686054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            /* Reset frame ROI when any layer which needs scaling also needs ROI
687054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             * cropping */
688054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!isSameRect(res, dstRect) && needsScaling (layer)) {
689054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
690054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.dropCount = 0;
691054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
692054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
693054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
694054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (layer->blending == HWC_BLENDING_NONE &&
695054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    layer->planeAlpha == 0xFF) {
696054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                visibleRectL = deductRect(visibleRectL, l_res);
697054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                visibleRectR = deductRect(visibleRectR, r_res);
698054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
699054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
700054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
701054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
702054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
703054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which
704054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * are updating. If DirtyRegion is applicable, calculate it by accounting all
705054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * the changing layer's dirtyRegion. */
706054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPCompSplit::generateROI(hwc_context_t *ctx,
707054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
708054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!canPartialUpdate(ctx, list))
709054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
710054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
711054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
712054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int lSplit = getLeftSplit(ctx, mDpy);
713054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
714054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int hw_h = (int)ctx->dpyAttr[mDpy].yres;
715054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int hw_w = (int)ctx->dpyAttr[mDpy].xres;
716054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
717054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h};
718054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h};
719054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
720054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0};
721054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0};
722054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
723054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0; index < numAppLayers; index++ ) {
724054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[index];
725054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
72672aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R
72772aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R        if (layerUpdating(layer) || isYuvBuffer(hnd)) {
72841ac35e73491eb7e3337abe257c042dac4ad2e1fArun Kumar K.R            hwc_rect_t l_dirtyRect = getIntersection(layer->displayFrame,
72941ac35e73491eb7e3337abe257c042dac4ad2e1fArun Kumar K.R                                        l_frame);
73041ac35e73491eb7e3337abe257c042dac4ad2e1fArun Kumar K.R            hwc_rect_t r_dirtyRect = getIntersection(layer->displayFrame,
73141ac35e73491eb7e3337abe257c042dac4ad2e1fArun Kumar K.R                                        r_frame);
73272aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R
73372aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R            if(!needsScaling(layer) && !layer->transform) {
73472aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R                l_dirtyRect = calculateDirtyRect(layer, l_frame);
73572aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R                r_dirtyRect = calculateDirtyRect(layer, r_frame);
736054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
73772aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R            if(isValidRect(l_dirtyRect))
73872aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R                l_roi = getUnion(l_roi, l_dirtyRect);
739054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
74072aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R            if(isValidRect(r_dirtyRect))
74172aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R                r_roi = getUnion(r_roi, r_dirtyRect);
742054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
743054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
744054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
745054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
746054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* For panels that cannot accept commands in both the interfaces, we cannot
747054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * send two ROI's (for each half). We merge them into single ROI and split
748054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * them across lSplit for MDP mixer use. The ROI's will be merged again
749054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * finally before udpating the panel in the driver. */
750054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(qdutils::MDPVersion::getInstance().needsROIMerge()) {
751054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t temp_roi = getUnion(l_roi, r_roi);
752054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        l_roi = getIntersection(temp_roi, l_frame);
753054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        r_roi = getIntersection(temp_roi, r_frame);
754054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
755054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
756054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* No layer is updating. Still SF wants a refresh. */
757054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isValidRect(l_roi) && !isValidRect(r_roi))
758054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
759054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
760054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    l_roi = getSanitizeROI(l_roi, l_frame);
761054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    r_roi = getSanitizeROI(r_roi, r_frame);
762054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
763054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[mDpy].lRoi = l_roi;
764054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->listStats[mDpy].rRoi = r_roi;
765054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
766054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!validateAndApplyROI(ctx, list))
767054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        resetROI(ctx, mDpy);
768054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
769054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]"
770054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            "R_ROI: [%d, %d, %d, %d]", __FUNCTION__,
771054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
772054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
773054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
774054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
775054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
776054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
777054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Checks for conditions where all the layers marked for MDP comp cannot be
778054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * bypassed. On such conditions we try to bypass atleast YUV layers */
779054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::tryFullFrame(hwc_context_t *ctx,
780054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                hwc_display_contents_1_t* list){
781054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
782054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
783054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
784054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Fall back to video only composition, if AIV video mode is enabled
785054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[mDpy].mAIVVideoMode) {
786054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
787054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            __FUNCTION__, mDpy);
788054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
789054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
790054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
791054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* No Idle fall back if secure display or secure RGB layers are present
792054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * or if there is only a single layer being composed */
793054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sIdleFallBack && !ctx->listStats[mDpy].secureUI &&
794054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  !ctx->listStats[mDpy].secureRGBCount &&
795054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  (ctx->listStats[mDpy].numAppLayers > 1)) {
796054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
797054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
798054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
799054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
800054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isSkipPresent(ctx, mDpy)) {
801054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: SKIP present: %d",
802054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__,
803054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                isSkipPresent(ctx, mDpy));
804054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
805054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
806054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
807054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // if secondary is configuring or Padding round, fall back to video only
808054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // composition and release all assigned non VIG pipes from primary.
809054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isSecondaryConfiguring(ctx)) {
810054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF( isDebug(),"%s: External Display connection is pending",
811054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  __FUNCTION__);
812054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
813054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else if(ctx->isPaddingRound) {
814054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d",
815054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 __FUNCTION__,mDpy);
816054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
817054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
818054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
819054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // check for action safe flag and MDP scaling mode which requires scaling.
820054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->dpyAttr[mDpy].mActionSafePresent
821054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            || ctx->dpyAttr[mDpy].mMDPScalingMode) {
822054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__);
823054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
824054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
825054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
826054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numAppLayers; ++i) {
827054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[i];
828054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
829054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
830054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
831054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!canUseRotator(ctx, mDpy)) {
832054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d",
833054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        __FUNCTION__, mDpy);
834054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
835054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
836054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
837054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
838054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
839054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // may not need it if Gfx pre-rotation can handle all flips & rotations
840054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        MDPVersion& mdpHw = MDPVersion::getInstance();
841054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
842054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
843054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
844054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
845054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
846054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
847054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mAD->isDoable()) {
848054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
849054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
850054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
851054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If all above hard conditions are met we can do full or partial MDP comp.
852054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool ret = false;
853054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(fullMDPComp(ctx, list)) {
854054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret = true;
855054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else if(fullMDPCompWithPTOR(ctx, list)) {
856054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret = true;
857054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else if(partialMDPComp(ctx, list)) {
858054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret = true;
859054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
860054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
861054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return ret;
862054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
863054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
864054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
865054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
866054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP)
867054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
868054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
869054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
870054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numAppLayers; i++) {
871054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[i];
872054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(not mCurrentFrame.drop[i] and
873054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           not isSupportedForMDPComp(ctx, layer)) {
874054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
875054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
876054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
877054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
878054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
879054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.fbCount = 0;
880054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop,
881054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           sizeof(mCurrentFrame.isFBComposed));
882054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount -
883054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCurrentFrame.dropCount;
884054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
885054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sEnableYUVsplit){
886054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        adjustForSourceSplit(ctx, list);
887054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
888054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
889054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!postHeuristicsHandling(ctx, list)) {
890054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "post heuristic handling failed");
891054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
892054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
893054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
894054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED",
895054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             __FUNCTION__);
896054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
897054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
898054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
899054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Full MDP Composition with Peripheral Tiny Overlap Removal.
900054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * MDP bandwidth limitations can be avoided, if the overlap region
901054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * covered by the smallest layer at a higher z-order, gets composed
902054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * by Copybit on a render buffer, which can be queued to MDP.
903054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */
904054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx,
905054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_display_contents_1_t* list) {
906054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
907054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
908054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int stagesForMDP = min(sMaxPipesPerMixer,
909054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
910054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
911054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Hard checks where we cannot use this mode
912054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (mDpy || !ctx->mCopyBit[mDpy]) {
913054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__);
914054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
915054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
916054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
917054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Frame level checks
918054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) ||
919054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount ||
920054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        isSecurePresent(ctx, mDpy)) {
921054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__);
922054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
923054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
924054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // MDP comp checks
925054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numAppLayers; i++) {
926054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[i];
927054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(not isSupportedForMDPComp(ctx, layer)) {
928054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__);
929054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
930054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
931054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
932054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
933054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* We cannot use this composition mode, if:
934054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     1. A below layer needs scaling.
935054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     2. Overlap is not peripheral to display.
936054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     3. Overlap or a below layer has 90 degree transform.
937054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
938054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     */
939054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
940054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1};
941054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t overlapRect[MAX_PTOR_LAYERS];
942054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(overlapRect, 0, sizeof(overlapRect));
943054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int layerPixelCount, minPixelCount = 0;
944054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numPTORLayersFound = 0;
945054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (int i = numAppLayers-1; (i >= 0 &&
946054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                  numPTORLayersFound < MAX_PTOR_LAYERS); i--) {
947054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[i];
948054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
949054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t dispFrame = layer->displayFrame;
950054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top);
951054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // PTOR layer should be peripheral and cannot have transform
952054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) ||
953054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                has90Transform(layer)) {
954054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
955054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
956054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((3 * (layerPixelCount + minPixelCount)) >
957054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) {
958054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs.
959054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
960054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
961054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bool found = false;
962054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        for (int j = i-1; j >= 0; j--) {
963054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // Check if the layers below this layer qualifies for PTOR comp
964054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_layer_1_t* layer = &list->hwLayers[j];
965054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_rect_t disFrame = layer->displayFrame;
966054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // Layer below PTOR is intersecting and has 90 degree transform or
967054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // needs scaling cannot be supported.
968054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (isValidRect(getIntersection(dispFrame, disFrame))) {
969054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if (has90Transform(layer) || needsScaling(layer)) {
970054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    found = false;
971054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    break;
972054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
973054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                found = true;
974054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
975054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
976054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Store the minLayer Index
977054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(found) {
978054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            minLayerIndex[numPTORLayersFound] = i;
979054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame;
980054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            minPixelCount += layerPixelCount;
981054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            numPTORLayersFound++;
982054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
983054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
984054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
985054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // No overlap layers
986054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (!numPTORLayersFound)
987054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
988054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
989054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Store the displayFrame and the sourceCrops of the layers
990054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t displayFrame[numAppLayers];
991054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t sourceCrop[numAppLayers];
992054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numAppLayers; i++) {
993054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[i];
994054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        displayFrame[i] = layer->displayFrame;
995054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf);
996054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
997054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
998054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /**
999054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * It's possible that 2 PTOR layers might have overlapping.
1000054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * In such case, remove the intersection(again if peripheral)
1001054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * from the lower PTOR layer to avoid overlapping.
1002054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * If intersection is not on peripheral then compromise
1003054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * by reducing number of PTOR layers.
1004054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     **/
1005054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t commonRect = getIntersection(overlapRect[0], overlapRect[1]);
1006054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isValidRect(commonRect)) {
1007054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        overlapRect[1] = deductRect(overlapRect[1], commonRect);
1008054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        list->hwLayers[minLayerIndex[1]].displayFrame = overlapRect[1];
1009054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1010054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1011054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ctx->mPtorInfo.count = numPTORLayersFound;
1012054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < MAX_PTOR_LAYERS; i++) {
1013054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i];
1014054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1015054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1016054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) {
1017054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // reset PTOR
1018054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mPtorInfo.count = 0;
1019054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isValidRect(commonRect)) {
1020054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // If PTORs are intersecting restore displayframe of PTOR[1]
1021054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // before returning, as we have modified it above.
1022054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            list->hwLayers[minLayerIndex[1]].displayFrame =
1023054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    displayFrame[minLayerIndex[1]];
1024054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1025054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1026054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1027054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *renderBuf = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
1028054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Whf layerWhf[numPTORLayersFound]; // To store w,h,f of PTOR layers
1029054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1030054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Store the blending mode, planeAlpha, and transform of PTOR layers
1031054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int32_t blending[numPTORLayersFound];
1032054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint8_t planeAlpha[numPTORLayersFound];
1033054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t transform[numPTORLayersFound];
1034054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1035054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int j = 0; j < numPTORLayersFound; j++) {
1036054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int index =  ctx->mPtorInfo.layerIndex[j];
1037054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1038054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Update src crop of PTOR layer
1039054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[index];
1040054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.left = (float)ctx->mPtorInfo.displayFrame[j].left;
1041054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.top = (float)ctx->mPtorInfo.displayFrame[j].top;
1042054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.right = (float)ctx->mPtorInfo.displayFrame[j].right;
1043054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.bottom =(float)ctx->mPtorInfo.displayFrame[j].bottom;
1044054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1045054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Store & update w, h, format of PTOR layer
1046054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
1047054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        Whf whf(hnd->width, hnd->height, hnd->format, hnd->size);
1048054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layerWhf[j] = whf;
1049054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hnd->width = renderBuf->width;
1050054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hnd->height = renderBuf->height;
1051054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hnd->format = renderBuf->format;
1052054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1053054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Store & update blending mode, planeAlpha and transform of PTOR layer
1054054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        blending[j] = layer->blending;
1055054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        planeAlpha[j] = layer->planeAlpha;
1056054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        transform[j] = layer->transform;
1057054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->blending = HWC_BLENDING_NONE;
1058054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->planeAlpha = 0xFF;
1059054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->transform = 0;
1060054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1061054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // Remove overlap from crop & displayFrame of below layers
1062054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        for (int i = 0; i < index && index !=-1; i++) {
1063054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layer = &list->hwLayers[i];
1064054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!isValidRect(getIntersection(layer->displayFrame,
1065054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                            overlapRect[j])))  {
1066054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                continue;
1067054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1068054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // Update layer attributes
1069054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf);
1070054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_rect_t destRect = deductRect(layer->displayFrame,
1071054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        getIntersection(layer->displayFrame, overlapRect[j]));
1072054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect,
1073054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                       layer->transform);
1074054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layer->sourceCropf.left = (float)srcCrop.left;
1075054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layer->sourceCropf.top = (float)srcCrop.top;
1076054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layer->sourceCropf.right = (float)srcCrop.right;
1077054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layer->sourceCropf.bottom = (float)srcCrop.bottom;
1078054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1079054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1080054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1081054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.mdpCount = numAppLayers;
1082054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.fbCount = 0;
1083054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.fbZ = -1;
1084054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1085054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (int j = 0; j < numAppLayers; j++) {
1086054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isValidRect(list->hwLayers[j].displayFrame)) {
1087054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.isFBComposed[j] = false;
1088054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
1089054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.mdpCount--;
1090054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.drop[j] = true;
1091054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1092054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1093054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1094054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool result = postHeuristicsHandling(ctx, list);
1095054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1096054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Restore layer attributes
1097054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numAppLayers; i++) {
1098054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[i];
1099054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->displayFrame = displayFrame[i];
1100054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.left = (float)sourceCrop[i].left;
1101054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.top = (float)sourceCrop[i].top;
1102054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.right = (float)sourceCrop[i].right;
1103054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->sourceCropf.bottom = (float)sourceCrop[i].bottom;
1104054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1105054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1106054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Restore w,h,f, blending attributes, and transform of PTOR layers
1107054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (int i = 0; i < numPTORLayersFound; i++) {
1108054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int idx = ctx->mPtorInfo.layerIndex[i];
1109054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[idx];
1110054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)list->hwLayers[idx].handle;
1111054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hnd->width = layerWhf[i].w;
1112054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hnd->height = layerWhf[i].h;
1113054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hnd->format = layerWhf[i].format;
1114054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->blending = blending[i];
1115054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->planeAlpha = planeAlpha[i];
1116054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layer->transform = transform[i];
1117054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1118054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1119054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (!result) {
1120054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // reset PTOR
1121054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mPtorInfo.count = 0;
1122054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1123054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
1124054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__,
1125054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 ctx->mPtorInfo.layerIndex[0],  ctx->mPtorInfo.layerIndex[1]);
1126054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1127054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1128054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__,
1129054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             (result ? "successful" : "failed"));
1130054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return result;
1131054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1132054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1133054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
1134054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin{
1135054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!sEnableMixedMode) {
1136054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Mixed mode is disabled. No need to even try caching.
1137054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1138054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1139054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1140054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool ret = false;
1141054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first
1142054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret =   loadBasedComp(ctx, list) or
1143054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                cacheBasedComp(ctx, list);
1144054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
1145054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret =   cacheBasedComp(ctx, list) or
1146054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                loadBasedComp(ctx, list);
1147054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1148054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1149054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return ret;
1150054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1151054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1152054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::cacheBasedComp(hwc_context_t *ctx,
1153054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
1154054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP)
1155054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1156054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1157054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1158054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.reset(numAppLayers);
1159054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateLayerCache(ctx, list, mCurrentFrame);
1160054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1161054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If an MDP marked layer is unsupported cannot do partial MDP Comp
1162054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numAppLayers; i++) {
1163054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!mCurrentFrame.isFBComposed[i]) {
1164054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_layer_1_t* layer = &list->hwLayers[i];
1165054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(not isSupportedForMDPComp(ctx, layer)) {
1166054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(), "%s: Unsupported layer in list",
1167054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        __FUNCTION__);
1168054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                reset(ctx);
1169054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
1170054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1171054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1172054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1173054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1174054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateYUV(ctx, list, false /*secure only*/, mCurrentFrame);
1175054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* mark secure RGB layers for MDP comp */
1176054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateSecureRGB(ctx, list);
1177054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1178054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ret) {
1179054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1180054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1181054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1182054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1183054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1184054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int mdpCount = mCurrentFrame.mdpCount;
1185054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1186054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sEnableYUVsplit){
1187054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        adjustForSourceSplit(ctx, list);
1188054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1189054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1190054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!postHeuristicsHandling(ctx, list)) {
1191054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "post heuristic handling failed");
1192054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1193054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1194054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1195054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED",
1196054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             __FUNCTION__);
1197054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1198054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1199054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1200054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1201054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::loadBasedComp(hwc_context_t *ctx,
1202054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
1203054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP)
1204054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1205054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1206054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(not isLoadBasedCompDoable(ctx)) {
1207054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1208054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1209054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1210054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1211054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount;
1212054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int stagesForMDP = min(sMaxPipesPerMixer,
1213054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT));
1214054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1215054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int mdpBatchSize = stagesForMDP - 1; //1 stage for FB
1216054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1217054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int lastMDPSupportedIndex = numAppLayers;
1218054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int dropCount = 0;
1219054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1220054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Find the minimum MDP batch size
1221054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numAppLayers;i++) {
1222054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mCurrentFrame.drop[i]) {
1223054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            dropCount++;
1224054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
1225054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1226054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[i];
1227054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(not isSupportedForMDPComp(ctx, layer)) {
1228054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            lastMDPSupportedIndex = i;
1229054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mdpBatchSize = min(i - dropCount, stagesForMDP - 1);
1230054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            fbBatchSize = numNonDroppedLayers - mdpBatchSize;
1231054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            break;
1232054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1233054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1234054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1235054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d "
1236054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize,
1237054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.dropCount);
1238054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1239054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Start at a point where the fb batch should at least have 2 layers, for
1240054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //this mode to be justified.
1241054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    while(fbBatchSize < 2) {
1242054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ++fbBatchSize;
1243054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        --mdpBatchSize;
1244054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1245054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1246054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If there are no layers for MDP, this mode doesnt make sense.
1247054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mdpBatchSize < 1) {
1248054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch",
1249054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__);
1250054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1251054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1252054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1253054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.reset(numAppLayers);
1254054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1255054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Try with successively smaller mdp batch sizes until we succeed or reach 1
1256054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    while(mdpBatchSize > 0) {
1257054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Mark layers for MDP comp
1258054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int mdpBatchLeft = mdpBatchSize;
1259054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) {
1260054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(mCurrentFrame.drop[i]) {
1261054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                continue;
1262054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1263054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.isFBComposed[i] = false;
1264054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            --mdpBatchLeft;
1265054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1266054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1267054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCurrentFrame.fbZ = mdpBatchSize;
1268054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCurrentFrame.fbCount = fbBatchSize;
1269054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCurrentFrame.mdpCount = mdpBatchSize;
1270054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1271054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d",
1272054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__, mdpBatchSize, fbBatchSize,
1273054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.dropCount);
1274054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1275054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(postHeuristicsHandling(ctx, list)) {
1276054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded",
1277054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     __FUNCTION__);
1278054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED",
1279054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                     __FUNCTION__);
1280054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return true;
1281054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1282054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1283054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1284054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        --mdpBatchSize;
1285054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ++fbBatchSize;
1286054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1287054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1288054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
1289054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1290054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1291054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) {
1292054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mDpy or isSecurePresent(ctx, mDpy) or
1293054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            isYuvPresent(ctx, mDpy)) {
1294054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1295054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1296054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1297054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1298054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1299054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::canPartialUpdate(hwc_context_t *ctx,
1300054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list){
1301054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() ||
1302054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) ||
1303054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            !sIsPartialUpdateActive || mDpy ) {
1304054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1305054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1306054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[mDpy].secureUI)
1307054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1308a2f8c1e71fe985a5306dd303850e9862d422249cNaseer Ahmed    if (sIsSingleFullScreenUpdate) {
1309a2f8c1e71fe985a5306dd303850e9862d422249cNaseer Ahmed        // make sure one full screen update
1310a2f8c1e71fe985a5306dd303850e9862d422249cNaseer Ahmed        sIsSingleFullScreenUpdate = false;
1311a2f8c1e71fe985a5306dd303850e9862d422249cNaseer Ahmed        return false;
1312a2f8c1e71fe985a5306dd303850e9862d422249cNaseer Ahmed    }
1313054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1314054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1315054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1316054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::tryVideoOnly(hwc_context_t *ctx,
1317054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
1318054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const bool secureOnly = true;
1319054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return videoOnlyComp(ctx, list, not secureOnly) or
1320054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            videoOnlyComp(ctx, list, secureOnly);
1321054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1322054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1323054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::videoOnlyComp(hwc_context_t *ctx,
1324054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list, bool secureOnly) {
1325054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY)
1326054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1327054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1328054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1329054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isSecurePresent(ctx, mDpy)) {
1330054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       /* Bail out if we are processing only secured video layers
1331054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        * and we dont have any */
1332054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       if(secureOnly) {
1333054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           ALOGD_IF(isDebug(),"%s: No Secure Video Layers", __FUNCTION__);
1334054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           return false;
1335054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       }
1336054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       /* No Idle fall back for secure video layers and if there is only
1337054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        * single layer being composed. */
1338054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1339054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1340054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           return false;
1341054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1342054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1343054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1344054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.reset(numAppLayers);
1345054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1346054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateYUV(ctx, list, secureOnly, mCurrentFrame);
1347054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int mdpCount = mCurrentFrame.mdpCount;
1348054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1349054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) {
1350054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1351054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1352054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1353054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1354054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.fbCount)
1355054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCurrentFrame.fbZ = mCurrentFrame.mdpCount;
1356054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1357054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sEnableYUVsplit){
1358054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        adjustForSourceSplit(ctx, list);
1359054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1360054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1361054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!postHeuristicsHandling(ctx, list)) {
1362054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "post heuristic handling failed");
1363054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(errno == ENOBUFS) {
1364054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(), "SMP Allocation failed");
1365054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //On SMP allocation failure in video only comp add padding round
1366054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->isPaddingRound = true;
1367054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1368054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1369054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1370054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1371054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1372054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED",
1373054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             __FUNCTION__);
1374054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1375054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1376054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1377054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* if tryFullFrame fails, try to push all video and secure RGB layers to MDP */
1378054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::tryMDPOnlyLayers(hwc_context_t *ctx,
1379054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
1380054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Fall back to video only composition, if AIV video mode is enabled
1381054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[mDpy].mAIVVideoMode) {
1382054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: AIV Video Mode enabled dpy %d",
1383054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            __FUNCTION__, mDpy);
1384054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1385054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1386054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1387054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const bool secureOnly = true;
1388054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return mdpOnlyLayersComp(ctx, list, not secureOnly) or
1389054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mdpOnlyLayersComp(ctx, list, secureOnly);
1390054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1391054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1392054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1393054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::mdpOnlyLayersComp(hwc_context_t *ctx,
1394054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list, bool secureOnly) {
1395054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1396054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sSimulationFlags & MDPCOMP_AVOID_MDP_ONLY_LAYERS)
1397054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1398054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1399054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1400054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isSecurePresent(ctx, mDpy) && !ctx->listStats[mDpy].secureUI) {
1401054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        /* Bail out if we are processing only secured video/ui layers
1402054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         * and we dont have any */
1403054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(secureOnly) {
1404abe67dd75cce255d3449ce9af5fa37109c83444eColin Cross            ALOGD_IF(isDebug(), "%s: No secure video/ui layers", __FUNCTION__);
1405054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
1406054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1407054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        /* No Idle fall back for secure video/ui layers and if there is only
1408054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         * single layer being composed. */
1409054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(sIdleFallBack && (ctx->listStats[mDpy].numAppLayers > 1)) {
1410054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
1411054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           return false;
1412054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       }
1413054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1414054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1415054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Bail out if we dont have any secure RGB layers */
1416054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (!ctx->listStats[mDpy].secureRGBCount) {
1417054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1418054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1419054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1420054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1421054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.reset(numAppLayers);
1422054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1423054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1424054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateYUV(ctx, list, secureOnly, mCurrentFrame);
1425054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* mark secure RGB layers for MDP comp */
1426054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateSecureRGB(ctx, list);
1427054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1428054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.mdpCount == 0) {
1429054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1430054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1431054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1432054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1433054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* find the maximum batch of layers to be marked for framebuffer */
1434054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool ret = markLayersForCaching(ctx, list); //sets up fbZ also
1435054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ret) {
1436054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy);
1437054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1438054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1439054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1440054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1441054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sEnableYUVsplit){
1442054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        adjustForSourceSplit(ctx, list);
1443054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1444054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1445054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!postHeuristicsHandling(ctx, list)) {
1446054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "post heuristic handling failed");
1447054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        reset(ctx);
1448054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1449054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1450054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1451054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(sSimulationFlags,"%s: MDP_ONLY_LAYERS_COMP SUCCEEDED",
1452054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             __FUNCTION__);
1453054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1454054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1455054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1456054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Checks for conditions where YUV layers cannot be bypassed */
1457054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1458054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isSkipLayer(layer)) {
1459054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy);
1460054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1461054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1462054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1463054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) {
1464054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__);
1465054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1466054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1467054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1468054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isSecuring(ctx, layer)) {
1469054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1470054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1471054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1472054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1473054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isValidDimension(ctx, layer)) {
1474054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
1475054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            __FUNCTION__);
1476054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1477054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1478054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1479054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(layer->planeAlpha < 0xFF) {
1480054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\
1481054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 in video only mode",
1482054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                 __FUNCTION__);
1483054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1484054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1485054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1486054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1487054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1488054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1489054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Checks for conditions where Secure RGB layers cannot be bypassed */
1490054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::isSecureRGBDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
1491054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isSkipLayer(layer)) {
1492054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Secure RGB layer marked SKIP dpy %d",
1493054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            __FUNCTION__, mDpy);
1494054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1495054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1496054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1497054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isSecuring(ctx, layer)) {
1498054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
1499054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1500054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1501054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1502054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(not isSupportedForMDPComp(ctx, layer)) {
1503054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Unsupported secure RGB layer",
1504054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            __FUNCTION__);
1505054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1506054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1507054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1508054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1509054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1510054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* starts at fromIndex and check for each layer to find
1511054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * if it it has overlapping with any Updating layer above it in zorder
1512054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * till the end of the batch. returns true if it finds any intersection */
1513054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list,
1514054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int fromIndex, int toIndex) {
1515054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = fromIndex; i < toIndex; i++) {
1516054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1517054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(intersectingUpdatingLayers(list, i+1, toIndex, i)) {
1518054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
1519054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1520054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1521054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1522054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1523054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1524054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1525054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* Checks if given layer at targetLayerIndex has any
1526054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * intersection with all the updating layers in beween
1527054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * fromIndex and toIndex. Returns true if it finds intersectiion */
1528054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list,
1529054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int fromIndex, int toIndex, int targetLayerIndex) {
1530054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = fromIndex; i <= toIndex; i++) {
1531054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!mCurrentFrame.isFBComposed[i]) {
1532054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(areLayersIntersecting(&list->hwLayers[i],
1533054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        &list->hwLayers[targetLayerIndex]))  {
1534054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return true;
1535054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1536054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1537054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1538054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return false;
1539054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1540054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1541054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::getBatch(hwc_display_contents_1_t* list,
1542054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int& maxBatchStart, int& maxBatchEnd,
1543054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int& maxBatchCount) {
1544054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int i = 0;
1545054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fbZOrder =-1;
1546054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int droppedLayerCt = 0;
1547054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    while (i < mCurrentFrame.layerCount) {
1548054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int batchCount = 0;
1549054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int batchStart = i;
1550054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int batchEnd = i;
1551054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        /* Adjust batch Z order with the dropped layers so far */
1552054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int fbZ = batchStart - droppedLayerCt;
1553054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int firstZReverseIndex = -1;
1554054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int updatingLayersAbove = 0;//Updating layer count in middle of batch
1555054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        while(i < mCurrentFrame.layerCount) {
1556054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mCurrentFrame.isFBComposed[i]) {
1557054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(!batchCount) {
1558054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    i++;
1559054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    break;
1560054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1561054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                updatingLayersAbove++;
1562054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                i++;
1563054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                continue;
1564054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            } else {
1565054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(mCurrentFrame.drop[i]) {
1566054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    i++;
1567054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    droppedLayerCt++;
1568054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    continue;
1569054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                } else if(updatingLayersAbove <= 0) {
1570054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    batchCount++;
1571054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    batchEnd = i;
1572054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    i++;
1573054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    continue;
1574054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                } else { //Layer is FBComposed, not a drop & updatingLayer > 0
1575054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1576054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    // We have a valid updating layer already. If layer-i not
1577054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    // have overlapping with all updating layers in between
1578054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    // batch-start and i, then we can add layer i to batch.
1579054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) {
1580054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        batchCount++;
1581054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        batchEnd = i;
1582054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        i++;
1583054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        continue;
1584054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    } else if(canPushBatchToTop(list, batchStart, i)) {
1585054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        //If All the non-updating layers with in this batch
1586054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        //does not have intersection with the updating layers
1587054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        //above in z-order, then we can safely move the batch to
1588054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        //higher z-order. Increment fbZ as it is moving up.
1589054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        if( firstZReverseIndex < 0) {
1590054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            firstZReverseIndex = i;
1591054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        }
1592054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        batchCount++;
1593054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        batchEnd = i;
1594054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        fbZ += updatingLayersAbove;
1595054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        i++;
1596054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        updatingLayersAbove = 0;
1597054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        continue;
1598054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    } else {
1599054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        //both failed.start the loop again from here.
1600054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        if(firstZReverseIndex >= 0) {
1601054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            i = firstZReverseIndex;
1602054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        }
1603054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        break;
1604054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    }
1605054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1606054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1607054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1608054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(batchCount > maxBatchCount) {
1609054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            maxBatchCount = batchCount;
1610054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            maxBatchStart = batchStart;
1611054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            maxBatchEnd = batchEnd;
1612054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            fbZOrder = fbZ;
1613054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1614054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1615054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return fbZOrder;
1616054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1617054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1618054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool  MDPComp::markLayersForCaching(hwc_context_t* ctx,
1619054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
1620054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Idea is to keep as many non-updating(cached) layers in FB and
1621054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * send rest of them through MDP. This is done in 2 steps.
1622054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     *   1. Find the maximum contiguous batch of non-updating layers.
1623054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     *   2. See if we can improve this batch size for caching by adding
1624054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     *      opaque layers around the batch, if they don't have
1625054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     *      any overlapping with the updating layers in between.
1626054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * NEVER mark an updating layer for caching.
1627054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * But cached ones can be marked for MDP */
1628054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1629054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int maxBatchStart = -1;
1630054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int maxBatchEnd = -1;
1631054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int maxBatchCount = 0;
1632054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fbZ = -1;
1633054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1634054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Nothing is cached. No batching needed */
1635054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.fbCount == 0) {
1636054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
1637054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1638054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1639054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* No MDP comp layers, try to use other comp modes */
1640054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.mdpCount == 0) {
1641054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1642054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1643054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1644054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount);
1645054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1646054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* reset rest of the layers lying inside ROI for MDP comp */
1647054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < mCurrentFrame.layerCount; i++) {
1648054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[i];
1649054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((i < maxBatchStart || i > maxBatchEnd) &&
1650054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.isFBComposed[i]){
1651054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mCurrentFrame.drop[i]){
1652054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                //If an unsupported layer is being attempted to
1653054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                //be pulled out we should fail
1654054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(not isSupportedForMDPComp(ctx, layer)) {
1655054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
1656054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1657054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.isFBComposed[i] = false;
1658054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1659054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1660054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1661054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1662054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // update the frame data
1663054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.fbZ = fbZ;
1664054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.fbCount = maxBatchCount;
1665054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1666054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1667054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1668054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
1669054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.fbCount);
1670054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1671054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1672054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1673054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1674054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::updateLayerCache(hwc_context_t* ctx,
1675054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list, FrameInfo& frame) {
1676054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
1677054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fbCount = 0;
1678054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1679054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numAppLayers; i++) {
168072aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R        hwc_layer_1_t * layer = &list->hwLayers[i];
168172aecbe8c0c4398ea5c996b913cda6adf2e01659Arun Kumar K.R        if (!layerUpdating(layer)) {
1682054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!frame.drop[i])
1683054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                fbCount++;
1684054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            frame.isFBComposed[i] = true;
1685054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
1686054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            frame.isFBComposed[i] = false;
1687054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1688054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1689054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1690054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    frame.fbCount = fbCount;
1691054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    frame.mdpCount = frame.layerCount - frame.fbCount
1692054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                            - frame.dropCount;
1693054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1694054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d",
1695054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            __FUNCTION__, frame.mdpCount, frame.fbCount, frame.dropCount);
1696054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1697054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1698054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// drop other non-AIV layers from external display list.
1699054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::dropNonAIVLayers(hwc_context_t* ctx,
1700054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                              hwc_display_contents_1_t* list) {
1701054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (size_t i = 0; i < (size_t)ctx->listStats[mDpy].numAppLayers; i++) {
1702054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t * layer = &list->hwLayers[i];
1703054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         if(!(isAIVVideoLayer(layer) || isAIVCCLayer(layer))) {
1704054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.dropCount++;
1705054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.drop[i] = true;
1706054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1707054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1708054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.fbCount -= mCurrentFrame.dropCount;
1709054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1710054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1711054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: fb count: %d mdp count %d drop count %d",
1712054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        __FUNCTION__, mCurrentFrame.fbCount, mCurrentFrame.mdpCount,
1713054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCurrentFrame.dropCount);
1714054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1715054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1716054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
1717054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bool secureOnly, FrameInfo& frame) {
1718054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int nYuvCount = ctx->listStats[mDpy].yuvCount;
1719054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0;index < nYuvCount; index++){
1720054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
1721054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
1722054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1723054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mCurrentFrame.drop[nYuvIndex]) {
1724054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
1725054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1726054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1727054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!isYUVDoable(ctx, layer)) {
1728054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!frame.isFBComposed[nYuvIndex]) {
1729054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                frame.isFBComposed[nYuvIndex] = true;
1730054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                frame.fbCount++;
1731054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1732054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
1733054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(frame.isFBComposed[nYuvIndex]) {
1734054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                private_handle_t *hnd = (private_handle_t *)layer->handle;
1735054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(!secureOnly || isSecureBuffer(hnd)) {
1736054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    frame.isFBComposed[nYuvIndex] = false;
1737054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    frame.fbCount--;
1738054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1739054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1740054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1741054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1742054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1743054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    frame.mdpCount = frame.layerCount - frame.fbCount - frame.dropCount;
1744054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, frame.fbCount);
1745054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1746054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1747054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::updateSecureRGB(hwc_context_t* ctx,
1748054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_display_contents_1_t* list) {
1749054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int nSecureRGBCount = ctx->listStats[mDpy].secureRGBCount;
1750054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0;index < nSecureRGBCount; index++){
1751054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int nSecureRGBIndex = ctx->listStats[mDpy].secureRGBIndices[index];
1752054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[nSecureRGBIndex];
1753054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1754054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!isSecureRGBDoable(ctx, layer)) {
1755054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1756054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.isFBComposed[nSecureRGBIndex] = true;
1757054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.fbCount++;
1758054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1759054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
1760054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(mCurrentFrame.isFBComposed[nSecureRGBIndex]) {
1761054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.isFBComposed[nSecureRGBIndex] = false;
1762054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mCurrentFrame.fbCount--;
1763054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1764054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1765054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1766054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1767054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
1768054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.fbCount - mCurrentFrame.dropCount;
1769054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__,
1770054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             mCurrentFrame.fbCount);
1771054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1772054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1773054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinhwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx,
1774054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list){
1775054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0};
1776054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1777054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Update only the region of FB needed for composition */
1778054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < mCurrentFrame.layerCount; i++ ) {
1779054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) {
1780054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_layer_1_t* layer = &list->hwLayers[i];
1781054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_rect_t dst = layer->displayFrame;
1782054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            fbRect = getUnion(fbRect, dst);
1783054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1784054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
17859f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    trimAgainstROI(ctx, fbRect, fbRect);
1786054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return fbRect;
1787054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1788054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1789054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::postHeuristicsHandling(hwc_context_t *ctx,
1790054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
1791054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1792054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Capability checks
1793054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!resourceCheck(ctx, list)) {
1794054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__);
1795054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1796054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1797054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1798054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Limitations checks
1799054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!hwLimitationsCheck(ctx, list)) {
1800054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
1801054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1802054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1803054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1804054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Configure framebuffer first if applicable
1805054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.fbZ >= 0) {
1806054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t fbRect = getUpdatingFBRect(ctx, list);
1807054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ))
1808054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        {
1809054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(), "%s configure framebuffer failed",
1810054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    __FUNCTION__);
1811054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
1812054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1813054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1814054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1815054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.map();
1816054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1817054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!allocLayerPipes(ctx, list)) {
1818054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
1819054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1820054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1821054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1822054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
1823054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            index++) {
1824054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!mCurrentFrame.isFBComposed[index]) {
1825054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int mdpIndex = mCurrentFrame.layerToMDP[index];
1826054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_layer_1_t* layer = &list->hwLayers[index];
1827054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1828054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //Leave fbZ for framebuffer. CACHE/GLES layers go here.
1829054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(mdpNextZOrder == mCurrentFrame.fbZ) {
1830054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mdpNextZOrder++;
1831054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1832054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1833054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            cur_pipe->zOrder = mdpNextZOrder++;
1834054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1835054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            private_handle_t *hnd = (private_handle_t *)layer->handle;
1836054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
1837054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(configure4k2kYuv(ctx, layer,
1838054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            mCurrentFrame.mdpToLayer[mdpIndex])
1839054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        != 0 ){
1840054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \
1841054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            for layer %d",__FUNCTION__, index);
1842054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
1843054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1844054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                else{
1845054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    mdpNextZOrder++;
1846054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1847054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                continue;
1848054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1849054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
1850054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
1851054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        layer %d",__FUNCTION__, index);
1852054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
1853054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1854054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1855054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1856054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1857054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) {
1858054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d"
1859054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ,__FUNCTION__, mDpy);
1860054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1861054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1862054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1863054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    setRedraw(ctx, list);
1864054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1865054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1866054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1867054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::resourceCheck(hwc_context_t* ctx,
1868054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
1869054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const bool fbUsed = mCurrentFrame.fbCount;
1870054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) {
1871054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
1872054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1873054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1874054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1875054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Will benefit cases where a video has non-updating background.
1876054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((mDpy > HWC_DISPLAY_PRIMARY) and
1877054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (mCurrentFrame.mdpCount > sMaxSecLayers)) {
1878054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__);
1879054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1880054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1881054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1882054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Init rotCount to number of rotate sessions used by other displays
1883054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int rotCount = ctx->mRotMgr->getNumActiveSessions();
1884054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Count the number of rotator sessions required for current display
1885054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for (int index = 0; index < mCurrentFrame.layerCount; index++) {
1886054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!mCurrentFrame.isFBComposed[index]) {
1887054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_layer_1_t* layer = &list->hwLayers[index];
1888054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            private_handle_t *hnd = (private_handle_t *)layer->handle;
1889054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
1890054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                rotCount++;
1891054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1892054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1893054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1894054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // if number of layers to rotate exceeds max rotator sessions, bail out.
1895054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(rotCount > RotMgr::MAX_ROT_SESS) {
1896054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions  %d",
1897054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                    __FUNCTION__, mDpy);
1898054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
1899054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1900054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1901054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1902054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1903054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
1904054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
1905054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1906054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //A-family hw limitation:
1907054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If a layer need alpha scaling, MDP can not support.
1908054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->mMDP.version < qdutils::MDSS_V5) {
1909054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
1910054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mCurrentFrame.isFBComposed[i] &&
1911054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    isAlphaScaled( &list->hwLayers[i])) {
1912054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
1913054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
1914054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1915054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1916054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1917054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1918054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
1919054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If multiple layers requires downscaling and also they are overlapping
1920054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //fall back to GPU since MDSS can not handle it.
1921054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(qdutils::MDPVersion::getInstance().is8x74v2() ||
1922054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qdutils::MDPVersion::getInstance().is8x26()) {
1923054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
1924054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_layer_1_t* botLayer = &list->hwLayers[i];
1925054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mCurrentFrame.isFBComposed[i] &&
1926054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    isDownscaleRequired(botLayer)) {
1927054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                //if layer-i is marked for MDP and needs downscaling
1928054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                //check if any MDP layer on top of i & overlaps with layer-i
1929054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
1930054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    hwc_layer_1_t* topLayer = &list->hwLayers[j];
1931054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    if(!mCurrentFrame.isFBComposed[j] &&
1932054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            isDownscaleRequired(topLayer)) {
1933054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        hwc_rect_t r = getIntersection(botLayer->displayFrame,
1934054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                topLayer->displayFrame);
1935054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        if(isValidRect(r))
1936054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            return false;
1937054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    }
1938054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
1939054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
1940054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1941054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1942054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
1943054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1944054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1945054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// Checks only if videos or single layer(RGB) is updating
1946054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// which is used for setting dynamic fps or perf hint for single
1947054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin// layer video playback
1948054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::onlyVideosUpdating(hwc_context_t *ctx,
1949054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                hwc_display_contents_1_t* list) {
1950054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool support = false;
1951054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    FrameInfo frame;
1952054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    frame.reset(mCurrentFrame.layerCount);
1953054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&frame.drop, 0, sizeof(frame.drop));
1954054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    frame.dropCount = 0;
1955054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(), "%s: Update Cache and YUVInfo", __FUNCTION__);
1956054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateLayerCache(ctx, list, frame);
1957054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    updateYUV(ctx, list, false /*secure only*/, frame);
1958054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // There are only updating YUV layers or there is single RGB
1959054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Layer(Youtube)
1960054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((ctx->listStats[mDpy].yuvCount == frame.mdpCount) ||
1961054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                        (frame.layerCount == 1)) {
1962054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        support = true;
1963054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1964054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return support;
1965054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1966054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1967054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::setDynRefreshRate(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1968054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //For primary display, set the dynamic refreshrate
1969054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!mDpy && qdutils::MDPVersion::getInstance().isDynFpsSupported() &&
1970054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                        ctx->mUseMetaDataRefreshRate) {
1971054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        uint32_t refreshRate = ctx->dpyAttr[mDpy].refreshRate;
1972054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        MDPVersion& mdpHw = MDPVersion::getInstance();
1973054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(sIdleFallBack) {
1974054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //Set minimum panel refresh rate during idle timeout
1975054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            refreshRate = mdpHw.getMinFpsSupported();
1976054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else if(onlyVideosUpdating(ctx, list)) {
1977054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //Set the new fresh rate, if there is only one updating YUV layer
1978054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //or there is one single RGB layer with this request
1979054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            refreshRate = ctx->listStats[mDpy].refreshRateRequest;
1980054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
1981054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        setRefreshRate(ctx, mDpy, refreshRate);
1982054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1983054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
1984054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1985054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1986054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int ret = 0;
1987054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char property[PROPERTY_VALUE_MAX];
1988054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1989054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx || !list) {
1990054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Invalid context or list",__FUNCTION__);
1991054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCachedFrame.reset();
1992054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
1993054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
1994054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
1995054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int numLayers = ctx->listStats[mDpy].numAppLayers;
1996054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mDpy == HWC_DISPLAY_PRIMARY) {
1997054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sSimulationFlags = 0;
1998054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(property_get("debug.hwc.simulate", property, NULL) > 0) {
1999054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int currentFlags = atoi(property);
2000054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(currentFlags != sSimulationFlags) {
2001054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                sSimulationFlags = currentFlags;
2002054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGI("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__,
2003054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        sSimulationFlags, sSimulationFlags);
2004054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2005054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2006054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2007054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // reset PTOR
2008054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!mDpy)
2009054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
2010054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2011054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //reset old data
2012054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.reset(numLayers);
2013054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2014054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCurrentFrame.dropCount = 0;
2015054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2016054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Do not cache the information for next draw cycle.
2017054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) {
201872579d94ed598c55a7faa2bedcb2689c7353b579Naseer Ahmed        ALOGI_IF(numLayers, "%s: Unsupported layer count for mdp composition: %d",
201972579d94ed598c55a7faa2bedcb2689c7353b579Naseer Ahmed                __FUNCTION__, numLayers);
2020054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCachedFrame.reset();
2021054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef DYNAMIC_FPS
20224986a66403dd53ee83d1b58cfc2c0cfd95e73112Arun Kumar K.R        // Reset refresh rate
20234986a66403dd53ee83d1b58cfc2c0cfd95e73112Arun Kumar K.R        setRefreshRate(ctx, mDpy, ctx->dpyAttr[mDpy].refreshRate);
2024054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
2025054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
2026054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2027054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2028054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Detect the start of animation and fall back to GPU only once to cache
2029054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // all the layers in FB and display FB content untill animation completes.
2030054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[mDpy].isDisplayAnimating) {
2031054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCurrentFrame.needsRedraw = false;
2032054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) {
2033054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.needsRedraw = true;
2034054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ctx->mAnimationState[mDpy] = ANIMATION_STARTED;
2035054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2036054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        setMDPCompLayerFlags(ctx, list);
2037054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mCachedFrame.updateCounts(mCurrentFrame);
2038054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef DYNAMIC_FPS
20394986a66403dd53ee83d1b58cfc2c0cfd95e73112Arun Kumar K.R        // Reset refresh rate
20404986a66403dd53ee83d1b58cfc2c0cfd95e73112Arun Kumar K.R        setRefreshRate(ctx, mDpy, ctx->dpyAttr[mDpy].refreshRate);
2041054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
2042054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret = -1;
2043054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return ret;
2044054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
2045054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mAnimationState[mDpy] = ANIMATION_STOPPED;
2046054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2047054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2048054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Hard conditions, if not met, cannot do MDP comp
2049054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isFrameDoable(ctx)) {
2050054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        generateROI(ctx, list);
2051054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // if AIV Video mode is enabled, drop all non AIV layers from the
2052054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // external display list.
2053054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(ctx->listStats[mDpy].mAIVVideoMode) {
2054054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            dropNonAIVLayers(ctx, list);
2055054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2056054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2057054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // if tryFullFrame fails, try to push all video and secure RGB layers
2058054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        // to MDP for composition.
2059054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        mModeOn = tryFullFrame(ctx, list) || tryMDPOnlyLayers(ctx, list) ||
2060054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                  tryVideoOnly(ctx, list);
2061054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mModeOn) {
2062054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            setMDPCompLayerFlags(ctx, list);
2063054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        } else {
2064054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            resetROI(ctx, mDpy);
2065054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            reset(ctx);
2066054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
2067054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mCurrentFrame.dropCount = 0;
2068054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ret = -1;
2069054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE_IF(sSimulationFlags && (mDpy == HWC_DISPLAY_PRIMARY),
2070054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    "MDP Composition Strategies Failed");
2071054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2072054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
2073054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if ((ctx->mMDP.version == qdutils::MDP_V3_0_5) && ctx->mCopyBit[mDpy] &&
2074054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                enablePartialUpdateForMDP3) {
2075054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            generateROI(ctx, list);
2076054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            for(int i = 0; i < ctx->listStats[mDpy].numAppLayers; i++) {
2077054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->copybitDrop[i] = mCurrentFrame.drop[i];
2078054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2079054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2080054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
2081054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__);
2082054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ret = -1;
2083054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2084054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2085054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(isDebug()) {
2086054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD("GEOMETRY change: %d",
2087054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (list->flags & HWC_GEOMETRY_CHANGED));
2088054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        android::String8 sDump("");
2089054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dump(sDump, ctx);
2090054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD("%s",sDump.string());
2091054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2092054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2093054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#ifdef DYNAMIC_FPS
2094054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    setDynRefreshRate(ctx, list);
2095054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#endif
2096054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    setPerfHint(ctx, list);
2097054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2098054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    mCachedFrame.updateCounts(mCurrentFrame);
2099054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return ret;
2100054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2101054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2102054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) {
2103054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2104054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool bRet = true;
2105054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int mdpIndex = mCurrentFrame.layerToMDP[index];
2106054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2107054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    info.pipeInfo = new MdpYUVPipeInfo;
2108054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    info.rot = NULL;
2109054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
2110054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2111054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.lIndex = ovutils::OV_INVALID;
2112054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.rIndex = ovutils::OV_INVALID;
2113054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2114054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Overlay::PipeSpecs pipeSpecs;
2115054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.formatClass = Overlay::FORMAT_YUV;
2116054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.needsScaling = true;
2117054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.dpy = mDpy;
2118054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.fb = false;
2119054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2120054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
2121054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(pipe_info.lIndex == ovutils::OV_INVALID){
2122054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bRet = false;
2123054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
2124054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__);
2125054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2126054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
2127054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(pipe_info.rIndex == ovutils::OV_INVALID){
2128054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bRet = false;
2129054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
2130054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                __FUNCTION__);
2131054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2132054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return bRet;
2133054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2134054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2135054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2136054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fd = -1;
2137054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (ctx->mPtorInfo.isActive()) {
2138054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list);
2139054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (fd < 0) {
2140054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__);
2141054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2142054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2143054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return fd;
2144054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2145054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//=============MDPCompNonSplit==================================================
2146054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2147054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx,
2148054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
2149054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If 4k2k Yuv layer split is possible,  and if
2150054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //fbz is above 4k2k layer, increment fb zorder by 1
2151054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //as we split 4k2k layer and increment zorder for right half
2152054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //of the layer
2153054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!ctx)
2154054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
2155054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.fbZ >= 0) {
2156054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2157054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                index++) {
2158054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mCurrentFrame.isFBComposed[index]) {
2159054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(mdpNextZOrder == mCurrentFrame.fbZ) {
2160054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    mdpNextZOrder++;
2161054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2162054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mdpNextZOrder++;
2163054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                hwc_layer_1_t* layer = &list->hwLayers[index];
2164054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                private_handle_t *hnd = (private_handle_t *)layer->handle;
2165054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(isYUVSplitNeeded(hnd)) {
2166054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    if(mdpNextZOrder <= mCurrentFrame.fbZ)
2167054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        mCurrentFrame.fbZ += 1;
2168054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    mdpNextZOrder++;
2169054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    //As we split 4kx2k yuv layer and program to 2 VG pipes
2170054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    //(if available) increase mdpcount by 1.
2171054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    mCurrentFrame.mdpCount++;
2172054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2173054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2174054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2175054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2176054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2177054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2178054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/*
2179054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Configures pipe(s) for MDP composition
2180054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */
2181054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2182054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                             PipeLayerPair& PipeLayerPair) {
2183054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MdpPipeInfoNonSplit& mdp_info =
2184054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo));
2185054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
2186054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2187054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eDest dest = mdp_info.index;
2188054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2189054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
2190054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             __FUNCTION__, layer, zOrder, dest);
2191054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2192054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, dest,
2193054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                           &PipeLayerPair.rot);
2194054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2195054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2196054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx,
2197054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
2198054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0; index < mCurrentFrame.layerCount; index++) {
2199054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2200054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mCurrentFrame.isFBComposed[index]) continue;
2201054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2202054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[index];
2203054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
2204054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2205054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(allocSplitVGPipesfor4k2k(ctx, index)){
2206054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                continue;
2207054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2208054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2209054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2210054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int mdpIndex = mCurrentFrame.layerToMDP[index];
2211054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2212054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        info.pipeInfo = new MdpPipeInfoNonSplit;
2213054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        info.rot = NULL;
2214054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
2215054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2216054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        Overlay::PipeSpecs pipeSpecs;
2217054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2218054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2219054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
2220054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (qdutils::MDPVersion::getInstance().is8x26() and
2221054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
2222054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipeSpecs.dpy = mDpy;
2223054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipeSpecs.fb = false;
2224054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipeSpecs.numActiveDisplays = ctx->numActiveDisplays;
2225054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2226054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
2227054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2228054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(pipe_info.index == ovutils::OV_INVALID) {
2229054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
2230054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
2231054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2232054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2233054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
2234054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2235054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2236054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2237054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeLayerPair& PipeLayerPair) {
2238054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MdpYUVPipeInfo& mdp_info =
2239054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2240054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2241054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
2242054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eDest lDest = mdp_info.lIndex;
2243054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eDest rDest = mdp_info.rIndex;
2244054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2245054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
2246054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            lDest, rDest, &PipeLayerPair.rot);
2247054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2248054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2249054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2250054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2251054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isEnabled() or !mModeOn) {
2252054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
2253054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
2254054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2255054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2256054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Set the Handle timeout to true for MDP or MIXED composition.
2257054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2258054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sHandleTimeout = true;
2259054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2260054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2261054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    overlay::Overlay& ov = *ctx->mOverlay;
2262054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    LayerProp *layerProp = ctx->layerProp[mDpy];
2263054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2264054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2265054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
2266054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    {
2267054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mCurrentFrame.isFBComposed[i]) continue;
2268054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2269054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t *layer = &list->hwLayers[i];
2270054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
2271054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!hnd) {
2272054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (!(layer->flags & HWC_COLOR_FILL)) {
2273054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGE("%s handle null", __FUNCTION__);
2274054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
2275054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2276054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            // No PLAY for Color layer
2277054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            layerProp[i].mFlags &= ~HWC_MDPCOMP;
2278054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
2279054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2280054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2281054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int mdpIndex = mCurrentFrame.layerToMDP[i];
2282054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2283054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
2284054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        {
2285054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            MdpYUVPipeInfo& pipe_info =
2286054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2287054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2288054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::eDest indexL = pipe_info.lIndex;
2289054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::eDest indexR = pipe_info.rIndex;
2290054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int fd = hnd->fd;
2291054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            uint32_t offset = (uint32_t)hnd->offset;
2292054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(rot) {
2293054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                rot->queueBuffer(fd, offset);
2294054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                fd = rot->getDstMemId();
2295054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                offset = rot->getDstOffset();
2296054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2297054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(indexL != ovutils::OV_INVALID) {
2298054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::eDest destL = (ovutils::eDest)indexL;
2299054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2300054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
2301054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if (!ov.queueBuffer(fd, offset, destL)) {
2302054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    ALOGE("%s: queueBuffer failed for display:%d",
2303054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            __FUNCTION__, mDpy);
2304054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
2305054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2306054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2307054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2308054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(indexR != ovutils::OV_INVALID) {
2309054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::eDest destR = (ovutils::eDest)indexR;
2310054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2311054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
2312054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if (!ov.queueBuffer(fd, offset, destR)) {
2313054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    ALOGE("%s: queueBuffer failed for display:%d",
2314054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            __FUNCTION__, mDpy);
2315054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
2316054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2317054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2318054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2319054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        else{
2320054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            MdpPipeInfoNonSplit& pipe_info =
2321054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2322054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::eDest dest = pipe_info.index;
2323054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(dest == ovutils::OV_INVALID) {
2324054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
2325054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
2326054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2327054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2328054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2329054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                continue;
2330054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2331054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2332054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int fd = hnd->fd;
2333054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            uint32_t offset = (uint32_t)hnd->offset;
2334054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2335054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (!mDpy && (index != -1)) {
2336054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2337054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                fd = hnd->fd;
2338054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                offset = 0;
2339054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2340054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2341054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2342054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    using  pipe: %d", __FUNCTION__, layer,
2343054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    hnd, dest );
2344054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2345054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2346054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(rot) {
2347054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(!rot->queueBuffer(fd, offset))
2348054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
2349054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                fd = rot->getDstMemId();
2350054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                offset = rot->getDstOffset();
2351054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2352054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2353054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (!ov.queueBuffer(fd, offset, dest)) {
2354054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGE("%s: queueBuffer failed for display:%d ",
2355054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        __FUNCTION__, mDpy);
2356054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                return false;
2357054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2358054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2359054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2360054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layerProp[i].mFlags &= ~HWC_MDPCOMP;
2361054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2362054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
2363054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2364054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2365054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//=============MDPCompSplit===================================================
2366054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2367054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx,
2368054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin         hwc_display_contents_1_t* list){
2369054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //if 4kx2k yuv layer is totally present in either in left half
2370054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //or right half then try splitting the yuv layer to avoid decimation
2371054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int lSplit = getLeftSplit(ctx, mDpy);
2372054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(mCurrentFrame.fbZ >= 0) {
2373054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
2374054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                index++) {
2375054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(!mCurrentFrame.isFBComposed[index]) {
2376054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(mdpNextZOrder == mCurrentFrame.fbZ) {
2377054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    mdpNextZOrder++;
2378054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2379054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                mdpNextZOrder++;
2380054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                hwc_layer_1_t* layer = &list->hwLayers[index];
2381054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                private_handle_t *hnd = (private_handle_t *)layer->handle;
2382054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(isYUVSplitNeeded(hnd)) {
2383054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    hwc_rect_t dst = layer->displayFrame;
2384054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    if((dst.left > lSplit) || (dst.right < lSplit)) {
2385054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        mCurrentFrame.mdpCount += 1;
2386054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    }
2387054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    if(mdpNextZOrder <= mCurrentFrame.fbZ)
2388054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        mCurrentFrame.fbZ += 1;
2389054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    mdpNextZOrder++;
2390054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2391054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2392054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2393054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2394054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2395054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2396054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
2397054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        MdpPipeInfoSplit& pipe_info) {
2398054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2399054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int lSplit = getLeftSplit(ctx, mDpy);
2400054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
2401054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
2402054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.lIndex = ovutils::OV_INVALID;
2403054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.rIndex = ovutils::OV_INVALID;
2404054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2405054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Overlay::PipeSpecs pipeSpecs;
2406054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2407054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2408054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
2409054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.dpy = mDpy;
2410054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.mixer = Overlay::MIXER_LEFT;
2411054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.fb = false;
2412054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2413054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Acquire pipe only for the updating half
2414054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi;
2415054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi;
2416054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2417054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) {
2418054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
2419054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(pipe_info.lIndex == ovutils::OV_INVALID)
2420054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
2421054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2422054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2423054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) {
2424054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipeSpecs.mixer = Overlay::MIXER_RIGHT;
2425054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
2426054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(pipe_info.rIndex == ovutils::OV_INVALID)
2427054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
2428054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2429054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2430054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
2431054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2432054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2433054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx,
2434054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_display_contents_1_t* list) {
2435054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
2436054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2437054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mCurrentFrame.isFBComposed[index]) continue;
2438054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2439054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t* layer = &list->hwLayers[index];
2440054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
2441054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_rect_t dst = layer->displayFrame;
2442054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        const int lSplit = getLeftSplit(ctx, mDpy);
2443054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isYUVSplitNeeded(hnd) && sEnableYUVsplit){
2444054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if((dst.left > lSplit)||(dst.right < lSplit)){
2445054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if(allocSplitVGPipesfor4k2k(ctx, index)){
2446054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    continue;
2447054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2448054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2449054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2450054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int mdpIndex = mCurrentFrame.layerToMDP[index];
2451054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
2452054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        info.pipeInfo = new MdpPipeInfoSplit;
2453054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        info.rot = NULL;
2454054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
2455054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2456054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!acquireMDPPipes(ctx, layer, pipe_info)) {
2457054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
2458054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    __FUNCTION__);
2459054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
2460054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2461054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2462054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
2463054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2464054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2465054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
2466054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeLayerPair& PipeLayerPair) {
2467054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int lSplit = getLeftSplit(ctx, mDpy);
2468054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
2469054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((dst.left > lSplit)||(dst.right < lSplit)){
2470054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        MdpYUVPipeInfo& mdp_info =
2471054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo));
2472054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2473054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
2474054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        eDest lDest = mdp_info.lIndex;
2475054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        eDest rDest = mdp_info.rIndex;
2476054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2477054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder,
2478054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                lDest, rDest, &PipeLayerPair.rot);
2479054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2480054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    else{
2481054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return configure(ctx, layer, PipeLayerPair);
2482054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2483054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2484054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2485054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/*
2486054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Configures pipe(s) for MDP composition
2487054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin */
2488054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2489054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeLayerPair& PipeLayerPair) {
2490054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MdpPipeInfoSplit& mdp_info =
2491054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2492054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
2493054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
2494054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eDest lDest = mdp_info.lIndex;
2495054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eDest rDest = mdp_info.rIndex;
2496054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2497054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2498054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
2499054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2500054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, lDest,
2501054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            rDest, &PipeLayerPair.rot);
2502054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2503054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2504054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2505054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2506054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!isEnabled() or !mModeOn) {
2507054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__);
2508054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return true;
2509054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2510054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2511054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Set the Handle timeout to true for MDP or MIXED composition.
2512054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sIdleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) {
2513054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sHandleTimeout = true;
2514054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2515054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2516054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    overlay::Overlay& ov = *ctx->mOverlay;
2517054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    LayerProp *layerProp = ctx->layerProp[mDpy];
2518054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2519054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int numHwLayers = ctx->listStats[mDpy].numAppLayers;
2520054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
2521054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    {
2522054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(mCurrentFrame.isFBComposed[i]) continue;
2523054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2524054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        hwc_layer_1_t *layer = &list->hwLayers[i];
2525054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        private_handle_t *hnd = (private_handle_t *)layer->handle;
2526054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!hnd) {
2527054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s handle null", __FUNCTION__);
2528054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
2529054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2530054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2531054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
2532054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            continue;
2533054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2534054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2535054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int mdpIndex = mCurrentFrame.layerToMDP[i];
2536054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2537054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(isYUVSplitNeeded(hnd) && sEnableYUVsplit)
2538054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        {
2539054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            MdpYUVPipeInfo& pipe_info =
2540054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2541054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2542054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::eDest indexL = pipe_info.lIndex;
2543054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::eDest indexR = pipe_info.rIndex;
2544054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int fd = hnd->fd;
2545054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            uint32_t offset = (uint32_t)hnd->offset;
2546054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(rot) {
2547054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                rot->queueBuffer(fd, offset);
2548054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                fd = rot->getDstMemId();
2549054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                offset = rot->getDstOffset();
2550054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2551054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(indexL != ovutils::OV_INVALID) {
2552054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::eDest destL = (ovutils::eDest)indexL;
2553054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2554054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
2555054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if (!ov.queueBuffer(fd, offset, destL)) {
2556054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    ALOGE("%s: queueBuffer failed for display:%d",
2557054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            __FUNCTION__, mDpy);
2558054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
2559054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2560054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2561054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2562054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(indexR != ovutils::OV_INVALID) {
2563054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::eDest destR = (ovutils::eDest)indexR;
2564054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2565054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
2566054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if (!ov.queueBuffer(fd, offset, destR)) {
2567054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    ALOGE("%s: queueBuffer failed for display:%d",
2568054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            __FUNCTION__, mDpy);
2569054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
2570054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2571054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2572054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2573054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        else{
2574054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            MdpPipeInfoSplit& pipe_info =
2575054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
2576054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
2577054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2578054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::eDest indexL = pipe_info.lIndex;
2579054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ovutils::eDest indexR = pipe_info.rIndex;
2580054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2581054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int fd = hnd->fd;
2582054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            uint32_t offset = (uint32_t)hnd->offset;
2583054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            int index = ctx->mPtorInfo.getPTORArrayIndex(i);
2584054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if (!mDpy && (index != -1)) {
2585054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer();
2586054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                fd = hnd->fd;
2587054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                offset = 0;
2588054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2589054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2590054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(ctx->mAD->draw(ctx, fd, offset)) {
2591054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                fd = ctx->mAD->getDstFd();
2592054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                offset = ctx->mAD->getDstOffset();
2593054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2594054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2595054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(rot) {
2596054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                rot->queueBuffer(fd, offset);
2597054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                fd = rot->getDstMemId();
2598054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                offset = rot->getDstOffset();
2599054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2600054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2601054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //************* play left mixer **********
2602054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(indexL != ovutils::OV_INVALID) {
2603054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::eDest destL = (ovutils::eDest)indexL;
2604054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2605054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
2606054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if (!ov.queueBuffer(fd, offset, destL)) {
2607054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    ALOGE("%s: queueBuffer failed for left mixer",
2608054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            __FUNCTION__);
2609054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
2610054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2611054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2612054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2613054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            //************* play right mixer **********
2614054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            if(indexR != ovutils::OV_INVALID) {
2615054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ovutils::eDest destR = (ovutils::eDest)indexR;
2616054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
2617054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                        using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
2618054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                if (!ov.queueBuffer(fd, offset, destR)) {
2619054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    ALOGE("%s: queueBuffer failed for right mixer",
2620054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                            __FUNCTION__);
2621054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    return false;
2622054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                }
2623054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            }
2624054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2625054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2626054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        layerProp[i].mFlags &= ~HWC_MDPCOMP;
2627054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2628054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2629054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
2630054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2631054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2632054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//================MDPCompSrcSplit==============================================
26339f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26349f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.Rbool MDPCompSrcSplit::validateAndApplyROI(hwc_context_t *ctx,
26359f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        hwc_display_contents_1_t* list) {
26369f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
26379f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi;
26389f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26399f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    for(int i = numAppLayers - 1; i >= 0; i--) {
26409f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        if(!isValidRect(visibleRect)) {
26419f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            mCurrentFrame.drop[i] = true;
26429f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            mCurrentFrame.dropCount++;
26439f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            continue;
26449f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        }
26459f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26469f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        const hwc_layer_1_t* layer =  &list->hwLayers[i];
26479f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        hwc_rect_t dstRect = layer->displayFrame;
26489f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        hwc_rect_t res  = getIntersection(visibleRect, dstRect);
26499f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26509f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        if(!isValidRect(res)) {
26519f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            mCurrentFrame.drop[i] = true;
26529f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            mCurrentFrame.dropCount++;
26539f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        } else {
26549f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            /* Reset frame ROI when any layer which needs scaling also needs ROI
26559f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R             * cropping */
26569f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            if(!isSameRect(res, dstRect) && needsScaling (layer)) {
26579f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R                ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
26589f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R                memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
26599f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R                mCurrentFrame.dropCount = 0;
26609f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R                return false;
26619f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            }
26629f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26639f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            /* deduct any opaque region from visibleRect */
26649f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            if (layer->blending == HWC_BLENDING_NONE &&
26659f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R                    layer->planeAlpha == 0xFF)
26669f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R                visibleRect = deductRect(visibleRect, res);
26679f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        }
26689f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    }
26699f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    return true;
26709f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R}
26719f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26729f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R/*
26739f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R * HW Limitation: ping pong split can always split the ping pong output
26749f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R * equally across two DSI's. So the ROI programmed should be of equal width
26759f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R * for both the halves
26769f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R */
26779f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.Rvoid MDPCompSrcSplit::generateROI(hwc_context_t *ctx,
26789f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        hwc_display_contents_1_t* list) {
26799f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
26809f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26819f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    if(!canPartialUpdate(ctx, list))
26829f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        return;
26839f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26849f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0};
26859f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres,
26869f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        (int)ctx->dpyAttr[mDpy].yres};
26879f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26889f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    for(int index = 0; index < numAppLayers; index++ ) {
26899f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        hwc_layer_1_t* layer = &list->hwLayers[index];
26909f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
26919f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        // If we have a RGB layer which needs rotation, no partial update
26929f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        if(!isYuvBuffer((private_handle_t *)layer->handle) && layer->transform)
26939f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            return;
26949f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2695de608742bddfc2840f4d49932884e9e62a3b8f0dArun Kumar K.R        if (layerUpdating(layer) ||
26969f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R                isYuvBuffer((private_handle_t *)layer->handle)) {
269741ac35e73491eb7e3337abe257c042dac4ad2e1fArun Kumar K.R            hwc_rect_t dirtyRect = getIntersection(layer->displayFrame,
269841ac35e73491eb7e3337abe257c042dac4ad2e1fArun Kumar K.R                                                    fullFrame);
2699de608742bddfc2840f4d49932884e9e62a3b8f0dArun Kumar K.R            if (!needsScaling(layer) && !layer->transform) {
2700de608742bddfc2840f4d49932884e9e62a3b8f0dArun Kumar K.R                dirtyRect = calculateDirtyRect(layer, fullFrame);
27019f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            }
2702de608742bddfc2840f4d49932884e9e62a3b8f0dArun Kumar K.R            roi = getUnion(roi, dirtyRect);
27039f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        }
27049f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    }
27059f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
27069f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    /* No layer is updating. Still SF wants a refresh.*/
27079f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    if(!isValidRect(roi))
27089f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        return;
27099f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2710298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R    if (isDisplaySplit(ctx, mDpy)) {
2711298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        hwc_rect lFrame = fullFrame;
2712298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        roi = expandROIFromMidPoint(roi, fullFrame);
27139f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2714298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        lFrame.right = fullFrame.right / 2;
2715298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        hwc_rect lRoi = getIntersection(roi, lFrame);
2716298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        // Align ROI coordinates to panel restrictions
2717298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        lRoi = getSanitizeROI(lRoi, lFrame);
27189f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2719298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        hwc_rect rFrame = fullFrame;
2720298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        rFrame.left = fullFrame.right/2;
2721298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        hwc_rect rRoi = getIntersection(roi, rFrame);
2722298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        // Align ROI coordinates to panel restrictions
2723298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        rRoi = getSanitizeROI(rRoi, rFrame);
27249f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2725298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        roi = getUnion(lRoi, rRoi);
27269f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2727298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R        ctx->listStats[mDpy].lRoi = roi;
2728298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R    } else {
2729298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R      hwc_rect lRoi = getIntersection(roi, fullFrame);
2730298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R      // Align ROI coordinates to panel restrictions
2731298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R      lRoi = getSanitizeROI(lRoi, fullFrame);
27329f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2733298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R      ctx->listStats[mDpy].lRoi = lRoi;
2734298391fb24e1303c50b9d4172efe2bb9940114faArun Kumar K.R    }
27359f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
27369f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    if(!validateAndApplyROI(ctx, list))
27379f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        resetROI(ctx, mDpy);
27389f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
27399f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d] [%d, %d, %d, %d]",
27409f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            __FUNCTION__,
27419f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top,
27429f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom,
27439f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top,
27449f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R            ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom);
27459f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R}
27469f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2747054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
2748054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        MdpPipeInfoSplit& pipe_info) {
2749054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
2750054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
2751054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2752054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.lIndex = ovutils::OV_INVALID;
2753054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.rIndex = ovutils::OV_INVALID;
2754054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
27559f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy)
27569f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        trimAgainstROI(ctx,crop, dst);
27579f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2758054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If 2 pipes are staged on a single stage of a mixer, then the left pipe
2759054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //should have a higher priority than the right one. Pipe priorities are
2760054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //starting with VG0, VG1 ... , RGB0 ..., DMA1
2761054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2762054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Overlay::PipeSpecs pipeSpecs;
2763054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.formatClass = isYuvBuffer(hnd) ?
2764054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
2765054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.needsScaling = qhwc::needsScaling(layer);
2766054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.dpy = mDpy;
2767054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipeSpecs.fb = false;
2768054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2769054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //1 pipe by default for a layer
2770054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
2771054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(pipe_info.lIndex == ovutils::OV_INVALID) {
2772054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
2773054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2774054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2775054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Use 2 pipes IF
2776054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        a) Layer's crop width is > 2048 or
2777054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        b) Layer's dest width > 2048 or
2778054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        c) On primary, driver has indicated with caps to split always. This is
2779054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           based on an empirically derived value of panel height. Applied only
2780054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin           if the layer's width is > mixer's width
2781054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    */
2782054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2783054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MDPVersion& mdpHw = MDPVersion::getInstance();
2784054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
2785054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            mdpHw.isSrcSplitAlways();
2786054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const uint32_t lSplit = getLeftSplit(ctx, mDpy);
2787054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const uint32_t dstWidth = dst.right - dst.left;
2788054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const uint32_t dstHeight = dst.bottom - dst.top;
2789fb06969f70d5810f844f5a4682f42b602ed1a152Arun Kumar K.R    uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
2790054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.right - crop.left;
2791fb06969f70d5810f844f5a4682f42b602ed1a152Arun Kumar K.R    uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
2792054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            crop.bottom - crop.top;
2793054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //Approximation to actual clock, ignoring the common factors in pipe and
2794054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //mixer cases like line_time
2795054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
2796054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const uint32_t mixerClock = lSplit;
2797054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2798fb06969f70d5810f844f5a4682f42b602ed1a152Arun Kumar K.R    const uint32_t downscale = getRotDownscale(ctx, layer);
2799fb06969f70d5810f844f5a4682f42b602ed1a152Arun Kumar K.R    if(downscale) {
2800fb06969f70d5810f844f5a4682f42b602ed1a152Arun Kumar K.R        cropWidth /= downscale;
2801fb06969f70d5810f844f5a4682f42b602ed1a152Arun Kumar K.R        cropHeight /= downscale;
2802fb06969f70d5810f844f5a4682f42b602ed1a152Arun Kumar K.R    }
2803fb06969f70d5810f844f5a4682f42b602ed1a152Arun Kumar K.R
2804054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(dstWidth > mdpHw.getMaxPipeWidth() or
2805054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            cropWidth > mdpHw.getMaxPipeWidth() or
2806054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (primarySplitAlways and
2807054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            (cropWidth > lSplit or layerClock > mixerClock))) {
2808054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
2809054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(pipe_info.rIndex == ovutils::OV_INVALID) {
2810054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
2811054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2812054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2813a4a71c6d0a4553a9edbbd2398ea05032abe395d6Arun Kumar K.R        if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
2814a4a71c6d0a4553a9edbbd2398ea05032abe395d6Arun Kumar K.R                    pipe_info.rIndex)) {
2815054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
2816054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2817054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2818054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2819054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return true;
2820054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2821054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2822054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
2823054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeLayerPair& PipeLayerPair) {
2824054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    private_handle_t *hnd = (private_handle_t *)layer->handle;
2825054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(!hnd) {
2826054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: layer handle is NULL", __FUNCTION__);
2827054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
2828054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2829054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
2830054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    MdpPipeInfoSplit& mdp_info =
2831054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo));
2832054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Rotator **rot = &PipeLayerPair.rot;
2833054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eZorder z = static_cast<eZorder>(mdp_info.zOrder);
2834054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eDest lDest = mdp_info.lIndex;
2835054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eDest rDest = mdp_info.rIndex;
2836054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
2837054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dst = layer->displayFrame;
2838054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int transform = layer->transform;
2839054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eTransform orient = static_cast<eTransform>(transform);
2840054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int rotFlags = ROT_FLAGS_NONE;
2841054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
2842054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
2843054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2844054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
2845054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin             "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest);
2846054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
28479f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    if(qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() && !mDpy) {
28489f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        /* MDP driver crops layer coordinates against ROI in Non-Split
28499f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R         * and Split MDP comp. But HWC needs to crop them for source split.
28509f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R         * Reason: 1) Source split is efficient only when the final effective
28519f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R         *            load is distributed evenly across mixers.
28529f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R         *         2) We have to know the effective width of the layer that
28539f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R         *            the ROI needs to find the no. of pipes the layer needs.
28549f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R         */
28559f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R        trimAgainstROI(ctx, crop, dst);
28569f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R    }
28579f4ab24b0f20c60739a93172d548ece1f88f6f87Arun Kumar K.R
2858054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // Handle R/B swap
2859054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (layer->flags & HWC_FORMAT_RB_SWAP) {
2860054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
2861054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
2862054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
2863054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
2864054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2865054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    // update source crop and destination position of AIV video layer.
2866054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ctx->listStats[mDpy].mAIVVideoMode && isYuvBuffer(hnd)) {
2867054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        updateCoordinates(ctx, crop, dst, mDpy);
2868054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2869054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Calculate the external display position based on MDP downscale,
2870054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin       ActionSafe, and extorientation features. */
2871054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
2872054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2873054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int downscale = getRotDownscale(ctx, layer);
2874054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
2875054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    setMdpFlags(ctx, layer, mdpFlags, downscale, transform);
2876054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2877054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(lDest != OV_INVALID && rDest != OV_INVALID) {
2878054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Enable overfetch
2879054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE);
2880054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2881054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2882054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
2883054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        (*rot) = ctx->mRotMgr->getNext();
2884054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((*rot) == NULL) return -1;
2885054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ctx->mLayerRotMap[mDpy]->add(layer, *rot);
2886054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //If the video is using a single pipe, enable BWC
2887054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(rDest == OV_INVALID) {
2888054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            BwcPM::setBwc(ctx, mDpy, hnd, crop, dst, transform, downscale,
2889054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    mdpFlags);
2890054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2891054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Configure rotator for pre-rotation
2892054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
2893054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: configRotator failed!", __FUNCTION__);
2894054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2895054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2896054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        updateSource(orient, whf, crop, *rot);
2897054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        rotFlags |= ovutils::ROT_PREROTATED;
2898054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2899054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2900054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //If 2 pipes being used, divide layer into half, crop and dst
2901054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t cropL = crop;
2902054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t cropR = crop;
2903054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dstL = dst;
2904054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    hwc_rect_t dstR = dst;
2905054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(lDest != OV_INVALID && rDest != OV_INVALID) {
2906054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        cropL.right = (crop.right + crop.left) / 2;
2907054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        cropR.left = cropL.right;
2908054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sanitizeSourceCrop(cropL, cropR, hnd);
2909054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2910054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        bool cropSwap = false;
2911054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //Swap crops on H flip since 2 pipes are being used
2912054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) {
2913054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            hwc_rect_t tmp = cropL;
2914054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            cropL = cropR;
2915054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            cropR = tmp;
2916054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            cropSwap = true;
2917054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2918054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2919054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //cropSwap trick: If the src and dst widths are both odd, let us say
2920054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //2507, then splitting both into half would cause left width to be 1253
2921054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //and right 1254. If crop is swapped because of H flip, this will cause
2922054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //left crop width to be 1254, whereas left dst width remains 1253, thus
2923054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //inducing a scaling that is unaccounted for. To overcome that we add 1
2924054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //to the dst width if there is a cropSwap. So if the original width was
2925054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //2507, the left dst width will be 1254. Even if the original width was
2926054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        //even for ex: 2508, the left dst width will still remain 1254.
2927054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dstL.right = (dst.right + dst.left + cropSwap) / 2;
2928054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        dstR.left = dstL.right;
2929054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2930054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2931054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //For the mdp, since either we are pre-rotating or MDP does flips
2932054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    orient = OVERLAY_TRANSFORM_0;
2933054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    transform = 0;
2934054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2935054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //configure left pipe
2936054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(lDest != OV_INVALID) {
2937054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeArgs pargL(mdpFlags, whf, z,
2938054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
2939054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (ovutils::eBlending) getBlending(layer->blending));
2940054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2941054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configMdp(ctx->mOverlay, pargL, orient,
2942054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    cropL, dstL, metadata, lDest) < 0) {
2943054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
2944054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2945054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2946054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2947054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2948054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    //configure right pipe
2949054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(rDest != OV_INVALID) {
2950054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        PipeArgs pargR(mdpFlags, whf, z,
2951054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                static_cast<eRotFlags>(rotFlags),
2952054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                layer->planeAlpha,
2953054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                (ovutils::eBlending) getBlending(layer->blending));
2954054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(configMdp(ctx->mOverlay, pargR, orient,
2955054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                    cropR, dstR, metadata, rDest) < 0) {
2956054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
2957054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return -1;
2958054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
2959054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2960054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2961054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
2962054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2963054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2964054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::getPartialUpdatePref(hwc_context_t *ctx) {
2965054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Locker::Autolock _l(ctx->mDrawLock);
2966054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2967054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char path[MAX_SYSFS_FILE_PATH];
2968054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2969054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fd = open(path, O_RDONLY);
2970054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(fd < 0) {
2971054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2972054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
2973054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2974054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char value[4];
2975054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ssize_t size_read = read(fd, value, sizeof(value)-1);
2976054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(size_read <= 0) {
2977054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Failed to read sysfd node: %s", __FUNCTION__, path);
2978054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(fd);
2979054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
2980054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2981054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    close(fd);
2982054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    value[size_read] = '\0';
2983054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return atoi(value);
2984054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
2985054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
2986054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint MDPComp::setPartialUpdatePref(hwc_context_t *ctx, bool enable) {
2987054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    Locker::Autolock _l(ctx->mDrawLock);
2988054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    const int fbNum = Overlay::getFbForDpy(Overlay::DPY_PRIMARY);
2989054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char path[MAX_SYSFS_FILE_PATH];
2990054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    snprintf (path, sizeof(path), "sys/class/graphics/fb%d/dyn_pu", fbNum);
2991054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    int fd = open(path, O_WRONLY);
2992054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(fd < 0) {
2993054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Failed to open sysfd node: %s", __FUNCTION__, path);
2994054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
2995054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
2996054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char value[4];
2997054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    snprintf(value, sizeof(value), "%d", (int)enable);
2998054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    ssize_t ret = write(fd, value, strlen(value));
2999054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(ret <= 0) {
3000054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("%s: Failed to write to sysfd nodes: %s", __FUNCTION__, path);
3001054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        close(fd);
3002054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return -1;
3003054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
3004054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    close(fd);
3005054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sIsPartialUpdateActive = enable;
3006054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return 0;
3007054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
3008054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
3009054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool MDPComp::loadPerfLib() {
3010054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    char perfLibPath[PROPERTY_VALUE_MAX] = {0};
3011054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    bool success = false;
3012054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if((property_get("ro.vendor.extension_library", perfLibPath, NULL) <= 0)) {
3013054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("vendor library not set in ro.vendor.extension_library");
3014054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return false;
3015054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
3016054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
3017054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    sLibPerfHint = dlopen(perfLibPath, RTLD_NOW);
3018054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if(sLibPerfHint) {
3019054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        *(void **)&sPerfLockAcquire = dlsym(sLibPerfHint, "perf_lock_acq");
3020054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        *(void **)&sPerfLockRelease = dlsym(sLibPerfHint, "perf_lock_rel");
3021054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (!sPerfLockAcquire || !sPerfLockRelease) {
3022054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            ALOGE("Failed to load symbols for perfLock");
3023054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            dlclose(sLibPerfHint);
3024054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            sLibPerfHint = NULL;
3025054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            return false;
3026054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
3027054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        success = true;
3028054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGI("Successfully Loaded perf hint API's");
3029054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
3030054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        ALOGE("Failed to open %s : %s", perfLibPath, dlerror());
3031054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
3032054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    return success;
3033054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
3034054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
3035054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid MDPComp::setPerfHint(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3036054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if ((sPerfHintWindow < 0) || mDpy || !sLibPerfHint) {
3037054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        return;
3038054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
3039054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    static int count = sPerfHintWindow;
3040054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    static int perflockFlag = 0;
3041054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
3042054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    /* Send hint to mpctl when single layer is updated
3043054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * for a successful number of windows. Hint release
3044054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     * happens immediately upon multiple layer update.
3045054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin     */
3046054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (onlyVideosUpdating(ctx, list)) {
3047054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if(count) {
3048054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            count--;
3049054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
3050054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    } else {
3051054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        if (perflockFlag) {
3052054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            perflockFlag = 0;
3053054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            sPerfLockRelease(sPerfLockHandle);
3054054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
3055054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        count = sPerfHintWindow;
3056054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
3057054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    if (count == 0 && !perflockFlag) {
3058054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        int perfHint = 0x4501; // 45-display layer hint, 01-Enable
3059054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        sPerfLockHandle = sPerfLockAcquire(0 /*handle*/, 0/*duration*/,
3060054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin                                    &perfHint, sizeof(perfHint)/sizeof(int));
30613bc091ceb76fc796bb0264678db9b3c9479dadfbArun Kumar K.R        if(sPerfLockHandle > 0) {
3062054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin            perflockFlag = 1;
3063054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin        }
3064054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin    }
3065054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}
3066054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
3067054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin}; //namespace
3068054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin
3069