blob: e9446adb611bd02f1d483cae704ca13f34ae91da [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 */
Arun Kumar K.R361da4f2012-11-28 10:42:59 -080020#define HWC_UTILS_DEBUG 0
Naseer Ahmed758bfc52012-11-28 17:02:08 -050021#include <sys/ioctl.h>
Saurabh Shah86c17292013-02-08 15:24:13 -080022#include <binder/IServiceManager.h>
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070023#include <EGL/egl.h>
Saurabh Shahfc2acbe2012-08-17 19:47:52 -070024#include <cutils/properties.h>
25#include <gralloc_priv.h>
26#include <fb_priv.h>
Naseer Ahmed758bfc52012-11-28 17:02:08 -050027#include <overlay.h>
Naseer Ahmed29a26812012-06-14 00:56:20 -070028#include "hwc_utils.h"
Naseer Ahmed54821fe2012-11-28 18:44:38 -050029#include "hwc_mdpcomp.h"
Saurabh Shahcf053c62012-12-13 12:32:55 -080030#include "hwc_fbupdate.h"
Naseer Ahmeda87da602012-07-01 23:54:19 -070031#include "mdp_version.h"
Arun Kumar K.R361da4f2012-11-28 10:42:59 -080032#include "hwc_copybit.h"
Saurabh Shah56f610d2012-08-07 15:27:06 -070033#include "external.h"
Saurabh Shah86c17292013-02-08 15:24:13 -080034#include "hwc_qclient.h"
Saurabh Shah56f610d2012-08-07 15:27:06 -070035#include "QService.h"
Arun Kumar K.R361da4f2012-11-28 10:42:59 -080036#include "comptype.h"
Saurabh Shah86c17292013-02-08 15:24:13 -080037
38using namespace qClient;
39using namespace qService;
40using namespace android;
41
Naseer Ahmed29a26812012-06-14 00:56:20 -070042namespace qhwc {
Naseer Ahmed72cf9762012-07-21 12:17:13 -070043
44// Opens Framebuffer device
45static void openFramebufferDevice(hwc_context_t *ctx)
46{
47 hw_module_t const *module;
48 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
49 framebuffer_open(module, &(ctx->mFbDev));
Saurabh Shah3e858eb2012-09-17 16:53:21 -070050 private_module_t* m = reinterpret_cast<private_module_t*>(
51 ctx->mFbDev->common.module);
52 //xres, yres may not be 32 aligned
Naseer Ahmed54821fe2012-11-28 18:44:38 -050053 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride = m->finfo.line_length /
54 (m->info.xres/8);
Saurabh Shah3e858eb2012-09-17 16:53:21 -070055 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = m->info.xres;
56 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = m->info.yres;
57 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = ctx->mFbDev->xdpi;
58 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ctx->mFbDev->ydpi;
59 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period =
60 1000000000l / ctx->mFbDev->fps;
61 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = openFb(HWC_DISPLAY_PRIMARY);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070062 }
63}
64
Naseer Ahmed29a26812012-06-14 00:56:20 -070065void initContext(hwc_context_t *ctx)
66{
Naseer Ahmed72cf9762012-07-21 12:17:13 -070067 openFramebufferDevice(ctx);
Saurabh Shahc4d034f2012-09-27 15:55:15 -070068 overlay::Overlay::initOverlay();
Naseer Ahmed758bfc52012-11-28 17:02:08 -050069 ctx->mOverlay = overlay::Overlay::getInstance();
Naseer Ahmed96c4c952012-07-25 18:27:14 -070070 ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
71 ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
72 ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
Saurabh Shahcf053c62012-12-13 12:32:55 -080073 //Is created and destroyed only once for primary
74 //For external it could get created and destroyed multiple times depending
75 //on what external we connect to.
76 ctx->mFBUpdate[HWC_DISPLAY_PRIMARY] =
77 IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
78 HWC_DISPLAY_PRIMARY);
Arun Kumar K.R361da4f2012-11-28 10:42:59 -080079
80 char value[PROPERTY_VALUE_MAX];
81 // Check if the target supports copybit compostion (dyn/mdp/c2d) to
82 // decide if we need to open the copybit module.
83 int compositionType =
84 qdutils::QCCompositionType::getInstance().getCompositionType();
85
86 if (compositionType & (qdutils::COMPOSITION_TYPE_DYN |
87 qdutils::COMPOSITION_TYPE_MDP |
88 qdutils::COMPOSITION_TYPE_C2D)) {
89 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit();
90 }
91
Naseer Ahmed72cf9762012-07-21 12:17:13 -070092 ctx->mExtDisplay = new ExternalDisplay(ctx);
Amara Venkata Mastan Manoj Kumar11a380d2013-01-17 09:30:56 -080093 for (uint32_t i = 0; i < MAX_DISPLAYS; i++)
Naseer Ahmede78f0522012-12-07 18:24:28 -050094 ctx->mLayerCache[i] = new LayerCache();
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -080095 ctx->mMDPComp = MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres);
Naseer Ahmed54821fe2012-11-28 18:44:38 -050096 MDPComp::init(ctx);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070097
Naseer Ahmedff4f0252012-10-01 13:03:01 -040098 pthread_mutex_init(&(ctx->vstate.lock), NULL);
99 pthread_cond_init(&(ctx->vstate.cond), NULL);
100 ctx->vstate.enable = false;
Naseer Ahmed56601cd2013-03-05 11:34:14 -0500101 ctx->vstate.fakevsync = false;
Amara Venkata Mastan Manoj Kumar75526f52012-12-27 18:27:01 -0800102 ctx->mExtDispConfiguring = false;
Saurabh Shah86c17292013-02-08 15:24:13 -0800103
104 //Right now hwc starts the service but anybody could do it, or it could be
105 //independent process as well.
106 QService::init();
107 sp<IQClient> client = new QClient(ctx);
108 interface_cast<IQService>(
109 defaultServiceManager()->getService(
110 String16("display.qservice")))->connect(client);
111
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700112 ALOGI("Initializing Qualcomm Hardware Composer");
Naseer Ahmed96c4c952012-07-25 18:27:14 -0700113 ALOGI("MDP version: %d", ctx->mMDP.version);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700114}
115
116void closeContext(hwc_context_t *ctx)
117{
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500118 if(ctx->mOverlay) {
119 delete ctx->mOverlay;
120 ctx->mOverlay = NULL;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700121 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700122
Amara Venkata Mastan Manoj Kumar11a380d2013-01-17 09:30:56 -0800123 for(int i = 0; i < MAX_DISPLAYS; i++) {
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800124 if(ctx->mCopyBit[i]) {
125 delete ctx->mCopyBit[i];
126 ctx->mCopyBit[i] = NULL;
127 }
128 }
129
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700130 if(ctx->mFbDev) {
131 framebuffer_close(ctx->mFbDev);
132 ctx->mFbDev = NULL;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700133 close(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd);
134 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700135 }
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700136
137 if(ctx->mExtDisplay) {
138 delete ctx->mExtDisplay;
139 ctx->mExtDisplay = NULL;
140 }
Naseer Ahmedff4f0252012-10-01 13:03:01 -0400141
Amara Venkata Mastan Manoj Kumar11a380d2013-01-17 09:30:56 -0800142 for(int i = 0; i < MAX_DISPLAYS; i++) {
Saurabh Shahcf053c62012-12-13 12:32:55 -0800143 if(ctx->mFBUpdate[i]) {
144 delete ctx->mFBUpdate[i];
145 ctx->mFBUpdate[i] = NULL;
146 }
147 }
148
Saurabh Shahcbf7ccc2012-12-19 16:45:51 -0800149 if(ctx->mMDPComp) {
150 delete ctx->mMDPComp;
151 ctx->mMDPComp = NULL;
152 }
153
Naseer Ahmedff4f0252012-10-01 13:03:01 -0400154 pthread_mutex_destroy(&(ctx->vstate.lock));
155 pthread_cond_destroy(&(ctx->vstate.cond));
Naseer Ahmed29a26812012-06-14 00:56:20 -0700156}
157
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500158
159void dumpsys_log(android::String8& buf, const char* fmt, ...)
Naseer Ahmed29a26812012-06-14 00:56:20 -0700160{
Naseer Ahmed1d183f52012-11-26 12:35:16 -0500161 va_list varargs;
162 va_start(varargs, fmt);
163 buf.appendFormatV(fmt, varargs);
164 va_end(varargs);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700165}
166
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800167/* Calculates the destination position based on the action safe rectangle */
168void getActionSafePosition(hwc_context_t *ctx, int dpy, uint32_t& x,
169 uint32_t& y, uint32_t& w, uint32_t& h) {
170
171 // if external supports underscan, do nothing
172 // it will be taken care in the driver
173 if(ctx->mExtDisplay->isCEUnderscanSupported())
174 return;
175
176 float wRatio = 1.0;
177 float hRatio = 1.0;
178 float xRatio = 1.0;
179 float yRatio = 1.0;
180
181 float fbWidth = ctx->dpyAttr[dpy].xres;
182 float fbHeight = ctx->dpyAttr[dpy].yres;
183
184 float asX = 0;
185 float asY = 0;
186 float asW = fbWidth;
187 float asH= fbHeight;
188 char value[PROPERTY_VALUE_MAX];
189
190 // Apply action safe parameters
191 property_get("hw.actionsafe.width", value, "0");
192 int asWidthRatio = atoi(value);
193 property_get("hw.actionsafe.height", value, "0");
194 int asHeightRatio = atoi(value);
195 // based on the action safe ratio, get the Action safe rectangle
196 asW = fbWidth * (1.0f - asWidthRatio / 100.0f);
197 asH = fbHeight * (1.0f - asHeightRatio / 100.0f);
198 asX = (fbWidth - asW) / 2;
199 asY = (fbHeight - asH) / 2;
200
201 // calculate the position ratio
202 xRatio = (float)x/fbWidth;
203 yRatio = (float)y/fbHeight;
204 wRatio = (float)w/fbWidth;
205 hRatio = (float)h/fbHeight;
206
207 //Calculate the position...
208 x = (xRatio * asW) + asX;
209 y = (yRatio * asH) + asY;
210 w = (wRatio * asW);
211 h = (hRatio * asH);
212
213 return;
214}
215
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800216bool needsScaling(hwc_layer_1_t const* layer) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500217 int dst_w, dst_h, src_w, src_h;
218
219 hwc_rect_t displayFrame = layer->displayFrame;
220 hwc_rect_t sourceCrop = layer->sourceCrop;
221
222 dst_w = displayFrame.right - displayFrame.left;
223 dst_h = displayFrame.bottom - displayFrame.top;
224
225 src_w = sourceCrop.right - sourceCrop.left;
226 src_h = sourceCrop.bottom - sourceCrop.top;
227
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800228 if(((src_w != dst_w) || (src_h != dst_h)))
229 return true;
230
231 return false;
232}
233
234bool isAlphaScaled(hwc_layer_1_t const* layer) {
235 if(needsScaling(layer)) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500236 if(layer->blending != HWC_BLENDING_NONE)
237 return true;
238 }
239 return false;
240}
241
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700242void setListStats(hwc_context_t *ctx,
243 const hwc_display_contents_1_t *list, int dpy) {
244
245 ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
246 ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700247 ctx->listStats[dpy].skipCount = 0;
Naseer Ahmed018e5452012-12-03 14:46:15 -0500248 ctx->listStats[dpy].needsAlphaScale = false;
Jeykumar Sankarancf537002013-01-21 21:19:15 -0800249 ctx->listStats[dpy].yuvCount = 0;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800250 ctx->mDMAInUse = false;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700251
252 for (size_t i = 0; i < list->numHwLayers; i++) {
Naseer Ahmed018e5452012-12-03 14:46:15 -0500253 hwc_layer_1_t const* layer = &list->hwLayers[i];
254 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700255
Jeykumar Sankarancf537002013-01-21 21:19:15 -0800256 //reset stored yuv index
257 ctx->listStats[dpy].yuvIndices[i] = -1;
258
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700259 if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
260 continue;
261 //We disregard FB being skip for now! so the else if
Saurabh Shah35712cb2012-09-14 10:28:18 -0700262 } else if (isSkipLayer(&list->hwLayers[i])) {
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700263 ctx->listStats[dpy].skipCount++;
Jeykumar Sankaran7535aba2013-02-04 11:03:09 -0800264 } else if (UNLIKELY(isYuvBuffer(hnd))) {
Jeykumar Sankarancf537002013-01-21 21:19:15 -0800265 int& yuvCount = ctx->listStats[dpy].yuvCount;
266 ctx->listStats[dpy].yuvIndices[yuvCount] = i;
267 yuvCount++;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800268
269 if((layer->transform & HWC_TRANSFORM_ROT_90) && !ctx->mDMAInUse)
270 ctx->mDMAInUse = true;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700271 }
Jeykumar Sankaran7535aba2013-02-04 11:03:09 -0800272
273 if(!ctx->listStats[dpy].needsAlphaScale)
274 ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700275 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700276}
277
Naseer Ahmed018e5452012-12-03 14:46:15 -0500278
Saurabh Shah541b59d2012-10-11 11:08:12 -0700279static inline void calc_cut(float& leftCutRatio, float& topCutRatio,
280 float& rightCutRatio, float& bottomCutRatio, int orient) {
Saurabh Shah27c1d652012-08-14 19:30:28 -0700281 if(orient & HAL_TRANSFORM_FLIP_H) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700282 swap(leftCutRatio, rightCutRatio);
Saurabh Shah27c1d652012-08-14 19:30:28 -0700283 }
284 if(orient & HAL_TRANSFORM_FLIP_V) {
Saurabh Shah541b59d2012-10-11 11:08:12 -0700285 swap(topCutRatio, bottomCutRatio);
Saurabh Shah27c1d652012-08-14 19:30:28 -0700286 }
287 if(orient & HAL_TRANSFORM_ROT_90) {
288 //Anti clock swapping
Saurabh Shah541b59d2012-10-11 11:08:12 -0700289 float tmpCutRatio = leftCutRatio;
290 leftCutRatio = topCutRatio;
291 topCutRatio = rightCutRatio;
292 rightCutRatio = bottomCutRatio;
293 bottomCutRatio = tmpCutRatio;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700294 }
295}
296
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500297bool isSecuring(hwc_context_t* ctx) {
298 if((ctx->mMDP.version < qdutils::MDSS_V5) &&
299 (ctx->mMDP.version > qdutils::MDP_V3_0) &&
300 ctx->mSecuring) {
301 return true;
302 }
303 return false;
304}
305
Sushil Chauhan2515abf2013-01-08 16:40:05 -0800306bool isSecureModePolicy(int mdpVersion) {
307 if (mdpVersion < qdutils::MDSS_V5)
308 return true;
309 else
310 return false;
311}
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500312
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700313//Crops source buffer against destination and FB boundaries
314void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800315 const hwc_rect_t& scissor, int orient) {
316
Saurabh Shah27c1d652012-08-14 19:30:28 -0700317 int& crop_l = crop.left;
318 int& crop_t = crop.top;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700319 int& crop_r = crop.right;
320 int& crop_b = crop.bottom;
321 int crop_w = crop.right - crop.left;
322 int crop_h = crop.bottom - crop.top;
323
Saurabh Shah27c1d652012-08-14 19:30:28 -0700324 int& dst_l = dst.left;
325 int& dst_t = dst.top;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700326 int& dst_r = dst.right;
327 int& dst_b = dst.bottom;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700328 int dst_w = abs(dst.right - dst.left);
329 int dst_h = abs(dst.bottom - dst.top);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700330
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800331 const int& sci_l = scissor.left;
332 const int& sci_t = scissor.top;
333 const int& sci_r = scissor.right;
334 const int& sci_b = scissor.bottom;
335 int sci_w = abs(sci_r - sci_l);
336 int sci_h = abs(sci_b - sci_t);
337
Saurabh Shah541b59d2012-10-11 11:08:12 -0700338 float leftCutRatio = 0.0f, rightCutRatio = 0.0f, topCutRatio = 0.0f,
339 bottomCutRatio = 0.0f;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700340
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800341 if(dst_l < sci_l) {
342 leftCutRatio = (float)(sci_l - dst_l) / (float)dst_w;
343 dst_l = sci_l;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700344 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800345
346 if(dst_r > sci_r) {
347 rightCutRatio = (float)(dst_r - sci_r) / (float)dst_w;
348 dst_r = sci_r;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700349 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800350
351 if(dst_t < sci_t) {
352 topCutRatio = (float)(sci_t - dst_t) / (float)dst_h;
353 dst_t = sci_t;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700354 }
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800355
356 if(dst_b > sci_b) {
357 bottomCutRatio = (float)(dst_b - sci_b) / (float)dst_h;
358 dst_b = sci_b;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700359 }
Saurabh Shah27c1d652012-08-14 19:30:28 -0700360
Saurabh Shah541b59d2012-10-11 11:08:12 -0700361 calc_cut(leftCutRatio, topCutRatio, rightCutRatio, bottomCutRatio, orient);
362 crop_l += crop_w * leftCutRatio;
363 crop_t += crop_h * topCutRatio;
364 crop_r -= crop_w * rightCutRatio;
365 crop_b -= crop_h * bottomCutRatio;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700366}
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700367
Naseer Ahmed64b81212013-02-14 10:29:47 -0500368void getNonWormholeRegion(hwc_display_contents_1_t* list,
369 hwc_rect_t& nwr)
370{
371 uint32_t last = list->numHwLayers - 1;
372 hwc_rect_t fbDisplayFrame = list->hwLayers[last].displayFrame;
373 //Initiliaze nwr to first frame
374 nwr.left = list->hwLayers[0].displayFrame.left;
375 nwr.top = list->hwLayers[0].displayFrame.top;
376 nwr.right = list->hwLayers[0].displayFrame.right;
377 nwr.bottom = list->hwLayers[0].displayFrame.bottom;
378
379 for (uint32_t i = 1; i < last; i++) {
380 hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
381 nwr.left = min(nwr.left, displayFrame.left);
382 nwr.top = min(nwr.top, displayFrame.top);
383 nwr.right = max(nwr.right, displayFrame.right);
384 nwr.bottom = max(nwr.bottom, displayFrame.bottom);
385 }
386
387 //Intersect with the framebuffer
388 nwr.left = max(nwr.left, fbDisplayFrame.left);
389 nwr.top = max(nwr.top, fbDisplayFrame.top);
390 nwr.right = min(nwr.right, fbDisplayFrame.right);
391 nwr.bottom = min(nwr.bottom, fbDisplayFrame.bottom);
392
393}
394
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700395bool isExternalActive(hwc_context_t* ctx) {
396 return ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive;
Saurabh Shahfc2acbe2012-08-17 19:47:52 -0700397}
398
Saurabh Shah747af1e2013-02-26 10:25:12 -0800399void closeAcquireFds(hwc_display_contents_1_t* list) {
400 for(uint32_t i = 0; list && i < list->numHwLayers; i++) {
401 //Close the acquireFenceFds
402 //HWC_FRAMEBUFFER are -1 already by SF, rest we close.
403 if(list->hwLayers[i].acquireFenceFd >= 0) {
404 close(list->hwLayers[i].acquireFenceFd);
405 list->hwLayers[i].acquireFenceFd = -1;
406 }
407 }
408}
409
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800410int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
411 int fd) {
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700412 int ret = 0;
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700413 struct mdp_buf_sync data;
Naseer Ahmedb1c76322012-10-17 00:32:50 -0400414 int acquireFd[MAX_NUM_LAYERS];
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700415 int count = 0;
416 int releaseFd = -1;
417 int fbFd = -1;
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800418 memset(&data, 0, sizeof(data));
Naseer Ahmed94baddc2012-12-17 18:51:01 -0500419 bool swapzero = false;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700420 data.flags = MDP_BUF_SYNC_FLAG_WAIT;
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700421 data.acq_fen_fd = acquireFd;
422 data.rel_fen_fd = &releaseFd;
Naseer Ahmed94baddc2012-12-17 18:51:01 -0500423 char property[PROPERTY_VALUE_MAX];
424 if(property_get("debug.egl.swapinterval", property, "1") > 0) {
425 if(atoi(property) == 0)
426 swapzero = true;
427 }
428
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700429 //Accumulate acquireFenceFds
430 for(uint32_t i = 0; i < list->numHwLayers; i++) {
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800431 if(list->hwLayers[i].compositionType == HWC_OVERLAY &&
432 list->hwLayers[i].acquireFenceFd != -1) {
Naseer Ahmed94baddc2012-12-17 18:51:01 -0500433 if(UNLIKELY(swapzero))
434 acquireFd[count++] = -1;
435 else
436 acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700437 }
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800438 if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
439 if(UNLIKELY(swapzero))
440 acquireFd[count++] = -1;
441 else if(fd != -1) {
442 //set the acquireFD from fd - which is coming from c2d
443 acquireFd[count++] = fd;
444 // Buffer sync IOCTL should be async when using c2d fence is
445 // used
446 data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
447 } else if(list->hwLayers[i].acquireFenceFd != -1)
448 acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
449 }
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700450 }
451
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -0700452 data.acq_fen_fd_cnt = count;
453 fbFd = ctx->dpyAttr[dpy].fd;
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -0700454 //Waits for acquire fences, returns a release fence
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800455 if(LIKELY(!swapzero)) {
456 uint64_t start = systemTime();
Naseer Ahmed94baddc2012-12-17 18:51:01 -0500457 ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800458 ALOGD_IF(HWC_UTILS_DEBUG, "%s: time taken for MSMFB_BUFFER_SYNC IOCTL = %d",
459 __FUNCTION__, (size_t) ns2ms(systemTime() - start));
460 }
Saurabh Shah747af1e2013-02-26 10:25:12 -0800461
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -0700462 if(ret < 0) {
463 ALOGE("ioctl MSMFB_BUFFER_SYNC failed, err=%s",
464 strerror(errno));
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700465 }
Saurabh Shah747af1e2013-02-26 10:25:12 -0800466
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -0700467 for(uint32_t i = 0; i < list->numHwLayers; i++) {
Arun Kumar K.R361da4f2012-11-28 10:42:59 -0800468 if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
469 list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -0700470 //Populate releaseFenceFds.
Naseer Ahmed94baddc2012-12-17 18:51:01 -0500471 if(UNLIKELY(swapzero))
472 list->hwLayers[i].releaseFenceFd = -1;
473 else
474 list->hwLayers[i].releaseFenceFd = dup(releaseFd);
Kinjal Bhavsar40a1cc52012-10-10 15:52:03 -0700475 }
476 }
Saurabh Shah747af1e2013-02-26 10:25:12 -0800477
478 if(fd >= 0) {
479 close(fd);
480 fd = -1;
481 }
482
Naseer Ahmed64b81212013-02-14 10:29:47 -0500483 if (ctx->mCopyBit[dpy])
484 ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
Naseer Ahmed94baddc2012-12-17 18:51:01 -0500485 if(UNLIKELY(swapzero)){
486 list->retireFenceFd = -1;
487 close(releaseFd);
488 } else {
489 list->retireFenceFd = releaseFd;
490 }
Saurabh Shah747af1e2013-02-26 10:25:12 -0800491
Kinjal Bhavsar2dd04a82012-09-18 18:27:59 -0700492 return ret;
493}
494
Naseer Ahmedb1c76322012-10-17 00:32:50 -0400495void LayerCache::resetLayerCache(int num) {
496 for(uint32_t i = 0; i < MAX_NUM_LAYERS; i++) {
497 hnd[i] = NULL;
498 }
499 numHwLayers = num;
500}
501
502void LayerCache::updateLayerCache(hwc_display_contents_1_t* list) {
503
504 int numFbLayers = 0;
505 int numCacheableLayers = 0;
506
507 canUseLayerCache = false;
508 //Bail if geometry changed or num of layers changed
509 if(list->flags & HWC_GEOMETRY_CHANGED ||
510 list->numHwLayers != numHwLayers ) {
511 resetLayerCache(list->numHwLayers);
512 return;
513 }
514
515 for(uint32_t i = 0; i < list->numHwLayers; i++) {
516 //Bail on skip layers
517 if(list->hwLayers[i].flags & HWC_SKIP_LAYER) {
518 resetLayerCache(list->numHwLayers);
519 return;
520 }
521
522 if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER) {
523 numFbLayers++;
524 if(hnd[i] == NULL) {
525 hnd[i] = list->hwLayers[i].handle;
526 } else if (hnd[i] ==
527 list->hwLayers[i].handle) {
528 numCacheableLayers++;
529 } else {
530 hnd[i] = NULL;
531 return;
532 }
533 } else {
534 hnd[i] = NULL;
535 }
536 }
537 if(numFbLayers == numCacheableLayers)
538 canUseLayerCache = true;
539
540 //XXX: The marking part is separate, if MDP comp wants
541 // to use it in the future. Right now getting MDP comp
542 // to use this is more trouble than it is worth.
543 markCachedLayersAsOverlay(list);
544}
545
546void LayerCache::markCachedLayersAsOverlay(hwc_display_contents_1_t* list) {
547 //This optimization only works if ALL the layer handles
548 //that were on the framebuffer didn't change.
549 if(canUseLayerCache){
550 for(uint32_t i = 0; i < list->numHwLayers; i++) {
551 if (list->hwLayers[i].handle &&
552 list->hwLayers[i].handle == hnd[i] &&
553 list->hwLayers[i].compositionType != HWC_FRAMEBUFFER_TARGET)
554 {
555 list->hwLayers[i].compositionType = HWC_OVERLAY;
556 }
557 }
558 }
559
560}
561
Naseer Ahmed29a26812012-06-14 00:56:20 -0700562};//namespace