blob: f95456b2641392364f274badf2ca1000d448654d [file] [log] [blame]
Naseer Ahmedf48aef62012-07-20 09:05:53 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -08003 * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are retained for
6 * attribution purposes only
Naseer Ahmedf48aef62012-07-20 09:05:53 -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 */
20
Naseer Ahmed72cf9762012-07-21 12:17:13 -070021#define VIDEO_DEBUG 0
22#include <overlay.h>
Naseer Ahmedf48aef62012-07-20 09:05:53 -070023#include "hwc_video.h"
Saurabh Shah3e858eb2012-09-17 16:53:21 -070024#include "hwc_utils.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080025#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080026#include "mdp_version.h"
Saurabh Shahacf10202013-02-26 10:15:15 -080027#include <overlayRotator.h>
28
29using overlay::Rotator;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070030
31namespace qhwc {
32
Naseer Ahmed758bfc52012-11-28 17:02:08 -050033namespace ovutils = overlay::utils;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070034
Saurabh Shahacf10202013-02-26 10:15:15 -080035//===========IVideoOverlay=========================
36IVideoOverlay* IVideoOverlay::getObject(const int& width, const int& dpy) {
37 if(width > MAX_DISPLAY_DIM) {
38 return new VideoOverlayHighRes(dpy);
39 }
40 return new VideoOverlayLowRes(dpy);
41}
42
43//===========VideoOverlayLowRes=========================
44
45VideoOverlayLowRes::VideoOverlayLowRes(const int& dpy): IVideoOverlay(dpy) {}
Naseer Ahmedf48aef62012-07-20 09:05:53 -070046
47//Cache stats, figure out the state, config overlay
Saurabh Shahacf10202013-02-26 10:15:15 -080048bool VideoOverlayLowRes::prepare(hwc_context_t *ctx,
49 hwc_display_contents_1_t *list) {
Saurabh Shahc4d034f2012-09-27 15:55:15 -070050
Saurabh Shahacf10202013-02-26 10:15:15 -080051 if(ctx->listStats[mDpy].yuvCount > 1)
Jeykumar Sankarancf537002013-01-21 21:19:15 -080052 return false;
53
Saurabh Shahacf10202013-02-26 10:15:15 -080054 int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
55 int hw_w = ctx->dpyAttr[mDpy].xres;
56 mModeOn = false;
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080057
58 if(hw_w > MAX_DISPLAY_DIM) {
59 ALOGD_IF(VIDEO_DEBUG,"%s, \
60 Cannot use video path for High Res Panels", __FUNCTION__);
61 return false;
62 }
63
Naseer Ahmed96c4c952012-07-25 18:27:14 -070064 if(!ctx->mMDP.hasOverlay) {
Naseer Ahmed31da0b12012-07-31 18:55:33 -070065 ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
66 return false;
67 }
Saurabh Shahc4d034f2012-09-27 15:55:15 -070068
Naseer Ahmed54821fe2012-11-28 18:44:38 -050069 if(isSecuring(ctx)) {
70 ALOGD_IF(VIDEO_DEBUG,"%s: MDP Secure is active", __FUNCTION__);
71 return false;
72 }
73
Saurabh Shahacf10202013-02-26 10:15:15 -080074 if(yuvIndex == -1 || ctx->listStats[mDpy].yuvCount != 1) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -070075 return false;
76 }
Naseer Ahmed4c588a22012-07-31 19:12:17 -070077
Saurabh Shah3e858eb2012-09-17 16:53:21 -070078 //index guaranteed to be not -1 at this point
Naseer Ahmed758bfc52012-11-28 17:02:08 -050079 hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
Sushil Chauhan2515abf2013-01-08 16:40:05 -080080 if (isSecureModePolicy(ctx->mMDP.version)) {
81 private_handle_t *hnd = (private_handle_t *)layer->handle;
82 if(ctx->mSecureMode) {
83 if (! isSecureBuffer(hnd)) {
84 ALOGD_IF(VIDEO_DEBUG, "%s: Handle non-secure video layer"
85 "during secure playback gracefully", __FUNCTION__);
86 return false;
87 }
88 } else {
89 if (isSecureBuffer(hnd)) {
90 ALOGD_IF(VIDEO_DEBUG, "%s: Handle secure video layer"
91 "during non-secure playback gracefully", __FUNCTION__);
92 return false;
93 }
Naseer Ahmedcb5f25b2012-10-04 15:56:00 -040094 }
Naseer Ahmed68b88cf2012-10-02 14:15:12 -040095 }
Saurabh Shahacf10202013-02-26 10:15:15 -080096
Jeykumar Sankarana37fdbf2013-03-06 18:59:28 -080097 if((layer->transform & HWC_TRANSFORM_ROT_90) && ctx->mDMAInUse) {
98 ctx->mDMAInUse = false;
99 ALOGD_IF(VIDEO_DEBUG, "%s: Rotator not available since \
100 DMA Pipe(s) are in use",__FUNCTION__);
101 return false;
102 }
103
Saurabh Shahacf10202013-02-26 10:15:15 -0800104 if(configure(ctx, layer)) {
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500105 markFlags(layer);
Saurabh Shahacf10202013-02-26 10:15:15 -0800106 mModeOn = true;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700107 }
108
Saurabh Shahacf10202013-02-26 10:15:15 -0800109 return mModeOn;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700110}
111
Saurabh Shahacf10202013-02-26 10:15:15 -0800112void VideoOverlayLowRes::markFlags(hwc_layer_1_t *layer) {
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500113 if(layer) {
114 layer->compositionType = HWC_OVERLAY;
115 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700116 }
117}
118
Saurabh Shahacf10202013-02-26 10:15:15 -0800119bool VideoOverlayLowRes::configure(hwc_context_t *ctx,
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500120 hwc_layer_1_t *layer) {
Saurabh Shahacf10202013-02-26 10:15:15 -0800121
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500122 overlay::Overlay& ov = *(ctx->mOverlay);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700123 private_handle_t *hnd = (private_handle_t *)layer->handle;
Saurabh Shahacf10202013-02-26 10:15:15 -0800124 ovutils::Whf info(hnd->width, hnd->height,
125 ovutils::getMdpFormat(hnd->format), hnd->size);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700126
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500127 //Request a VG pipe
Saurabh Shahacf10202013-02-26 10:15:15 -0800128 ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500129 if(dest == ovutils::OV_INVALID) { //None available
130 return false;
131 }
132
Saurabh Shahacf10202013-02-26 10:15:15 -0800133 mDest = dest;
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700134 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530135 ovutils::eZorder zOrder = ovutils::ZORDER_0;
Saurabh Shahacf10202013-02-26 10:15:15 -0800136 ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
137 if (ctx->listStats[mDpy].numAppLayers == 1) {
138 isFg = ovutils::IS_FG_SET;
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700139 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700140
Saurabh Shahacf10202013-02-26 10:15:15 -0800141 return (configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
142 &mRot) == 0 );
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700143}
144
Saurabh Shahacf10202013-02-26 10:15:15 -0800145bool VideoOverlayLowRes::draw(hwc_context_t *ctx,
146 hwc_display_contents_1_t *list) {
147 if(!mModeOn) {
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700148 return true;
149 }
150
Saurabh Shahacf10202013-02-26 10:15:15 -0800151 int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700152 if(yuvIndex == -1) {
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700153 return true;
154 }
155
Naseer Ahmed4c588a22012-07-31 19:12:17 -0700156 private_handle_t *hnd = (private_handle_t *)
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700157 list->hwLayers[yuvIndex].handle;
Naseer Ahmed4c588a22012-07-31 19:12:17 -0700158
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500159 overlay::Overlay& ov = *(ctx->mOverlay);
Saurabh Shahacf10202013-02-26 10:15:15 -0800160 int fd = hnd->fd;
161 uint32_t offset = hnd->offset;
162 Rotator *rot = mRot;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700163
Saurabh Shahacf10202013-02-26 10:15:15 -0800164 if(rot) {
165 if(!rot->queueBuffer(fd, offset))
166 return false;
167 fd = rot->getDstMemId();
168 offset = rot->getDstOffset();
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700169 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500170
Saurabh Shahacf10202013-02-26 10:15:15 -0800171 if (!ov.queueBuffer(fd, offset, mDest)) {
172 ALOGE("%s: queueBuffer failed for dpy=%d", __FUNCTION__, mDpy);
173 return false;
174 }
175
176 return true;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700177}
178
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530179bool VideoOverlayLowRes::isModeOn() {
180 return mModeOn;
181}
182
Saurabh Shahacf10202013-02-26 10:15:15 -0800183//===========VideoOverlayHighRes=========================
184
185VideoOverlayHighRes::VideoOverlayHighRes(const int& dpy): IVideoOverlay(dpy) {}
186
187//Cache stats, figure out the state, config overlay
188bool VideoOverlayHighRes::prepare(hwc_context_t *ctx,
189 hwc_display_contents_1_t *list) {
190
191 int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
192 int hw_w = ctx->dpyAttr[mDpy].xres;
193 mModeOn = false;
194
195 if(!ctx->mMDP.hasOverlay) {
196 ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
197 return false;
198 }
199
200 if(yuvIndex == -1 || ctx->listStats[mDpy].yuvCount != 1) {
201 return false;
202 }
203
204 //index guaranteed to be not -1 at this point
205 hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
206 if(configure(ctx, layer)) {
207 markFlags(layer);
208 mModeOn = true;
209 }
210
211 return mModeOn;
212}
213
214void VideoOverlayHighRes::markFlags(hwc_layer_1_t *layer) {
215 if(layer) {
216 layer->compositionType = HWC_OVERLAY;
217 layer->hints |= HWC_HINT_CLEAR_FB;
218 }
219}
220
221bool VideoOverlayHighRes::configure(hwc_context_t *ctx,
222 hwc_layer_1_t *layer) {
223
224 int hw_w = ctx->dpyAttr[mDpy].xres;
225 overlay::Overlay& ov = *(ctx->mOverlay);
226 private_handle_t *hnd = (private_handle_t *)layer->handle;
227 ovutils::Whf info(hnd->width, hnd->height,
228 ovutils::getMdpFormat(hnd->format), hnd->size);
229
230 //Request a VG pipe
231 mDestL = ovutils::OV_INVALID;
232 mDestR = ovutils::OV_INVALID;
233 hwc_rect_t dst = layer->displayFrame;
234 if(dst.left > hw_w/2) {
235 mDestR = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
236 if(mDestR == ovutils::OV_INVALID)
237 return false;
238 } else if (dst.right <= hw_w/2) {
239 mDestL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
240 if(mDestL == ovutils::OV_INVALID)
241 return false;
242 } else {
243 mDestL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
244 mDestR = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
245 if(mDestL == ovutils::OV_INVALID ||
246 mDestR == ovutils::OV_INVALID)
247 return false;
248 }
249
250 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530251 ovutils::eZorder zOrder = ovutils::ZORDER_0;
Saurabh Shahacf10202013-02-26 10:15:15 -0800252 ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
253 if (ctx->listStats[mDpy].numAppLayers == 1) {
254 isFg = ovutils::IS_FG_SET;
255 }
256
257 return (configureHighRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, mDestL,
258 mDestR, &mRot) == 0 );
259}
260
261bool VideoOverlayHighRes::draw(hwc_context_t *ctx,
262 hwc_display_contents_1_t *list) {
263 if(!mModeOn) {
264 return true;
265 }
266
267 int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
268 if(yuvIndex == -1) {
269 return true;
270 }
271
272 private_handle_t *hnd = (private_handle_t *)
273 list->hwLayers[yuvIndex].handle;
274
275 overlay::Overlay& ov = *(ctx->mOverlay);
276 int fd = hnd->fd;
277 uint32_t offset = hnd->offset;
278 Rotator *rot = mRot;
279
280 if(rot) {
281 if(!rot->queueBuffer(fd, offset))
282 return false;
283 fd = rot->getDstMemId();
284 offset = rot->getDstOffset();
285 }
286
287 if(mDestL != ovutils::OV_INVALID) {
288 if (!ov.queueBuffer(fd, offset, mDestL)) {
289 ALOGE("%s: queueBuffer failed for dpy=%d's left mixer",
290 __FUNCTION__, mDpy);
291 return false;
292 }
293 }
294
295 if(mDestR != ovutils::OV_INVALID) {
296 if (!ov.queueBuffer(fd, offset, mDestR)) {
297 ALOGE("%s: queueBuffer failed for dpy=%d's right mixer"
298 , __FUNCTION__, mDpy);
299 return false;
300 }
301 }
302
303 return true;
304}
305
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530306bool VideoOverlayHighRes::isModeOn() {
307 return mModeOn;
308}
Saurabh Shahacf10202013-02-26 10:15:15 -0800309
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700310}; //namespace qhwc