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