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 if (!mapper) {
221 ELOGTRACE("failed to map buffer %#x", handle);
222 bm->unlockDataBuffer(buffer);
223 return false;
224 }
225 } else {
226 VLOGTRACE("got mapper in saved data buffers and update source Crop");
227 mapper = mDataBuffers.valueAt(index);
228 }
229
230 // always update source crop to mapper
231 mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);
232
233 mapper->setIsCompression(isCompression);
234
235 // unlock buffer after getting mapper
236 bm->unlockDataBuffer(buffer);
237 buffer = NULL;
238
239 ret = setDataBuffer(*mapper);
240 if (ret) {
241 mCurrentDataBuffer = handle;
242 // update active buffers
243 updateActiveBuffers(mapper);
244 }
245 return ret;
246 }
247
mapBuffer(DataBuffer * buffer)248 BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer)
249 {
250 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
251
252 // invalidate buffer cache if cache is full
253 if ((int)mDataBuffers.size() >= mCacheCapacity) {
254 invalidateBufferCache();
255 }
256
257 BufferMapper *mapper = bm->map(*buffer);
258 if (!mapper) {
259 ELOGTRACE("failed to map buffer");
260 return NULL;
261 }
262
263 // add it to data buffers
264 ssize_t index = mDataBuffers.add(buffer->getKey(), mapper);
265 if (index < 0) {
266 ELOGTRACE("failed to add mapper");
267 bm->unmap(mapper);
268 return NULL;
269 }
270
271 return mapper;
272 }
273
isActiveBuffer(BufferMapper * mapper)274 bool DisplayPlane::isActiveBuffer(BufferMapper *mapper)
275 {
276 for (size_t i = 0; i < mActiveBuffers.size(); i++) {
277 BufferMapper *activeMapper = mActiveBuffers.itemAt(i);
278 if (!activeMapper)
279 continue;
280 if (activeMapper->getKey() == mapper->getKey())
281 return true;
282 }
283
284 return false;
285 }
286
updateActiveBuffers(BufferMapper * mapper)287 void DisplayPlane::updateActiveBuffers(BufferMapper *mapper)
288 {
289 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
290
291 // unmap the first entry (oldest buffer)
292 if (mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) {
293 BufferMapper *oldest = mActiveBuffers.itemAt(0);
294 bm->unmap(oldest);
295 mActiveBuffers.removeAt(0);
296 }
297
298 // queue it to active buffers
299 if (!isActiveBuffer(mapper)) {
300 mapper->incRef();
301 mActiveBuffers.push_back(mapper);
302 }
303 }
304
invalidateActiveBuffers()305 void DisplayPlane::invalidateActiveBuffers()
306 {
307 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
308 BufferMapper* mapper;
309
310 RETURN_VOID_IF_NOT_INIT();
311
312 VLOGTRACE("invalidating active buffers");
313
314 for (size_t i = 0; i < mActiveBuffers.size(); i++) {
315 mapper = mActiveBuffers.itemAt(i);
316 // unmap it
317 bm->unmap(mapper);
318 }
319
320 // clear recorded data buffers
321 mActiveBuffers.clear();
322 }
323
invalidateBufferCache()324 void DisplayPlane::invalidateBufferCache()
325 {
326 BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
327 BufferMapper* mapper;
328
329 RETURN_VOID_IF_NOT_INIT();
330
331 for (size_t i = 0; i < mDataBuffers.size(); i++) {
332 mapper = mDataBuffers.valueAt(i);
333 bm->unmap(mapper);
334 }
335
336 mDataBuffers.clear();
337 // reset current buffer
338 mCurrentDataBuffer = 0;
339 }
340
assignToDevice(int disp)341 bool DisplayPlane::assignToDevice(int disp)
342 {
343 RETURN_FALSE_IF_NOT_INIT();
344 ALOGTRACE("disp = %d", disp);
345
346 mDevice = disp;
347
348 Drm *drm = Hwcomposer::getInstance().getDrm();
349 if (!drm->getModeInfo(mDevice, mModeInfo)) {
350 ELOGTRACE("failed to get mode info");
351 }
352
353 mPanelOrientation = drm->getPanelOrientation(mDevice);
354
355 mForceScaling = DisplayQuery::forceFbScaling(disp);
356 drm->getDisplayResolution(disp, mDisplayWidth, mDisplayHeight);
357
358 if (mForceScaling) {
359 mModeInfo.hdisplay = mDisplayWidth;
360 mModeInfo.vdisplay = mDisplayHeight;
361
362 }
363
364 return true;
365 }
366
flip(void *)367 bool DisplayPlane::flip(void * /* ctx */)
368 {
369 RETURN_FALSE_IF_NOT_INIT();
370
371 // always flip
372 return true;
373 }
374
postFlip()375 void DisplayPlane::postFlip()
376 {
377 mUpdateMasks = 0;
378 }
379
reset()380 bool DisplayPlane::reset()
381 {
382 // reclaim all allocated resources
383 if (mDataBuffers.size() > 0) {
384 invalidateBufferCache();
385 }
386
387 if (mActiveBuffers.size() > 0) {
388 invalidateActiveBuffers();
389 }
390
391 return true;
392 }
393
setZOrder(int zorder)394 void DisplayPlane::setZOrder(int zorder)
395 {
396 mZOrder = zorder;
397 }
398
getZOrder() const399 int DisplayPlane::getZOrder() const
400 {
401 return mZOrder;
402 }
403
404 } // namespace intel
405 } // namespace android
406