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