blob: 249affc014457700dd9644aeb9f2be8c009ff745 [file] [log] [blame]
Saurabh Shah86c17292013-02-08 15:24:13 -08001/*
Arun Kumar K.Rc62935a2013-12-03 16:47:47 -08002 * Copyright (c) 2013-14, The Linux Foundation. All rights reserved.
Saurabh Shah86c17292013-02-08 15:24:13 -08003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR CLIENTS; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <hwc_qclient.h>
31#include <IQService.h>
32#include <hwc_utils.h>
Zohaib Alam1bb65612013-09-28 03:38:20 -040033#include <mdp_version.h>
Naseer Ahmed35a268c2014-06-24 19:07:13 -040034#include <hwc_mdpcomp.h>
Tatenda Chipeperekwa06af9cb2014-08-26 14:51:05 -070035#include <hwc_virtual.h>
Saurabh Shah24eec8a2014-08-22 15:07:25 -070036#include <overlay.h>
Saurabh Shah86c17292013-02-08 15:24:13 -080037
38#define QCLIENT_DEBUG 0
39
40using namespace android;
41using namespace qService;
Arun Kumar K.Rc62935a2013-12-03 16:47:47 -080042using namespace qhwc;
Saurabh Shah24eec8a2014-08-22 15:07:25 -070043using namespace overlay;
Saurabh Shahcd018352014-11-11 13:54:19 -080044using namespace qdutils;
Saurabh Shah86c17292013-02-08 15:24:13 -080045
46namespace qClient {
47
48// ----------------------------------------------------------------------------
Saurabh Shah7128e502013-02-20 13:24:48 -080049QClient::QClient(hwc_context_t *ctx) : mHwcContext(ctx),
50 mMPDeathNotifier(new MPDeathNotifier(ctx))
Saurabh Shah86c17292013-02-08 15:24:13 -080051{
52 ALOGD_IF(QCLIENT_DEBUG, "QClient Constructor invoked");
53}
54
55QClient::~QClient()
56{
57 ALOGD_IF(QCLIENT_DEBUG,"QClient Destructor invoked");
58}
59
Naseer Ahmed4957c522013-11-12 18:07:15 -050060static void securing(hwc_context_t *ctx, uint32_t startEnd) {
61 Locker::Autolock _sl(ctx->mDrawLock);
Saurabh Shahc2125772013-03-15 16:49:50 -070062 //The only way to make this class in this process subscribe to media
63 //player's death.
64 IMediaDeathNotifier::getMediaPlayerService();
65
Naseer Ahmed4957c522013-11-12 18:07:15 -050066 ctx->mSecuring = startEnd;
Saurabh Shah86c17292013-02-08 15:24:13 -080067 //We're done securing
68 if(startEnd == IQService::END)
Naseer Ahmed4957c522013-11-12 18:07:15 -050069 ctx->mSecureMode = true;
70 if(ctx->proc)
71 ctx->proc->invalidate(ctx->proc);
Saurabh Shah86c17292013-02-08 15:24:13 -080072}
73
Naseer Ahmed4957c522013-11-12 18:07:15 -050074static void unsecuring(hwc_context_t *ctx, uint32_t startEnd) {
75 Locker::Autolock _sl(ctx->mDrawLock);
76 ctx->mSecuring = startEnd;
Saurabh Shah86c17292013-02-08 15:24:13 -080077 //We're done unsecuring
78 if(startEnd == IQService::END)
Naseer Ahmed4957c522013-11-12 18:07:15 -050079 ctx->mSecureMode = false;
80 if(ctx->proc)
81 ctx->proc->invalidate(ctx->proc);
Saurabh Shah86c17292013-02-08 15:24:13 -080082}
83
Saurabh Shah7128e502013-02-20 13:24:48 -080084void QClient::MPDeathNotifier::died() {
Saurabh Shahb39f8152013-08-22 10:21:44 -070085 Locker::Autolock _sl(mHwcContext->mDrawLock);
Saurabh Shah7128e502013-02-20 13:24:48 -080086 ALOGD_IF(QCLIENT_DEBUG, "Media Player died");
87 mHwcContext->mSecuring = false;
88 mHwcContext->mSecureMode = false;
89 if(mHwcContext->proc)
90 mHwcContext->proc->invalidate(mHwcContext->proc);
91}
92
Naseer Ahmed4957c522013-11-12 18:07:15 -050093static android::status_t screenRefresh(hwc_context_t *ctx) {
Jeykumar Sankaran9f59a762013-02-28 10:45:56 -080094 status_t result = NO_INIT;
Naseer Ahmed4957c522013-11-12 18:07:15 -050095 if(ctx->proc) {
96 ctx->proc->invalidate(ctx->proc);
Jeykumar Sankaran9f59a762013-02-28 10:45:56 -080097 result = NO_ERROR;
98 }
Jeykumar Sankaran9f59a762013-02-28 10:45:56 -080099 return result;
100}
Arun Kumar K.Rffef7482013-04-10 14:17:22 -0700101
Naseer Ahmed4957c522013-11-12 18:07:15 -0500102static void setExtOrientation(hwc_context_t *ctx, uint32_t orientation) {
103 ctx->mExtOrientation = orientation;
Arun Kumar K.Rffef7482013-04-10 14:17:22 -0700104}
105
Naseer Ahmed78c952e2013-11-25 18:12:23 -0500106static void isExternalConnected(hwc_context_t* ctx, Parcel* outParcel) {
107 int connected;
108 connected = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected ? 1 : 0;
109 outParcel->writeInt32(connected);
110}
111
112static void getDisplayAttributes(hwc_context_t* ctx, const Parcel* inParcel,
113 Parcel* outParcel) {
114 int dpy = inParcel->readInt32();
115 outParcel->writeInt32(ctx->dpyAttr[dpy].vsync_period);
Dileep Kumar Reddie351d842014-03-25 10:39:21 +0530116 if (ctx->dpyAttr[dpy].customFBSize) {
117 outParcel->writeInt32(ctx->dpyAttr[dpy].xres_new);
118 outParcel->writeInt32(ctx->dpyAttr[dpy].yres_new);
119 } else {
120 outParcel->writeInt32(ctx->dpyAttr[dpy].xres);
121 outParcel->writeInt32(ctx->dpyAttr[dpy].yres);
122 }
Naseer Ahmed78c952e2013-11-25 18:12:23 -0500123 outParcel->writeFloat(ctx->dpyAttr[dpy].xdpi);
124 outParcel->writeFloat(ctx->dpyAttr[dpy].ydpi);
125 //XXX: Need to check what to return for HDMI
126 outParcel->writeInt32(ctx->mMDP.panel);
127}
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -0800128static void setHSIC(const Parcel* inParcel) {
Naseer Ahmed78c952e2013-11-25 18:12:23 -0500129 int dpy = inParcel->readInt32();
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -0800130 ALOGD_IF(0, "In %s: dpy = %d", __FUNCTION__, dpy);
Naseer Ahmed78c952e2013-11-25 18:12:23 -0500131 HSICData_t hsic_data;
132 hsic_data.hue = inParcel->readInt32();
133 hsic_data.saturation = inParcel->readFloat();
134 hsic_data.intensity = inParcel->readInt32();
135 hsic_data.contrast = inParcel->readFloat();
136 //XXX: Actually set the HSIC data through ABL lib
137}
138
139
Naseer Ahmed4957c522013-11-12 18:07:15 -0500140static void setBufferMirrorMode(hwc_context_t *ctx, uint32_t enable) {
141 ctx->mBufferMirrorMode = enable;
Arun Kumar K.Rfb5bfa62013-07-25 03:10:51 -0700142}
143
Arun Kumar K.R8e7a62f2013-12-06 18:55:41 -0800144static status_t getDisplayVisibleRegion(hwc_context_t* ctx, int dpy,
145 Parcel* outParcel) {
146 // Get the info only if the dpy is valid
147 if(dpy >= HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
148 Locker::Autolock _sl(ctx->mDrawLock);
149 if(dpy && (ctx->mExtOrientation || ctx->mBufferMirrorMode)) {
150 // Return the destRect on external, if external orienation
151 // is enabled
152 outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.left);
153 outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.top);
154 outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.right);
155 outParcel->writeInt32(ctx->dpyAttr[dpy].mDstRect.bottom);
156 } else {
157 outParcel->writeInt32(ctx->mViewFrame[dpy].left);
158 outParcel->writeInt32(ctx->mViewFrame[dpy].top);
159 outParcel->writeInt32(ctx->mViewFrame[dpy].right);
160 outParcel->writeInt32(ctx->mViewFrame[dpy].bottom);
161 }
162 return NO_ERROR;
163 } else {
164 ALOGE("In %s: invalid dpy index %d", __FUNCTION__, dpy);
165 return BAD_VALUE;
166 }
167}
168
Arun Kumar K.R33888f52014-10-09 15:56:33 -0700169// USed for setting the secondary(hdmi/wfd) status
170static void setSecondaryDisplayStatus(hwc_context_t *ctx,
171 const Parcel* inParcel) {
172 uint32_t dpy = inParcel->readInt32();
173 uint32_t status = inParcel->readInt32();
174 ALOGD_IF(QCLIENT_DEBUG, "%s: dpy = %d status = %s", __FUNCTION__,
175 dpy, getExternalDisplayState(status));
176
177 if(dpy > HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
178 if(dpy == HWC_DISPLAY_VIRTUAL && status == EXTERNAL_OFFLINE) {
179 ctx->mWfdSyncLock.lock();
180 ctx->mWfdSyncLock.signal();
181 ctx->mWfdSyncLock.unlock();
182 } else if(status == EXTERNAL_PAUSE) {
183 handle_pause(ctx, dpy);
184 } else if(status == EXTERNAL_RESUME) {
185 handle_resume(ctx, dpy);
186 }
Arun Kumar K.Rc62935a2013-12-03 16:47:47 -0800187 } else {
Arun Kumar K.R33888f52014-10-09 15:56:33 -0700188 ALOGE("%s: Invalid dpy", __FUNCTION__, dpy);
189 return;
Raj kamal59fea562014-04-01 16:52:19 +0530190 }
191}
192
Ramkumar Radhakrishnan0a021a82014-05-19 19:53:56 -0700193
194static status_t setViewFrame(hwc_context_t* ctx, const Parcel* inParcel) {
195 int dpy = inParcel->readInt32();
196 if(dpy >= HWC_DISPLAY_PRIMARY && dpy <= HWC_DISPLAY_VIRTUAL) {
197 Locker::Autolock _sl(ctx->mDrawLock);
198 ctx->mViewFrame[dpy].left = inParcel->readInt32();
199 ctx->mViewFrame[dpy].top = inParcel->readInt32();
200 ctx->mViewFrame[dpy].right = inParcel->readInt32();
201 ctx->mViewFrame[dpy].bottom = inParcel->readInt32();
202 ALOGD_IF(QCLIENT_DEBUG, "%s: mViewFrame[%d] = [%d %d %d %d]",
203 __FUNCTION__, dpy,
204 ctx->mViewFrame[dpy].left, ctx->mViewFrame[dpy].top,
205 ctx->mViewFrame[dpy].right, ctx->mViewFrame[dpy].bottom);
206 return NO_ERROR;
207 } else {
208 ALOGE("In %s: invalid dpy index %d", __FUNCTION__, dpy);
209 return BAD_VALUE;
210 }
211}
212
Naseer Ahmed35a268c2014-06-24 19:07:13 -0400213static void toggleDynamicDebug(hwc_context_t* ctx, const Parcel* inParcel) {
214 int debug_type = inParcel->readInt32();
215 bool enable = !!inParcel->readInt32();
216 ALOGD("%s: debug_type: %d enable:%d",
217 __FUNCTION__, debug_type, enable);
218 Locker::Autolock _sl(ctx->mDrawLock);
219 switch (debug_type) {
220 //break is ignored for DEBUG_ALL to toggle all of them at once
221 case IQService::DEBUG_ALL:
222 case IQService::DEBUG_MDPCOMP:
223 qhwc::MDPComp::dynamicDebug(enable);
224 if (debug_type != IQService::DEBUG_ALL)
225 break;
226 case IQService::DEBUG_VSYNC:
227 ctx->vstate.debug = enable;
228 if (debug_type != IQService::DEBUG_ALL)
229 break;
Tatenda Chipeperekwa06af9cb2014-08-26 14:51:05 -0700230 case IQService::DEBUG_VD:
Manoj Kumar AVM9591a5e2014-08-21 22:50:21 -0700231 HWCVirtualVDS::dynamicDebug(enable);
Tatenda Chipeperekwa06af9cb2014-08-26 14:51:05 -0700232 if (debug_type != IQService::DEBUG_ALL)
233 break;
Saurabh Shah24eec8a2014-08-22 15:07:25 -0700234 case IQService::DEBUG_PIPE_LIFECYCLE:
235 Overlay::debugPipeLifecycle(enable);
236 if (debug_type != IQService::DEBUG_ALL)
237 break;
Naseer Ahmed35a268c2014-06-24 19:07:13 -0400238 }
239}
240
Saurabh Shah59562ff2014-09-30 16:13:12 -0700241static void setIdleTimeout(hwc_context_t* ctx, const Parcel* inParcel) {
242 uint32_t timeout = (uint32_t)inParcel->readInt32();
243 ALOGD("%s :%u ms", __FUNCTION__, timeout);
244 Locker::Autolock _sl(ctx->mDrawLock);
245 MDPComp::setIdleTimeout(timeout);
246}
247
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700248static void setMaxPipesPerMixer(hwc_context_t* ctx, const Parcel* inParcel) {
249 uint32_t value = (uint32_t)inParcel->readInt32();
250 ALOGD("%s : setting MaxPipesPerMixer: %d ", __FUNCTION__, value);
251 Locker::Autolock _sl(ctx->mDrawLock);
252 MDPComp::setMaxPipesPerMixer(value);
253}
254
Saurabh Shahcd018352014-11-11 13:54:19 -0800255static void toggleBWC(hwc_context_t* ctx, const Parcel* inParcel) {
256 uint32_t enable = (uint32_t)inParcel->readInt32();
257 if(MDPVersion::getInstance().supportsBWC()) {
258 Locker::Autolock _sl(ctx->mDrawLock);
259 ctx->mBWCEnabled = (bool) enable;
260 ALOGI("%s: Set BWC to %d", __FUNCTION__, enable);
261 } else {
262 ALOGI("%s: Target doesn't support BWC", __FUNCTION__);
263 }
264}
265
Naseer Ahmed4957c522013-11-12 18:07:15 -0500266status_t QClient::notifyCallback(uint32_t command, const Parcel* inParcel,
267 Parcel* outParcel) {
Arun Kumar K.R8e7a62f2013-12-06 18:55:41 -0800268 status_t ret = NO_ERROR;
Naseer Ahmed4957c522013-11-12 18:07:15 -0500269
Naseer Ahmed4957c522013-11-12 18:07:15 -0500270 switch(command) {
271 case IQService::SECURING:
272 securing(mHwcContext, inParcel->readInt32());
273 break;
274 case IQService::UNSECURING:
275 unsecuring(mHwcContext, inParcel->readInt32());
276 break;
277 case IQService::SCREEN_REFRESH:
278 return screenRefresh(mHwcContext);
279 break;
280 case IQService::EXTERNAL_ORIENTATION:
281 setExtOrientation(mHwcContext, inParcel->readInt32());
282 break;
283 case IQService::BUFFER_MIRRORMODE:
284 setBufferMirrorMode(mHwcContext, inParcel->readInt32());
285 break;
Arun Kumar K.R8e7a62f2013-12-06 18:55:41 -0800286 case IQService::GET_DISPLAY_VISIBLE_REGION:
287 ret = getDisplayVisibleRegion(mHwcContext, inParcel->readInt32(),
288 outParcel);
289 break;
Naseer Ahmed78c952e2013-11-25 18:12:23 -0500290 case IQService::CHECK_EXTERNAL_STATUS:
291 isExternalConnected(mHwcContext, outParcel);
292 break;
293 case IQService::GET_DISPLAY_ATTRIBUTES:
294 getDisplayAttributes(mHwcContext, inParcel, outParcel);
295 break;
296 case IQService::SET_HSIC_DATA:
Arun Kumar K.R2aa44c62014-01-21 23:08:28 -0800297 setHSIC(inParcel);
Raj kamal59fea562014-04-01 16:52:19 +0530298 break;
Arun Kumar K.R33888f52014-10-09 15:56:33 -0700299 case IQService::SET_SECONDARY_DISPLAY_STATUS:
300 setSecondaryDisplayStatus(mHwcContext, inParcel);
Raj kamal59fea562014-04-01 16:52:19 +0530301 break;
Ramkumar Radhakrishnan0a021a82014-05-19 19:53:56 -0700302 case IQService::SET_VIEW_FRAME:
303 setViewFrame(mHwcContext, inParcel);
304 break;
Naseer Ahmed35a268c2014-06-24 19:07:13 -0400305 case IQService::DYNAMIC_DEBUG:
306 toggleDynamicDebug(mHwcContext, inParcel);
307 break;
Saurabh Shah59562ff2014-09-30 16:13:12 -0700308 case IQService::SET_IDLE_TIMEOUT:
309 setIdleTimeout(mHwcContext, inParcel);
310 break;
Jeykumar Sankaranbe93e272014-06-19 18:15:57 -0700311 case IQService::SET_MAX_PIPES_PER_MIXER:
312 setMaxPipesPerMixer(mHwcContext, inParcel);
313 break;
Saurabh Shahcd018352014-11-11 13:54:19 -0800314 case IQService::TOGGLE_BWC:
315 toggleBWC(mHwcContext, inParcel);
316 break;
Naseer Ahmed4957c522013-11-12 18:07:15 -0500317 default:
Arun Kumar K.R8e7a62f2013-12-06 18:55:41 -0800318 ret = NO_ERROR;
Naseer Ahmed4957c522013-11-12 18:07:15 -0500319 }
Arun Kumar K.R8e7a62f2013-12-06 18:55:41 -0800320 return ret;
Naseer Ahmed4957c522013-11-12 18:07:15 -0500321}
322
Saurabh Shah86c17292013-02-08 15:24:13 -0800323}