blob: 5fba951327fee67bebf2a59ede26bbffb62a5a68 [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"
Naseer Ahmedf48aef62012-07-20 09:05:53 -070022
23namespace qhwc {
24
Naseer Ahmed758bfc52012-11-28 17:02:08 -050025namespace ovutils = overlay::utils;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070026
27//Static Members
Saurabh Shahc4d034f2012-09-27 15:55:15 -070028bool VideoOverlay::sIsModeOn[] = {false};
Naseer Ahmed758bfc52012-11-28 17:02:08 -050029ovutils::eDest VideoOverlay::sDest[] = {ovutils::OV_INVALID};
Naseer Ahmedf48aef62012-07-20 09:05:53 -070030
31//Cache stats, figure out the state, config overlay
Saurabh Shah3e858eb2012-09-17 16:53:21 -070032bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
33 int dpy) {
Saurabh Shahc4d034f2012-09-27 15:55:15 -070034
Saurabh Shah3e858eb2012-09-17 16:53:21 -070035 int yuvIndex = ctx->listStats[dpy].yuvIndex;
Saurabh Shahc4d034f2012-09-27 15:55:15 -070036 sIsModeOn[dpy] = false;
Saurabh Shah3e858eb2012-09-17 16:53:21 -070037
Naseer Ahmed96c4c952012-07-25 18:27:14 -070038 if(!ctx->mMDP.hasOverlay) {
Naseer Ahmed31da0b12012-07-31 18:55:33 -070039 ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
40 return false;
41 }
Saurabh Shahc4d034f2012-09-27 15:55:15 -070042
43 if(yuvIndex == -1 || ctx->listStats[dpy].yuvCount != 1) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -070044 return false;
45 }
Naseer Ahmed4c588a22012-07-31 19:12:17 -070046
Saurabh Shah3e858eb2012-09-17 16:53:21 -070047 //index guaranteed to be not -1 at this point
Naseer Ahmed758bfc52012-11-28 17:02:08 -050048 hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
Naseer Ahmed68b88cf2012-10-02 14:15:12 -040049
Naseer Ahmed758bfc52012-11-28 17:02:08 -050050 private_handle_t *hnd = (private_handle_t *)layer->handle;
Naseer Ahmed68b88cf2012-10-02 14:15:12 -040051 if(ctx->mSecureMode) {
Naseer Ahmed68b88cf2012-10-02 14:15:12 -040052 if (! isSecureBuffer(hnd)) {
53 ALOGD_IF(VIDEO_DEBUG, "%s: Handle non-secure video layer"
54 "during secure playback gracefully", __FUNCTION__);
55 return false;
56 }
Naseer Ahmedcb5f25b2012-10-04 15:56:00 -040057 } else {
58 if (isSecureBuffer(hnd)) {
59 ALOGD_IF(VIDEO_DEBUG, "%s: Handle secure video layer"
60 "during non-secure playback gracefully", __FUNCTION__);
61 return false;
62 }
Naseer Ahmed68b88cf2012-10-02 14:15:12 -040063 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -050064 if(configure(ctx, dpy, layer)) {
65 markFlags(layer);
Saurabh Shahc4d034f2012-09-27 15:55:15 -070066 sIsModeOn[dpy] = true;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070067 }
68
Saurabh Shahc4d034f2012-09-27 15:55:15 -070069 return sIsModeOn[dpy];
Naseer Ahmedf48aef62012-07-20 09:05:53 -070070}
71
Naseer Ahmed758bfc52012-11-28 17:02:08 -050072void VideoOverlay::markFlags(hwc_layer_1_t *layer) {
73 if(layer) {
74 layer->compositionType = HWC_OVERLAY;
75 layer->hints |= HWC_HINT_CLEAR_FB;
Naseer Ahmedf48aef62012-07-20 09:05:53 -070076 }
77}
78
Naseer Ahmed758bfc52012-11-28 17:02:08 -050079bool VideoOverlay::configure(hwc_context_t *ctx, int dpy,
80 hwc_layer_1_t *layer) {
81 overlay::Overlay& ov = *(ctx->mOverlay);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -070082 private_handle_t *hnd = (private_handle_t *)layer->handle;
83 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
Naseer Ahmedf48aef62012-07-20 09:05:53 -070084
Naseer Ahmed758bfc52012-11-28 17:02:08 -050085 //Request a VG pipe
86 ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
87 if(dest == ovutils::OV_INVALID) { //None available
88 return false;
89 }
90
91 sDest[dpy] = dest;
92
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -070093 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Saurabh Shah3e858eb2012-09-17 16:53:21 -070094 if (isSecureBuffer(hnd)) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -070095 ovutils::setMdpFlags(mdpFlags,
96 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
97 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -070098
Saurabh Shah91a6a992012-08-20 15:25:28 -070099 if(layer->blending == HWC_BLENDING_PREMULT) {
100 ovutils::setMdpFlags(mdpFlags,
101 ovutils::OV_MDP_BLEND_FG_PREMULT);
102 }
103
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700104 ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500105 if (ctx->listStats[dpy].numAppLayers == 1) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700106 isFgFlag = ovutils::IS_FG_SET;
107 }
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700108
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500109 //TODO change to 1 always when primary FB uses overlay.
110 const ovutils::eZorder zorder = (dpy == HWC_DISPLAY_PRIMARY) ?
111 ovutils::ZORDER_0 : ovutils::ZORDER_1;
112
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700113 ovutils::PipeArgs parg(mdpFlags,
114 info,
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500115 zorder,
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700116 isFgFlag,
117 ovutils::ROT_FLAG_DISABLED);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700118
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500119 ov.setSource(parg, dest);
120
121 int transform = layer->transform;
Saurabh Shah27c1d652012-08-14 19:30:28 -0700122 ovutils::eTransform orient =
123 static_cast<ovutils::eTransform>(transform);
124
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700125 hwc_rect_t sourceCrop = layer->sourceCrop;
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700126 hwc_rect_t displayFrame = layer->displayFrame;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700127
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700128 //Calculate the rect for primary based on whether the supplied position
129 //is within or outside bounds.
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500130 const int fbWidth = ctx->dpyAttr[dpy].xres;
131 const int fbHeight = ctx->dpyAttr[dpy].yres;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700132
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700133 if( displayFrame.left < 0 ||
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700134 displayFrame.top < 0 ||
135 displayFrame.right > fbWidth ||
136 displayFrame.bottom > fbHeight) {
Saurabh Shah27c1d652012-08-14 19:30:28 -0700137 calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight,
138 transform);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700139 }
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700140
Saurabh Shah1023ce22012-09-05 18:45:59 -0700141 // source crop x,y,w,h
142 ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
143 sourceCrop.right - sourceCrop.left,
144 sourceCrop.bottom - sourceCrop.top);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700145 //Only for Primary
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500146 ov.setCrop(dcrop, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700147
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500148 ov.setTransform(orient, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700149
Saurabh Shah1023ce22012-09-05 18:45:59 -0700150 // position x,y,w,h
151 ovutils::Dim dpos(displayFrame.left,
152 displayFrame.top,
153 displayFrame.right - displayFrame.left,
154 displayFrame.bottom - displayFrame.top);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500155 ov.setPosition(dpos, dest);
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700156
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500157 if (!ov.commit(dest)) {
Naseer Ahmed2cc53dd2012-07-31 19:11:48 -0700158 ALOGE("%s: commit fails", __FUNCTION__);
159 return false;
160 }
161 return true;
162}
163
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700164bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
165 int dpy)
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700166{
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700167 if(!sIsModeOn[dpy]) {
168 return true;
169 }
170
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700171 int yuvIndex = ctx->listStats[dpy].yuvIndex;
Saurabh Shahc4d034f2012-09-27 15:55:15 -0700172 if(yuvIndex == -1) {
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700173 return true;
174 }
175
Naseer Ahmed4c588a22012-07-31 19:12:17 -0700176 private_handle_t *hnd = (private_handle_t *)
Saurabh Shah3e858eb2012-09-17 16:53:21 -0700177 list->hwLayers[yuvIndex].handle;
Naseer Ahmed4c588a22012-07-31 19:12:17 -0700178
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700179 bool ret = true;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500180 overlay::Overlay& ov = *(ctx->mOverlay);
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700181
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500182 if (!ov.queueBuffer(hnd->fd, hnd->offset,
183 sDest[dpy])) {
184 ALOGE("%s: queueBuffer failed for dpy=%d", __FUNCTION__, dpy);
185 ret = false;
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700186 }
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500187
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700188 return ret;
189}
190
Naseer Ahmedf48aef62012-07-20 09:05:53 -0700191}; //namespace qhwc