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