overlayRotator.cpp revision ee7fc0347e52276d43413e91f31d72d6db99dcfb
1/* 2* Copyright (C) 2008 The Android Open Source Project 3* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved. 4* 5* Licensed under the Apache License, Version 2.0 (the "License"); 6* you may not use this file except in compliance with the License. 7* You may obtain a copy of the License at 8* 9* http://www.apache.org/licenses/LICENSE-2.0 10* 11* Unless required by applicable law or agreed to in writing, software 12* distributed under the License is distributed on an "AS IS" BASIS, 13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14* See the License for the specific language governing permissions and 15* limitations under the License. 16*/ 17 18#include "overlayRotator.h" 19#include "overlayUtils.h" 20 21namespace ovutils = overlay::utils; 22 23namespace overlay { 24 25int IRotatorHw::getRotatorHwType() { 26 //TODO figure out based on ioctl 27 return TYPE_MDP; 28} 29 30bool RotMem::close() { 31 bool ret = true; 32 for(uint32_t i=0; i < RotMem::MAX_ROT_MEM; ++i) { 33 // skip current, and if valid, close 34 if(m[i].valid()) { 35 if(m[i].close() == false) { 36 ALOGE("%s error in closing rot mem %d", __FUNCTION__, i); 37 ret = false; 38 } 39 } 40 } 41 return ret; 42} 43 44bool MdpRot::init() 45{ 46 if(!mFd.open(Res::rotPath, O_RDWR)){ 47 ALOGE("MdpRot failed to init %s", Res::rotPath); 48 return false; 49 } 50 return true; 51} 52 53void MdpRot::setSource(const overlay::utils::Whf& awhf) { 54 utils::Whf whf(awhf); 55 56 mRotImgInfo.src.format = whf.format; 57 if(whf.format == MDP_Y_CRCB_H2V2_TILE || 58 whf.format == MDP_Y_CBCR_H2V2_TILE) { 59 whf.w = utils::alignup(awhf.w, 64); 60 whf.h = utils::alignup(awhf.h, 32); 61 } 62 63 mRotImgInfo.src.width = whf.w; 64 mRotImgInfo.src.height = whf.h; 65 66 mRotImgInfo.src_rect.w = whf.w; 67 mRotImgInfo.src_rect.h = whf.h; 68 69 mRotImgInfo.dst.width = whf.w; 70 mRotImgInfo.dst.height = whf.h; 71 72 mBufSize = awhf.size; 73} 74 75void MdpRot::setFlags(const utils::eMdpFlags& flags) { 76 mRotImgInfo.secure = 0; 77 if(flags & utils::OV_MDP_SECURE_OVERLAY_SESSION) 78 mRotImgInfo.secure = 1; 79} 80 81void MdpRot::setTransform(const utils::eTransform& rot, const bool& rotUsed) 82{ 83 mOrientation = rot; 84 int r = utils::getMdpOrient(rot); 85 ALOGE_IF(DEBUG_OVERLAY, "%s: r=%d", __FUNCTION__, r); 86 setRotations(r); 87 setDisable(); 88 if(rotUsed) { 89 setEnable(); 90 } 91} 92 93void MdpRot::doTransform() { 94 switch(mOrientation) { 95 case utils::OVERLAY_TRANSFORM_ROT_90: 96 case utils::OVERLAY_TRANSFORM_ROT_90_FLIP_H: 97 case utils::OVERLAY_TRANSFORM_ROT_90_FLIP_V: 98 case utils::OVERLAY_TRANSFORM_ROT_270: 99 utils::swap(mRotImgInfo.dst.width, mRotImgInfo.dst.height); 100 break; 101 default: 102 break; 103 } 104} 105 106bool MdpRot::commit() { 107 doTransform(); 108 if(!overlay::mdp_wrapper::startRotator(mFd.getFD(), mRotImgInfo)) { 109 ALOGE("MdpRot commit failed"); 110 dump(); 111 return false; 112 } 113 mRotDataInfo.session_id = mRotImgInfo.session_id; 114 return true; 115} 116 117bool MdpRot::open_i(uint32_t numbufs, uint32_t bufsz) 118{ 119 OvMem mem; 120 121 OVASSERT(MAP_FAILED == mem.addr(), "MAP failed in open_i"); 122 123 if(!mem.open(numbufs, bufsz, mRotImgInfo.secure)){ 124 ALOGE("%s: Failed to open", __func__); 125 mem.close(); 126 return false; 127 } 128 129 OVASSERT(MAP_FAILED != mem.addr(), "MAP failed"); 130 OVASSERT(mem.getFD() != -1, "getFd is -1"); 131 132 mRotDataInfo.dst.memory_id = mem.getFD(); 133 mRotDataInfo.dst.offset = 0; 134 mMem.curr().m = mem; 135 return true; 136} 137 138bool MdpRot::close() { 139 bool success = true; 140 if(mFd.valid() && (getSessId() > 0)) { 141 if(!mdp_wrapper::endRotator(mFd.getFD(), getSessId())) { 142 ALOGE("Mdp Rot error endRotator, fd=%d sessId=%d", 143 mFd.getFD(), getSessId()); 144 success = false; 145 } 146 } 147 if (!mFd.close()) { 148 ALOGE("Mdp Rot error closing fd"); 149 success = false; 150 } 151 if (!mMem.close()) { 152 ALOGE("Mdp Rot error closing mem"); 153 success = false; 154 } 155 reset(); 156 return success; 157} 158 159bool MdpRot::remap(uint32_t numbufs) { 160 // if current size changed, remap 161 if(mBufSize == mMem.curr().size()) { 162 ALOGE_IF(DEBUG_OVERLAY, "%s: same size %d", __FUNCTION__, mBufSize); 163 return true; 164 } 165 166 ALOGE_IF(DEBUG_OVERLAY, "%s: size changed - remapping", __FUNCTION__); 167 OVASSERT(!mMem.prev().valid(), "Prev should not be valid"); 168 169 // ++mMem will make curr to be prev, and prev will be curr 170 ++mMem; 171 if(!open_i(numbufs, mBufSize)) { 172 ALOGE("%s Error could not open", __FUNCTION__); 173 return false; 174 } 175 for (uint32_t i = 0; i < numbufs; ++i) { 176 mMem.curr().mRotOffset[i] = i * mBufSize; 177 } 178 return true; 179} 180 181void MdpRot::reset() { 182 ovutils::memset0(mRotImgInfo); 183 ovutils::memset0(mRotDataInfo); 184 ovutils::memset0(mMem.curr().mRotOffset); 185 ovutils::memset0(mMem.prev().mRotOffset); 186 mMem.curr().mCurrOffset = 0; 187 mMem.prev().mCurrOffset = 0; 188 mBufSize = 0; 189 mOrientation = utils::OVERLAY_TRANSFORM_0; 190} 191 192bool MdpRot::queueBuffer(int fd, uint32_t offset) { 193 if(enabled()) { 194 mRotDataInfo.src.memory_id = fd; 195 mRotDataInfo.src.offset = offset; 196 197 remap(RotMem::Mem::ROT_NUM_BUFS); 198 OVASSERT(mMem.curr().m.numBufs(), 199 "queueBuffer numbufs is 0"); 200 mRotDataInfo.dst.offset = 201 mMem.curr().mRotOffset[mMem.curr().mCurrOffset]; 202 mMem.curr().mCurrOffset = 203 (mMem.curr().mCurrOffset + 1) % mMem.curr().m.numBufs(); 204 205 if(!overlay::mdp_wrapper::rotate(mFd.getFD(), mRotDataInfo)) { 206 ALOGE("MdpRot failed rotate"); 207 dump(); 208 return false; 209 } 210 211 // if the prev mem is valid, we need to close 212 if(mMem.prev().valid()) { 213 // FIXME if no wait for vsync the above 214 // play will return immediatly and might cause 215 // tearing when prev.close is called. 216 if(!mMem.prev().close()) { 217 ALOGE("%s error in closing prev rot mem", __FUNCTION__); 218 return false; 219 } 220 } 221 } 222 return true; 223} 224 225void MdpRot::dump() const { 226 ALOGE("== Dump MdpRot start =="); 227 mFd.dump(); 228 mMem.curr().m.dump(); 229 mdp_wrapper::dump("mRotImgInfo", mRotImgInfo); 230 mdp_wrapper::dump("mRotDataInfo", mRotDataInfo); 231 ALOGE("== Dump MdpRot end =="); 232} 233} 234