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 <HwcTrace.h>
17 #include <Hwcomposer.h>
18 #include <DisplayPlane.h>
19 #include <GraphicBuffer.h>
20 
21 namespace android {
22 namespace intel {
23 
DisplayPlane(int index,int type,int disp)24 DisplayPlane::DisplayPlane(int index, int type, int disp)
25     : mIndex(index),
26       mType(type),
27       mZOrder(-1),
28       mDevice(disp),
29       mInitialized(false),
30       mDataBuffers(),
31       mActiveBuffers(),
32       mCacheCapacity(0),
33       mIsProtectedBuffer(false),
34       mTransform(0),
35       mPlaneAlpha(0),
36       mBlending(HWC_BLENDING_NONE),
37       mCurrentDataBuffer(0),
38       mUpdateMasks(0)
39 {
40     CTRACE();
41     memset(&mPosition, 0, sizeof(mPosition));
42     memset(&mSrcCrop, 0, sizeof(mSrcCrop));
43 }
44 
~DisplayPlane()45 DisplayPlane::~DisplayPlane()
46 {
47     WARN_IF_NOT_DEINIT();
48 }
49 
initialize(uint32_t bufferCount)50 bool DisplayPlane::initialize(uint32_t bufferCount)
51 {
52     CTRACE();
53 
54     if (bufferCount < MIN_DATA_BUFFER_COUNT) {
55         WTRACE("buffer count %d is too small", bufferCount);
56         bufferCount = MIN_DATA_BUFFER_COUNT;
57     }
58 
59     // create buffer cache, adding few extra slots as buffer rendering is async
60     // buffer could still be queued in the display pipeline such that they
61     // can't be unmapped]
62     mCacheCapacity = bufferCount;
63     mDataBuffers.setCapacity(bufferCount);
64     mActiveBuffers.setCapacity(MIN_DATA_BUFFER_COUNT);
65     mInitialized = true;
66     return true;
67 }
68 
deinitialize()69 void DisplayPlane::deinitialize()
70 {
71     // invalidate cached data buffers
72     if (mDataBuffers.size()) {
73         // invalidateBufferCache will assert if object is not initialized
74         // so invoking it only there is buffer to invalidate.
75         invalidateBufferCache();
76     }
77 
78     // invalidate active buffers
79     if (mActiveBuffers.size()) {
80         invalidateActiveBuffers();
81     }
82 
83     mCurrentDataBuffer = 0;
84     mInitialized = false;
85 }
86 
checkPosition(int & x,int & y,int & w,int & h)87 void DisplayPlane::checkPosition(int& x, int& y, int& w, int& h)
88 {
89     drmModeModeInfoPtr mode = &mModeInfo;
90 
91     if (mode->hdisplay == 0 || mode->vdisplay == 0)
92         return;
93 
94     if (x < 0)
95         x = 0;
96     if (y < 0)
97         y = 0;
98     if ((x + w) > mode->hdisplay)
99         w = mode->hdisplay - x;
100     if ((y + h) > mode->vdisplay)
101         h = mode->vdisplay - y;
102 }
103 
setPosition(int x,int y,int w,int h)104 void DisplayPlane::setPosition(int x, int y, int w, int h)
105 {
106     ATRACE("Position = %d, %d - %dx%d", x, y, w, h);
107 
108     if (mPosition.x != x || mPosition.y != y ||
109         mPosition.w != w || mPosition.h != h) {
110         mUpdateMasks |= PLANE_POSITION_CHANGED;
111         mPosition.x = x;
112         mPosition.y = y;
113         mPosition.w = w;
114         mPosition.h = h;
115     }
116 }
117 
setSourceCrop(int x,int y,int w,int h)118 void DisplayPlane::setSourceCrop(int x, int y, int w, int h)
119 {
120     ATRACE("Source crop = %d, %d - %dx%d", x, y, w, h);
121 
122     if (mSrcCrop.x != x || mSrcCrop.y != y ||
123         mSrcCrop.w != w || mSrcCrop.h != h) {
124         mUpdateMasks |= PLANE_SOURCE_CROP_CHANGED;
125         mSrcCrop.x = x;
126         mSrcCrop.y = y;
127         if (mType == DisplayPlane::PLANE_OVERLAY) {
128             mSrcCrop.w = w & (~0x01);
129             mSrcCrop.h = h & (~0x01);
130         } else {
131             mSrcCrop.w = w;
132             mSrcCrop.h = h;
133         }
134     }
135 }
136 
setTransform(int trans)137 void DisplayPlane::setTransform(int trans)
138 {
139     ATRACE("transform = %d", trans);
140 
141     if (mTransform == trans) {
142         return;
143     }
144 
145     mTransform = trans;
146 
147     mUpdateMasks |= PLANE_TRANSFORM_CHANGED;
148 }
149 
setPlaneAlpha(uint8_t alpha,uint32_t blending)150 void DisplayPlane::setPlaneAlpha(uint8_t alpha, uint32_t blending)
151 {
152     ATRACE("plane alpha = 0x%x", alpha);
153 
154     if (mPlaneAlpha != alpha) {
155         mPlaneAlpha = alpha;
156         mUpdateMasks |= PLANE_BUFFER_CHANGED;
157     }
158 
159     if (mBlending != blending) {
160         mBlending = blending;
161         mUpdateMasks |= PLANE_BUFFER_CHANGED;
162     }
163 }
164 
setDataBuffer(buffer_handle_t handle)165 bool DisplayPlane::setDataBuffer(buffer_handle_t handle)
166 {
167     DataBuffer *buffer;
168     BufferMapper *mapper;
169     ssize_t index;
170     bool ret;
171     bool isCompression;
172     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
173 
174     RETURN_FALSE_IF_NOT_INIT();
175     ATRACE("handle = %#x", handle);
176 
177     if (!handle) {
178         WTRACE("invalid buffer handle");
179         return false;
180     }
181 
182     // do not need to update the buffer handle
183     if (mCurrentDataBuffer != handle)
184         mUpdateMasks |= PLANE_BUFFER_CHANGED;
185 
186     // if no update then do Not need set data buffer
187     if (!mUpdateMasks)
188         return true;
189 
190     buffer = bm->lockDataBuffer(handle);
191     if (!buffer) {
192         ETRACE("failed to get buffer");
193         return false;
194     }
195 
196     mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
197     isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer);
198 
199     // map buffer if it's not in cache
200     index = mDataBuffers.indexOfKey(buffer->getKey());
201     if (index < 0) {
202         VTRACE("unmapped buffer, mapping...");
203         mapper = mapBuffer(buffer);
204         if (!mapper) {
205             ETRACE("failed to map buffer %p", handle);
206             bm->unlockDataBuffer(buffer);
207             return false;
208         }
209     } else {
210         VTRACE("got mapper in saved data buffers and update source Crop");
211         mapper = mDataBuffers.valueAt(index);
212     }
213 
214     // always update source crop to mapper
215     mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);
216 
217     mapper->setIsCompression(isCompression);
218 
219     // unlock buffer after getting mapper
220     bm->unlockDataBuffer(buffer);
221     buffer = NULL;
222 
223     ret = setDataBuffer(*mapper);
224     if (ret) {
225         mCurrentDataBuffer = handle;
226         // update active buffers
227         updateActiveBuffers(mapper);
228     }
229     return ret;
230 }
231 
mapBuffer(DataBuffer * buffer)232 BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer)
233 {
234     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
235 
236     // invalidate buffer cache  if cache is full
237     if ((int)mDataBuffers.size() >= mCacheCapacity) {
238         invalidateBufferCache();
239     }
240 
241     BufferMapper *mapper = bm->map(*buffer);
242     if (!mapper) {
243         ETRACE("failed to map buffer");
244         return NULL;
245     }
246 
247     // add it to data buffers
248     ssize_t index = mDataBuffers.add(buffer->getKey(), mapper);
249     if (index < 0) {
250         ETRACE("failed to add mapper");
251         bm->unmap(mapper);
252         return NULL;
253     }
254 
255     return mapper;
256 }
257 
findActiveBuffer(BufferMapper * mapper)258 int DisplayPlane::findActiveBuffer(BufferMapper *mapper)
259 {
260     for (size_t i = 0; i < mActiveBuffers.size(); i++) {
261         BufferMapper *activeMapper = mActiveBuffers.itemAt(i);
262         if (!activeMapper)
263             continue;
264         if (activeMapper->getKey() == mapper->getKey())
265             return i;
266     }
267 
268     return -1;
269 }
270 
updateActiveBuffers(BufferMapper * mapper)271 void DisplayPlane::updateActiveBuffers(BufferMapper *mapper)
272 {
273     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
274     int index = findActiveBuffer(mapper);
275     bool exist = (0 <= index && index < (int)mActiveBuffers.size());
276 
277     // unmap the first entry (oldest buffer)
278     if (!exist && mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) {
279         BufferMapper *oldest = mActiveBuffers.itemAt(0);
280         bm->unmap(oldest);
281         mActiveBuffers.removeAt(0);
282     }
283 
284     // queue it to active buffers
285     if (!exist) {
286         mapper->incRef();
287     } else {
288         mActiveBuffers.removeAt(index);
289     }
290     mActiveBuffers.push_back(mapper);
291 }
292 
invalidateActiveBuffers()293 void DisplayPlane::invalidateActiveBuffers()
294 {
295     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
296     BufferMapper* mapper;
297 
298     RETURN_VOID_IF_NOT_INIT();
299 
300     VTRACE("invalidating active buffers");
301 
302     for (size_t i = 0; i < mActiveBuffers.size(); i++) {
303         mapper = mActiveBuffers.itemAt(i);
304         // unmap it
305         bm->unmap(mapper);
306     }
307 
308     // clear recorded data buffers
309     mActiveBuffers.clear();
310 }
311 
invalidateBufferCache()312 void DisplayPlane::invalidateBufferCache()
313 {
314     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
315     BufferMapper* mapper;
316 
317     RETURN_VOID_IF_NOT_INIT();
318 
319     for (size_t i = 0; i < mDataBuffers.size(); i++) {
320         mapper = mDataBuffers.valueAt(i);
321         bm->unmap(mapper);
322     }
323 
324     mDataBuffers.clear();
325     // reset current buffer
326     mCurrentDataBuffer = 0;
327 }
328 
assignToDevice(int disp)329 bool DisplayPlane::assignToDevice(int disp)
330 {
331     RETURN_FALSE_IF_NOT_INIT();
332     ATRACE("disp = %d", disp);
333 
334     mDevice = disp;
335 
336     Drm *drm = Hwcomposer::getInstance().getDrm();
337     if (!drm->getModeInfo(mDevice, mModeInfo)) {
338         ETRACE("failed to get mode info");
339     }
340 
341     mPanelOrientation = drm->getPanelOrientation(mDevice);
342 
343     return true;
344 }
345 
flip(void * ctx)346 bool DisplayPlane::flip(void *ctx)
347 {
348     RETURN_FALSE_IF_NOT_INIT();
349 
350     // always flip
351     return true;
352 }
353 
postFlip()354 void DisplayPlane::postFlip()
355 {
356     mUpdateMasks = 0;
357 }
358 
reset()359 bool DisplayPlane::reset()
360 {
361     // reclaim all allocated resources
362     if (mDataBuffers.size() > 0) {
363         invalidateBufferCache();
364     }
365 
366     if (mActiveBuffers.size() > 0) {
367         invalidateActiveBuffers();
368     }
369 
370     return true;
371 }
372 
setZOrder(int zorder)373 void DisplayPlane::setZOrder(int zorder)
374 {
375     mZOrder = zorder;
376 }
377 
getZOrder() const378 int DisplayPlane::getZOrder() const
379 {
380     return mZOrder;
381 }
382 
383 } // namespace intel
384 } // namespace android
385