1054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin/* 2054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Copyright (C) 2008 The Android Open Source Project 3054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. 4054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Not a Contribution, Apache license notifications and license are retained 5054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * for attribution purposes only. 6054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 7054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Licensed under the Apache License, Version 2.0 (the "License"); 8054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * you may not use this file except in compliance with the License. 9054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * You may obtain a copy of the License at 10054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 11054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * http://www.apache.org/licenses/LICENSE-2.0 12054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * 13054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * Unless required by applicable law or agreed to in writing, software 14054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * distributed under the License is distributed on an "AS IS" BASIS, 15054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * See the License for the specific language governing permissions and 17054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * limitations under the License. 18054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin*/ 19054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 20054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "overlayRotator.h" 21054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "overlayUtils.h" 22054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "mdp_version.h" 23054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "sync/sync.h" 24054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin#include "gr.h" 25054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 26054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinnamespace ovutils = overlay::utils; 27054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 28054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinnamespace overlay { 29054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 30054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//============Rotator========================= 31054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 32054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotator::Rotator() { 33054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin char property[PROPERTY_VALUE_MAX]; 34054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRotCacheDisabled = false; 35054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if((property_get("debug.rotcache.disable", property, NULL) > 0) && 36054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 37054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 38054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* Used in debugging to turnoff rotator caching */ 39054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRotCacheDisabled = true; 40054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 41054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 42054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 43054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotator::~Rotator() {} 44054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 45054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotator* Rotator::getRotator() { 46054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int type = getRotatorHwType(); 47054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(type == TYPE_MDP) { 48054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return new MdpRot(); //will do reset 49054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } else if(type == TYPE_MDSS) { 50054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return new MdssRot(); 51054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } else { 52054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s Unknown h/w type %d", __FUNCTION__, type); 53054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return NULL; 54054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 55054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 56054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 57054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint Rotator::getDownscaleFactor(const int& srcW, const int& srcH, 58054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const int& dstW, const int& dstH, const uint32_t& mdpFormat, 59054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin const bool& isInterlaced) { 60054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(getRotatorHwType() == TYPE_MDSS) { 61054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return MdssRot::getDownscaleFactor(srcW, srcH, dstW, dstH, 62054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mdpFormat, isInterlaced); 63054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 64054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return MdpRot::getDownscaleFactor(srcW, srcH, dstW, dstH, 65054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mdpFormat, isInterlaced); 66054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 67054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 68054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinuint32_t Rotator::calcOutputBufSize(const utils::Whf& destWhf) { 69054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //dummy aligned w & h. 70054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int alW = 0, alH = 0; 71054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int halFormat = ovutils::getHALFormat(destWhf.format); 72054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //A call into gralloc/memalloc 73054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return getBufferSizeAndDimensions( 74054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin destWhf.w, destWhf.h, halFormat, alW, alH); 75054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 76054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 77054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint Rotator::getRotatorHwType() { 78054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); 79054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if (mdpVersion == qdutils::MDSS_V5) 80054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return TYPE_MDSS; 81054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return TYPE_MDP; 82054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 83054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 84054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool Rotator::isRotCached(int fd, uint32_t offset) const { 85054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRotCacheDisabled or rotConfChanged() or rotDataChanged(fd,offset)) 86054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return false; 87054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return true; 88054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 89054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 90054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool Rotator::rotDataChanged(int fd, uint32_t offset) const { 91054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* fd and offset are the attributes of the current rotator input buffer. 92054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * At this instance, getSrcMemId() and getSrcOffset() return the 93054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * attributes of the previous rotator input buffer */ 94054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if( (fd == getSrcMemId()) and (offset == getSrcOffset()) ) 95054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return false; 96054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return true; 97054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 98054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 99054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//============RotMem========================= 100054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 101054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinbool RotMem::close() { 102054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin bool ret = true; 103054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(valid()) { 104054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mem.close() == false) { 105054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s error in closing rot mem", __FUNCTION__); 106054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = false; 107054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 108054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 109054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return ret; 110054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 111054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 112054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotMem::RotMem() : mCurrIndex(0) { 113054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin utils::memset0(mRotOffset); 114054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = 0; i < ROT_NUM_BUFS; i++) { 115054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRelFence[i] = -1; 116054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 117054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 118054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 119054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotMem::~RotMem() { 120054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = 0; i < ROT_NUM_BUFS; i++) { 121054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ::close(mRelFence[i]); 122054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRelFence[i] = -1; 123054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 124054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 125054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 126054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid RotMem::setCurrBufReleaseFd(const int& fence) { 127054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin int ret = 0; 128054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 129054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRelFence[mCurrIndex] >= 0) { 130054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Wait for previous usage of this buffer to be over. 131054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Can happen if rotation takes > vsync and a fast producer. i.e queue 132054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //happens in subsequent vsyncs either because content is 60fps or 133054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //because the producer is hasty sometimes. 134054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ret = sync_wait(mRelFence[mCurrIndex], 1000); 135054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(ret < 0) { 136054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s: sync_wait error!! error no = %d err str = %s", 137054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin __FUNCTION__, errno, strerror(errno)); 138054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 139054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ::close(mRelFence[mCurrIndex]); 140054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 141054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRelFence[mCurrIndex] = fence; 142054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 143054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 144054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid RotMem::setPrevBufReleaseFd(const int& fence) { 145054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t numRotBufs = mem.numBufs(); 146054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin uint32_t prevIndex = (mCurrIndex + numRotBufs - 1) % (numRotBufs); 147054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 148054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRelFence[prevIndex] >= 0) { 149054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin /* No need of any wait as nothing will be written into this 150054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * buffer by the rotator (this func is called when rotator is 151054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin * in cache mode) */ 152054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ::close(mRelFence[prevIndex]); 153054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 154054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 155054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRelFence[prevIndex] = fence; 156054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 157054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 158054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin//============RotMgr========================= 159054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotMgr * RotMgr::sRotMgr = NULL; 160054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 161054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotMgr* RotMgr::getInstance() { 162054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(sRotMgr == NULL) { 163054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin sRotMgr = new RotMgr(); 164054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 165054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return sRotMgr; 166054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 167054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 168054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotMgr::RotMgr() { 169054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = 0; i < MAX_ROT_SESS; i++) { 170054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRot[i] = 0; 171054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 172054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mUseCount = 0; 173054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRotDevFd = -1; 174054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 175054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 176054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotMgr::~RotMgr() { 177054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin clear(); 178054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 179054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 180054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid RotMgr::configBegin() { 181054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Reset the number of objects used 182054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mUseCount = 0; 183054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 184054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 185054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid RotMgr::configDone() { 186054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Remove the top most unused objects. Videos come and go. 187054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = mUseCount; i < MAX_ROT_SESS; i++) { 188054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRot[i]) { 189054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin delete mRot[i]; 190054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRot[i] = 0; 191054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 192054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 193054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 194054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 195054df959aef7dce630a7f41d4aba6626c130756bPatrick TjinRotator* RotMgr::getNext() { 196054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Return a rot object, creating one if necessary 197054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin overlay::Rotator *rot = NULL; 198054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mUseCount >= MAX_ROT_SESS) { 199054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGW("%s, MAX rotator sessions reached, request rejected", __func__); 200054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } else { 201054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRot[mUseCount] == NULL) 202054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRot[mUseCount] = overlay::Rotator::getRotator(); 203054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin rot = mRot[mUseCount++]; 204054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 205054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return rot; 206054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 207054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 208054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid RotMgr::clear() { 209054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin //Brute force obj destruction, helpful in suspend. 210054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = 0; i < MAX_ROT_SESS; i++) { 211054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRot[i]) { 212054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin delete mRot[i]; 213054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRot[i] = 0; 214054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 215054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 216054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mUseCount = 0; 217054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ::close(mRotDevFd); 218054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRotDevFd = -1; 219054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 220054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 221054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinvoid RotMgr::getDump(char *buf, size_t len) { 222054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin for(int i = 0; i < MAX_ROT_SESS; i++) { 223054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRot[i]) { 224054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRot[i]->getDump(buf, len); 225054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 226054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 227054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin char str[4] = {'\0'}; 228054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin snprintf(str, 4, "\n"); 229054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin strlcat(buf, str, len); 230054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 231054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 232054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjinint RotMgr::getRotDevFd() { 233054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRotDevFd < 0 && Rotator::getRotatorHwType() == Rotator::TYPE_MDSS) { 234054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin mRotDevFd = ::open("/dev/graphics/fb0", O_RDWR, 0); 235054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin if(mRotDevFd < 0) { 236054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin ALOGE("%s failed to open fb0", __FUNCTION__); 237054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 238054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin } 239054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin return mRotDevFd; 240054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 241054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin 242054df959aef7dce630a7f41d4aba6626c130756bPatrick Tjin} 243