blob: 8b3b6f59635340ef12c36aaca87b5baf1ef1e5b5 [file] [log] [blame]
Naseer Ahmed29a26812012-06-14 00:56:20 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08003 * Copyright (C) 2012-2013, The Linux Foundation All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are retained
6 * for attribution purposes only.
Naseer Ahmed29a26812012-06-14 00:56:20 -07007 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
Naseer Ahmed099a6932013-09-09 14:25:20 -040020#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
Arun Kumar K.R361da4f2012-11-28 10:42:59 -080021#define HWC_UTILS_DEBUG 0
Saurabh Shahc5b96dc2013-06-05 13:19:52 -070022#include <math.h>
Naseer Ahmed758bfc52012-11-28 17:02:08 -050023#include <sys/ioctl.h>
Naseer Ahmed66e97882013-03-19 20:42:11 -040024#include <linux/fb.h>
Saurabh Shah86c17292013-02-08 15:24:13 -080025#include <binder/IServiceManager.h>
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070026#include <EGL/egl.h>
Saurabh Shahfc2acbe2012-08-17 19:47:52 -070027#include <cutils/properties.h>
Naseer Ahmed099a6932013-09-09 14:25:20 -040028#include <utils/Trace.h>
Saurabh Shahfc2acbe2012-08-17 19:47:52 -070029#include <gralloc_priv.h>
Naseer Ahmed758bfc52012-11-28 17:02:08 -050030#include <overlay.h>
Saurabh Shahacf10202013-02-26 10:15:15 -080031#include <overlayRotator.h>
Saurabh Shaha9da08f2013-07-03 13:27:53 -070032#include <overlayWriteback.h>
Naseer Ahmed29a26812012-06-14 00:56:20 -070033#include "hwc_utils.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050034#include "hwc_mdpcomp.h"
Saurabh Shahcf053c62012-12-13 12:32:55 -080035#include "hwc_fbupdate.h"
Saurabh Shaha9da08f2013-07-03 13:27:53 -070036#include "hwc_ad.h"
Naseer Ahmeda87da602012-07-01 23:54:19 -070037#include "mdp_version.h"
Arun Kumar K.R361da4f2012-11-28 10:42:59 -080038#include "hwc_copybit.h"
Ramkumar Radhakrishnand224a1a2013-04-05 17:46:55 -070039#include "hwc_dump_layers.h"
Naseer Ahmed58780b92013-07-29 17:41:40 -040040#include "hwc_vpuclient.h"
Saurabh Shah56f610d2012-08-07 15:27:06 -070041#include "external.h"
Jeykumar Sankaran27dee262013-08-01 17:09:54 -070042#include "virtual.h"
Saurabh Shah86c17292013-02-08 15:24:13 -080043#include "hwc_qclient.h"
Saurabh Shah56f610d2012-08-07 15:27:06 -070044#include "QService.h"
Arun Kumar K.R361da4f2012-11-28 10:42:59 -080045#include "comptype.h"
Saurabh Shah86c17292013-02-08 15:24:13 -080046
47using namespace qClient;
48using namespace qService;
49using namespace android;
Saurabh Shahacf10202013-02-26 10:15:15 -080050using namespace overlay;
51using namespace overlay::utils;
52namespace ovutils = overlay::utils;
Saurabh Shah86c17292013-02-08 15:24:13 -080053
Naseer Ahmed29a26812012-06-14 00:56:20 -070054namespace qhwc {
Naseer Ahmed72cf9762012-07-21 12:17:13 -070055
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -080056static int openFramebufferDevice(hwc_context_t *ctx)
Naseer Ahmed72cf9762012-07-21 12:17:13 -070057{
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -080058 struct fb_fix_screeninfo finfo;
59 struct fb_var_screeninfo info;
60
61 int fb_fd = openFb(HWC_DISPLAY_PRIMARY);
Sravan Kumar D.V.N78f51e72013-04-16 10:24:55 +053062 if(fb_fd < 0) {
63 ALOGE("%s: Error Opening FB : %s", __FUNCTION__, strerror(errno));
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -080064 return -errno;
Sravan Kumar D.V.N78f51e72013-04-16 10:24:55 +053065 }
66
67 if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &info) == -1) {
68 ALOGE("%s:Error in ioctl FBIOGET_VSCREENINFO: %s", __FUNCTION__,
69 strerror(errno));
70 close(fb_fd);
71 return -errno;
72 }
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -080073
74 if (int(info.width) <= 0 || int(info.height) <= 0) {
75 // the driver doesn't return that information
76 // default to 160 dpi
77 info.width = ((info.xres * 25.4f)/160.0f + 0.5f);
78 info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070079 }
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -080080
81 float xdpi = (info.xres * 25.4f) / info.width;
82 float ydpi = (info.yres * 25.4f) / info.height;
83
84#ifdef MSMFB_METADATA_GET
85 struct msmfb_metadata metadata;
86 memset(&metadata, 0 , sizeof(metadata));
87 metadata.op = metadata_op_frame_rate;
88
89 if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) {
Sravan Kumar D.V.N78f51e72013-04-16 10:24:55 +053090 ALOGE("%s:Error retrieving panel frame rate: %s", __FUNCTION__,
91 strerror(errno));
92 close(fb_fd);
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -080093 return -errno;
94 }
95
96 float fps = metadata.data.panel_frame_rate;
97#else
98 //XXX: Remove reserved field usage on all baselines
99 //The reserved[3] field is used to store FPS by the driver.
100 float fps = info.reserved[3] & 0xFF;
101#endif
102
Sravan Kumar D.V.N78f51e72013-04-16 10:24:55 +0530103 if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
104 ALOGE("%s:Error in ioctl FBIOGET_FSCREENINFO: %s", __FUNCTION__,
105 strerror(errno));
106 close(fb_fd);
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -0800107 return -errno;
Sravan Kumar D.V.N78f51e72013-04-16 10:24:55 +0530108 }
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -0800109
110 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = fb_fd;
111 //xres, yres may not be 32 aligned
112 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride = finfo.line_length /(info.xres/8);
113 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = info.xres;
114 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = info.yres;
115 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
116 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
117 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period = 1000000000l / fps;
118
Naseer Ahmed22616d92013-05-15 17:20:26 -0400119 //Unblank primary on first boot
120 if(ioctl(fb_fd, FBIOBLANK,FB_BLANK_UNBLANK) < 0) {
121 ALOGE("%s: Failed to unblank display", __FUNCTION__);
122 return -errno;
123 }
124 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive = true;
125
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -0800126 return 0;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700127}
128
Naseer Ahmed29a26812012-06-14 00:56:20 -0700129void initContext(hwc_context_t *ctx)
130{
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700131 openFramebufferDevice(ctx);
Naseer Ahmed96c4c952012-07-25 18:27:14 -0700132 ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
133 ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
134 ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
Sushil Chauhan07a2c762013-03-06 15:36:49 -0800135 overlay::Overlay::initOverlay();
136 ctx->mOverlay = overlay::Overlay::getInstance();
Saurabh Shah7a606842013-12-11 14:36:04 -0800137 ctx->mRotMgr = RotMgr::getInstance();
Sushil Chauhan07a2c762013-03-06 15:36:49 -0800138
Saurabh Shahcf053c62012-12-13 12:32:55 -0800139 //Is created and destroyed only once for primary
140 //For external it could get created and destroyed multiple times depending
141 //on what external we connect to.
142 ctx->mFBUpdate[HWC_DISPLAY_PRIMARY] =
Saurabh Shah88e4d272013-09-03 13:31:29 -0700143 IFBUpdate::getObject(ctx, HWC_DISPLAY_PRIMARY);
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800144
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800145 // Check if the target supports copybit compostion (dyn/mdp/c2d) to
146 // decide if we need to open the copybit module.
147 int compositionType =
148 qdutils::QCCompositionType::getInstance().getCompositionType();
149
150 if (compositionType & (qdutils::COMPOSITION_TYPE_DYN |
151 qdutils::COMPOSITION_TYPE_MDP |
152 qdutils::COMPOSITION_TYPE_C2D)) {
Saurabh Shah220a30c2013-10-29 16:12:12 -0700153 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
154 HWC_DISPLAY_PRIMARY);
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800155 }
156
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700157 ctx->mExtDisplay = new ExternalDisplay(ctx);
Jeykumar Sankaran27dee262013-08-01 17:09:54 -0700158 ctx->mVirtualDisplay = new VirtualDisplay(ctx);
159 ctx->mVirtualonExtActive = false;
160 ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
161 ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
162 ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = false;
163 ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected = false;
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700164 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].mDownScaleMode= false;
165 ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode = false;
166 ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = false;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800167
168 ctx->mMDPComp[HWC_DISPLAY_PRIMARY] =
Saurabh Shah88e4d272013-09-03 13:31:29 -0700169 MDPComp::getObject(ctx, HWC_DISPLAY_PRIMARY);
Jeykumar Sankaran27dee262013-08-01 17:09:54 -0700170 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800171
Amara Venkata Mastan Manoj Kumar7fb13272013-07-01 13:59:34 -0700172 for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
Ramkumar Radhakrishnand224a1a2013-04-05 17:46:55 -0700173 ctx->mHwcDebug[i] = new HwcDebug(i);
Saurabh Shah23a813c2013-03-20 16:58:12 -0700174 ctx->mLayerRotMap[i] = new LayerRotMap();
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -0700175 ctx->mAnimationState[i] = ANIMATION_STOPPED;
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800176 ctx->dpyAttr[i].mActionSafePresent = false;
177 ctx->dpyAttr[i].mAsWidthRatio = 0;
178 ctx->dpyAttr[i].mAsHeightRatio = 0;
Ramkumar Radhakrishnand224a1a2013-04-05 17:46:55 -0700179 }
Saurabh Shah23a813c2013-03-20 16:58:12 -0700180
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500181 MDPComp::init(ctx);
Saurabh Shahc4f1fa62013-09-03 13:12:14 -0700182 ctx->mAD = new AssertiveDisplay(ctx);
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700183
Naseer Ahmedff4f0252012-10-01 13:03:01 -0400184 ctx->vstate.enable = false;
Naseer Ahmed56601cd2013-03-05 11:34:14 -0500185 ctx->vstate.fakevsync = false;
Arun Kumar K.Rffef7482013-04-10 14:17:22 -0700186 ctx->mExtOrientation = 0;
Saurabh Shah86c17292013-02-08 15:24:13 -0800187
188 //Right now hwc starts the service but anybody could do it, or it could be
189 //independent process as well.
190 QService::init();
191 sp<IQClient> client = new QClient(ctx);
192 interface_cast<IQService>(
193 defaultServiceManager()->getService(
194 String16("display.qservice")))->connect(client);
195
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -0700196 // Initialize device orientation to its default orientation
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -0700197 ctx->deviceOrientation = 0;
Arun Kumar K.Rfb5bfa62013-07-25 03:10:51 -0700198 ctx->mBufferMirrorMode = false;
Naseer Ahmed58780b92013-07-29 17:41:40 -0400199#ifdef VPU_TARGET
200 ctx->mVPUClient = new VPUClient();
201#endif
Arun Kumar K.Rfb5bfa62013-07-25 03:10:51 -0700202
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700203 ALOGI("Initializing Qualcomm Hardware Composer");
Naseer Ahmed96c4c952012-07-25 18:27:14 -0700204 ALOGI("MDP version: %d", ctx->mMDP.version);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700205}
206
207void closeContext(hwc_context_t *ctx)
208{
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500209 if(ctx->mOverlay) {
210 delete ctx->mOverlay;
211 ctx->mOverlay = NULL;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700212 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700213
Saurabh Shahacf10202013-02-26 10:15:15 -0800214 if(ctx->mRotMgr) {
215 delete ctx->mRotMgr;
216 ctx->mRotMgr = NULL;
217 }
218
Amara Venkata Mastan Manoj Kumar7fb13272013-07-01 13:59:34 -0700219 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800220 if(ctx->mCopyBit[i]) {
221 delete ctx->mCopyBit[i];
222 ctx->mCopyBit[i] = NULL;
223 }
224 }
225
Jeykumar Sankaranc1f86822013-02-20 18:32:01 -0800226 if(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700227 close(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd);
228 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700229 }
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700230
231 if(ctx->mExtDisplay) {
232 delete ctx->mExtDisplay;
233 ctx->mExtDisplay = NULL;
234 }
Naseer Ahmedff4f0252012-10-01 13:03:01 -0400235
Naseer Ahmed58780b92013-07-29 17:41:40 -0400236#ifdef VPU_TARGET
237 if(ctx->mVPUClient) {
238 delete ctx->mVPUClient;
239 }
240#endif
241
Amara Venkata Mastan Manoj Kumar7fb13272013-07-01 13:59:34 -0700242 for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
Saurabh Shahcf053c62012-12-13 12:32:55 -0800243 if(ctx->mFBUpdate[i]) {
244 delete ctx->mFBUpdate[i];
245 ctx->mFBUpdate[i] = NULL;
246 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800247 if(ctx->mMDPComp[i]) {
248 delete ctx->mMDPComp[i];
249 ctx->mMDPComp[i] = NULL;
Saurabh Shahacf10202013-02-26 10:15:15 -0800250 }
Ramkumar Radhakrishnand224a1a2013-04-05 17:46:55 -0700251 if(ctx->mHwcDebug[i]) {
252 delete ctx->mHwcDebug[i];
253 ctx->mHwcDebug[i] = NULL;
254 }
Saurabh Shah23a813c2013-03-20 16:58:12 -0700255 if(ctx->mLayerRotMap[i]) {
256 delete ctx->mLayerRotMap[i];
257 ctx->mLayerRotMap[i] = NULL;
258 }
Saurabh Shahcf053c62012-12-13 12:32:55 -0800259 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700260 if(ctx->mAD) {
261 delete ctx->mAD;
262 ctx->mAD = NULL;
263 }
Saurabh Shahcf053c62012-12-13 12:32:55 -0800264
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800265
Naseer Ahmed29a26812012-06-14 00:56:20 -0700266}
267
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500268
269void dumpsys_log(android::String8& buf, const char* fmt, ...)
Naseer Ahmed29a26812012-06-14 00:56:20 -0700270{
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500271 va_list varargs;
272 va_start(varargs, fmt);
273 buf.appendFormatV(fmt, varargs);
274 va_end(varargs);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700275}
276
Ramkumar Radhakrishnan66f856c2013-08-21 16:09:47 -0700277int getExtOrientation(hwc_context_t* ctx) {
278 int extOrient = ctx->mExtOrientation;
279 if(ctx->mBufferMirrorMode)
280 extOrient = getMirrorModeOrientation(ctx);
281 return extOrient;
282}
283
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800284/* Calculates the destination position based on the action safe rectangle */
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700285void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& rect) {
286 // Position
287 int x = rect.left, y = rect.top;
288 int w = rect.right - rect.left;
289 int h = rect.bottom - rect.top;
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800290
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800291 if(!ctx->dpyAttr[dpy].mActionSafePresent)
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800292 return;
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800293 // Read action safe properties
294 int asWidthRatio = ctx->dpyAttr[dpy].mAsWidthRatio;
295 int asHeightRatio = ctx->dpyAttr[dpy].mAsHeightRatio;
Arun Kumar K.R82f1d282013-05-17 15:37:31 -0700296
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800297 float wRatio = 1.0;
298 float hRatio = 1.0;
299 float xRatio = 1.0;
300 float yRatio = 1.0;
301
Arpita Banerjeeb28b3092013-12-06 20:14:23 -0800302 int fbWidth = ctx->dpyAttr[dpy].xres;
303 int fbHeight = ctx->dpyAttr[dpy].yres;
Arun Kumar KR7b7f4012013-10-29 11:53:11 -0700304 if(ctx->dpyAttr[dpy].mDownScaleMode) {
305 // if downscale Mode is enabled for external, need to query
306 // the actual width and height, as that is the physical w & h
Arpita Banerjeeb28b3092013-12-06 20:14:23 -0800307 ctx->mExtDisplay->getAttributes(fbWidth, fbHeight);
Arun Kumar KR7b7f4012013-10-29 11:53:11 -0700308 }
309
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800310
Arun Kumar K.R82f1d282013-05-17 15:37:31 -0700311 // Since external is rotated 90, need to swap width/height
Ramkumar Radhakrishnan66f856c2013-08-21 16:09:47 -0700312 int extOrient = getExtOrientation(ctx);
Arun Kumar K.Rfb5bfa62013-07-25 03:10:51 -0700313
314 if(extOrient & HWC_TRANSFORM_ROT_90)
Arun Kumar K.R82f1d282013-05-17 15:37:31 -0700315 swap(fbWidth, fbHeight);
316
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800317 float asX = 0;
318 float asY = 0;
319 float asW = fbWidth;
Arpita Banerjeeb28b3092013-12-06 20:14:23 -0800320 float asH = fbHeight;
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800321
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800322 // based on the action safe ratio, get the Action safe rectangle
323 asW = fbWidth * (1.0f - asWidthRatio / 100.0f);
324 asH = fbHeight * (1.0f - asHeightRatio / 100.0f);
325 asX = (fbWidth - asW) / 2;
326 asY = (fbHeight - asH) / 2;
327
328 // calculate the position ratio
329 xRatio = (float)x/fbWidth;
330 yRatio = (float)y/fbHeight;
331 wRatio = (float)w/fbWidth;
332 hRatio = (float)h/fbHeight;
333
334 //Calculate the position...
335 x = (xRatio * asW) + asX;
336 y = (yRatio * asH) + asY;
337 w = (wRatio * asW);
338 h = (hRatio * asH);
339
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700340 // Convert it back to hwc_rect_t
341 rect.left = x;
342 rect.top = y;
343 rect.right = w + rect.left;
344 rect.bottom = h + rect.top;
345
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800346 return;
347}
348
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700349/* Calculates the aspect ratio for based on src & dest */
350void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
351 int srcHeight, hwc_rect_t& rect) {
352 int x =0, y =0;
Arun Kumar K.Rffef7482013-04-10 14:17:22 -0700353
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700354 if (srcWidth * destHeight > destWidth * srcHeight) {
355 srcHeight = destWidth * srcHeight / srcWidth;
356 srcWidth = destWidth;
357 } else if (srcWidth * destHeight < destWidth * srcHeight) {
358 srcWidth = destHeight * srcWidth / srcHeight;
359 srcHeight = destHeight;
360 } else {
361 srcWidth = destWidth;
362 srcHeight = destHeight;
363 }
364 if (srcWidth > destWidth) srcWidth = destWidth;
365 if (srcHeight > destHeight) srcHeight = destHeight;
366 x = (destWidth - srcWidth) / 2;
367 y = (destHeight - srcHeight) / 2;
368 ALOGD_IF(HWC_UTILS_DEBUG, "%s: AS Position: x = %d, y = %d w = %d h = %d",
369 __FUNCTION__, x, y, srcWidth , srcHeight);
370 // Convert it back to hwc_rect_t
371 rect.left = x;
372 rect.top = y;
373 rect.right = srcWidth + rect.left;
374 rect.bottom = srcHeight + rect.top;
Arun Kumar K.Rffef7482013-04-10 14:17:22 -0700375}
376
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700377// This function gets the destination position for Seconday display
378// based on the position and aspect ratio with orientation
379void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
380 hwc_rect_t& inRect, hwc_rect_t& outRect) {
Ramkumar Radhakrishnandebfc5a2013-12-04 15:15:42 -0800381 hwc_rect_t viewFrame = ctx->mViewFrame[dpy];
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700382 // Physical display resolution
383 float fbWidth = ctx->dpyAttr[dpy].xres;
384 float fbHeight = ctx->dpyAttr[dpy].yres;
385 //display position(x,y,w,h) in correct aspectratio after rotation
386 int xPos = 0;
387 int yPos = 0;
388 float width = fbWidth;
389 float height = fbHeight;
390 // Width/Height used for calculation, after rotation
391 float actualWidth = fbWidth;
392 float actualHeight = fbHeight;
393
394 float wRatio = 1.0;
395 float hRatio = 1.0;
396 float xRatio = 1.0;
397 float yRatio = 1.0;
398 hwc_rect_t rect = {0, 0, (int)fbWidth, (int)fbHeight};
399
400 Dim inPos(inRect.left, inRect.top, inRect.right - inRect.left,
401 inRect.bottom - inRect.top);
402 Dim outPos(outRect.left, outRect.top, outRect.right - outRect.left,
403 outRect.bottom - outRect.top);
404
405 Whf whf(fbWidth, fbHeight, 0);
406 eTransform extorient = static_cast<eTransform>(extOrientation);
407 // To calculate the destination co-ordinates in the new orientation
408 preRotateSource(extorient, whf, inPos);
409
410 if(extOrientation & HAL_TRANSFORM_ROT_90) {
411 // Swap width/height for input position
412 swapWidthHeight(actualWidth, actualHeight);
413 getAspectRatioPosition(fbWidth, fbHeight, (int)actualWidth,
414 (int)actualHeight, rect);
415 xPos = rect.left;
416 yPos = rect.top;
417 width = rect.right - rect.left;
418 height = rect.bottom - rect.top;
Ramkumar Radhakrishnandebfc5a2013-12-04 15:15:42 -0800419 // swap viewframe coordinates for 90 degree rotation.
420 swap(viewFrame.left, viewFrame.top);
421 swap(viewFrame.right, viewFrame.bottom);
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700422 }
Ramkumar Radhakrishnandebfc5a2013-12-04 15:15:42 -0800423 // if viewframe left and top coordinates are non zero value then exclude it
424 // during the computation of xRatio and yRatio
425 xRatio = (inPos.x - viewFrame.left)/actualWidth;
426 yRatio = (inPos.y - viewFrame.top)/actualHeight;
427 // Use viewframe width and height to compute wRatio and hRatio.
428 wRatio = inPos.w/(viewFrame.right - viewFrame.left);
429 hRatio = inPos.h/(viewFrame.bottom - viewFrame.top);
430
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700431
432 //Calculate the position...
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700433 outPos.x = (xRatio * width) + xPos;
434 outPos.y = (yRatio * height) + yPos;
435 outPos.w = wRatio * width;
436 outPos.h = hRatio * height;
437 ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio Position: x = %d,"
438 "y = %d w = %d h = %d", __FUNCTION__, outPos.x, outPos.y,
439 outPos.w, outPos.h);
440
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700441 // For sidesync, the dest fb will be in portrait orientation, and the crop
442 // will be updated to avoid the black side bands, and it will be upscaled
443 // to fit the dest RB, so recalculate
444 // the position based on the new width and height
445 if ((extOrientation & HWC_TRANSFORM_ROT_90) &&
446 isOrientationPortrait(ctx)) {
447 hwc_rect_t r;
448 //Calculate the position
449 xRatio = (outPos.x - xPos)/width;
450 // GetaspectRatio -- tricky to get the correct aspect ratio
451 // But we need to do this.
452 getAspectRatioPosition(width, height, width, height, r);
453 xPos = r.left;
454 yPos = r.top;
455 float tempWidth = r.right - r.left;
456 float tempHeight = r.bottom - r.top;
457 yRatio = yPos/height;
458 wRatio = outPos.w/width;
459 hRatio = tempHeight/height;
460
461 //Map the coordinates back to Framebuffer domain
462 outPos.x = (xRatio * fbWidth);
463 outPos.y = (yRatio * fbHeight);
464 outPos.w = wRatio * fbWidth;
465 outPos.h = hRatio * fbHeight;
466
467 ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio for device in"
468 "portrait: x = %d,y = %d w = %d h = %d", __FUNCTION__,
469 outPos.x, outPos.y,
470 outPos.w, outPos.h);
471 }
472 if(ctx->dpyAttr[dpy].mDownScaleMode) {
473 int extW, extH;
474 if(dpy == HWC_DISPLAY_EXTERNAL)
475 ctx->mExtDisplay->getAttributes(extW, extH);
476 else
477 ctx->mVirtualDisplay->getAttributes(extW, extH);
478 fbWidth = ctx->dpyAttr[dpy].xres;
479 fbHeight = ctx->dpyAttr[dpy].yres;
480 //Calculate the position...
481 xRatio = outPos.x/fbWidth;
482 yRatio = outPos.y/fbHeight;
483 wRatio = outPos.w/fbWidth;
484 hRatio = outPos.h/fbHeight;
485
486 outPos.x = xRatio * extW;
487 outPos.y = yRatio * extH;
488 outPos.w = wRatio * extW;
489 outPos.h = hRatio * extH;
490 }
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700491 // Convert Dim to hwc_rect_t
492 outRect.left = outPos.x;
493 outRect.top = outPos.y;
494 outRect.right = outPos.x + outPos.w;
495 outRect.bottom = outPos.y + outPos.h;
496
497 return;
498}
499
500bool isPrimaryPortrait(hwc_context_t *ctx) {
501 int fbWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
502 int fbHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
503 if(fbWidth < fbHeight) {
504 return true;
505 }
506 return false;
507}
508
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700509bool isOrientationPortrait(hwc_context_t *ctx) {
510 if(isPrimaryPortrait(ctx)) {
511 return !(ctx->deviceOrientation & 0x1);
512 }
513 return (ctx->deviceOrientation & 0x1);
514}
515
Ramkumar Radhakrishnan66f856c2013-08-21 16:09:47 -0700516void calcExtDisplayPosition(hwc_context_t *ctx,
517 private_handle_t *hnd,
518 int dpy,
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700519 hwc_rect_t& sourceCrop,
Ramkumar Radhakrishnan66f856c2013-08-21 16:09:47 -0700520 hwc_rect_t& displayFrame,
521 int& transform,
522 ovutils::eTransform& orient) {
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700523 // Swap width and height when there is a 90deg transform
Ramkumar Radhakrishnan66f856c2013-08-21 16:09:47 -0700524 int extOrient = getExtOrientation(ctx);
525 if(dpy && !qdutils::MDPVersion::getInstance().is8x26()) {
526 if(!isYuvBuffer(hnd)) {
527 if(extOrient & HWC_TRANSFORM_ROT_90) {
528 int dstWidth = ctx->dpyAttr[dpy].xres;
529 int dstHeight = ctx->dpyAttr[dpy].yres;;
530 int srcWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
531 int srcHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
532 if(!isPrimaryPortrait(ctx)) {
533 swap(srcWidth, srcHeight);
534 } // Get Aspect Ratio for external
535 getAspectRatioPosition(dstWidth, dstHeight, srcWidth,
536 srcHeight, displayFrame);
537 // Crop - this is needed, because for sidesync, the dest fb will
538 // be in portrait orientation, so update the crop to not show the
539 // black side bands.
540 if (isOrientationPortrait(ctx)) {
541 sourceCrop = displayFrame;
542 displayFrame.left = 0;
543 displayFrame.top = 0;
544 displayFrame.right = dstWidth;
545 displayFrame.bottom = dstHeight;
546 }
547 }
548 if(ctx->dpyAttr[dpy].mDownScaleMode) {
549 int extW, extH;
550 // if downscale is enabled, map the co-ordinates to new
551 // domain(downscaled)
552 float fbWidth = ctx->dpyAttr[dpy].xres;
553 float fbHeight = ctx->dpyAttr[dpy].yres;
554 // query MDP configured attributes
555 if(dpy == HWC_DISPLAY_EXTERNAL)
556 ctx->mExtDisplay->getAttributes(extW, extH);
557 else
558 ctx->mVirtualDisplay->getAttributes(extW, extH);
559 //Calculate the ratio...
560 float wRatio = ((float)extW)/fbWidth;
561 float hRatio = ((float)extH)/fbHeight;
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700562
Ramkumar Radhakrishnan66f856c2013-08-21 16:09:47 -0700563 //convert Dim to hwc_rect_t
564 displayFrame.left *= wRatio;
565 displayFrame.top *= hRatio;
566 displayFrame.right *= wRatio;
567 displayFrame.bottom *= hRatio;
568 }
569 }else {
570 if(extOrient || ctx->dpyAttr[dpy].mDownScaleMode) {
571 getAspectRatioPosition(ctx, dpy, extOrient,
572 displayFrame, displayFrame);
573 }
574 }
575 // If there is a external orientation set, use that
576 if(extOrient) {
577 transform = extOrient;
578 orient = static_cast<ovutils::eTransform >(extOrient);
579 }
580 // Calculate the actionsafe dimensions for External(dpy = 1 or 2)
581 getActionSafePosition(ctx, dpy, displayFrame);
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700582 }
Arun Kumar K.Rfb5bfa62013-07-25 03:10:51 -0700583}
Amara Venkata Mastan Manoj Kumar376d8a82013-03-13 19:18:47 -0700584
Arun Kumar K.Rfb5bfa62013-07-25 03:10:51 -0700585/* Returns the orientation which needs to be set on External for
586 * SideSync/Buffer Mirrormode
587 */
588int getMirrorModeOrientation(hwc_context_t *ctx) {
589 int extOrientation = 0;
590 int deviceOrientation = ctx->deviceOrientation;
591 if(!isPrimaryPortrait(ctx))
592 deviceOrientation = (deviceOrientation + 1) % 4;
593 if (deviceOrientation == 0)
594 extOrientation = HWC_TRANSFORM_ROT_270;
595 else if (deviceOrientation == 1)//90
596 extOrientation = 0;
597 else if (deviceOrientation == 2)//180
598 extOrientation = HWC_TRANSFORM_ROT_90;
599 else if (deviceOrientation == 3)//270
600 extOrientation = HWC_TRANSFORM_FLIP_V | HWC_TRANSFORM_FLIP_H;
601
602 return extOrientation;
Arun Kumar K.R5898c652013-07-17 14:20:32 -0700603}
Arun Kumar K.Rffef7482013-04-10 14:17:22 -0700604
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530605bool isDownscaleRequired(hwc_layer_1_t const* layer) {
606 hwc_rect_t displayFrame = layer->displayFrame;
607 hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
608 int dst_w, dst_h, src_w, src_h;
609 dst_w = displayFrame.right - displayFrame.left;
610 dst_h = displayFrame.bottom - displayFrame.top;
611 src_w = sourceCrop.right - sourceCrop.left;
612 src_h = sourceCrop.bottom - sourceCrop.top;
613
614 if(((src_w > dst_w) || (src_h > dst_h)))
615 return true;
616
617 return false;
618}
619bool needsScaling(hwc_layer_1_t const* layer) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500620 int dst_w, dst_h, src_w, src_h;
Naseer Ahmed018e5452012-12-03 14:46:15 -0500621 hwc_rect_t displayFrame = layer->displayFrame;
Saurabh Shah62e1d732013-09-17 10:44:05 -0700622 hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
Naseer Ahmed018e5452012-12-03 14:46:15 -0500623
624 dst_w = displayFrame.right - displayFrame.left;
625 dst_h = displayFrame.bottom - displayFrame.top;
Naseer Ahmed018e5452012-12-03 14:46:15 -0500626 src_w = sourceCrop.right - sourceCrop.left;
627 src_h = sourceCrop.bottom - sourceCrop.top;
628
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800629 if(((src_w != dst_w) || (src_h != dst_h)))
630 return true;
631
632 return false;
633}
634
Sushil Chauhan15a2ea62013-09-04 18:28:36 -0700635// Checks if layer needs scaling with split
636bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
637 const int& dpy) {
638
639 int src_width_l, src_height_l;
640 int src_width_r, src_height_r;
641 int dst_width_l, dst_height_l;
642 int dst_width_r, dst_height_r;
643 int hw_w = ctx->dpyAttr[dpy].xres;
644 int hw_h = ctx->dpyAttr[dpy].yres;
645 hwc_rect_t cropL, dstL, cropR, dstR;
646 const int lSplit = getLeftSplit(ctx, dpy);
Saurabh Shah62e1d732013-09-17 10:44:05 -0700647 hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
Sushil Chauhan15a2ea62013-09-04 18:28:36 -0700648 hwc_rect_t displayFrame = layer->displayFrame;
649 private_handle_t *hnd = (private_handle_t *)layer->handle;
Sushil Chauhan15a2ea62013-09-04 18:28:36 -0700650
651 cropL = sourceCrop;
652 dstL = displayFrame;
653 hwc_rect_t scissorL = { 0, 0, lSplit, hw_h };
Ramkumar Radhakrishnand8559482013-12-05 11:21:44 -0800654 scissorL = getIntersection(ctx->mViewFrame[dpy], scissorL);
Sushil Chauhan15a2ea62013-09-04 18:28:36 -0700655 qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);
656
657 cropR = sourceCrop;
658 dstR = displayFrame;
659 hwc_rect_t scissorR = { lSplit, 0, hw_w, hw_h };
Ramkumar Radhakrishnand8559482013-12-05 11:21:44 -0800660 scissorR = getIntersection(ctx->mViewFrame[dpy], scissorR);
Sushil Chauhan15a2ea62013-09-04 18:28:36 -0700661 qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);
662
663 // Sanitize Crop to stitch
664 sanitizeSourceCrop(cropL, cropR, hnd);
665
666 // Calculate the left dst
667 dst_width_l = dstL.right - dstL.left;
668 dst_height_l = dstL.bottom - dstL.top;
669 src_width_l = cropL.right - cropL.left;
670 src_height_l = cropL.bottom - cropL.top;
671
672 // check if there is any scaling on the left
673 if(((src_width_l != dst_width_l) || (src_height_l != dst_height_l)))
674 return true;
675
676 // Calculate the right dst
677 dst_width_r = dstR.right - dstR.left;
678 dst_height_r = dstR.bottom - dstR.top;
679 src_width_r = cropR.right - cropR.left;
680 src_height_r = cropR.bottom - cropR.top;
681
682 // check if there is any scaling on the right
683 if(((src_width_r != dst_width_r) || (src_height_r != dst_height_r)))
684 return true;
685
686 return false;
687}
688
Prabhanjan Kandula21918db2013-11-26 15:51:58 +0530689bool isAlphaScaled(hwc_layer_1_t const* layer) {
690 if(needsScaling(layer) && isAlphaPresent(layer)) {
Sravan Kumar D.V.N075ef002013-03-20 05:22:26 +0530691 return true;
692 }
693 return false;
694}
695
696bool isAlphaPresent(hwc_layer_1_t const* layer) {
697 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed7a4287c2013-03-26 18:11:41 -0400698 if(hnd) {
699 int format = hnd->format;
700 switch(format) {
Sravan Kumar D.V.N075ef002013-03-20 05:22:26 +0530701 case HAL_PIXEL_FORMAT_RGBA_8888:
702 case HAL_PIXEL_FORMAT_BGRA_8888:
703 // In any more formats with Alpha go here..
Naseer Ahmed018e5452012-12-03 14:46:15 -0500704 return true;
Sravan Kumar D.V.N075ef002013-03-20 05:22:26 +0530705 default : return false;
Naseer Ahmed7a4287c2013-03-26 18:11:41 -0400706 }
Naseer Ahmed018e5452012-12-03 14:46:15 -0500707 }
708 return false;
709}
710
Saurabh Shahd9ff30b2013-10-03 16:37:06 -0700711static void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
712 hwc_rect_t& crop, hwc_rect_t& dst) {
713 int hw_w = ctx->dpyAttr[dpy].xres;
714 int hw_h = ctx->dpyAttr[dpy].yres;
715 if(dst.left < 0 || dst.top < 0 ||
716 dst.right > hw_w || dst.bottom > hw_h) {
717 hwc_rect_t scissor = {0, 0, hw_w, hw_h };
Ramkumar Radhakrishnand8559482013-12-05 11:21:44 -0800718 scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
Saurabh Shahd9ff30b2013-10-03 16:37:06 -0700719 qhwc::calculate_crop_rects(crop, dst, scissor, transform);
720 }
721}
722
723static void trimList(hwc_context_t *ctx, hwc_display_contents_1_t *list,
724 const int& dpy) {
725 for(uint32_t i = 0; i < list->numHwLayers - 1; i++) {
726 hwc_layer_1_t *layer = &list->hwLayers[i];
727 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
728 trimLayer(ctx, dpy,
729 list->hwLayers[i].transform,
730 (hwc_rect_t&)crop,
731 (hwc_rect_t&)list->hwLayers[i].displayFrame);
732 layer->sourceCropf.left = crop.left;
733 layer->sourceCropf.right = crop.right;
734 layer->sourceCropf.top = crop.top;
735 layer->sourceCropf.bottom = crop.bottom;
736 }
737}
738
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700739void setListStats(hwc_context_t *ctx,
Saurabh Shahd9ff30b2013-10-03 16:37:06 -0700740 hwc_display_contents_1_t *list, int dpy) {
Saurabh Shahd4e65852013-06-17 11:33:53 -0700741 const int prevYuvCount = ctx->listStats[dpy].yuvCount;
742 memset(&ctx->listStats[dpy], 0, sizeof(ListStats));
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700743 ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
744 ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700745 ctx->listStats[dpy].skipCount = 0;
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530746 ctx->listStats[dpy].preMultipliedAlpha = false;
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700747 ctx->listStats[dpy].isSecurePresent = false;
Jeykumar Sankarancf537002013-01-21 21:19:15 -0800748 ctx->listStats[dpy].yuvCount = 0;
Ping Li9404e2a2013-04-24 16:36:03 -0400749 char property[PROPERTY_VALUE_MAX];
Arun Kumar K.Ra2978452013-02-07 01:34:24 -0800750 ctx->listStats[dpy].extOnlyLayerIndex = -1;
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -0700751 ctx->listStats[dpy].isDisplayAnimating = false;
Jeykumar Sankaran6a9bb9e2013-08-01 14:19:26 -0700752 ctx->listStats[dpy].roi = ovutils::Dim(0, 0,
753 (int)ctx->dpyAttr[dpy].xres, (int)ctx->dpyAttr[dpy].yres);
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700754 ctx->listStats[dpy].secureUI = false;
radhakrishnac9a67412013-09-25 17:40:42 +0530755 ctx->listStats[dpy].yuv4k2kCount = 0;
Ramkumar Radhakrishnandd38b822013-12-04 15:15:42 -0800756 ctx->mViewFrame[dpy] = (hwc_rect_t){0, 0, 0, 0};
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800757 ctx->dpyAttr[dpy].mActionSafePresent = isActionSafePresent(ctx, dpy);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700758
Saurabh Shahd9ff30b2013-10-03 16:37:06 -0700759 trimList(ctx, list, dpy);
Prabhanjan Kandulaa5dc8e92013-09-25 15:20:33 +0530760 optimizeLayerRects(ctx, list, dpy);
761
Ramkumar Radhakrishnan26bdee92013-06-20 16:56:56 -0700762 for (size_t i = 0; i < (size_t)ctx->listStats[dpy].numAppLayers; i++) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500763 hwc_layer_1_t const* layer = &list->hwLayers[i];
764 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700765
Ramkumar Radhakrishnandd38b822013-12-04 15:15:42 -0800766 // Calculate view frame of each display from the layer displayframe
767 ctx->mViewFrame[dpy] = getUnion(ctx->mViewFrame[dpy],
768 layer->displayFrame);
Ramkumar Radhakrishnane661f962013-06-05 17:21:38 -0700769#ifdef QCOM_BSP
770 if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
771 ctx->listStats[dpy].isDisplayAnimating = true;
772 }
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -0700773 if(isSecureDisplayBuffer(hnd)) {
774 ctx->listStats[dpy].secureUI = true;
775 }
Ramkumar Radhakrishnane661f962013-06-05 17:21:38 -0700776#endif
Ramkumar Radhakrishnan26bdee92013-06-20 16:56:56 -0700777 // continue if number of app layers exceeds MAX_NUM_APP_LAYERS
778 if(ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS)
Ramkumar Radhakrishnane661f962013-06-05 17:21:38 -0700779 continue;
Jeykumar Sankarancf537002013-01-21 21:19:15 -0800780
Ramkumar Radhakrishnan26bdee92013-06-20 16:56:56 -0700781 //reset yuv indices
782 ctx->listStats[dpy].yuvIndices[i] = -1;
radhakrishnac9a67412013-09-25 17:40:42 +0530783 ctx->listStats[dpy].yuv4k2kIndices[i] = -1;
Ramkumar Radhakrishnan26bdee92013-06-20 16:56:56 -0700784
Saurabh Shah8028e3b2013-10-15 12:27:59 -0700785 if (isSecureBuffer(hnd)) {
786 ctx->listStats[dpy].isSecurePresent = true;
787 }
788
Ramkumar Radhakrishnan26bdee92013-06-20 16:56:56 -0700789 if (isSkipLayer(&list->hwLayers[i])) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700790 ctx->listStats[dpy].skipCount++;
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -0700791 }
792
793 if (UNLIKELY(isYuvBuffer(hnd))) {
Jeykumar Sankarancf537002013-01-21 21:19:15 -0800794 int& yuvCount = ctx->listStats[dpy].yuvCount;
795 ctx->listStats[dpy].yuvIndices[yuvCount] = i;
796 yuvCount++;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800797
radhakrishnac9a67412013-09-25 17:40:42 +0530798 if(UNLIKELY(is4kx2kYuvBuffer(hnd))){
799 int& yuv4k2kCount = ctx->listStats[dpy].yuv4k2kCount;
800 ctx->listStats[dpy].yuv4k2kIndices[yuv4k2kCount] = i;
801 yuv4k2kCount++;
802 }
803
Saurabh Shahe2474082013-05-15 16:32:13 -0700804 if((layer->transform & HWC_TRANSFORM_ROT_90) &&
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -0700805 canUseRotator(ctx, dpy)) {
806 if( (dpy == HWC_DISPLAY_PRIMARY) &&
807 ctx->mOverlay->isPipeTypeAttached(OV_MDP_PIPE_DMA)) {
Saurabh Shah0ceeb6a2013-04-23 10:46:07 -0700808 ctx->isPaddingRound = true;
809 }
Saurabh Shah85234ec2013-04-12 17:09:00 -0700810 Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
811 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700812 }
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530813 if(layer->blending == HWC_BLENDING_PREMULT)
814 ctx->listStats[dpy].preMultipliedAlpha = true;
Jeykumar Sankaran7535aba2013-02-04 11:03:09 -0800815
Arun Kumar K.Ra2978452013-02-07 01:34:24 -0800816
817 if(UNLIKELY(isExtOnly(hnd))){
818 ctx->listStats[dpy].extOnlyLayerIndex = i;
819 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700820 }
Ping Li9404e2a2013-04-24 16:36:03 -0400821 if(ctx->listStats[dpy].yuvCount > 0) {
822 if (property_get("hw.cabl.yuv", property, NULL) > 0) {
823 if (atoi(property) != 1) {
824 property_set("hw.cabl.yuv", "1");
825 }
826 }
827 } else {
828 if (property_get("hw.cabl.yuv", property, NULL) > 0) {
829 if (atoi(property) != 0) {
830 property_set("hw.cabl.yuv", "0");
831 }
832 }
833 }
Arun Kumar K.Rffef7482013-04-10 14:17:22 -0700834 if(dpy) {
835 //uncomment the below code for testing purpose.
836 /* char value[PROPERTY_VALUE_MAX];
837 property_get("sys.ext_orientation", value, "0");
838 // Assuming the orientation value is in terms of HAL_TRANSFORM,
839 // This needs mapping to HAL, if its in different convention
840 ctx->mExtOrientation = atoi(value); */
841 // Assuming the orientation value is in terms of HAL_TRANSFORM,
842 // This needs mapping to HAL, if its in different convention
Arun Kumar K.Rfb5bfa62013-07-25 03:10:51 -0700843 if(ctx->mExtOrientation || ctx->mBufferMirrorMode) {
844 ALOGD_IF(HWC_UTILS_DEBUG, "%s: ext orientation = %d"
845 "BufferMirrorMode = %d", __FUNCTION__,
846 ctx->mExtOrientation, ctx->mBufferMirrorMode);
Arun Kumar K.Rffef7482013-04-10 14:17:22 -0700847 if(ctx->mOverlay->isPipeTypeAttached(OV_MDP_PIPE_DMA)) {
848 ctx->isPaddingRound = true;
849 }
850 Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
851 }
852 }
Saurabh Shahd4e65852013-06-17 11:33:53 -0700853
854 //The marking of video begin/end is useful on some targets where we need
855 //to have a padding round to be able to shift pipes across mixers.
856 if(prevYuvCount != ctx->listStats[dpy].yuvCount) {
857 ctx->mVideoTransFlag = true;
858 }
Saurabh Shaha9da08f2013-07-03 13:27:53 -0700859 if(dpy == HWC_DISPLAY_PRIMARY) {
860 ctx->mAD->markDoable(ctx, list);
861 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700862}
863
Naseer Ahmed018e5452012-12-03 14:46:15 -0500864
Saurabh Shah68107422013-07-09 11:12:42 -0700865static void calc_cut(double& leftCutRatio, double& topCutRatio,
866 double& rightCutRatio, double& bottomCutRatio, int orient) {
Saurabh Shah27c1d652012-08-14 19:30:28 -0700867 if(orient & HAL_TRANSFORM_FLIP_H) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700868 swap(leftCutRatio, rightCutRatio);
Saurabh Shah27c1d652012-08-14 19:30:28 -0700869 }
870 if(orient & HAL_TRANSFORM_FLIP_V) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700871 swap(topCutRatio, bottomCutRatio);
Saurabh Shah27c1d652012-08-14 19:30:28 -0700872 }
873 if(orient & HAL_TRANSFORM_ROT_90) {
874 //Anti clock swapping
Saurabh Shah68107422013-07-09 11:12:42 -0700875 double tmpCutRatio = leftCutRatio;
Saurabh Shah541b59d2012-10-11 11:08:12 -0700876 leftCutRatio = topCutRatio;
877 topCutRatio = rightCutRatio;
878 rightCutRatio = bottomCutRatio;
879 bottomCutRatio = tmpCutRatio;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700880 }
881}
882
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800883bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer) {
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500884 if((ctx->mMDP.version < qdutils::MDSS_V5) &&
885 (ctx->mMDP.version > qdutils::MDP_V3_0) &&
886 ctx->mSecuring) {
887 return true;
888 }
Jeykumar Sankaran85977e32013-02-25 17:06:08 -0800889 if (isSecureModePolicy(ctx->mMDP.version)) {
890 private_handle_t *hnd = (private_handle_t *)layer->handle;
891 if(ctx->mSecureMode) {
892 if (! isSecureBuffer(hnd)) {
893 ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning ON ...",
894 __FUNCTION__);
895 return true;
896 }
897 } else {
898 if (isSecureBuffer(hnd)) {
899 ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning OFF ...",
900 __FUNCTION__);
901 return true;
902 }
903 }
904 }
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500905 return false;
906}
907
Sushil Chauhan2515abf2013-01-08 16:40:05 -0800908bool isSecureModePolicy(int mdpVersion) {
909 if (mdpVersion < qdutils::MDSS_V5)
910 return true;
911 else
912 return false;
913}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500914
Ramkumar Radhakrishnan4af1ef02013-12-12 11:53:08 -0800915// returns true if Action safe dimensions are set and target supports Actionsafe
916bool isActionSafePresent(hwc_context_t *ctx, int dpy) {
917 // if external supports underscan, do nothing
918 // it will be taken care in the driver
919 if(!dpy || ctx->mExtDisplay->isCEUnderscanSupported())
920 return false;
921
922 char value[PROPERTY_VALUE_MAX];
923 // Read action safe properties
924 property_get("persist.sys.actionsafe.width", value, "0");
925 ctx->dpyAttr[dpy].mAsWidthRatio = atoi(value);
926 property_get("persist.sys.actionsafe.height", value, "0");
927 ctx->dpyAttr[dpy].mAsHeightRatio = atoi(value);
928
929 if(!ctx->dpyAttr[dpy].mAsWidthRatio && !ctx->dpyAttr[dpy].mAsHeightRatio) {
930 //No action safe ratio set, return
931 return false;
932 }
933 return true;
934}
935
Naseer Ahmed522ce662013-03-18 20:14:05 -0400936int getBlending(int blending) {
937 switch(blending) {
938 case HWC_BLENDING_NONE:
939 return overlay::utils::OVERLAY_BLENDING_OPAQUE;
940 case HWC_BLENDING_PREMULT:
941 return overlay::utils::OVERLAY_BLENDING_PREMULT;
942 case HWC_BLENDING_COVERAGE :
943 default:
944 return overlay::utils::OVERLAY_BLENDING_COVERAGE;
945 }
946}
947
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700948//Crops source buffer against destination and FB boundaries
949void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800950 const hwc_rect_t& scissor, int orient) {
951
Saurabh Shah27c1d652012-08-14 19:30:28 -0700952 int& crop_l = crop.left;
953 int& crop_t = crop.top;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700954 int& crop_r = crop.right;
955 int& crop_b = crop.bottom;
956 int crop_w = crop.right - crop.left;
957 int crop_h = crop.bottom - crop.top;
958
Saurabh Shah27c1d652012-08-14 19:30:28 -0700959 int& dst_l = dst.left;
960 int& dst_t = dst.top;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700961 int& dst_r = dst.right;
962 int& dst_b = dst.bottom;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700963 int dst_w = abs(dst.right - dst.left);
964 int dst_h = abs(dst.bottom - dst.top);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700965
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800966 const int& sci_l = scissor.left;
967 const int& sci_t = scissor.top;
968 const int& sci_r = scissor.right;
969 const int& sci_b = scissor.bottom;
970 int sci_w = abs(sci_r - sci_l);
971 int sci_h = abs(sci_b - sci_t);
972
Saurabh Shah68107422013-07-09 11:12:42 -0700973 double leftCutRatio = 0.0, rightCutRatio = 0.0, topCutRatio = 0.0,
974 bottomCutRatio = 0.0;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700975
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800976 if(dst_l < sci_l) {
Saurabh Shah68107422013-07-09 11:12:42 -0700977 leftCutRatio = (double)(sci_l - dst_l) / (double)dst_w;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800978 dst_l = sci_l;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700979 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800980
981 if(dst_r > sci_r) {
Saurabh Shah68107422013-07-09 11:12:42 -0700982 rightCutRatio = (double)(dst_r - sci_r) / (double)dst_w;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800983 dst_r = sci_r;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700984 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800985
986 if(dst_t < sci_t) {
Saurabh Shah68107422013-07-09 11:12:42 -0700987 topCutRatio = (double)(sci_t - dst_t) / (double)dst_h;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800988 dst_t = sci_t;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700989 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800990
991 if(dst_b > sci_b) {
Saurabh Shah68107422013-07-09 11:12:42 -0700992 bottomCutRatio = (double)(dst_b - sci_b) / (double)dst_h;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800993 dst_b = sci_b;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700994 }
Saurabh Shah27c1d652012-08-14 19:30:28 -0700995
Saurabh Shah541b59d2012-10-11 11:08:12 -0700996 calc_cut(leftCutRatio, topCutRatio, rightCutRatio, bottomCutRatio, orient);
997 crop_l += crop_w * leftCutRatio;
998 crop_t += crop_h * topCutRatio;
999 crop_r -= crop_w * rightCutRatio;
1000 crop_b -= crop_h * bottomCutRatio;
Naseer Ahmed29a26812012-06-14 00:56:20 -07001001}
Naseer Ahmedf48aef62012-07-20 09:05:53 -07001002
Prabhanjan Kandula9bd5f642013-09-25 17:00:36 +05301003bool areLayersIntersecting(const hwc_layer_1_t* layer1,
1004 const hwc_layer_1_t* layer2) {
1005 hwc_rect_t irect = getIntersection(layer1->displayFrame,
1006 layer2->displayFrame);
1007 return isValidRect(irect);
1008}
1009
Jeykumar Sankaran6a585792013-10-03 11:30:55 -07001010bool isValidRect(const hwc_rect& rect)
1011{
1012 return ((rect.bottom > rect.top) && (rect.right > rect.left)) ;
Prabhanjan Kandulaa5dc8e92013-09-25 15:20:33 +05301013}
1014
Jeykumar Sankaran6a585792013-10-03 11:30:55 -07001015/* computes the intersection of two rects */
1016hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2)
1017{
1018 hwc_rect_t res;
1019
1020 if(!isValidRect(rect1) || !isValidRect(rect2)){
1021 return (hwc_rect_t){0, 0, 0, 0};
1022 }
1023
1024
1025 res.left = max(rect1.left, rect2.left);
1026 res.top = max(rect1.top, rect2.top);
1027 res.right = min(rect1.right, rect2.right);
1028 res.bottom = min(rect1.bottom, rect2.bottom);
1029
1030 if(!isValidRect(res))
1031 return (hwc_rect_t){0, 0, 0, 0};
1032
1033 return res;
Prabhanjan Kandulaa5dc8e92013-09-25 15:20:33 +05301034}
1035
Jeykumar Sankaran6a585792013-10-03 11:30:55 -07001036/* computes the union of two rects */
1037hwc_rect_t getUnion(const hwc_rect &rect1, const hwc_rect &rect2)
1038{
1039 hwc_rect_t res;
1040
1041 if(!isValidRect(rect1)){
1042 return rect2;
1043 }
1044
1045 if(!isValidRect(rect2)){
1046 return rect1;
1047 }
1048
1049 res.left = min(rect1.left, rect2.left);
1050 res.top = min(rect1.top, rect2.top);
1051 res.right = max(rect1.right, rect2.right);
1052 res.bottom = max(rect1.bottom, rect2.bottom);
1053
1054 return res;
Prabhanjan Kandulaa5dc8e92013-09-25 15:20:33 +05301055}
1056
Jeykumar Sankaran93943532013-11-08 18:05:11 -08001057/* Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results
1058 * a single rect */
1059hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
Prabhanjan Kandulaa5dc8e92013-09-25 15:20:33 +05301060
Jeykumar Sankaran93943532013-11-08 18:05:11 -08001061 hwc_rect_t res = rect1;
1062
1063 if((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
1064 if((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom))
1065 res.top = rect2.bottom;
1066 else if((rect1.bottom == rect2.bottom)&& (rect2.top >= rect1.top))
1067 res.bottom = rect2.top;
1068 }
1069 else if((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
1070 if((rect1.left == rect2.left) && (rect2.right <= rect1.right))
1071 res.left = rect2.right;
1072 else if((rect1.right == rect2.right)&& (rect2.left >= rect1.left))
1073 res.right = rect2.left;
1074 }
1075 return res;
Prabhanjan Kandulaa5dc8e92013-09-25 15:20:33 +05301076}
1077
1078void optimizeLayerRects(hwc_context_t *ctx,
1079 const hwc_display_contents_1_t *list, const int& dpy) {
1080 int i=list->numHwLayers-2;
1081 hwc_rect_t irect;
1082 while(i > 0) {
1083
1084 //see if there is no blending required.
1085 //If it is opaque see if we can substract this region from below layers.
1086 if(list->hwLayers[i].blending == HWC_BLENDING_NONE) {
1087 int j= i-1;
1088 hwc_rect_t& topframe =
1089 (hwc_rect_t&)list->hwLayers[i].displayFrame;
1090 while(j >= 0) {
Prabhanjan Kandula21918db2013-11-26 15:51:58 +05301091 if(!needsScaling(&list->hwLayers[j])) {
Jeykumar Sankaran93943532013-11-08 18:05:11 -08001092 hwc_layer_1_t* layer = (hwc_layer_1_t*)&list->hwLayers[j];
1093 hwc_rect_t& bottomframe = layer->displayFrame;
1094 hwc_rect_t& bottomCrop = layer->sourceCrop;
1095 int transform =layer->transform;
Jeykumar Sankaran6a585792013-10-03 11:30:55 -07001096
Jeykumar Sankaran93943532013-11-08 18:05:11 -08001097 hwc_rect_t irect = getIntersection(bottomframe, topframe);
1098 if(isValidRect(irect)) {
Jeykumar Sankaran1b3da402013-12-04 16:22:34 -08001099 hwc_rect_t dest_rect;
Jeykumar Sankaran93943532013-11-08 18:05:11 -08001100 //if intersection is valid rect, deduct it
Jeykumar Sankaran1b3da402013-12-04 16:22:34 -08001101 dest_rect = deductRect(bottomframe, irect);
Jeykumar Sankaran93943532013-11-08 18:05:11 -08001102 qhwc::calculate_crop_rects(bottomCrop, bottomframe,
Jeykumar Sankaran1b3da402013-12-04 16:22:34 -08001103 dest_rect, transform);
Jeykumar Sankaran93943532013-11-08 18:05:11 -08001104
1105 }
1106 }
1107 j--;
Prabhanjan Kandulaa5dc8e92013-09-25 15:20:33 +05301108 }
1109 }
1110 i--;
1111 }
1112}
1113
Naseer Ahmed64b81212013-02-14 10:29:47 -05001114void getNonWormholeRegion(hwc_display_contents_1_t* list,
1115 hwc_rect_t& nwr)
1116{
1117 uint32_t last = list->numHwLayers - 1;
1118 hwc_rect_t fbDisplayFrame = list->hwLayers[last].displayFrame;
1119 //Initiliaze nwr to first frame
1120 nwr.left = list->hwLayers[0].displayFrame.left;
1121 nwr.top = list->hwLayers[0].displayFrame.top;
1122 nwr.right = list->hwLayers[0].displayFrame.right;
1123 nwr.bottom = list->hwLayers[0].displayFrame.bottom;
1124
1125 for (uint32_t i = 1; i < last; i++) {
1126 hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
Jeykumar Sankaran6a585792013-10-03 11:30:55 -07001127 nwr = getUnion(nwr, displayFrame);
Naseer Ahmed64b81212013-02-14 10:29:47 -05001128 }
1129
1130 //Intersect with the framebuffer
Jeykumar Sankaran6a585792013-10-03 11:30:55 -07001131 nwr = getIntersection(nwr, fbDisplayFrame);
Naseer Ahmed64b81212013-02-14 10:29:47 -05001132}
1133
Saurabh Shah3e858eb2012-09-17 16:53:21 -07001134bool isExternalActive(hwc_context_t* ctx) {
1135 return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive;
Saurabh Shahfc2acbe2012-08-17 19:47:52 -07001136}
1137
Saurabh Shah747af1e2013-02-26 10:25:12 -08001138void closeAcquireFds(hwc_display_contents_1_t* list) {
1139 for(uint32_t i = 0; list && i < list->numHwLayers; i++) {
1140 //Close the acquireFenceFds
1141 //HWC_FRAMEBUFFER are -1 already by SF, rest we close.
1142 if(list->hwLayers[i].acquireFenceFd >= 0) {
1143 close(list->hwLayers[i].acquireFenceFd);
1144 list->hwLayers[i].acquireFenceFd = -1;
1145 }
1146 }
1147}
1148
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08001149int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
Saurabh Shah23a813c2013-03-20 16:58:12 -07001150 int fd) {
Naseer Ahmed099a6932013-09-09 14:25:20 -04001151 ATRACE_CALL();
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -07001152 int ret = 0;
Ramkumar Radhakrishnane661f962013-06-05 17:21:38 -07001153 int acquireFd[MAX_NUM_APP_LAYERS];
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -07001154 int count = 0;
1155 int releaseFd = -1;
1156 int fbFd = -1;
Naseer Ahmed94baddc2012-12-17 18:51:01 -05001157 bool swapzero = false;
Saurabh Shah23a813c2013-03-20 16:58:12 -07001158 int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
1159
1160 struct mdp_buf_sync data;
1161 memset(&data, 0, sizeof(data));
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -07001162 data.acq_fen_fd = acquireFd;
1163 data.rel_fen_fd = &releaseFd;
Saurabh Shah23a813c2013-03-20 16:58:12 -07001164
Naseer Ahmed94baddc2012-12-17 18:51:01 -05001165 char property[PROPERTY_VALUE_MAX];
1166 if(property_get("debug.egl.swapinterval", property, "1") > 0) {
1167 if(atoi(property) == 0)
1168 swapzero = true;
1169 }
Saurabh Shahe9b5a8f2013-06-28 11:33:25 -07001170
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001171 bool isExtAnimating = false;
1172 if(dpy)
1173 isExtAnimating = ctx->listStats[dpy].isDisplayAnimating;
Naseer Ahmed94baddc2012-12-17 18:51:01 -05001174
Saurabh Shah23a813c2013-03-20 16:58:12 -07001175 //Send acquireFenceFds to rotator
Saurabh Shah23a813c2013-03-20 16:58:12 -07001176 for(uint32_t i = 0; i < ctx->mLayerRotMap[dpy]->getCount(); i++) {
Saurabh Shahe9b5a8f2013-06-28 11:33:25 -07001177 int rotFd = ctx->mRotMgr->getRotDevFd();
1178 int rotReleaseFd = -1;
1179 struct mdp_buf_sync rotData;
Saurabh Shah23a813c2013-03-20 16:58:12 -07001180 memset(&rotData, 0, sizeof(rotData));
Saurabh Shahe9b5a8f2013-06-28 11:33:25 -07001181 rotData.acq_fen_fd =
1182 &ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd;
1183 rotData.rel_fen_fd = &rotReleaseFd; //driver to populate this
Saurabh Shah23a813c2013-03-20 16:58:12 -07001184 rotData.session_id = ctx->mLayerRotMap[dpy]->getRot(i)->getSessId();
Saurabh Shahe9b5a8f2013-06-28 11:33:25 -07001185 int ret = 0;
1186 ret = ioctl(rotFd, MSMFB_BUFFER_SYNC, &rotData);
1187 if(ret < 0) {
1188 ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed for rot sync, err=%s",
1189 __FUNCTION__, strerror(errno));
1190 } else {
1191 close(ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd);
1192 //For MDP to wait on.
1193 ctx->mLayerRotMap[dpy]->getLayer(i)->acquireFenceFd =
1194 dup(rotReleaseFd);
1195 //A buffer is free to be used by producer as soon as its copied to
1196 //rotator
1197 ctx->mLayerRotMap[dpy]->getLayer(i)->releaseFenceFd =
1198 rotReleaseFd;
1199 }
Saurabh Shah23a813c2013-03-20 16:58:12 -07001200 }
Saurabh Shah23a813c2013-03-20 16:58:12 -07001201
1202 //Accumulate acquireFenceFds for MDP
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -07001203 for(uint32_t i = 0; i < list->numHwLayers; i++) {
Terence Hampsonc67b0372013-10-09 11:32:21 -04001204 if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
1205 list->hwLayers[i].compositionType == HWC_BLIT) &&
Saurabh Shah23a813c2013-03-20 16:58:12 -07001206 list->hwLayers[i].acquireFenceFd >= 0) {
Naseer Ahmed94baddc2012-12-17 18:51:01 -05001207 if(UNLIKELY(swapzero))
1208 acquireFd[count++] = -1;
1209 else
1210 acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -07001211 }
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08001212 if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
1213 if(UNLIKELY(swapzero))
1214 acquireFd[count++] = -1;
Saurabh Shah23a813c2013-03-20 16:58:12 -07001215 else if(fd >= 0) {
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08001216 //set the acquireFD from fd - which is coming from c2d
1217 acquireFd[count++] = fd;
1218 // Buffer sync IOCTL should be async when using c2d fence is
1219 // used
1220 data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
Saurabh Shah23a813c2013-03-20 16:58:12 -07001221 } else if(list->hwLayers[i].acquireFenceFd >= 0)
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08001222 acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
1223 }
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -07001224 }
1225
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -07001226 data.acq_fen_fd_cnt = count;
1227 fbFd = ctx->dpyAttr[dpy].fd;
Saurabh Shah23a813c2013-03-20 16:58:12 -07001228
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -07001229 //Waits for acquire fences, returns a release fence
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08001230 if(LIKELY(!swapzero)) {
1231 uint64_t start = systemTime();
Naseer Ahmed94baddc2012-12-17 18:51:01 -05001232 ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08001233 ALOGD_IF(HWC_UTILS_DEBUG, "%s: time taken for MSMFB_BUFFER_SYNC IOCTL = %d",
1234 __FUNCTION__, (size_t) ns2ms(systemTime() - start));
1235 }
Saurabh Shah747af1e2013-02-26 10:25:12 -08001236
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -07001237 if(ret < 0) {
Ramkumar Radhakrishnanb32a0bc2013-04-11 17:57:32 -07001238 ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed, err=%s",
1239 __FUNCTION__, strerror(errno));
1240 ALOGE("%s: acq_fen_fd_cnt=%d flags=%d fd=%d dpy=%d numHwLayers=%d",
1241 __FUNCTION__, data.acq_fen_fd_cnt, data.flags, fbFd,
1242 dpy, list->numHwLayers);
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -07001243 }
Saurabh Shah747af1e2013-02-26 10:25:12 -08001244
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -07001245 for(uint32_t i = 0; i < list->numHwLayers; i++) {
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08001246 if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
Terence Hampsonc67b0372013-10-09 11:32:21 -04001247 list->hwLayers[i].compositionType == HWC_BLIT ||
Arun Kumar K.R361da4f2012-11-28 10:42:59 -08001248 list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -07001249 //Populate releaseFenceFds.
Saurabh Shah23a813c2013-03-20 16:58:12 -07001250 if(UNLIKELY(swapzero)) {
Naseer Ahmed94baddc2012-12-17 18:51:01 -05001251 list->hwLayers[i].releaseFenceFd = -1;
Saurabh Shah23a813c2013-03-20 16:58:12 -07001252 } else if(isExtAnimating) {
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001253 // Release all the app layer fds immediately,
1254 // if animation is in progress.
Ramkumar Radhakrishnana70981a2013-08-28 11:33:53 -07001255 list->hwLayers[i].releaseFenceFd = -1;
Saurabh Shah23a813c2013-03-20 16:58:12 -07001256 } else if(list->hwLayers[i].releaseFenceFd < 0) {
1257 //If rotator has not already populated this field.
Naseer Ahmed94baddc2012-12-17 18:51:01 -05001258 list->hwLayers[i].releaseFenceFd = dup(releaseFd);
Saurabh Shah23a813c2013-03-20 16:58:12 -07001259 }
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -07001260 }
1261 }
Saurabh Shah747af1e2013-02-26 10:25:12 -08001262
1263 if(fd >= 0) {
1264 close(fd);
1265 fd = -1;
1266 }
1267
Naseer Ahmed64b81212013-02-14 10:29:47 -05001268 if (ctx->mCopyBit[dpy])
1269 ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
Saurabh Shah23a813c2013-03-20 16:58:12 -07001270
Saurabh Shah23a813c2013-03-20 16:58:12 -07001271 //Signals when MDP finishes reading rotator buffers.
1272 ctx->mLayerRotMap[dpy]->setReleaseFd(releaseFd);
Saurabh Shah23a813c2013-03-20 16:58:12 -07001273
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001274 // if external is animating, close the relaseFd
1275 if(isExtAnimating) {
1276 close(releaseFd);
1277 releaseFd = -1;
1278 }
Saurabh Shah23a813c2013-03-20 16:58:12 -07001279
Naseer Ahmed94baddc2012-12-17 18:51:01 -05001280 if(UNLIKELY(swapzero)){
1281 list->retireFenceFd = -1;
1282 close(releaseFd);
1283 } else {
1284 list->retireFenceFd = releaseFd;
1285 }
Saurabh Shah747af1e2013-02-26 10:25:12 -08001286
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -07001287 return ret;
1288}
1289
Saurabh Shahacf10202013-02-26 10:15:15 -08001290void setMdpFlags(hwc_layer_1_t *layer,
1291 ovutils::eMdpFlags &mdpFlags,
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001292 int rotDownscale, int transform) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001293 private_handle_t *hnd = (private_handle_t *)layer->handle;
Saurabh Shah220a30c2013-10-29 16:12:12 -07001294 MetaData_t *metadata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
Saurabh Shahacf10202013-02-26 10:15:15 -08001295
1296 if(layer->blending == HWC_BLENDING_PREMULT) {
1297 ovutils::setMdpFlags(mdpFlags,
1298 ovutils::OV_MDP_BLEND_FG_PREMULT);
1299 }
1300
1301 if(isYuvBuffer(hnd)) {
1302 if(isSecureBuffer(hnd)) {
1303 ovutils::setMdpFlags(mdpFlags,
1304 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
1305 }
1306 if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
1307 metadata->interlaced) {
1308 ovutils::setMdpFlags(mdpFlags,
1309 ovutils::OV_MDP_DEINTERLACE);
1310 }
1311 //Pre-rotation will be used using rotator.
1312 if(transform & HWC_TRANSFORM_ROT_90) {
1313 ovutils::setMdpFlags(mdpFlags,
1314 ovutils::OV_MDP_SOURCE_ROTATED_90);
1315 }
1316 }
1317
Ramkumar Radhakrishnanba713382013-08-30 18:41:07 -07001318 if(isSecureDisplayBuffer(hnd)) {
1319 // Secure display needs both SECURE_OVERLAY and SECURE_DISPLAY_OV
1320 ovutils::setMdpFlags(mdpFlags,
1321 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
1322 ovutils::setMdpFlags(mdpFlags,
1323 ovutils::OV_MDP_SECURE_DISPLAY_OVERLAY_SESSION);
1324 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001325 //No 90 component and no rot-downscale then flips done by MDP
1326 //If we use rot then it might as well do flips
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001327 if(!(transform & HWC_TRANSFORM_ROT_90) && !rotDownscale) {
1328 if(transform & HWC_TRANSFORM_FLIP_H) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001329 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
1330 }
1331
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001332 if(transform & HWC_TRANSFORM_FLIP_V) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001333 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_V);
1334 }
1335 }
Saurabh Shah5daeee52013-01-23 16:52:26 +08001336
1337 if(metadata &&
1338 ((metadata->operation & PP_PARAM_HSIC)
1339 || (metadata->operation & PP_PARAM_IGC)
1340 || (metadata->operation & PP_PARAM_SHARP2))) {
1341 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_PP_EN);
1342 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001343}
1344
Prabhanjan Kandulaa1d83012013-04-23 13:06:02 +05301345int configRotator(Rotator *rot, Whf& whf,
Sushil Chauhan1cac8152013-05-08 15:53:51 -07001346 hwc_rect_t& crop, const eMdpFlags& mdpFlags,
Sushil Chauhan80fc1f92013-04-23 17:30:05 -07001347 const eTransform& orient, const int& downscale) {
Sushil Chauhan1cac8152013-05-08 15:53:51 -07001348
Prabhanjan Kandulaa1d83012013-04-23 13:06:02 +05301349 // Fix alignments for TILED format
1350 if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
1351 whf.format == MDP_Y_CBCR_H2V2_TILE) {
1352 whf.w = utils::alignup(whf.w, 64);
1353 whf.h = utils::alignup(whf.h, 32);
1354 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001355 rot->setSource(whf);
Sushil Chauhan1cac8152013-05-08 15:53:51 -07001356
1357 if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
1358 qdutils::MDSS_V5) {
1359 uint32_t crop_w = (crop.right - crop.left);
1360 uint32_t crop_h = (crop.bottom - crop.top);
Sushil Chauhan6181aa22013-05-17 18:04:10 -07001361 if (ovutils::isYuv(whf.format)) {
1362 ovutils::normalizeCrop((uint32_t&)crop.left, crop_w);
1363 ovutils::normalizeCrop((uint32_t&)crop.top, crop_h);
Sushil Chauhan5491c8a2013-05-24 10:15:30 -07001364 // For interlaced, crop.h should be 4-aligned
1365 if ((mdpFlags & ovutils::OV_MDP_DEINTERLACE) && (crop_h % 4))
1366 crop_h = ovutils::aligndown(crop_h, 4);
Sushil Chauhan6181aa22013-05-17 18:04:10 -07001367 crop.right = crop.left + crop_w;
1368 crop.bottom = crop.top + crop_h;
1369 }
Sushil Chauhan1cac8152013-05-08 15:53:51 -07001370 Dim rotCrop(crop.left, crop.top, crop_w, crop_h);
1371 rot->setCrop(rotCrop);
1372 }
1373
Saurabh Shahacf10202013-02-26 10:15:15 -08001374 rot->setFlags(mdpFlags);
1375 rot->setTransform(orient);
1376 rot->setDownscale(downscale);
1377 if(!rot->commit()) return -1;
1378 return 0;
1379}
1380
Saurabh Shahe2474082013-05-15 16:32:13 -07001381int configMdp(Overlay *ov, const PipeArgs& parg,
Saurabh Shahacf10202013-02-26 10:15:15 -08001382 const eTransform& orient, const hwc_rect_t& crop,
Saurabh Shah5daeee52013-01-23 16:52:26 +08001383 const hwc_rect_t& pos, const MetaData_t *metadata,
1384 const eDest& dest) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001385 ov->setSource(parg, dest);
1386 ov->setTransform(orient, dest);
1387
1388 int crop_w = crop.right - crop.left;
1389 int crop_h = crop.bottom - crop.top;
1390 Dim dcrop(crop.left, crop.top, crop_w, crop_h);
1391 ov->setCrop(dcrop, dest);
1392
1393 int posW = pos.right - pos.left;
1394 int posH = pos.bottom - pos.top;
1395 Dim position(pos.left, pos.top, posW, posH);
1396 ov->setPosition(position, dest);
1397
Saurabh Shah5daeee52013-01-23 16:52:26 +08001398 if (metadata)
1399 ov->setVisualParams(*metadata, dest);
1400
Saurabh Shahacf10202013-02-26 10:15:15 -08001401 if (!ov->commit(dest)) {
1402 return -1;
1403 }
1404 return 0;
1405}
1406
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001407int configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer,
1408 const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
1409 eIsFg& isFg, const eDest& dest) {
1410
1411 hwc_rect_t dst = layer->displayFrame;
1412 trimLayer(ctx, dpy, 0, dst, dst);
1413
1414 int w = ctx->dpyAttr[dpy].xres;
1415 int h = ctx->dpyAttr[dpy].yres;
1416 int dst_w = dst.right - dst.left;
1417 int dst_h = dst.bottom - dst.top;
1418 uint32_t color = layer->transform;
1419 Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888), 0);
1420
Sushil Chauhanf10c5232013-12-19 10:35:54 -08001421 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SOLID_FILL);
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001422 if (layer->blending == HWC_BLENDING_PREMULT)
1423 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_BLEND_FG_PREMULT);
1424
1425 PipeArgs parg(mdpFlags, whf, z, isFg, static_cast<eRotFlags>(0),
1426 layer->planeAlpha,
1427 (ovutils::eBlending) getBlending(layer->blending));
1428
1429 // Configure MDP pipe for Color layer
1430 Dim pos(dst.left, dst.top, dst_w, dst_h);
1431 ctx->mOverlay->setSource(parg, dest);
1432 ctx->mOverlay->setColor(color, dest);
1433 ctx->mOverlay->setTransform(0, dest);
1434 ctx->mOverlay->setCrop(pos, dest);
1435 ctx->mOverlay->setPosition(pos, dest);
1436
1437 if (!ctx->mOverlay->commit(dest)) {
1438 ALOGE("%s: Configure color layer failed!", __FUNCTION__);
1439 return -1;
1440 }
1441 return 0;
1442}
1443
Saurabh Shahe2474082013-05-15 16:32:13 -07001444void updateSource(eTransform& orient, Whf& whf,
Saurabh Shahacf10202013-02-26 10:15:15 -08001445 hwc_rect_t& crop) {
1446 Dim srcCrop(crop.left, crop.top,
1447 crop.right - crop.left,
1448 crop.bottom - crop.top);
Saurabh Shah76fd6552013-03-14 14:45:38 -07001449 orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
Saurabh Shahacf10202013-02-26 10:15:15 -08001450 preRotateSource(orient, whf, srcCrop);
Sushil Chauhan80fc1f92013-04-23 17:30:05 -07001451 if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
1452 qdutils::MDSS_V5) {
1453 // Source for overlay will be the cropped (and rotated)
1454 crop.left = 0;
1455 crop.top = 0;
1456 crop.right = srcCrop.w;
1457 crop.bottom = srcCrop.h;
1458 // Set width & height equal to sourceCrop w & h
1459 whf.w = srcCrop.w;
1460 whf.h = srcCrop.h;
1461 } else {
1462 crop.left = srcCrop.x;
1463 crop.top = srcCrop.y;
1464 crop.right = srcCrop.x + srcCrop.w;
1465 crop.bottom = srcCrop.y + srcCrop.h;
1466 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001467}
1468
Saurabh Shah88e4d272013-09-03 13:31:29 -07001469int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001470 const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
1471 eIsFg& isFg, const eDest& dest, Rotator **rot) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001472
1473 private_handle_t *hnd = (private_handle_t *)layer->handle;
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001474
Saurabh Shahacf10202013-02-26 10:15:15 -08001475 if(!hnd) {
Sushil Chauhan897a9c32013-07-18 11:09:55 -07001476 if (layer->flags & HWC_COLOR_FILL) {
1477 // Configure Color layer
1478 return configColorLayer(ctx, layer, dpy, mdpFlags, z, isFg, dest);
1479 }
Saurabh Shahacf10202013-02-26 10:15:15 -08001480 ALOGE("%s: layer handle is NULL", __FUNCTION__);
1481 return -1;
1482 }
1483
Saurabh Shah5daeee52013-01-23 16:52:26 +08001484 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
1485
Saurabh Shah62e1d732013-09-17 10:44:05 -07001486 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shahacf10202013-02-26 10:15:15 -08001487 hwc_rect_t dst = layer->displayFrame;
1488 int transform = layer->transform;
1489 eTransform orient = static_cast<eTransform>(transform);
1490 int downscale = 0;
1491 int rotFlags = ovutils::ROT_FLAGS_NONE;
Ramkumar Radhakrishnan92f3abe2013-06-05 13:52:40 -07001492 Whf whf(getWidth(hnd), getHeight(hnd),
Saurabh Shahacf10202013-02-26 10:15:15 -08001493 getMdpFormat(hnd->format), hnd->size);
1494
Sushil Chauhan1f6d68f2013-10-11 11:49:35 -07001495 // Handle R/B swap
1496 if (layer->flags & HWC_FORMAT_RB_SWAP) {
1497 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
1498 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
1499 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
1500 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
1501 }
1502
Ramkumar Radhakrishnan939a9e72013-12-04 18:30:18 -08001503 calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
Arun Kumar K.Rffef7482013-04-10 14:17:22 -07001504
Saurabh Shahacf10202013-02-26 10:15:15 -08001505 if(isYuvBuffer(hnd) && ctx->mMDP.version >= qdutils::MDP_V4_2 &&
Jeykumar Sankaran85977e32013-02-25 17:06:08 -08001506 ctx->mMDP.version < qdutils::MDSS_V5) {
1507 downscale = getDownscaleFactor(
1508 crop.right - crop.left,
1509 crop.bottom - crop.top,
1510 dst.right - dst.left,
1511 dst.bottom - dst.top);
Saurabh Shahacf10202013-02-26 10:15:15 -08001512 if(downscale) {
1513 rotFlags = ROT_DOWNSCALE_ENABLED;
1514 }
1515 }
1516
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001517 setMdpFlags(layer, mdpFlags, downscale, transform);
Saurabh Shahacf10202013-02-26 10:15:15 -08001518
1519 if(isYuvBuffer(hnd) && //if 90 component or downscale, use rot
1520 ((transform & HWC_TRANSFORM_ROT_90) || downscale)) {
1521 *rot = ctx->mRotMgr->getNext();
1522 if(*rot == NULL) return -1;
Tatenda Chipeperekwa88562702013-10-19 19:56:16 -07001523 if(!dpy)
1524 BwcPM::setBwc(ctx, crop, dst, transform, mdpFlags);
Saurabh Shahacf10202013-02-26 10:15:15 -08001525 //Configure rotator for pre-rotation
Sushil Chauhan80fc1f92013-04-23 17:30:05 -07001526 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
1527 ALOGE("%s: configRotator failed!", __FUNCTION__);
Saurabh Shahacf10202013-02-26 10:15:15 -08001528 return -1;
Sushil Chauhan80fc1f92013-04-23 17:30:05 -07001529 }
Saurabh Shah23a813c2013-03-20 16:58:12 -07001530 ctx->mLayerRotMap[dpy]->add(layer, *rot);
Saurabh Shahacf10202013-02-26 10:15:15 -08001531 whf.format = (*rot)->getDstFormat();
1532 updateSource(orient, whf, crop);
Saurabh Shahacf10202013-02-26 10:15:15 -08001533 rotFlags |= ovutils::ROT_PREROTATED;
1534 }
1535
Saurabh Shah76fd6552013-03-14 14:45:38 -07001536 //For the mdp, since either we are pre-rotating or MDP does flips
1537 orient = OVERLAY_TRANSFORM_0;
1538 transform = 0;
Naseer Ahmed522ce662013-03-18 20:14:05 -04001539 PipeArgs parg(mdpFlags, whf, z, isFg,
1540 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
1541 (ovutils::eBlending) getBlending(layer->blending));
1542
Saurabh Shah5daeee52013-01-23 16:52:26 +08001543 if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001544 ALOGE("%s: commit failed for low res panel", __FUNCTION__);
1545 return -1;
1546 }
1547 return 0;
1548}
1549
Saurabh Shahd9e426d2013-08-01 13:35:31 -07001550//Helper to 1) Ensure crops dont have gaps 2) Ensure L and W are even
Sushil Chauhan15a2ea62013-09-04 18:28:36 -07001551void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
Saurabh Shahd9e426d2013-08-01 13:35:31 -07001552 private_handle_t *hnd) {
1553 if(cropL.right - cropL.left) {
1554 if(isYuvBuffer(hnd)) {
1555 //Always safe to even down left
1556 ovutils::even_floor(cropL.left);
1557 //If right is even, automatically width is even, since left is
1558 //already even
1559 ovutils::even_floor(cropL.right);
1560 }
1561 //Make sure there are no gaps between left and right splits if the layer
1562 //is spread across BOTH halves
1563 if(cropR.right - cropR.left) {
1564 cropR.left = cropL.right;
1565 }
1566 }
1567
1568 if(cropR.right - cropR.left) {
1569 if(isYuvBuffer(hnd)) {
1570 //Always safe to even down left
1571 ovutils::even_floor(cropR.left);
1572 //If right is even, automatically width is even, since left is
1573 //already even
1574 ovutils::even_floor(cropR.right);
1575 }
1576 }
1577}
1578
Saurabh Shah88e4d272013-09-03 13:31:29 -07001579int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
Ramkumar Radhakrishnan59a11072013-04-15 16:14:49 -07001580 const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
1581 eIsFg& isFg, const eDest& lDest, const eDest& rDest,
Saurabh Shahacf10202013-02-26 10:15:15 -08001582 Rotator **rot) {
1583 private_handle_t *hnd = (private_handle_t *)layer->handle;
1584 if(!hnd) {
1585 ALOGE("%s: layer handle is NULL", __FUNCTION__);
1586 return -1;
1587 }
1588
Saurabh Shah5daeee52013-01-23 16:52:26 +08001589 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
1590
Saurabh Shahacf10202013-02-26 10:15:15 -08001591 int hw_w = ctx->dpyAttr[dpy].xres;
1592 int hw_h = ctx->dpyAttr[dpy].yres;
Saurabh Shah62e1d732013-09-17 10:44:05 -07001593 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
Saurabh Shahacf10202013-02-26 10:15:15 -08001594 hwc_rect_t dst = layer->displayFrame;
1595 int transform = layer->transform;
1596 eTransform orient = static_cast<eTransform>(transform);
1597 const int downscale = 0;
1598 int rotFlags = ROT_FLAGS_NONE;
1599
Ramkumar Radhakrishnan92f3abe2013-06-05 13:52:40 -07001600 Whf whf(getWidth(hnd), getHeight(hnd),
Saurabh Shahacf10202013-02-26 10:15:15 -08001601 getMdpFormat(hnd->format), hnd->size);
1602
Sushil Chauhan1f6d68f2013-10-11 11:49:35 -07001603 // Handle R/B swap
1604 if (layer->flags & HWC_FORMAT_RB_SWAP) {
1605 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
1606 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
1607 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
1608 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
1609 }
1610
Ramkumar Radhakrishnan9d52f432013-05-14 14:46:59 -07001611 setMdpFlags(layer, mdpFlagsL, 0, transform);
Saurabh Shahd9e426d2013-08-01 13:35:31 -07001612
1613 if(lDest != OV_INVALID && rDest != OV_INVALID) {
1614 //Enable overfetch
1615 setMdpFlags(mdpFlagsL, OV_MDSS_MDP_DUAL_PIPE);
1616 }
1617
Saurabh Shaha9da08f2013-07-03 13:27:53 -07001618 //Will do something only if feature enabled and conditions suitable
1619 //hollow call otherwise
1620 if(ctx->mAD->prepare(ctx, crop, whf, hnd)) {
1621 overlay::Writeback *wb = overlay::Writeback::getInstance();
1622 whf.format = wb->getOutputFormat();
1623 }
1624
Saurabh Shahacf10202013-02-26 10:15:15 -08001625 if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
1626 (*rot) = ctx->mRotMgr->getNext();
1627 if((*rot) == NULL) return -1;
1628 //Configure rotator for pre-rotation
Sushil Chauhan80fc1f92013-04-23 17:30:05 -07001629 if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
1630 ALOGE("%s: configRotator failed!", __FUNCTION__);
Saurabh Shahacf10202013-02-26 10:15:15 -08001631 return -1;
Sushil Chauhan80fc1f92013-04-23 17:30:05 -07001632 }
Saurabh Shah23a813c2013-03-20 16:58:12 -07001633 ctx->mLayerRotMap[dpy]->add(layer, *rot);
Saurabh Shahacf10202013-02-26 10:15:15 -08001634 whf.format = (*rot)->getDstFormat();
1635 updateSource(orient, whf, crop);
Saurabh Shahacf10202013-02-26 10:15:15 -08001636 rotFlags |= ROT_PREROTATED;
1637 }
1638
1639 eMdpFlags mdpFlagsR = mdpFlagsL;
1640 setMdpFlags(mdpFlagsR, OV_MDSS_MDP_RIGHT_MIXER);
1641
Saurabh Shahd9e426d2013-08-01 13:35:31 -07001642 hwc_rect_t tmp_cropL = {0}, tmp_dstL = {0};
1643 hwc_rect_t tmp_cropR = {0}, tmp_dstR = {0};
Saurabh Shahacf10202013-02-26 10:15:15 -08001644
Saurabh Shah07a8ca82013-08-06 18:45:42 -07001645 const int lSplit = getLeftSplit(ctx, dpy);
1646
Saurabh Shahacf10202013-02-26 10:15:15 -08001647 if(lDest != OV_INVALID) {
1648 tmp_cropL = crop;
1649 tmp_dstL = dst;
Saurabh Shah67a38c32013-06-10 16:23:15 -07001650 hwc_rect_t scissor = {0, 0, lSplit, hw_h };
Ramkumar Radhakrishnand8559482013-12-05 11:21:44 -08001651 scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
Saurabh Shahacf10202013-02-26 10:15:15 -08001652 qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
1653 }
1654 if(rDest != OV_INVALID) {
1655 tmp_cropR = crop;
1656 tmp_dstR = dst;
Saurabh Shah67a38c32013-06-10 16:23:15 -07001657 hwc_rect_t scissor = {lSplit, 0, hw_w, hw_h };
Ramkumar Radhakrishnand8559482013-12-05 11:21:44 -08001658 scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
Saurabh Shahacf10202013-02-26 10:15:15 -08001659 qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
1660 }
1661
Saurabh Shahd9e426d2013-08-01 13:35:31 -07001662 sanitizeSourceCrop(tmp_cropL, tmp_cropR, hnd);
1663
Saurabh Shah94d62362013-07-02 10:58:48 -07001664 //When buffer is H-flipped, contents of mixer config also needs to swapped
Saurabh Shahacf10202013-02-26 10:15:15 -08001665 //Not needed if the layer is confined to one half of the screen.
1666 //If rotator has been used then it has also done the flips, so ignore them.
Saurabh Shah94d62362013-07-02 10:58:48 -07001667 if((orient & OVERLAY_TRANSFORM_FLIP_H) && lDest != OV_INVALID
Ramkumar Radhakrishnanfe7ce802013-04-30 11:19:17 -07001668 && rDest != OV_INVALID && (*rot) == NULL) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001669 hwc_rect_t new_cropR;
1670 new_cropR.left = tmp_cropL.left;
1671 new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);
1672
1673 hwc_rect_t new_cropL;
1674 new_cropL.left = new_cropR.right;
1675 new_cropL.right = tmp_cropR.right;
1676
1677 tmp_cropL.left = new_cropL.left;
1678 tmp_cropL.right = new_cropL.right;
1679
1680 tmp_cropR.left = new_cropR.left;
1681 tmp_cropR.right = new_cropR.right;
1682
1683 }
1684
Saurabh Shah76fd6552013-03-14 14:45:38 -07001685 //For the mdp, since either we are pre-rotating or MDP does flips
1686 orient = OVERLAY_TRANSFORM_0;
1687 transform = 0;
1688
Saurabh Shahacf10202013-02-26 10:15:15 -08001689 //configure left mixer
1690 if(lDest != OV_INVALID) {
1691 PipeArgs pargL(mdpFlagsL, whf, z, isFg,
Naseer Ahmed522ce662013-03-18 20:14:05 -04001692 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
1693 (ovutils::eBlending) getBlending(layer->blending));
1694
Saurabh Shahacf10202013-02-26 10:15:15 -08001695 if(configMdp(ctx->mOverlay, pargL, orient,
Saurabh Shah5daeee52013-01-23 16:52:26 +08001696 tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001697 ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
1698 return -1;
1699 }
1700 }
1701
1702 //configure right mixer
1703 if(rDest != OV_INVALID) {
1704 PipeArgs pargR(mdpFlagsR, whf, z, isFg,
Naseer Ahmed522ce662013-03-18 20:14:05 -04001705 static_cast<eRotFlags>(rotFlags),
1706 layer->planeAlpha,
1707 (ovutils::eBlending) getBlending(layer->blending));
Saurabh Shah67a38c32013-06-10 16:23:15 -07001708 tmp_dstR.right = tmp_dstR.right - lSplit;
1709 tmp_dstR.left = tmp_dstR.left - lSplit;
Saurabh Shahacf10202013-02-26 10:15:15 -08001710 if(configMdp(ctx->mOverlay, pargR, orient,
Saurabh Shah5daeee52013-01-23 16:52:26 +08001711 tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
Saurabh Shahacf10202013-02-26 10:15:15 -08001712 ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
1713 return -1;
1714 }
1715 }
1716
1717 return 0;
1718}
Arun Kumar K.Ra2978452013-02-07 01:34:24 -08001719
radhakrishnac9a67412013-09-25 17:40:42 +05301720int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
1721 const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
1722 eIsFg& isFg, const eDest& lDest, const eDest& rDest,
1723 Rotator **rot) {
1724 private_handle_t *hnd = (private_handle_t *)layer->handle;
1725 if(!hnd) {
1726 ALOGE("%s: layer handle is NULL", __FUNCTION__);
1727 return -1;
1728 }
1729
1730 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
1731
1732 int hw_w = ctx->dpyAttr[dpy].xres;
1733 int hw_h = ctx->dpyAttr[dpy].yres;
1734 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);;
1735 hwc_rect_t dst = layer->displayFrame;
1736 int transform = layer->transform;
1737 eTransform orient = static_cast<eTransform>(transform);
1738 const int downscale = 0;
1739 int rotFlags = ROT_FLAGS_NONE;
1740 //Splitting only YUV layer on primary panel needs different zorders
1741 //for both layers as both the layers are configured to single mixer
1742 eZorder lz = z;
1743 eZorder rz = (eZorder)(z + 1);
1744
1745 Whf whf(getWidth(hnd), getHeight(hnd),
1746 getMdpFormat(hnd->format), hnd->size);
1747
1748 setMdpFlags(layer, mdpFlagsL, 0, transform);
1749 trimLayer(ctx, dpy, transform, crop, dst);
1750
1751 if(isYuvBuffer(hnd) && (transform & HWC_TRANSFORM_ROT_90)) {
1752 (*rot) = ctx->mRotMgr->getNext();
1753 if((*rot) == NULL) return -1;
1754 if(!dpy)
1755 BwcPM::setBwc(ctx, crop, dst, transform, mdpFlagsL);
1756 //Configure rotator for pre-rotation
1757 if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
1758 ALOGE("%s: configRotator failed!", __FUNCTION__);
radhakrishnac9a67412013-09-25 17:40:42 +05301759 return -1;
1760 }
1761 ctx->mLayerRotMap[dpy]->add(layer, *rot);
1762 whf.format = (*rot)->getDstFormat();
1763 updateSource(orient, whf, crop);
1764 rotFlags |= ROT_PREROTATED;
1765 }
1766
1767 eMdpFlags mdpFlagsR = mdpFlagsL;
1768 int lSplit = dst.left + (dst.right - dst.left)/2;
1769
1770 hwc_rect_t tmp_cropL = {0}, tmp_dstL = {0};
1771 hwc_rect_t tmp_cropR = {0}, tmp_dstR = {0};
1772
1773 if(lDest != OV_INVALID) {
1774 tmp_cropL = crop;
1775 tmp_dstL = dst;
1776 hwc_rect_t scissor = {dst.left, dst.top, lSplit, dst.bottom };
1777 qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
1778 }
1779 if(rDest != OV_INVALID) {
1780 tmp_cropR = crop;
1781 tmp_dstR = dst;
1782 hwc_rect_t scissor = {lSplit, dst.top, dst.right, dst.bottom };
1783 qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
1784 }
1785
1786 sanitizeSourceCrop(tmp_cropL, tmp_cropR, hnd);
1787
1788 //When buffer is H-flipped, contents of mixer config also needs to swapped
1789 //Not needed if the layer is confined to one half of the screen.
1790 //If rotator has been used then it has also done the flips, so ignore them.
1791 if((orient & OVERLAY_TRANSFORM_FLIP_H) && lDest != OV_INVALID
1792 && rDest != OV_INVALID && (*rot) == NULL) {
1793 hwc_rect_t new_cropR;
1794 new_cropR.left = tmp_cropL.left;
1795 new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);
1796
1797 hwc_rect_t new_cropL;
1798 new_cropL.left = new_cropR.right;
1799 new_cropL.right = tmp_cropR.right;
1800
1801 tmp_cropL.left = new_cropL.left;
1802 tmp_cropL.right = new_cropL.right;
1803
1804 tmp_cropR.left = new_cropR.left;
1805 tmp_cropR.right = new_cropR.right;
1806
1807 }
1808
1809 //For the mdp, since either we are pre-rotating or MDP does flips
1810 orient = OVERLAY_TRANSFORM_0;
1811 transform = 0;
1812
1813 //configure left half
1814 if(lDest != OV_INVALID) {
1815 PipeArgs pargL(mdpFlagsL, whf, lz, isFg,
1816 static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
1817 (ovutils::eBlending) getBlending(layer->blending));
1818
1819 if(configMdp(ctx->mOverlay, pargL, orient,
1820 tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
1821 ALOGE("%s: commit failed for left half config", __FUNCTION__);
1822 return -1;
1823 }
1824 }
1825
1826 //configure right half
1827 if(rDest != OV_INVALID) {
1828 PipeArgs pargR(mdpFlagsR, whf, rz, isFg,
1829 static_cast<eRotFlags>(rotFlags),
1830 layer->planeAlpha,
1831 (ovutils::eBlending) getBlending(layer->blending));
1832 if(configMdp(ctx->mOverlay, pargR, orient,
1833 tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
1834 ALOGE("%s: commit failed for right half config", __FUNCTION__);
1835 return -1;
1836 }
1837 }
1838
1839 return 0;
1840}
1841
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001842bool canUseRotator(hwc_context_t *ctx, int dpy) {
Saurabh Shahe2474082013-05-15 16:32:13 -07001843 if(qdutils::MDPVersion::getInstance().is8x26() &&
Amara Venkata Mastan Manoj Kumar5cbac942013-08-13 19:00:14 -07001844 ctx->mVirtualDisplay->isConnected() &&
1845 !ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause) {
Raj Kamala8c065f2013-10-22 14:52:45 +05301846 /* 8x26 mdss driver supports multiplexing of DMA pipe
1847 * in LINE and BLOCK modes for writeback panels.
1848 */
Amara Venkata Mastan Manoj Kumar9d373c02013-08-20 14:30:09 -07001849 if(dpy == HWC_DISPLAY_PRIMARY)
1850 return false;
Saurabh Shahe2474082013-05-15 16:32:13 -07001851 }
Terence Hampson45c02ef2013-05-17 17:00:11 -04001852 if(ctx->mMDP.version == qdutils::MDP_V3_0_4)
1853 return false;
Saurabh Shahe2474082013-05-15 16:32:13 -07001854 return true;
1855}
1856
Saurabh Shah07a8ca82013-08-06 18:45:42 -07001857int getLeftSplit(hwc_context_t *ctx, const int& dpy) {
1858 //Default even split for all displays with high res
1859 int lSplit = ctx->dpyAttr[dpy].xres / 2;
1860 if(dpy == HWC_DISPLAY_PRIMARY &&
1861 qdutils::MDPVersion::getInstance().getLeftSplit()) {
1862 //Override if split published by driver for primary
1863 lSplit = qdutils::MDPVersion::getInstance().getLeftSplit();
1864 }
1865 return lSplit;
1866}
Saurabh Shah1a03d482013-05-29 13:44:20 -07001867
Saurabh Shah88e4d272013-09-03 13:31:29 -07001868bool isDisplaySplit(hwc_context_t* ctx, int dpy) {
1869 if(ctx->dpyAttr[dpy].xres > qdutils::MAX_DISPLAY_DIM) {
1870 return true;
1871 }
1872 //For testing we could split primary via device tree values
1873 if(dpy == HWC_DISPLAY_PRIMARY &&
1874 qdutils::MDPVersion::getInstance().getRightSplit()) {
1875 return true;
1876 }
1877 return false;
1878}
1879
Saurabh Shah1a03d482013-05-29 13:44:20 -07001880void BwcPM::setBwc(hwc_context_t *ctx, const hwc_rect_t& crop,
1881 const hwc_rect_t& dst, const int& transform,
1882 ovutils::eMdpFlags& mdpFlags) {
1883 //Target doesnt support Bwc
1884 if(!qdutils::MDPVersion::getInstance().supportsBWC()) {
1885 return;
1886 }
1887 //src width > MAX mixer supported dim
1888 if((crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) {
1889 return;
1890 }
Saurabh Shah1a03d482013-05-29 13:44:20 -07001891 //Decimation necessary, cannot use BWC. H/W requirement.
1892 if(qdutils::MDPVersion::getInstance().supportsDecimation()) {
1893 int src_w = crop.right - crop.left;
1894 int src_h = crop.bottom - crop.top;
1895 int dst_w = dst.right - dst.left;
1896 int dst_h = dst.bottom - dst.top;
1897 if(transform & HAL_TRANSFORM_ROT_90) {
1898 swap(src_w, src_h);
1899 }
1900 float horDscale = 0.0f;
1901 float verDscale = 0.0f;
Saurabh Shahc5b96dc2013-06-05 13:19:52 -07001902 int horzDeci = 0;
1903 int vertDeci = 0;
Saurabh Shah1a03d482013-05-29 13:44:20 -07001904 ovutils::getDecimationFactor(src_w, src_h, dst_w, dst_h, horDscale,
1905 verDscale);
Saurabh Shahc5b96dc2013-06-05 13:19:52 -07001906 //TODO Use log2f once math.h has it
1907 if((int)horDscale)
1908 horzDeci = (int)(log(horDscale) / log(2));
1909 if((int)verDscale)
1910 vertDeci = (int)(log(verDscale) / log(2));
1911 if(horzDeci || vertDeci) return;
Saurabh Shah1a03d482013-05-29 13:44:20 -07001912 }
1913 //Property
1914 char value[PROPERTY_VALUE_MAX];
1915 property_get("debug.disable.bwc", value, "0");
1916 if(atoi(value)) return;
1917
1918 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDSS_MDP_BWC_EN);
1919}
1920
Saurabh Shah23a813c2013-03-20 16:58:12 -07001921void LayerRotMap::add(hwc_layer_1_t* layer, Rotator *rot) {
1922 if(mCount >= MAX_SESS) return;
1923 mLayer[mCount] = layer;
1924 mRot[mCount] = rot;
1925 mCount++;
1926}
1927
1928void LayerRotMap::reset() {
1929 for (int i = 0; i < MAX_SESS; i++) {
1930 mLayer[i] = 0;
1931 mRot[i] = 0;
1932 }
1933 mCount = 0;
1934}
1935
Saurabh Shahda5b3ce2013-11-26 10:48:06 -08001936void LayerRotMap::clear() {
Saurabh Shah7a606842013-12-11 14:36:04 -08001937 RotMgr::getInstance()->markUnusedTop(mCount);
Saurabh Shahda5b3ce2013-11-26 10:48:06 -08001938 reset();
1939}
1940
Saurabh Shah23a813c2013-03-20 16:58:12 -07001941void LayerRotMap::setReleaseFd(const int& fence) {
1942 for(uint32_t i = 0; i < mCount; i++) {
1943 mRot[i]->setReleaseFd(dup(fence));
1944 }
1945}
1946
Saurabh Shahacf10202013-02-26 10:15:15 -08001947};//namespace qhwc