1 /*
2 // Copyright (c) 2014 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 #include <common/utils/HwcTrace.h>
17 #include <IDisplayDevice.h>
18 #include <DisplayPlaneManager.h>
19
20 namespace android {
21 namespace intel {
22
DisplayPlaneManager()23 DisplayPlaneManager::DisplayPlaneManager()
24 : mTotalPlaneCount(0),
25 mPrimaryPlaneCount(DEFAULT_PRIMARY_PLANE_COUNT),
26 mSpritePlaneCount(0),
27 mOverlayPlaneCount(0),
28 mInitialized(false)
29 {
30 int i;
31
32 for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
33 mPlaneCount[i] = 0;
34 mFreePlanes[i] = 0;
35 mReclaimedPlanes[i] = 0;
36 }
37 }
38
~DisplayPlaneManager()39 DisplayPlaneManager::~DisplayPlaneManager()
40 {
41 WARN_IF_NOT_DEINIT();
42 }
43
deinitialize()44 void DisplayPlaneManager::deinitialize()
45 {
46 int i;
47 size_t j;
48
49 for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
50 for (j = 0; j < mPlanes[i].size(); j++) {
51 // reset plane
52 DisplayPlane *plane = mPlanes[i].itemAt(j);
53 plane->reset();
54
55 DEINIT_AND_DELETE_OBJ(plane);
56 }
57 mPlanes[i].clear();
58 }
59
60 mInitialized = false;
61 }
62
initialize()63 bool DisplayPlaneManager::initialize()
64 {
65 int i, j;
66
67 if (mInitialized) {
68 WLOGTRACE("object has been initialized");
69 return true;
70 }
71
72
73 // calculate total plane number and free plane bitmaps
74 mPlaneCount[DisplayPlane::PLANE_SPRITE] = mSpritePlaneCount;
75 mPlaneCount[DisplayPlane::PLANE_OVERLAY] = mOverlayPlaneCount;
76 mPlaneCount[DisplayPlane::PLANE_PRIMARY] = mPrimaryPlaneCount;
77 mPlaneCount[DisplayPlane::PLANE_CURSOR] = mCursorPlaneCount;
78
79 mTotalPlaneCount = mSpritePlaneCount+ mOverlayPlaneCount+ mPrimaryPlaneCount + mCursorPlaneCount;
80 if (mTotalPlaneCount == 0) {
81 ELOGTRACE("plane count is not initialized");
82 return false;
83 }
84
85 for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
86 mFreePlanes[i] = ((1 << mPlaneCount[i]) - 1);
87 }
88
89 // allocate plane pools
90 for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
91 if (mPlaneCount[i]) {
92 mPlanes[i].setCapacity(mPlaneCount[i]);
93
94 for (j = 0; j < mPlaneCount[i]; j++) {
95 DisplayPlane* plane = allocPlane(j, i);
96 if (!plane) {
97 ELOGTRACE("failed to allocate plane %d, type %d", j, i);
98 DEINIT_AND_RETURN_FALSE();
99 }
100 mPlanes[i].push_back(plane);
101 }
102 }
103 }
104
105 mInitialized = true;
106 return true;
107 }
108
getPlane(uint32_t & mask)109 int DisplayPlaneManager::getPlane(uint32_t& mask)
110 {
111 if (!mask)
112 return -1;
113
114 for (int i = 0; i < 32; i++) {
115 int bit = (1 << i);
116 if (bit & mask) {
117 mask &= ~bit;
118 return i;
119 }
120 }
121
122 return -1;
123 }
124
putPlane(int index,uint32_t & mask)125 void DisplayPlaneManager::putPlane(int index, uint32_t& mask)
126 {
127 if (index < 0 || index >= 32)
128 return;
129
130 int bit = (1 << index);
131
132 if (bit & mask) {
133 WLOGTRACE("bit %d was set", index);
134 return;
135 }
136
137 mask |= bit;
138 }
139
getPlane(uint32_t & mask,int index)140 int DisplayPlaneManager::getPlane(uint32_t& mask, int index)
141 {
142 if (!mask || index < 0 || index > mTotalPlaneCount)
143 return -1;
144
145 int bit = (1 << index);
146 if (bit & mask) {
147 mask &= ~bit;
148 return index;
149 }
150
151 return -1;
152 }
153
getPlane(int type,int index)154 DisplayPlane* DisplayPlaneManager::getPlane(int type, int index)
155 {
156 RETURN_NULL_IF_NOT_INIT();
157
158 if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
159 ELOGTRACE("Invalid plane type %d", type);
160 return 0;
161 }
162
163 int freePlaneIndex = getPlane(mReclaimedPlanes[type], index);
164 if (freePlaneIndex >= 0)
165 return mPlanes[type].itemAt(freePlaneIndex);
166
167 freePlaneIndex = getPlane(mFreePlanes[type], index);
168 if (freePlaneIndex >= 0)
169 return mPlanes[type].itemAt(freePlaneIndex);
170
171 return 0;
172 }
173
getAnyPlane(int type)174 DisplayPlane* DisplayPlaneManager::getAnyPlane(int type)
175 {
176 RETURN_NULL_IF_NOT_INIT();
177
178 if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
179 ELOGTRACE("Invalid plane type %d", type);
180 return 0;
181 }
182
183 int freePlaneIndex = getPlane(mReclaimedPlanes[type]);
184 if (freePlaneIndex >= 0)
185 return mPlanes[type].itemAt(freePlaneIndex);
186
187 freePlaneIndex = getPlane(mFreePlanes[type]);
188 if (freePlaneIndex >= 0)
189 return mPlanes[type].itemAt(freePlaneIndex);
190
191 return 0;
192 }
193
putPlane(int,DisplayPlane & plane)194 void DisplayPlaneManager::putPlane(int /* dsp */, DisplayPlane& plane)
195 {
196 int index;
197 int type;
198
199 RETURN_VOID_IF_NOT_INIT();
200
201 index = plane.getIndex();
202 type = plane.getType();
203
204 if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
205 ELOGTRACE("Invalid plane type %d", type);
206 return;
207 }
208
209 putPlane(index, mFreePlanes[type]);
210 }
211
isFreePlane(int type,int index)212 bool DisplayPlaneManager::isFreePlane(int type, int index)
213 {
214 if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
215 ELOGTRACE("Invalid plane type %d", type);
216 return false;
217 }
218
219 int freePlanes = mFreePlanes[type] | mReclaimedPlanes[type];
220 if ((freePlanes & (1 << index)) == 0)
221 return false;
222
223 return true;
224 }
225
getFreePlanes(int dsp,int type)226 int DisplayPlaneManager::getFreePlanes(int dsp, int type)
227 {
228 RETURN_NULL_IF_NOT_INIT();
229
230 if (dsp < 0 || dsp > IDisplayDevice::DEVICE_EXTERNAL) {
231 ELOGTRACE("Invalid display device %d", dsp);
232 return 0;
233 }
234
235 if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
236 ELOGTRACE("Invalid plane type %d", type);
237 return 0;
238 }
239
240
241 uint32_t freePlanes = mFreePlanes[type] | mReclaimedPlanes[type];
242 if (type == DisplayPlane::PLANE_PRIMARY ||
243 type == DisplayPlane::PLANE_CURSOR) {
244 return ((freePlanes & (1 << dsp)) == 0) ? 0 : 1;
245 } else {
246 int count = 0;
247 for (int i = 0; i < 32; i++) {
248 if ((1 << i) & freePlanes) {
249 count++;
250 }
251 }
252 return count;
253 }
254 return 0;
255 }
256
reclaimPlane(int,DisplayPlane & plane)257 void DisplayPlaneManager::reclaimPlane(int /* dsp */, DisplayPlane& plane)
258 {
259 RETURN_VOID_IF_NOT_INIT();
260
261 int index = plane.getIndex();
262 int type = plane.getType();
263
264 ALOGTRACE("reclaimPlane = %d, type = %d", index, plane.getType());
265
266 if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
267 ELOGTRACE("Invalid plane type %d", type);
268 return;
269 }
270
271 putPlane(index, mReclaimedPlanes[type]);
272
273 // NOTE: don't invalidate plane's data cache here because the reclaimed
274 // plane might be re-assigned to the same layer later
275 }
276
disableReclaimedPlanes()277 void DisplayPlaneManager::disableReclaimedPlanes()
278 {
279 int i, j;
280 bool ret;
281
282 RETURN_VOID_IF_NOT_INIT();
283
284 for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
285 // disable reclaimed planes
286 if (mReclaimedPlanes[i]) {
287 for (j = 0; j < mPlaneCount[i]; j++) {
288 int bit = (1 << j);
289 if (mReclaimedPlanes[i] & bit) {
290 DisplayPlane* plane = mPlanes[i].itemAt(j);
291 // check plane state first
292 ret = plane->isDisabled();
293 // reset plane
294 if (ret)
295 ret = plane->reset();
296 if (ret) {
297 // only merge into free bitmap if it is successfully disabled and reset
298 // otherwise, plane will be disabled and reset again.
299 mFreePlanes[i] |=bit;
300 mReclaimedPlanes[i] &= ~bit;
301 }
302 }
303 }
304 }
305 }
306 }
307
isOverlayPlanesDisabled()308 bool DisplayPlaneManager::isOverlayPlanesDisabled()
309 {
310 for (int i = 0; i < DisplayPlane::PLANE_MAX; i++) {
311 for (int j = 0; j < mPlaneCount[i]; j++) {
312 DisplayPlane* plane = (DisplayPlane *)mPlanes[i][j];
313 if (plane && plane->getType() == DisplayPlane::PLANE_OVERLAY) {
314 if (!plane->isDisabled())
315 return false;
316 }
317 }
318 }
319
320 return true;
321 }
322
dump(Dump & d)323 void DisplayPlaneManager::dump(Dump& d)
324 {
325 d.append("Display Plane Manager state:\n");
326 d.append("-------------------------------------------------------------\n");
327 d.append(" PLANE TYPE | COUNT | FREE | RECLAIMED \n");
328 d.append("------------+-------+----------+-----------\n");
329 d.append(" SPRITE | %2d | %08x | %08x\n",
330 mPlaneCount[DisplayPlane::PLANE_SPRITE],
331 mFreePlanes[DisplayPlane::PLANE_SPRITE],
332 mReclaimedPlanes[DisplayPlane::PLANE_SPRITE]);
333 d.append(" OVERLAY | %2d | %08x | %08x\n",
334 mPlaneCount[DisplayPlane::PLANE_OVERLAY],
335 mFreePlanes[DisplayPlane::PLANE_OVERLAY],
336 mReclaimedPlanes[DisplayPlane::PLANE_OVERLAY]);
337 d.append(" PRIMARY | %2d | %08x | %08x\n",
338 mPlaneCount[DisplayPlane::PLANE_PRIMARY],
339 mFreePlanes[DisplayPlane::PLANE_PRIMARY],
340 mReclaimedPlanes[DisplayPlane::PLANE_PRIMARY]);
341 d.append(" CURSOR | %2d | %08x | %08x\n",
342 mPlaneCount[DisplayPlane::PLANE_CURSOR],
343 mFreePlanes[DisplayPlane::PLANE_CURSOR],
344 mReclaimedPlanes[DisplayPlane::PLANE_CURSOR]);
345 }
346
347 } // namespace intel
348 } // namespace android
349
350
351