blob: edd0ba886a17dd1296fa1782341dac60b212d4c9 [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"
Naseer Ahmedf48aef62012-07-20 09:05:53 -070027
28namespace qhwc {
29
Naseer Ahmed758bfc52012-11-28 17:02:08 -050030namespace ovutils = overlay::utils;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070031
32//Static Members
Saurabh Shahc4d034f2012-09-27 15:55:15 -070033bool VideoOverlay::sIsModeOn[] = {false};
Naseer Ahmed758bfc52012-11-28 17:02:08 -050034ovutils::eDest VideoOverlay::sDest[] = {ovutils::OV_INVALID};
Naseer Ahmedf48aef62012-07-20 09:05:53 -070035
36//Cache stats, figure out the state, config overlay
Saurabh Shah3e858eb2012-09-17 16:53:21 -070037bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
38 int dpy) {
Saurabh Shahc4d034f2012-09-27 15:55:15 -070039
Jeykumar Sankarancf537002013-01-21 21:19:15 -080040 if(ctx->listStats[dpy].yuvCount > 1)
41 return false;
42
43 int yuvIndex = ctx->listStats[dpy].yuvIndices[0];
Saurabh Shahc4d034f2012-09-27 15:55:15 -070044 sIsModeOn[dpy] = false;
Saurabh Shah3e858eb2012-09-17 16:53:21 -070045
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -080046 int hw_w = ctx->dpyAttr[dpy].xres;
47
48 if(hw_w > MAX_DISPLAY_DIM) {
49 ALOGD_IF(VIDEO_DEBUG,"%s, \
50 Cannot use video path for High Res Panels", __FUNCTION__);
51 return false;
52 }
53
Naseer Ahmed96c4c952012-07-25 18:27:14 -070054 if(!ctx->mMDP.hasOverlay) {
Naseer Ahmed31da0b12012-07-31 18:55:33 -070055 ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
56 return false;
57 }
Saurabh Shahc4d034f2012-09-27 15:55:15 -070058
Naseer Ahmed54821fe2012-11-28 18:44:38 -050059 if(isSecuring(ctx)) {
60 ALOGD_IF(VIDEO_DEBUG,"%s: MDP Secure is active", __FUNCTION__);
61 return false;
62 }
63
Saurabh Shahc4d034f2012-09-27 15:55:15 -070064 if(yuvIndex == -1 || ctx->listStats[dpy].yuvCount != 1) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -070065 return false;
66 }
Naseer Ahmed4c588a22012-07-31 19:12:17 -070067
Saurabh Shah3e858eb2012-09-17 16:53:21 -070068 //index guaranteed to be not -1 at this point
Naseer Ahmed758bfc52012-11-28 17:02:08 -050069 hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
Sushil Chauhan2515abf2013-01-08 16:40:05 -080070 if (isSecureModePolicy(ctx->mMDP.version)) {
71 private_handle_t *hnd = (private_handle_t *)layer->handle;
72 if(ctx->mSecureMode) {
73 if (! isSecureBuffer(hnd)) {
74 ALOGD_IF(VIDEO_DEBUG, "%s: Handle non-secure video layer"
75 "during secure playback gracefully", __FUNCTION__);
76 return false;
77 }
78 } else {
79 if (isSecureBuffer(hnd)) {
80 ALOGD_IF(VIDEO_DEBUG, "%s: Handle secure video layer"
81 "during non-secure playback gracefully", __FUNCTION__);
82 return false;
83 }
Naseer Ahmedcb5f25b2012-10-04 15:56:00 -040084 }
Naseer Ahmed68b88cf2012-10-02 14:15:12 -040085 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -050086 if(configure(ctx, dpy, layer)) {
87 markFlags(layer);
Saurabh Shahc4d034f2012-09-27 15:55:15 -070088 sIsModeOn[dpy] = true;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070089 }
90
Saurabh Shahc4d034f2012-09-27 15:55:15 -070091 return sIsModeOn[dpy];
Naseer Ahmedf48aef62012-07-20 09:05:53 -070092}
93
Naseer Ahmed758bfc52012-11-28 17:02:08 -050094void VideoOverlay::markFlags(hwc_layer_1_t *layer) {
95 if(layer) {
96 layer->compositionType = HWC_OVERLAY;
97 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070098 }
99}
100
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500101bool VideoOverlay::configure(hwc_context_t *ctx, int dpy,
102 hwc_layer_1_t *layer) {
103 overlay::Overlay& ov = *(ctx->mOverlay);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700104 private_handle_t *hnd = (private_handle_t *)layer->handle;
105 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700106
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500107 //Request a VG pipe
108 ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
109 if(dest == ovutils::OV_INVALID) { //None available
110 return false;
111 }
112
113 sDest[dpy] = dest;
114
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700115 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700116 if (isSecureBuffer(hnd)) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700117 ovutils::setMdpFlags(mdpFlags,
118 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
119 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700120
Saurabh Shah91a6a992012-08-20 15:25:28 -0700121 if(layer->blending == HWC_BLENDING_PREMULT) {
122 ovutils::setMdpFlags(mdpFlags,
123 ovutils::OV_MDP_BLEND_FG_PREMULT);
124 }
125
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800126 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
Ramkumar Radhakrishnan12b103b2013-01-09 17:47:56 -0800127 if (metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
128 metadata->interlaced) {
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800129 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
130 }
131
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700132 ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500133 if (ctx->listStats[dpy].numAppLayers == 1) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700134 isFgFlag = ovutils::IS_FG_SET;
135 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700136
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800137 ovutils::eRotFlags rotFlags = ovutils::ROT_FLAGS_NONE;
138 if(ctx->mMDP.version >= qdutils::MDP_V4_2 &&
139 ctx->mMDP.version < qdutils::MDSS_V5) {
140 rotFlags = ovutils::ROT_DOWNSCALE_ENABLED;
141 }
142
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700143 ovutils::PipeArgs parg(mdpFlags,
144 info,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500145 ovutils::ZORDER_1,
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700146 isFgFlag,
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800147 rotFlags);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700148
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500149 ov.setSource(parg, dest);
150
151 int transform = layer->transform;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700152 ovutils::eTransform orient =
153 static_cast<ovutils::eTransform>(transform);
154
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700155 hwc_rect_t sourceCrop = layer->sourceCrop;
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700156 hwc_rect_t displayFrame = layer->displayFrame;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700157
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700158 //Calculate the rect for primary based on whether the supplied position
159 //is within or outside bounds.
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500160 const int fbWidth = ctx->dpyAttr[dpy].xres;
161 const int fbHeight = ctx->dpyAttr[dpy].yres;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700162
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700163 if( displayFrame.left < 0 ||
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700164 displayFrame.top < 0 ||
165 displayFrame.right > fbWidth ||
166 displayFrame.bottom > fbHeight) {
Jeykumar Sankaranb551ce42013-01-10 16:26:48 -0800167 hwc_rect_t scissor = {0, 0, fbWidth, fbHeight};
168 calculate_crop_rects(sourceCrop, displayFrame, scissor, transform);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700169 }
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700170
Saurabh Shah1023ce22012-09-05 18:45:59 -0700171 // source crop x,y,w,h
172 ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
173 sourceCrop.right - sourceCrop.left,
174 sourceCrop.bottom - sourceCrop.top);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700175 //Only for Primary
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500176 ov.setCrop(dcrop, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700177
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500178 ov.setTransform(orient, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700179
Saurabh Shah1023ce22012-09-05 18:45:59 -0700180 // position x,y,w,h
181 ovutils::Dim dpos(displayFrame.left,
182 displayFrame.top,
183 displayFrame.right - displayFrame.left,
184 displayFrame.bottom - displayFrame.top);
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800185 // Calculate the actionsafe dimensions for External(dpy = 1 or 2)
186 if(dpy)
187 getActionSafePosition(ctx, dpy, dpos.x, dpos.y, dpos.w, dpos.h);
188
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500189 ov.setPosition(dpos, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700190
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500191 if (!ov.commit(dest)) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700192 ALOGE("%s: commit fails", __FUNCTION__);
193 return false;
194 }
195 return true;
196}
197
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700198bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
199 int dpy)
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700200{
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700201 if(!sIsModeOn[dpy]) {
202 return true;
203 }
204
Jeykumar Sankarancf537002013-01-21 21:19:15 -0800205 int yuvIndex = ctx->listStats[dpy].yuvIndices[0];
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700206 if(yuvIndex == -1) {
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700207 return true;
208 }
209
Naseer Ahmed4c588a22012-07-31 19:12:17 -0700210 private_handle_t *hnd = (private_handle_t *)
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700211 list->hwLayers[yuvIndex].handle;
Naseer Ahmed4c588a22012-07-31 19:12:17 -0700212
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700213 bool ret = true;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500214 overlay::Overlay& ov = *(ctx->mOverlay);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700215
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500216 if (!ov.queueBuffer(hnd->fd, hnd->offset,
217 sDest[dpy])) {
218 ALOGE("%s: queueBuffer failed for dpy=%d", __FUNCTION__, dpy);
219 ret = false;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700220 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500221
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700222 return ret;
223}
224
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700225}; //namespace qhwc