blob: ecbf81360d3fcb6e1792bb56069137f41d4b1a7b [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>
23#include <fb_priv.h>
24#include "hwc_fbupdate.h"
25#include "external.h"
26
27namespace qhwc {
28
29namespace ovutils = overlay::utils;
30
Saurabh Shahcf053c62012-12-13 12:32:55 -080031IFBUpdate* IFBUpdate::getObject(const int& width, const int& dpy) {
32 if(width > MAX_DISPLAY_DIM) {
33 return new FBUpdateHighRes(dpy);
34 }
35 return new FBUpdateLowRes(dpy);
Naseer Ahmed758bfc52012-11-28 17:02:08 -050036}
37
Saurabh Shahcf053c62012-12-13 12:32:55 -080038inline void IFBUpdate::reset() {
39 mModeOn = false;
40}
41
42//================= Low res====================================
43FBUpdateLowRes::FBUpdateLowRes(const int& dpy): IFBUpdate(dpy) {}
44
45inline void FBUpdateLowRes::reset() {
46 IFBUpdate::reset();
47 mDest = ovutils::OV_INVALID;
48}
49
50bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) {
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 }
Saurabh Shahcf053c62012-12-13 12:32:55 -080056 mModeOn = configure(ctx, fblayer);
57 ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
58 return mModeOn;
Naseer Ahmed758bfc52012-11-28 17:02:08 -050059}
60
61// Configure
Saurabh Shahcf053c62012-12-13 12:32:55 -080062bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer)
Naseer Ahmed758bfc52012-11-28 17:02:08 -050063{
64 bool ret = false;
65 if (LIKELY(ctx->mOverlay)) {
66 overlay::Overlay& ov = *(ctx->mOverlay);
67 private_handle_t *hnd = (private_handle_t *)layer->handle;
68 if (!hnd) {
69 ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
70 return false;
71 }
72 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
73
74 //Request an RGB pipe
Saurabh Shahcf053c62012-12-13 12:32:55 -080075 ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
Naseer Ahmed758bfc52012-11-28 17:02:08 -050076 if(dest == ovutils::OV_INVALID) { //None available
77 return false;
78 }
79
Saurabh Shahcf053c62012-12-13 12:32:55 -080080 mDest = dest;
Naseer Ahmed758bfc52012-11-28 17:02:08 -050081
82 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
83 if(ctx->mSecureMode) {
84 ovutils::setMdpFlags(mdpFlags,
85 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
86 }
87
88 ovutils::PipeArgs parg(mdpFlags,
89 info,
90 ovutils::ZORDER_0,
91 ovutils::IS_FG_SET,
92 ovutils::ROT_FLAG_DISABLED);
93 ov.setSource(parg, dest);
94
95 hwc_rect_t sourceCrop = layer->sourceCrop;
96 // x,y,w,h
97 ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
98 sourceCrop.right - sourceCrop.left,
99 sourceCrop.bottom - sourceCrop.top);
100 ov.setCrop(dcrop, dest);
101
102 int transform = layer->transform;
103 ovutils::eTransform orient =
104 static_cast<ovutils::eTransform>(transform);
105 ov.setTransform(orient, dest);
106
107 hwc_rect_t displayFrame = layer->displayFrame;
108 ovutils::Dim dpos(displayFrame.left,
109 displayFrame.top,
110 displayFrame.right - displayFrame.left,
111 displayFrame.bottom - displayFrame.top);
112 ov.setPosition(dpos, dest);
113
114 ret = true;
115 if (!ov.commit(dest)) {
116 ALOGE("%s: commit fails", __FUNCTION__);
117 ret = false;
118 }
119 }
120 return ret;
121}
122
Saurabh Shahcf053c62012-12-13 12:32:55 -0800123bool FBUpdateLowRes::draw(hwc_context_t *ctx, hwc_layer_1_t *layer)
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500124{
Saurabh Shahcf053c62012-12-13 12:32:55 -0800125 if(!mModeOn) {
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500126 return true;
127 }
128 bool ret = true;
129 overlay::Overlay& ov = *(ctx->mOverlay);
Saurabh Shahcf053c62012-12-13 12:32:55 -0800130 ovutils::eDest dest = mDest;
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500131 private_handle_t *hnd = (private_handle_t *)layer->handle;
132 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
133 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
134 ret = false;
135 }
136 return ret;
137}
138
Saurabh Shahcf053c62012-12-13 12:32:55 -0800139//================= High res====================================
140FBUpdateHighRes::FBUpdateHighRes(const int& dpy): IFBUpdate(dpy) {}
141
142inline void FBUpdateHighRes::reset() {
143 IFBUpdate::reset();
144 mDestLeft = ovutils::OV_INVALID;
145 mDestRight = ovutils::OV_INVALID;
146}
147
148bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) {
149 if(!ctx->mMDP.hasOverlay) {
150 ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
151 __FUNCTION__);
152 return false;
153 }
154 ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
155 mModeOn = configure(ctx, fblayer);
156 return mModeOn;
157}
158
159// Configure
160bool FBUpdateHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer)
161{
162 bool ret = false;
163 if (LIKELY(ctx->mOverlay)) {
164 overlay::Overlay& ov = *(ctx->mOverlay);
165 private_handle_t *hnd = (private_handle_t *)layer->handle;
166 if (!hnd) {
167 ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
168 return false;
169 }
170 ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
171
172 //Request left RGB pipe
173 ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
174 if(destL == ovutils::OV_INVALID) { //None available
175 return false;
176 }
177 //Request right RGB pipe
178 ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
179 if(destR == ovutils::OV_INVALID) { //None available
180 return false;
181 }
182
183 mDestLeft = destL;
184 mDestRight = destR;
185
186 ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
187 if(ctx->mSecureMode) {
188 ovutils::setMdpFlags(mdpFlagsL,
189 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
190 }
191
192 ovutils::PipeArgs pargL(mdpFlagsL,
193 info,
194 ovutils::ZORDER_0,
195 ovutils::IS_FG_SET,
196 ovutils::ROT_FLAG_DISABLED);
197 ov.setSource(pargL, destL);
198
199 ovutils::eMdpFlags mdpFlagsR = mdpFlagsL;
200 ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
201 ovutils::PipeArgs pargR(mdpFlagsR,
202 info,
203 ovutils::ZORDER_0,
204 ovutils::IS_FG_SET,
205 ovutils::ROT_FLAG_DISABLED);
206 ov.setSource(pargR, destR);
207
208 hwc_rect_t sourceCrop = layer->sourceCrop;
209 ovutils::Dim dcropL(sourceCrop.left, sourceCrop.top,
210 (sourceCrop.right - sourceCrop.left) / 2,
211 sourceCrop.bottom - sourceCrop.top);
212 ovutils::Dim dcropR(
213 sourceCrop.left + (sourceCrop.right - sourceCrop.left) / 2,
214 sourceCrop.top,
215 (sourceCrop.right - sourceCrop.left) / 2,
216 sourceCrop.bottom - sourceCrop.top);
217 ov.setCrop(dcropL, destL);
218 ov.setCrop(dcropR, destR);
219
220 int transform = layer->transform;
221 ovutils::eTransform orient =
222 static_cast<ovutils::eTransform>(transform);
223 ov.setTransform(orient, destL);
224 ov.setTransform(orient, destR);
225
226 hwc_rect_t displayFrame = layer->displayFrame;
227 //For FB left, top will always be 0
228 //That should also be the case if using 2 mixers for single display
229 ovutils::Dim dpos(displayFrame.left,
230 displayFrame.top,
231 (displayFrame.right - displayFrame.left) / 2,
232 displayFrame.bottom - displayFrame.top);
233 ov.setPosition(dpos, destL);
234 ov.setPosition(dpos, destR);
235
236 ret = true;
237 if (!ov.commit(destL)) {
238 ALOGE("%s: commit fails for left", __FUNCTION__);
239 ret = false;
240 }
241 if (!ov.commit(destR)) {
242 ALOGE("%s: commit fails for right", __FUNCTION__);
243 ret = false;
244 }
245 }
246 return ret;
247}
248
249bool FBUpdateHighRes::draw(hwc_context_t *ctx, hwc_layer_1_t *layer)
250{
251 if(!mModeOn) {
252 return true;
253 }
254 bool ret = true;
255 overlay::Overlay& ov = *(ctx->mOverlay);
256 ovutils::eDest destL = mDestLeft;
257 ovutils::eDest destR = mDestRight;
258 private_handle_t *hnd = (private_handle_t *)layer->handle;
259 if (!ov.queueBuffer(hnd->fd, hnd->offset, destL)) {
260 ALOGE("%s: queue failed for left of dpy = %d",
261 __FUNCTION__, mDpy);
262 ret = false;
263 }
264 if (!ov.queueBuffer(hnd->fd, hnd->offset, destR)) {
265 ALOGE("%s: queue failed for right of dpy = %d",
266 __FUNCTION__, mDpy);
267 ret = false;
268 }
269 return ret;
270}
271
Naseer Ahmed758bfc52012-11-28 17:02:08 -0500272//---------------------------------------------------------------------
273}; //namespace qhwc