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