1 /*
2 * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "overlay.h"
31 #include "pipes/overlayGenPipe.h"
32 #include "mdp_version.h"
33
34 #define PIPE_DEBUG 0
35
36 namespace overlay {
37 using namespace utils;
38
Overlay()39 Overlay::Overlay() {
40 int numPipes = 0;
41 int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
42 if (mdpVersion > qdutils::MDP_V3_1) numPipes = 4;
43 if (mdpVersion >= qdutils::MDSS_V5) numPipes = 6;
44
45 PipeBook::NUM_PIPES = numPipes;
46 for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
47 mPipeBook[i].init();
48 }
49
50 mDumpStr[0] = '\0';
51 }
52
~Overlay()53 Overlay::~Overlay() {
54 for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
55 mPipeBook[i].destroy();
56 }
57 }
58
configBegin()59 void Overlay::configBegin() {
60 for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
61 //Mark as available for this round.
62 PipeBook::resetUse(i);
63 PipeBook::resetAllocation(i);
64 }
65 mDumpStr[0] = '\0';
66 }
67
configDone()68 void Overlay::configDone() {
69 if(PipeBook::pipeUsageUnchanged()) return;
70
71 for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
72 if(PipeBook::isNotUsed(i)) {
73 //Forces UNSET on pipes, flushes rotator memory and session, closes
74 //fds
75 if(mPipeBook[i].valid()) {
76 char str[32];
77 sprintf(str, "Unset pipe=%s dpy=%d; ", getDestStr((eDest)i),
78 mPipeBook[i].mDisplay);
79 strncat(mDumpStr, str, strlen(str));
80 }
81 mPipeBook[i].destroy();
82 }
83 }
84 dump();
85 PipeBook::save();
86 }
87
nextPipe(eMdpPipeType type,int dpy)88 eDest Overlay::nextPipe(eMdpPipeType type, int dpy) {
89 eDest dest = OV_INVALID;
90
91 for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
92 //Match requested pipe type
93 if(type == OV_MDP_PIPE_ANY || type == getPipeType((eDest)i)) {
94 //If the pipe is not allocated to any display or used by the
95 //requesting display already in previous round.
96 if((mPipeBook[i].mDisplay == PipeBook::DPY_UNUSED ||
97 mPipeBook[i].mDisplay == dpy) &&
98 PipeBook::isNotAllocated(i)) {
99 dest = (eDest)i;
100 PipeBook::setAllocation(i);
101 break;
102 }
103 }
104 }
105
106 if(dest != OV_INVALID) {
107 int index = (int)dest;
108 //If the pipe is not registered with any display OR if the pipe is
109 //requested again by the same display using it, then go ahead.
110 mPipeBook[index].mDisplay = dpy;
111 if(not mPipeBook[index].valid()) {
112 mPipeBook[index].mPipe = new GenericPipe(dpy);
113 char str[32];
114 snprintf(str, 32, "Set pipe=%s dpy=%d; ", getDestStr(dest), dpy);
115 strncat(mDumpStr, str, strlen(str));
116 }
117 } else {
118 ALOGD_IF(PIPE_DEBUG, "Pipe unavailable type=%d display=%d",
119 (int)type, dpy);
120 }
121
122 return dest;
123 }
124
commit(utils::eDest dest)125 bool Overlay::commit(utils::eDest dest) {
126 bool ret = false;
127 int index = (int)dest;
128 validate(index);
129
130 if(mPipeBook[index].mPipe->commit()) {
131 ret = true;
132 PipeBook::setUse((int)dest);
133 } else {
134 PipeBook::resetUse((int)dest);
135 }
136 return ret;
137 }
138
queueBuffer(int fd,uint32_t offset,utils::eDest dest)139 bool Overlay::queueBuffer(int fd, uint32_t offset,
140 utils::eDest dest) {
141 int index = (int)dest;
142 bool ret = false;
143 validate(index);
144 //Queue only if commit() has succeeded (and the bit set)
145 if(PipeBook::isUsed((int)dest)) {
146 ret = mPipeBook[index].mPipe->queueBuffer(fd, offset);
147 }
148 return ret;
149 }
150
setCrop(const utils::Dim & d,utils::eDest dest)151 void Overlay::setCrop(const utils::Dim& d,
152 utils::eDest dest) {
153 int index = (int)dest;
154 validate(index);
155 mPipeBook[index].mPipe->setCrop(d);
156 }
157
setPosition(const utils::Dim & d,utils::eDest dest)158 void Overlay::setPosition(const utils::Dim& d,
159 utils::eDest dest) {
160 int index = (int)dest;
161 validate(index);
162 mPipeBook[index].mPipe->setPosition(d);
163 }
164
setTransform(const int orient,utils::eDest dest)165 void Overlay::setTransform(const int orient,
166 utils::eDest dest) {
167 int index = (int)dest;
168 validate(index);
169
170 utils::eTransform transform =
171 static_cast<utils::eTransform>(orient);
172 mPipeBook[index].mPipe->setTransform(transform);
173
174 }
175
setSource(const utils::PipeArgs args,utils::eDest dest)176 void Overlay::setSource(const utils::PipeArgs args,
177 utils::eDest dest) {
178 int index = (int)dest;
179 validate(index);
180
181 PipeArgs newArgs(args);
182 if(dest == OV_VG0 || dest == OV_VG1) {
183 setMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE);
184 } else {
185 clearMdpFlags(newArgs.mdpFlags, OV_MDP_PIPE_SHARE);
186 }
187 mPipeBook[index].mPipe->setSource(newArgs);
188 }
189
getInstance()190 Overlay* Overlay::getInstance() {
191 if(sInstance == NULL) {
192 sInstance = new Overlay();
193 }
194 return sInstance;
195 }
196
initOverlay()197 void Overlay::initOverlay() {
198 if(utils::initOverlay() == -1) {
199 ALOGE("%s failed", __FUNCTION__);
200 }
201 }
202
dump() const203 void Overlay::dump() const {
204 if(strlen(mDumpStr)) { //dump only on state change
205 ALOGD("%s\n", mDumpStr);
206 }
207 }
208
init()209 void Overlay::PipeBook::init() {
210 mPipe = NULL;
211 mDisplay = DPY_UNUSED;
212 }
213
destroy()214 void Overlay::PipeBook::destroy() {
215 if(mPipe) {
216 delete mPipe;
217 mPipe = NULL;
218 }
219 mDisplay = DPY_UNUSED;
220 }
221
222 Overlay* Overlay::sInstance = 0;
223 int Overlay::PipeBook::NUM_PIPES = 0;
224 int Overlay::PipeBook::sPipeUsageBitmap = 0;
225 int Overlay::PipeBook::sLastUsageBitmap = 0;
226 int Overlay::PipeBook::sAllocatedBitmap = 0;
227
228 }; // namespace overlay
229