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 return;
117 }
118
119 if (mPosition.x != x || mPosition.y != y ||
120 mPosition.w != w || mPosition.h != h) {
121 mUpdateMasks |= PLANE_POSITION_CHANGED;
122 mPosition.x = x;
123 mPosition.y = y;
124 mPosition.w = w;
125 mPosition.h = h;
126 }
127 }
128
setSourceCrop(int x,int y,int w,int h)129 void DisplayPlane::setSourceCrop(int x, int y, int w, int h)
130 {
131 ALOGTRACE("Source crop = %d, %d - %dx%d", x, y, w, h);
132
133 if (mSrcCrop.x != x || mSrcCrop.y != y ||
134 mSrcCrop.w != w || mSrcCrop.h != h) {
135 mUpdateMasks |= PLANE_SOURCE_CROP_CHANGED;
136 mSrcCrop.x = x;
137 mSrcCrop.y = y;
138 mSrcCrop.w = w;
139 mSrcCrop.h = h;
140 }
141 }
142
setTransform(int trans)143 void DisplayPlane::setTransform(int trans)
144 {
145 ALOGTRACE("transform = %d", trans);
146
147 if (mTransform == trans) {
148 return;
149 }
150
151 mTransform = trans;
152
153 mUpdateMasks |= PLANE_TRANSFORM_CHANGED;
154 }
155
setPlaneAlpha(uint8_t alpha,uint32_t blending)156 void DisplayPlane::setPlaneAlpha(uint8_t alpha, uint32_t blending)
157 {
158 ALOGTRACE("plane alpha = 0x%x", alpha);
159
160 if (mPlaneAlpha != alpha) {
161 mPlaneAlpha = alpha;
162 mUpdateMasks |= PLANE_BUFFER_CHANGED;
163 }
164
165 if (mBlending != blending) {
166 mBlending = blending;
167 mUpdateMasks |= PLANE_BUFFER_CHANGED;
168 }
169 }
170
setDataBuffer(uint32_t handle)171 bool DisplayPlane::setDataBuffer(uint32_t handle)
172 {
173 DataBuffer *buffer;
174 BufferMapper *mapper;
175 ssize_t index;
176 bool ret;
177 bool isCompression;
178 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
179
180 RETURN_FALSE_IF_NOT_INIT();
181 ALOGTRACE("handle = %#x", handle);
182
183 if (!handle) {
184 WLOGTRACE("invalid buffer handle");
185 return false;
186 }
187
188 // do not need to update the buffer handle
189 if (mCurrentDataBuffer != handle)
190 mUpdateMasks |= PLANE_BUFFER_CHANGED;
191
192 // if no update then do Not need set data buffer
193 if (!mUpdateMasks)
194 return true;
195
196 buffer = bm->lockDataBuffer(handle);
197 if (!buffer) {
198 ELOGTRACE("failed to get buffer");
199 return false;
200 }
201
202 mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
203 isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer);
204
205 // map buffer if it's not in cache
206 index = mDataBuffers.indexOfKey(buffer->getKey());
207 if (index < 0) {
208 VLOGTRACE("unmapped buffer, mapping...");
209 mapper = mapBuffer(buffer);
210 if (!mapper) {
211 ELOGTRACE("failed to map buffer %#x", handle);
212 bm->unlockDataBuffer(buffer);
213 return false;
214 }
215 } else {
216 VLOGTRACE("got mapper in saved data buffers and update source Crop");
217 mapper = mDataBuffers.valueAt(index);
218 }
219
220 // always update source crop to mapper
221 mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);
222
223 mapper->setIsCompression(isCompression);
224
225 // unlock buffer after getting mapper
226 bm->unlockDataBuffer(buffer);
227 buffer = NULL;
228
229 ret = setDataBuffer(*mapper);
230 if (ret) {
231 mCurrentDataBuffer = handle;
232 // update active buffers
233 updateActiveBuffers(mapper);
234 }
235 return ret;
236 }
237
mapBuffer(DataBuffer * buffer)238 BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer)
239 {
240 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
241
242 // invalidate buffer cache if cache is full
243 if ((int)mDataBuffers.size() >= mCacheCapacity) {
244 invalidateBufferCache();
245 }
246
247 BufferMapper *mapper = bm->map(*buffer);
248 if (!mapper) {
249 ELOGTRACE("failed to map buffer");
250 return NULL;
251 }
252
253 // add it to data buffers
254 ssize_t index = mDataBuffers.add(buffer->getKey(), mapper);
255 if (index < 0) {
256 ELOGTRACE("failed to add mapper");
257 bm->unmap(mapper);
258 return NULL;
259 }
260
261 return mapper;
262 }
263
isActiveBuffer(BufferMapper * mapper)264 bool DisplayPlane::isActiveBuffer(BufferMapper *mapper)
265 {
266 for (size_t i = 0; i < mActiveBuffers.size(); i++) {
267 BufferMapper *activeMapper = mActiveBuffers.itemAt(i);
268 if (!activeMapper)
269 continue;
270 if (activeMapper->getKey() == mapper->getKey())
271 return true;
272 }
273
274 return false;
275 }
276
updateActiveBuffers(BufferMapper * mapper)277 void DisplayPlane::updateActiveBuffers(BufferMapper *mapper)
278 {
279 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
280
281 // unmap the first entry (oldest buffer)
282 if (mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) {
283 BufferMapper *oldest = mActiveBuffers.itemAt(0);
284 bm->unmap(oldest);
285 mActiveBuffers.removeAt(0);
286 }
287
288 // queue it to active buffers
289 if (!isActiveBuffer(mapper)) {
290 mapper->incRef();
291 mActiveBuffers.push_back(mapper);
292 }
293 }
294
invalidateActiveBuffers()295 void DisplayPlane::invalidateActiveBuffers()
296 {
297 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
298 BufferMapper* mapper;
299
300 RETURN_VOID_IF_NOT_INIT();
301
302 VLOGTRACE("invalidating active buffers");
303
304 for (size_t i = 0; i < mActiveBuffers.size(); i++) {
305 mapper = mActiveBuffers.itemAt(i);
306 // unmap it
307 bm->unmap(mapper);
308 }
309
310 // clear recorded data buffers
311 mActiveBuffers.clear();
312 }
313
invalidateBufferCache()314 void DisplayPlane::invalidateBufferCache()
315 {
316 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
317 BufferMapper* mapper;
318
319 RETURN_VOID_IF_NOT_INIT();
320
321 for (size_t i = 0; i < mDataBuffers.size(); i++) {
322 mapper = mDataBuffers.valueAt(i);
323 bm->unmap(mapper);
324 }
325
326 mDataBuffers.clear();
327 // reset current buffer
328 mCurrentDataBuffer = 0;
329 }
330
assignToDevice(int disp)331 bool DisplayPlane::assignToDevice(int disp)
332 {
333 RETURN_FALSE_IF_NOT_INIT();
334 ALOGTRACE("disp = %d", disp);
335
336 mDevice = disp;
337
338 Drm *drm = Hwcomposer::getInstance().getDrm();
339 if (!drm->getModeInfo(mDevice, mModeInfo)) {
340 ELOGTRACE("failed to get mode info");
341 }
342
343 mPanelOrientation = drm->getPanelOrientation(mDevice);
344
345 mForceScaling = DisplayQuery::forceFbScaling(disp);
346 drm->getDisplayResolution(disp, mDisplayWidth, mDisplayHeight);
347
348 if (mForceScaling) {
349 mModeInfo.hdisplay = mDisplayWidth;
350 mModeInfo.vdisplay = mDisplayHeight;
351 mPosition.x = 0;
352 mPosition.y = 0;
353 mPosition.w = mDisplayWidth;
354 mPosition.h = mDisplayHeight;
355 }
356 mDisplayCrop.x = 0;
357 mDisplayCrop.y = 0;
358 mDisplayCrop.w = mDisplayWidth;
359 mDisplayCrop.h = mDisplayHeight;
360
361 return true;
362 }
363
flip(void *)364 bool DisplayPlane::flip(void * /* ctx */)
365 {
366 RETURN_FALSE_IF_NOT_INIT();
367
368 // always flip
369 return true;
370 }
371
postFlip()372 void DisplayPlane::postFlip()
373 {
374 mUpdateMasks = 0;
375 }
376
reset()377 bool DisplayPlane::reset()
378 {
379 // reclaim all allocated resources
380 if (mDataBuffers.size() > 0) {
381 invalidateBufferCache();
382 }
383
384 if (mActiveBuffers.size() > 0) {
385 invalidateActiveBuffers();
386 }
387
388 return true;
389 }
390
setZOrder(int zorder)391 void DisplayPlane::setZOrder(int zorder)
392 {
393 mZOrder = zorder;
394 }
395
getZOrder() const396 int DisplayPlane::getZOrder() const
397 {
398 return mZOrder;
399 }
400
401 } // namespace intel
402 } // namespace android
403