1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. 4 * Not a Contribution, Apache license notifications and license are retained 5 * for attribution purposes only. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18*/ 19 20#include "overlayRotator.h" 21#include "overlayUtils.h" 22#include "mdp_version.h" 23#include "gr.h" 24#include <sync/sync.h> 25 26namespace ovutils = overlay::utils; 27 28namespace overlay { 29 30//============Rotator========================= 31 32Rotator::~Rotator() {} 33 34Rotator* Rotator::getRotator() { 35 int type = getRotatorHwType(); 36 if(type == TYPE_MDP) { 37 return new MdpRot(); //will do reset 38 } else if(type == TYPE_MDSS) { 39 return new MdssRot(); 40 } else { 41 ALOGE("%s Unknown h/w type %d", __FUNCTION__, type); 42 return NULL; 43 } 44} 45 46uint32_t Rotator::calcOutputBufSize(const utils::Whf& destWhf) { 47 //dummy aligned w & h. 48 int alW = 0, alH = 0; 49 int halFormat = ovutils::getHALFormat(destWhf.format); 50 //A call into gralloc/memalloc 51 return getBufferSizeAndDimensions( 52 destWhf.w, destWhf.h, halFormat, alW, alH); 53} 54 55int Rotator::getRotatorHwType() { 56 int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion(); 57 if (mdpVersion == qdutils::MDSS_V5) 58 return TYPE_MDSS; 59 return TYPE_MDP; 60} 61 62 63//============RotMem========================= 64 65bool RotMem::close() { 66 bool ret = true; 67 if(valid()) { 68 if(mem.close() == false) { 69 ALOGE("%s error in closing rot mem", __FUNCTION__); 70 ret = false; 71 } 72 } 73 return ret; 74} 75 76RotMem::RotMem() : mCurrIndex(0) { 77 utils::memset0(mRotOffset); 78 for(int i = 0; i < ROT_NUM_BUFS; i++) { 79 mRelFence[i] = -1; 80 } 81} 82 83RotMem::~RotMem() { 84 for(int i = 0; i < ROT_NUM_BUFS; i++) { 85 ::close(mRelFence[i]); 86 mRelFence[i] = -1; 87 } 88} 89 90void RotMem::setReleaseFd(const int& fence) { 91 int ret = 0; 92 93 if(mRelFence[mCurrIndex] >= 0) { 94 //Wait for previous usage of this buffer to be over. 95 //Can happen if rotation takes > vsync and a fast producer. i.e queue 96 //happens in subsequent vsyncs either because content is 60fps or 97 //because the producer is hasty sometimes. 98 ret = sync_wait(mRelFence[mCurrIndex], 1000); 99 if(ret < 0) { 100 ALOGE("%s: sync_wait error!! error no = %d err str = %s", 101 __FUNCTION__, errno, strerror(errno)); 102 } 103 ::close(mRelFence[mCurrIndex]); 104 } 105 mRelFence[mCurrIndex] = fence; 106} 107 108//============RotMgr========================= 109RotMgr * RotMgr::sRotMgr = NULL; 110 111RotMgr* RotMgr::getInstance() { 112 if(sRotMgr == NULL) { 113 sRotMgr = new RotMgr(); 114 } 115 return sRotMgr; 116} 117 118RotMgr::RotMgr() { 119 for(int i = 0; i < MAX_ROT_SESS; i++) { 120 mRot[i] = 0; 121 } 122 mUseCount = 0; 123 mRotDevFd = -1; 124} 125 126RotMgr::~RotMgr() { 127 clear(); 128} 129 130void RotMgr::configBegin() { 131 //Reset the number of objects used 132 mUseCount = 0; 133} 134 135void RotMgr::configDone() { 136 //Remove the top most unused objects. Videos come and go. 137 for(int i = mUseCount; i < MAX_ROT_SESS; i++) { 138 if(mRot[i]) { 139 delete mRot[i]; 140 mRot[i] = 0; 141 } 142 } 143} 144 145Rotator* RotMgr::getNext() { 146 //Return a rot object, creating one if necessary 147 overlay::Rotator *rot = NULL; 148 if(mUseCount >= MAX_ROT_SESS) { 149 ALOGE("%s, MAX rotator sessions reached", __func__); 150 } else { 151 if(mRot[mUseCount] == NULL) 152 mRot[mUseCount] = overlay::Rotator::getRotator(); 153 rot = mRot[mUseCount++]; 154 } 155 return rot; 156} 157 158void RotMgr::clear() { 159 //Brute force obj destruction, helpful in suspend. 160 for(int i = 0; i < MAX_ROT_SESS; i++) { 161 if(mRot[i]) { 162 delete mRot[i]; 163 mRot[i] = 0; 164 } 165 } 166 mUseCount = 0; 167 ::close(mRotDevFd); 168 mRotDevFd = -1; 169} 170 171void RotMgr::getDump(char *buf, size_t len) { 172 for(int i = 0; i < MAX_ROT_SESS; i++) { 173 if(mRot[i]) { 174 mRot[i]->getDump(buf, len); 175 } 176 } 177 char str[4] = {'\0'}; 178 snprintf(str, 4, "\n"); 179 strlcat(buf, str, len); 180} 181 182int RotMgr::getRotDevFd() { 183 if(mRotDevFd < 0 && Rotator::getRotatorHwType() == Rotator::TYPE_MDSS) { 184 mRotDevFd = ::open("/dev/graphics/fb0", O_RDWR, 0); 185 if(mRotDevFd < 0) { 186 ALOGE("%s failed to open fb0", __FUNCTION__); 187 } 188 } 189 return mRotDevFd; 190} 191 192} 193