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