blob: e370ecb8595a3147d158d483824e7a49e14d9dc0 [file] [log] [blame]
Naseer Ahmed758bfc52012-11-28 17:02:08 -05001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012, The Linux Foundation. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are
6 * retained for attribution purposes only.
7 *
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
Saurabh Shahcf053c62012-12-13 12:32:55 -080021#define DEBUG_FBUPDATE 0
Naseer Ahmed758bfc52012-11-28 17:02:08 -050022#include <gralloc_priv.h>
Naseer Ahmed758bfc52012-11-28 17:02:08 -050023#include "hwc_fbupdate.h"
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +053024#include "hwc_video.h"
Naseer Ahmed758bfc52012-11-28 17:02:08 -050025
26namespace qhwc {
27
28namespace ovutils = overlay::utils;
29
Saurabh Shahcf053c62012-12-13 12:32:55 -080030IFBUpdate* IFBUpdate::getObject(const int& width, const int& dpy) {
31 if(width > MAX_DISPLAY_DIM) {
32 return new FBUpdateHighRes(dpy);
33 }
34 return new FBUpdateLowRes(dpy);
Naseer Ahmed758bfc52012-11-28 17:02:08 -050035}
36
Saurabh Shahcf053c62012-12-13 12:32:55 -080037inline void IFBUpdate::reset() {
38 mModeOn = false;
39}
40
41//================= Low res====================================
42FBUpdateLowRes::FBUpdateLowRes(const int& dpy): IFBUpdate(dpy) {}
43
44inline void FBUpdateLowRes::reset() {
45 IFBUpdate::reset();
46 mDest = ovutils::OV_INVALID;
47}
48
Naseer Ahmed64b81212013-02-14 10:29:47 -050049bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list)
50{
Naseer Ahmed758bfc52012-11-28 17:02:08 -050051 if(!ctx->mMDP.hasOverlay) {
Saurabh Shahcf053c62012-12-13 12:32:55 -080052 ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
Naseer Ahmed758bfc52012-11-28 17:02:08 -050053 __FUNCTION__);
54 return false;
55 }
Naseer Ahmed64b81212013-02-14 10:29:47 -050056 mModeOn = configure(ctx, list);
Saurabh Shahcf053c62012-12-13 12:32:55 -080057 ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
58 return mModeOn;
Naseer Ahmed758bfc52012-11-28 17:02:08 -050059}
60
61// Configure
Naseer Ahmed64b81212013-02-14 10:29:47 -050062bool FBUpdateLowRes::configure(hwc_context_t *ctx,
63 hwc_display_contents_1 *list)
Naseer Ahmed758bfc52012-11-28 17:02:08 -050064{
65 bool ret = false;
Naseer Ahmed64b81212013-02-14 10:29:47 -050066 hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
Naseer Ahmed758bfc52012-11-28 17:02:08 -050067 if (LIKELY(ctx->mOverlay)) {
68 overlay::Overlay& ov = *(ctx->mOverlay);
69 private_handle_t *hnd = (private_handle_t *)layer->handle;
Saurabh Shahacf10202013-02-26 10:15:15 -080070 ovutils::Whf info(hnd->width, hnd->height,
71 ovutils::getMdpFormat(hnd->format), hnd->size);
Naseer Ahmed758bfc52012-11-28 17:02:08 -050072
73 //Request an RGB pipe
Saurabh Shahcf053c62012-12-13 12:32:55 -080074 ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
Naseer Ahmed758bfc52012-11-28 17:02:08 -050075 if(dest == ovutils::OV_INVALID) { //None available
76 return false;
77 }
78
Saurabh Shahcf053c62012-12-13 12:32:55 -080079 mDest = dest;
Naseer Ahmed758bfc52012-11-28 17:02:08 -050080
81 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +053082 // If any of the layers has pre-multiplied alpha, set Pre multiplied
83 // Flag as the compositied output is alpha pre-multiplied.
84 if(ctx->listStats[mDpy].preMultipliedAlpha == true)
85 ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_BLEND_FG_PREMULT);
86
87 ovutils::eZorder z_order =
88 ctx->mVidOv[mDpy]->isModeOn()?ovutils::ZORDER_1:ovutils::ZORDER_0;
89 ovutils::eIsFg is_fg =
90 ctx->mVidOv[mDpy]->isModeOn()? ovutils::IS_FG_OFF:ovutils::IS_FG_SET;
Naseer Ahmed758bfc52012-11-28 17:02:08 -050091
92 ovutils::PipeArgs parg(mdpFlags,
93 info,
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +053094 z_order,
95 is_fg,
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -080096 ovutils::ROT_FLAGS_NONE);
Naseer Ahmed758bfc52012-11-28 17:02:08 -050097 ov.setSource(parg, dest);
98
Naseer Ahmed64b81212013-02-14 10:29:47 -050099 hwc_rect_t sourceCrop;
100 getNonWormholeRegion(list, sourceCrop);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500101 // x,y,w,h
102 ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
103 sourceCrop.right - sourceCrop.left,
104 sourceCrop.bottom - sourceCrop.top);
105 ov.setCrop(dcrop, dest);
106
107 int transform = layer->transform;
108 ovutils::eTransform orient =
109 static_cast<ovutils::eTransform>(transform);
110 ov.setTransform(orient, dest);
111
Naseer Ahmed64b81212013-02-14 10:29:47 -0500112 hwc_rect_t displayFrame = sourceCrop;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500113 ovutils::Dim dpos(displayFrame.left,
114 displayFrame.top,
115 displayFrame.right - displayFrame.left,
116 displayFrame.bottom - displayFrame.top);
Arun Kumar K.Rfeb2d8a2013-02-01 02:53:13 -0800117 // Calculate the actionsafe dimensions for External(dpy = 1 or 2)
118 if(mDpy)
119 getActionSafePosition(ctx, mDpy, dpos.x, dpos.y, dpos.w, dpos.h);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500120 ov.setPosition(dpos, dest);
121
122 ret = true;
123 if (!ov.commit(dest)) {
124 ALOGE("%s: commit fails", __FUNCTION__);
125 ret = false;
126 }
127 }
128 return ret;
129}
130
Naseer Ahmed64b81212013-02-14 10:29:47 -0500131bool FBUpdateLowRes::draw(hwc_context_t *ctx, private_handle_t *hnd)
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500132{
Saurabh Shahcf053c62012-12-13 12:32:55 -0800133 if(!mModeOn) {
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500134 return true;
135 }
136 bool ret = true;
137 overlay::Overlay& ov = *(ctx->mOverlay);
Saurabh Shahcf053c62012-12-13 12:32:55 -0800138 ovutils::eDest dest = mDest;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500139 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
Amara Venkata Mastan Manoj Kumardc01a532013-01-30 18:34:56 -0800140 ALOGE("%s: queueBuffer failed for FBUpdate", __FUNCTION__);
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500141 ret = false;
142 }
143 return ret;
144}
145
Saurabh Shahcf053c62012-12-13 12:32:55 -0800146//================= High res====================================
147FBUpdateHighRes::FBUpdateHighRes(const int& dpy): IFBUpdate(dpy) {}
148
149inline void FBUpdateHighRes::reset() {
150 IFBUpdate::reset();
151 mDestLeft = ovutils::OV_INVALID;
152 mDestRight = ovutils::OV_INVALID;
153}
154
Naseer Ahmed64b81212013-02-14 10:29:47 -0500155bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list)
156{
Saurabh Shahcf053c62012-12-13 12:32:55 -0800157 if(!ctx->mMDP.hasOverlay) {
158 ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
159 __FUNCTION__);
160 return false;
161 }
162 ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
Naseer Ahmed64b81212013-02-14 10:29:47 -0500163 mModeOn = configure(ctx, list);
Saurabh Shahcf053c62012-12-13 12:32:55 -0800164 return mModeOn;
165}
166
167// Configure
Naseer Ahmed64b81212013-02-14 10:29:47 -0500168bool FBUpdateHighRes::configure(hwc_context_t *ctx,
169 hwc_display_contents_1 *list)
Saurabh Shahcf053c62012-12-13 12:32:55 -0800170{
171 bool ret = false;
Naseer Ahmed64b81212013-02-14 10:29:47 -0500172 hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
Saurabh Shahcf053c62012-12-13 12:32:55 -0800173 if (LIKELY(ctx->mOverlay)) {
174 overlay::Overlay& ov = *(ctx->mOverlay);
175 private_handle_t *hnd = (private_handle_t *)layer->handle;
Saurabh Shahacf10202013-02-26 10:15:15 -0800176 ovutils::Whf info(hnd->width, hnd->height,
177 ovutils::getMdpFormat(hnd->format), hnd->size);
Saurabh Shahcf053c62012-12-13 12:32:55 -0800178
179 //Request left RGB pipe
180 ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
181 if(destL == ovutils::OV_INVALID) { //None available
182 return false;
183 }
184 //Request right RGB pipe
185 ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
186 if(destR == ovutils::OV_INVALID) { //None available
187 return false;
188 }
189
190 mDestLeft = destL;
191 mDestRight = destR;
192
193 ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530194 //If any layer has pre-multiplied alpha, set Pre multiplied
195 //Flag as the compositied output is alpha pre-multiplied.
196 if(ctx->listStats[mDpy].preMultipliedAlpha == true)
197 ovutils::setMdpFlags(mdpFlagsL, ovutils::OV_MDP_BLEND_FG_PREMULT);
198
199 ovutils::eZorder z_order =
200 ctx->mVidOv[mDpy]->isModeOn()?ovutils::ZORDER_1:ovutils::ZORDER_0;
201 ovutils::eIsFg is_fg =
202 ctx->mVidOv[mDpy]->isModeOn()? ovutils::IS_FG_OFF:ovutils::IS_FG_SET;
Saurabh Shahcf053c62012-12-13 12:32:55 -0800203
204 ovutils::PipeArgs pargL(mdpFlagsL,
205 info,
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530206 z_order,
207 is_fg,
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800208 ovutils::ROT_FLAGS_NONE);
Saurabh Shahcf053c62012-12-13 12:32:55 -0800209 ov.setSource(pargL, destL);
210
211 ovutils::eMdpFlags mdpFlagsR = mdpFlagsL;
212 ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
213 ovutils::PipeArgs pargR(mdpFlagsR,
214 info,
Sravan Kumar D.V.Nb5ed0292013-03-15 08:51:16 +0530215 z_order,
216 is_fg,
Ramkumar Radhakrishnan288f8c72013-01-15 11:37:54 -0800217 ovutils::ROT_FLAGS_NONE);
Saurabh Shahcf053c62012-12-13 12:32:55 -0800218 ov.setSource(pargR, destR);
219
Naseer Ahmed64b81212013-02-14 10:29:47 -0500220 hwc_rect_t sourceCrop;
221 getNonWormholeRegion(list, sourceCrop);
Saurabh Shahcf053c62012-12-13 12:32:55 -0800222 ovutils::Dim dcropL(sourceCrop.left, sourceCrop.top,
223 (sourceCrop.right - sourceCrop.left) / 2,
224 sourceCrop.bottom - sourceCrop.top);
225 ovutils::Dim dcropR(
226 sourceCrop.left + (sourceCrop.right - sourceCrop.left) / 2,
227 sourceCrop.top,
228 (sourceCrop.right - sourceCrop.left) / 2,
229 sourceCrop.bottom - sourceCrop.top);
230 ov.setCrop(dcropL, destL);
231 ov.setCrop(dcropR, destR);
232
233 int transform = layer->transform;
234 ovutils::eTransform orient =
235 static_cast<ovutils::eTransform>(transform);
236 ov.setTransform(orient, destL);
237 ov.setTransform(orient, destR);
238
Naseer Ahmed64b81212013-02-14 10:29:47 -0500239 hwc_rect_t displayFrame = sourceCrop;
Saurabh Shahcf053c62012-12-13 12:32:55 -0800240 //For FB left, top will always be 0
241 //That should also be the case if using 2 mixers for single display
Arun Kumar K.R0e8efb82013-03-18 17:31:50 -0700242 ovutils::Dim dposL(displayFrame.left,
Saurabh Shahcf053c62012-12-13 12:32:55 -0800243 displayFrame.top,
244 (displayFrame.right - displayFrame.left) / 2,
245 displayFrame.bottom - displayFrame.top);
Arun Kumar K.R0e8efb82013-03-18 17:31:50 -0700246 ov.setPosition(dposL, destL);
247 ovutils::Dim dposR(0,
248 displayFrame.top,
249 (displayFrame.right - displayFrame.left) / 2,
250 displayFrame.bottom - displayFrame.top);
251 ov.setPosition(dposR, destR);
Saurabh Shahcf053c62012-12-13 12:32:55 -0800252
253 ret = true;
254 if (!ov.commit(destL)) {
255 ALOGE("%s: commit fails for left", __FUNCTION__);
256 ret = false;
257 }
258 if (!ov.commit(destR)) {
259 ALOGE("%s: commit fails for right", __FUNCTION__);
260 ret = false;
261 }
262 }
263 return ret;
264}
265
Naseer Ahmed64b81212013-02-14 10:29:47 -0500266bool FBUpdateHighRes::draw(hwc_context_t *ctx, private_handle_t *hnd)
Saurabh Shahcf053c62012-12-13 12:32:55 -0800267{
268 if(!mModeOn) {
269 return true;
270 }
271 bool ret = true;
272 overlay::Overlay& ov = *(ctx->mOverlay);
273 ovutils::eDest destL = mDestLeft;
274 ovutils::eDest destR = mDestRight;
Saurabh Shahcf053c62012-12-13 12:32:55 -0800275 if (!ov.queueBuffer(hnd->fd, hnd->offset, destL)) {
276 ALOGE("%s: queue failed for left of dpy = %d",
277 __FUNCTION__, mDpy);
278 ret = false;
279 }
280 if (!ov.queueBuffer(hnd->fd, hnd->offset, destR)) {
281 ALOGE("%s: queue failed for right of dpy = %d",
282 __FUNCTION__, mDpy);
283 ret = false;
284 }
285 return ret;
286}
287
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500288//---------------------------------------------------------------------
289}; //namespace qhwc