• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "sync/sync.h"
24 #include "gr.h"
25 
26 namespace ovutils = overlay::utils;
27 
28 namespace overlay {
29 
30 //============Rotator=========================
31 
Rotator()32 Rotator::Rotator() {
33     char property[PROPERTY_VALUE_MAX];
34     mRotCacheDisabled = false;
35     if((property_get("debug.rotcache.disable", property, NULL) > 0) &&
36        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
37         (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
38         /* Used in debugging to turnoff rotator caching */
39         mRotCacheDisabled = true;
40     }
41 }
42 
~Rotator()43 Rotator::~Rotator() {}
44 
getRotator()45 Rotator* Rotator::getRotator() {
46     int type = getRotatorHwType();
47     if(type == TYPE_MDP) {
48         return new MdpRot(); //will do reset
49     } else if(type == TYPE_MDSS) {
50         return new MdssRot();
51     } else {
52         ALOGE("%s Unknown h/w type %d", __FUNCTION__, type);
53         return NULL;
54     }
55 }
56 
getDownscaleFactor(const int & srcW,const int & srcH,const int & dstW,const int & dstH,const uint32_t & mdpFormat,const bool & isInterlaced)57 int Rotator::getDownscaleFactor(const int& srcW, const int& srcH,
58         const int& dstW, const int& dstH, const uint32_t& mdpFormat,
59         const bool& isInterlaced) {
60     if(getRotatorHwType() == TYPE_MDSS) {
61         return MdssRot::getDownscaleFactor(srcW, srcH, dstW, dstH,
62                 mdpFormat, isInterlaced);
63     }
64     return MdpRot::getDownscaleFactor(srcW, srcH, dstW, dstH,
65             mdpFormat, isInterlaced);
66 }
67 
calcOutputBufSize(const utils::Whf & destWhf)68 uint32_t Rotator::calcOutputBufSize(const utils::Whf& destWhf) {
69     //dummy aligned w & h.
70     int alW = 0, alH = 0;
71     int halFormat = ovutils::getHALFormat(destWhf.format);
72     //A call into gralloc/memalloc
73     return getBufferSizeAndDimensions(
74             destWhf.w, destWhf.h, halFormat, alW, alH);
75 }
76 
getRotatorHwType()77 int Rotator::getRotatorHwType() {
78     int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
79     if (mdpVersion == qdutils::MDSS_V5)
80         return TYPE_MDSS;
81     return TYPE_MDP;
82 }
83 
isRotCached(int fd,uint32_t offset) const84 bool Rotator::isRotCached(int fd, uint32_t offset) const {
85     if(mRotCacheDisabled or rotConfChanged() or rotDataChanged(fd,offset))
86         return false;
87     return true;
88 }
89 
rotDataChanged(int fd,uint32_t offset) const90 bool Rotator::rotDataChanged(int fd, uint32_t offset) const {
91     /* fd and offset are the attributes of the current rotator input buffer.
92      * At this instance, getSrcMemId() and getSrcOffset() return the
93      * attributes of the previous rotator input buffer */
94     if( (fd == getSrcMemId()) and (offset == getSrcOffset()) )
95         return false;
96     return true;
97 }
98 
99 //============RotMem=========================
100 
close()101 bool RotMem::close() {
102     bool ret = true;
103     if(valid()) {
104         if(mem.close() == false) {
105             ALOGE("%s error in closing rot mem", __FUNCTION__);
106             ret = false;
107         }
108     }
109     return ret;
110 }
111 
RotMem()112 RotMem::RotMem() : mCurrIndex(0) {
113     utils::memset0(mRotOffset);
114     for(int i = 0; i < ROT_NUM_BUFS; i++) {
115         mRelFence[i] = -1;
116     }
117 }
118 
~RotMem()119 RotMem::~RotMem() {
120     for(int i = 0; i < ROT_NUM_BUFS; i++) {
121         ::close(mRelFence[i]);
122         mRelFence[i] = -1;
123     }
124 }
125 
setCurrBufReleaseFd(const int & fence)126 void RotMem::setCurrBufReleaseFd(const int& fence) {
127     int ret = 0;
128 
129     if(mRelFence[mCurrIndex] >= 0) {
130         //Wait for previous usage of this buffer to be over.
131         //Can happen if rotation takes > vsync and a fast producer. i.e queue
132         //happens in subsequent vsyncs either because content is 60fps or
133         //because the producer is hasty sometimes.
134         ret = sync_wait(mRelFence[mCurrIndex], 1000);
135         if(ret < 0) {
136             ALOGE("%s: sync_wait error!! error no = %d err str = %s",
137                 __FUNCTION__, errno, strerror(errno));
138         }
139         ::close(mRelFence[mCurrIndex]);
140     }
141     mRelFence[mCurrIndex] = fence;
142 }
143 
setPrevBufReleaseFd(const int & fence)144 void RotMem::setPrevBufReleaseFd(const int& fence) {
145     uint32_t numRotBufs = mem.numBufs();
146     uint32_t prevIndex = (mCurrIndex + numRotBufs - 1) % (numRotBufs);
147 
148     if(mRelFence[prevIndex] >= 0) {
149         /* No need of any wait as nothing will be written into this
150          * buffer by the rotator (this func is called when rotator is
151          * in cache mode) */
152         ::close(mRelFence[prevIndex]);
153     }
154 
155     mRelFence[prevIndex] = fence;
156 }
157 
158 //============RotMgr=========================
159 RotMgr * RotMgr::sRotMgr = NULL;
160 
getInstance()161 RotMgr* RotMgr::getInstance() {
162     if(sRotMgr == NULL) {
163         sRotMgr = new RotMgr();
164     }
165     return sRotMgr;
166 }
167 
RotMgr()168 RotMgr::RotMgr() {
169     for(int i = 0; i < MAX_ROT_SESS; i++) {
170         mRot[i] = 0;
171     }
172     mUseCount = 0;
173     mRotDevFd = -1;
174 }
175 
~RotMgr()176 RotMgr::~RotMgr() {
177     clear();
178 }
179 
configBegin()180 void RotMgr::configBegin() {
181     //Reset the number of objects used
182     mUseCount = 0;
183 }
184 
configDone()185 void RotMgr::configDone() {
186     //Remove the top most unused objects. Videos come and go.
187     for(int i = mUseCount; i < MAX_ROT_SESS; i++) {
188         if(mRot[i]) {
189             delete mRot[i];
190             mRot[i] = 0;
191         }
192     }
193 }
194 
getNext()195 Rotator* RotMgr::getNext() {
196     //Return a rot object, creating one if necessary
197     overlay::Rotator *rot = NULL;
198     if(mUseCount >= MAX_ROT_SESS) {
199         ALOGW("%s, MAX rotator sessions reached, request rejected", __func__);
200     } else {
201         if(mRot[mUseCount] == NULL)
202             mRot[mUseCount] = overlay::Rotator::getRotator();
203         rot = mRot[mUseCount++];
204     }
205     return rot;
206 }
207 
clear()208 void RotMgr::clear() {
209     //Brute force obj destruction, helpful in suspend.
210     for(int i = 0; i < MAX_ROT_SESS; i++) {
211         if(mRot[i]) {
212             delete mRot[i];
213             mRot[i] = 0;
214         }
215     }
216     mUseCount = 0;
217     ::close(mRotDevFd);
218     mRotDevFd = -1;
219 }
220 
getDump(char * buf,size_t len)221 void RotMgr::getDump(char *buf, size_t len) {
222     for(int i = 0; i < MAX_ROT_SESS; i++) {
223         if(mRot[i]) {
224             mRot[i]->getDump(buf, len);
225         }
226     }
227     char str[4] = {'\0'};
228     snprintf(str, 4, "\n");
229     strlcat(buf, str, len);
230 }
231 
getRotDevFd()232 int RotMgr::getRotDevFd() {
233     if(mRotDevFd < 0 && Rotator::getRotatorHwType() == Rotator::TYPE_MDSS) {
234         mRotDevFd = ::open("/dev/graphics/fb0", O_RDWR, 0);
235         if(mRotDevFd < 0) {
236             ALOGE("%s failed to open fb0", __FUNCTION__);
237         }
238     }
239     return mRotDevFd;
240 }
241 
242 }
243