hwc_fbupdate.cpp revision 04af919f7d16572b16a91d8b681afe42386fb4e1
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * Copyright (C) 2012-2013, 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 21#define DEBUG_FBUPDATE 0 22#include <gralloc_priv.h> 23#include "hwc_fbupdate.h" 24#include "mdp_version.h" 25 26using namespace qdutils; 27 28namespace qhwc { 29 30namespace ovutils = overlay::utils; 31 32IFBUpdate* IFBUpdate::getObject(const int& width, const int& dpy) { 33 if(width > MAX_DISPLAY_DIM) { 34 return new FBUpdateHighRes(dpy); 35 } 36 return new FBUpdateLowRes(dpy); 37} 38 39inline void IFBUpdate::reset() { 40 mModeOn = false; 41} 42 43//================= Low res==================================== 44FBUpdateLowRes::FBUpdateLowRes(const int& dpy): IFBUpdate(dpy) {} 45 46inline void FBUpdateLowRes::reset() { 47 IFBUpdate::reset(); 48 mDest = ovutils::OV_INVALID; 49} 50 51bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list, 52 int fbZorder) { 53 if(!ctx->mMDP.hasOverlay) { 54 ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays", 55 __FUNCTION__); 56 return false; 57 } 58 mModeOn = configure(ctx, list, fbZorder); 59 return mModeOn; 60} 61 62// Configure 63bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_display_contents_1 *list, 64 int fbZorder) { 65 bool ret = false; 66 hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1]; 67 if (LIKELY(ctx->mOverlay)) { 68 overlay::Overlay& ov = *(ctx->mOverlay); 69 private_handle_t *hnd = (private_handle_t *)layer->handle; 70 ovutils::Whf info(hnd->width, hnd->height, 71 ovutils::getMdpFormat(hnd->format), hnd->size); 72 73 //Request a pipe 74 ovutils::eMdpPipeType type = ovutils::OV_MDP_PIPE_ANY; 75 if(qdutils::MDPVersion::getInstance().is8x26() && mDpy) { 76 //For 8x26 external always use DMA pipe 77 type = ovutils::OV_MDP_PIPE_DMA; 78 } 79 ovutils::eDest dest = ov.nextPipe(type, mDpy); 80 if(dest == ovutils::OV_INVALID) { //None available 81 ALOGE("%s: No pipes available to configure framebuffer", 82 __FUNCTION__); 83 return false; 84 } 85 86 mDest = dest; 87 88 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT; 89 90 ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder); 91 92 //XXX: FB layer plane alpha is currently sent as zero from 93 //surfaceflinger 94 ovutils::PipeArgs parg(mdpFlags, 95 info, 96 zOrder, 97 ovutils::IS_FG_OFF, 98 ovutils::ROT_FLAGS_NONE, 99 ovutils::DEFAULT_PLANE_ALPHA, 100 (ovutils::eBlending) getBlending(layer->blending)); 101 ov.setSource(parg, dest); 102 103 hwc_rect_t sourceCrop; 104 getNonWormholeRegion(list, sourceCrop); 105 // x,y,w,h 106 ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, 107 sourceCrop.right - sourceCrop.left, 108 sourceCrop.bottom - sourceCrop.top); 109 ov.setCrop(dcrop, dest); 110 111 int transform = layer->transform; 112 ovutils::eTransform orient = 113 static_cast<ovutils::eTransform>(transform); 114 ov.setTransform(orient, dest); 115 116 if(!qdutils::MDPVersion::getInstance().is8x26()) { 117 getNonWormholeRegion(list, sourceCrop); 118 } 119 120 hwc_rect_t displayFrame = sourceCrop; 121 ovutils::Dim dpos(displayFrame.left, 122 displayFrame.top, 123 displayFrame.right - displayFrame.left, 124 displayFrame.bottom - displayFrame.top); 125 126 if(mDpy && !qdutils::MDPVersion::getInstance().is8x26()) 127 // Calculate the actionsafe dimensions for External(dpy = 1 or 2) 128 getActionSafePosition(ctx, mDpy, dpos.x, dpos.y, dpos.w, dpos.h); 129 ov.setPosition(dpos, dest); 130 131 ret = true; 132 if (!ov.commit(dest)) { 133 ALOGE("%s: commit fails", __FUNCTION__); 134 ret = false; 135 } 136 } 137 return ret; 138} 139 140bool FBUpdateLowRes::draw(hwc_context_t *ctx, private_handle_t *hnd) 141{ 142 if(!mModeOn) { 143 return true; 144 } 145 bool ret = true; 146 overlay::Overlay& ov = *(ctx->mOverlay); 147 ovutils::eDest dest = mDest; 148 if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) { 149 ALOGE("%s: queueBuffer failed for FBUpdate", __FUNCTION__); 150 ret = false; 151 } 152 return ret; 153} 154 155//================= High res==================================== 156FBUpdateHighRes::FBUpdateHighRes(const int& dpy): IFBUpdate(dpy) {} 157 158inline void FBUpdateHighRes::reset() { 159 IFBUpdate::reset(); 160 mDestLeft = ovutils::OV_INVALID; 161 mDestRight = ovutils::OV_INVALID; 162} 163 164bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list, 165 int fbZorder) { 166 if(!ctx->mMDP.hasOverlay) { 167 ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays", 168 __FUNCTION__); 169 return false; 170 } 171 ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn); 172 mModeOn = configure(ctx, list, fbZorder); 173 return mModeOn; 174} 175 176// Configure 177bool FBUpdateHighRes::configure(hwc_context_t *ctx, 178 hwc_display_contents_1 *list, int fbZorder) { 179 bool ret = false; 180 hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1]; 181 if (LIKELY(ctx->mOverlay)) { 182 overlay::Overlay& ov = *(ctx->mOverlay); 183 private_handle_t *hnd = (private_handle_t *)layer->handle; 184 ovutils::Whf info(hnd->width, hnd->height, 185 ovutils::getMdpFormat(hnd->format), hnd->size); 186 187 //Request left pipe 188 ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy); 189 if(destL == ovutils::OV_INVALID) { //None available 190 ALOGE("%s: No pipes available to configure framebuffer", 191 __FUNCTION__); 192 return false; 193 } 194 //Request right pipe 195 ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy); 196 if(destR == ovutils::OV_INVALID) { //None available 197 ALOGE("%s: No pipes available to configure framebuffer", 198 __FUNCTION__); 199 return false; 200 } 201 202 mDestLeft = destL; 203 mDestRight = destR; 204 205 ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_BLEND_FG_PREMULT; 206 207 ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder); 208 209 //XXX: FB layer plane alpha is currently sent as zero from 210 //surfaceflinger 211 ovutils::PipeArgs pargL(mdpFlagsL, 212 info, 213 zOrder, 214 ovutils::IS_FG_OFF, 215 ovutils::ROT_FLAGS_NONE, 216 ovutils::DEFAULT_PLANE_ALPHA, 217 (ovutils::eBlending) getBlending(layer->blending)); 218 ov.setSource(pargL, destL); 219 220 ovutils::eMdpFlags mdpFlagsR = mdpFlagsL; 221 ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER); 222 ovutils::PipeArgs pargR(mdpFlagsR, 223 info, 224 zOrder, 225 ovutils::IS_FG_OFF, 226 ovutils::ROT_FLAGS_NONE, 227 ovutils::DEFAULT_PLANE_ALPHA, 228 (ovutils::eBlending) getBlending(layer->blending)); 229 ov.setSource(pargR, destR); 230 231 hwc_rect_t sourceCrop; 232 getNonWormholeRegion(list, sourceCrop); 233 ovutils::Dim dcropL(sourceCrop.left, sourceCrop.top, 234 (sourceCrop.right - sourceCrop.left) / 2, 235 sourceCrop.bottom - sourceCrop.top); 236 ovutils::Dim dcropR( 237 sourceCrop.left + (sourceCrop.right - sourceCrop.left) / 2, 238 sourceCrop.top, 239 (sourceCrop.right - sourceCrop.left) / 2, 240 sourceCrop.bottom - sourceCrop.top); 241 ov.setCrop(dcropL, destL); 242 ov.setCrop(dcropR, destR); 243 244 int transform = layer->transform; 245 ovutils::eTransform orient = 246 static_cast<ovutils::eTransform>(transform); 247 ov.setTransform(orient, destL); 248 ov.setTransform(orient, destR); 249 250 hwc_rect_t displayFrame = sourceCrop; 251 const int halfWidth = (displayFrame.right - displayFrame.left) / 2; 252 const int height = displayFrame.bottom - displayFrame.top; 253 254 const int halfDpy = ctx->dpyAttr[mDpy].xres / 2; 255 ovutils::Dim dposL(halfDpy - halfWidth, 256 displayFrame.top, 257 halfWidth, 258 height); 259 ov.setPosition(dposL, destL); 260 261 ovutils::Dim dposR(0, 262 displayFrame.top, 263 halfWidth, 264 height); 265 ov.setPosition(dposR, destR); 266 267 ret = true; 268 if (!ov.commit(destL)) { 269 ALOGE("%s: commit fails for left", __FUNCTION__); 270 ret = false; 271 } 272 if (!ov.commit(destR)) { 273 ALOGE("%s: commit fails for right", __FUNCTION__); 274 ret = false; 275 } 276 } 277 return ret; 278} 279 280bool FBUpdateHighRes::draw(hwc_context_t *ctx, private_handle_t *hnd) 281{ 282 if(!mModeOn) { 283 return true; 284 } 285 bool ret = true; 286 overlay::Overlay& ov = *(ctx->mOverlay); 287 ovutils::eDest destL = mDestLeft; 288 ovutils::eDest destR = mDestRight; 289 if (!ov.queueBuffer(hnd->fd, hnd->offset, destL)) { 290 ALOGE("%s: queue failed for left of dpy = %d", 291 __FUNCTION__, mDpy); 292 ret = false; 293 } 294 if (!ov.queueBuffer(hnd->fd, hnd->offset, destR)) { 295 ALOGE("%s: queue failed for right of dpy = %d", 296 __FUNCTION__, mDpy); 297 ret = false; 298 } 299 return ret; 300} 301 302//--------------------------------------------------------------------- 303}; //namespace qhwc 304