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