• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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