blob: 0c0a40dac293609befdbe76ad3e37747a22bd89a [file] [log] [blame]
Naseer Ahmedf48aef62012-07-20 09:05:53 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
Saurabh Shah56f610d2012-08-07 15:27:06 -07003 * Copyright (C) 2012, The Linux Foundation. All rights reserved.
Naseer Ahmedf48aef62012-07-20 09:05:53 -07004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
Naseer Ahmed72cf9762012-07-21 12:17:13 -070018#define VIDEO_DEBUG 0
19#include <overlay.h>
Naseer Ahmedf48aef62012-07-20 09:05:53 -070020#include "hwc_video.h"
Saurabh Shah3e858eb2012-09-17 16:53:21 -070021#include "hwc_utils.h"
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -080022#include "qdMetaData.h"
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080023#include "mdp_version.h"
Naseer Ahmedf48aef62012-07-20 09:05:53 -070024
25namespace qhwc {
26
Naseer Ahmed758bfc52012-11-28 17:02:08 -050027namespace ovutils = overlay::utils;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070028
29//Static Members
Saurabh Shahc4d034f2012-09-27 15:55:15 -070030bool VideoOverlay::sIsModeOn[] = {false};
Naseer Ahmed758bfc52012-11-28 17:02:08 -050031ovutils::eDest VideoOverlay::sDest[] = {ovutils::OV_INVALID};
Naseer Ahmedf48aef62012-07-20 09:05:53 -070032
33//Cache stats, figure out the state, config overlay
Saurabh Shah3e858eb2012-09-17 16:53:21 -070034bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
35 int dpy) {
Saurabh Shahc4d034f2012-09-27 15:55:15 -070036
Jeykumar Sankarancf537002013-01-21 21:19:15 -080037 if(ctx->listStats[dpy].yuvCount > 1)
38 return false;
39
40 int yuvIndex = ctx->listStats[dpy].yuvIndices[0];
Saurabh Shahc4d034f2012-09-27 15:55:15 -070041 sIsModeOn[dpy] = false;
Saurabh Shah3e858eb2012-09-17 16:53:21 -070042
Naseer Ahmed96c4c952012-07-25 18:27:14 -070043 if(!ctx->mMDP.hasOverlay) {
Naseer Ahmed31da0b12012-07-31 18:55:33 -070044 ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
45 return false;
46 }
Saurabh Shahc4d034f2012-09-27 15:55:15 -070047
Naseer Ahmed54821fe2012-11-28 18:44:38 -050048 if(isSecuring(ctx)) {
49 ALOGD_IF(VIDEO_DEBUG,"%s: MDP Secure is active", __FUNCTION__);
50 return false;
51 }
52
Saurabh Shahc4d034f2012-09-27 15:55:15 -070053 if(yuvIndex == -1 || ctx->listStats[dpy].yuvCount != 1) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -070054 return false;
55 }
Naseer Ahmed4c588a22012-07-31 19:12:17 -070056
Saurabh Shah3e858eb2012-09-17 16:53:21 -070057 //index guaranteed to be not -1 at this point
Naseer Ahmed758bfc52012-11-28 17:02:08 -050058 hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
Sushil Chauhan2515abf2013-01-08 16:40:05 -080059 if (isSecureModePolicy(ctx->mMDP.version)) {
60 private_handle_t *hnd = (private_handle_t *)layer->handle;
61 if(ctx->mSecureMode) {
62 if (! isSecureBuffer(hnd)) {
63 ALOGD_IF(VIDEO_DEBUG, "%s: Handle non-secure video layer"
64 "during secure playback gracefully", __FUNCTION__);
65 return false;
66 }
67 } else {
68 if (isSecureBuffer(hnd)) {
69 ALOGD_IF(VIDEO_DEBUG, "%s: Handle secure video layer"
70 "during non-secure playback gracefully", __FUNCTION__);
71 return false;
72 }
Naseer Ahmedcb5f25b2012-10-04 15:56:00 -040073 }
Naseer Ahmed68b88cf2012-10-02 14:15:12 -040074 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -050075 if(configure(ctx, dpy, layer)) {
76 markFlags(layer);
Saurabh Shahc4d034f2012-09-27 15:55:15 -070077 sIsModeOn[dpy] = true;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070078 }
79
Saurabh Shahc4d034f2012-09-27 15:55:15 -070080 return sIsModeOn[dpy];
Naseer Ahmedf48aef62012-07-20 09:05:53 -070081}
82
Naseer Ahmed758bfc52012-11-28 17:02:08 -050083void VideoOverlay::markFlags(hwc_layer_1_t *layer) {
84 if(layer) {
85 layer->compositionType = HWC_OVERLAY;
86 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070087 }
88}
89
Naseer Ahmed758bfc52012-11-28 17:02:08 -050090bool VideoOverlay::configure(hwc_context_t *ctx, int dpy,
91 hwc_layer_1_t *layer) {
92 overlay::Overlay& ov = *(ctx->mOverlay);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -070093 private_handle_t *hnd = (private_handle_t *)layer->handle;
94 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
Naseer Ahmedf48aef62012-07-20 09:05:53 -070095
Naseer Ahmed758bfc52012-11-28 17:02:08 -050096 //Request a VG pipe
97 ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
98 if(dest == ovutils::OV_INVALID) { //None available
99 return false;
100 }
101
102 sDest[dpy] = dest;
103
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700104 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700105 if (isSecureBuffer(hnd)) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700106 ovutils::setMdpFlags(mdpFlags,
107 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
108 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700109
Saurabh Shah91a6a992012-08-20 15:25:28 -0700110 if(layer->blending == HWC_BLENDING_PREMULT) {
111 ovutils::setMdpFlags(mdpFlags,
112 ovutils::OV_MDP_BLEND_FG_PREMULT);
113 }
114
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800115 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
Ramkumar Radhakrishnan12b103b2013-01-09 17:47:56 -0800116 if (metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
117 metadata->interlaced) {
Ramkumar Radhakrishnan47573e22012-11-07 11:36:41 -0800118 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
119 }
120
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700121 ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500122 if (ctx->listStats[dpy].numAppLayers == 1) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700123 isFgFlag = ovutils::IS_FG_SET;
124 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700125
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800126 ovutils::eRotFlags rotFlags = ovutils::ROT_FLAGS_NONE;
127 if(ctx->mMDP.version >= qdutils::MDP_V4_2 &&
128 ctx->mMDP.version < qdutils::MDSS_V5) {
129 rotFlags = ovutils::ROT_DOWNSCALE_ENABLED;
130 }
131
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700132 ovutils::PipeArgs parg(mdpFlags,
133 info,
Naseer Ahmed54821fe2012-11-28 18:44:38 -0500134 ovutils::ZORDER_1,
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700135 isFgFlag,
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800136 rotFlags);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700137
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500138 ov.setSource(parg, dest);
139
140 int transform = layer->transform;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700141 ovutils::eTransform orient =
142 static_cast<ovutils::eTransform>(transform);
143
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700144 hwc_rect_t sourceCrop = layer->sourceCrop;
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700145 hwc_rect_t displayFrame = layer->displayFrame;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700146
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700147 //Calculate the rect for primary based on whether the supplied position
148 //is within or outside bounds.
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500149 const int fbWidth = ctx->dpyAttr[dpy].xres;
150 const int fbHeight = ctx->dpyAttr[dpy].yres;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700151
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700152 if( displayFrame.left < 0 ||
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700153 displayFrame.top < 0 ||
154 displayFrame.right > fbWidth ||
155 displayFrame.bottom > fbHeight) {
Saurabh Shah27c1d652012-08-14 19:30:28 -0700156 calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight,
157 transform);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700158 }
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700159
Saurabh Shah1023ce22012-09-05 18:45:59 -0700160 // source crop x,y,w,h
161 ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
162 sourceCrop.right - sourceCrop.left,
163 sourceCrop.bottom - sourceCrop.top);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700164 //Only for Primary
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500165 ov.setCrop(dcrop, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700166
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500167 ov.setTransform(orient, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700168
Saurabh Shah1023ce22012-09-05 18:45:59 -0700169 // position x,y,w,h
170 ovutils::Dim dpos(displayFrame.left,
171 displayFrame.top,
172 displayFrame.right - displayFrame.left,
173 displayFrame.bottom - displayFrame.top);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500174 ov.setPosition(dpos, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700175
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500176 if (!ov.commit(dest)) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700177 ALOGE("%s: commit fails", __FUNCTION__);
178 return false;
179 }
180 return true;
181}
182
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700183bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
184 int dpy)
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700185{
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700186 if(!sIsModeOn[dpy]) {
187 return true;
188 }
189
Jeykumar Sankarancf537002013-01-21 21:19:15 -0800190 int yuvIndex = ctx->listStats[dpy].yuvIndices[0];
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700191 if(yuvIndex == -1) {
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700192 return true;
193 }
194
Naseer Ahmed4c588a22012-07-31 19:12:17 -0700195 private_handle_t *hnd = (private_handle_t *)
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700196 list->hwLayers[yuvIndex].handle;
Naseer Ahmed4c588a22012-07-31 19:12:17 -0700197
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700198 bool ret = true;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500199 overlay::Overlay& ov = *(ctx->mOverlay);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700200
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500201 if (!ov.queueBuffer(hnd->fd, hnd->offset,
202 sDest[dpy])) {
203 ALOGE("%s: queueBuffer failed for dpy=%d", __FUNCTION__, dpy);
204 ret = false;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700205 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500206
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700207 return ret;
208}
209
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700210}; //namespace qhwc