DisplayPlane.cpp revision 9f379685f09ddd7c4d98b23121487e8ac4b4dd40
1/*
2 * Copyright © 2012 Intel Corporation
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Jackie Li <yaodong.li@intel.com>
26 *
27 */
28#include <HwcTrace.h>
29#include <Hwcomposer.h>
30#include <DisplayPlane.h>
31#include <GraphicBuffer.h>
32
33namespace android {
34namespace intel {
35
36DisplayPlane::DisplayPlane(int index, int type, int disp)
37    : mIndex(index),
38      mType(type),
39      mZOrder(-1),
40      mDevice(disp),
41      mInitialized(false),
42      mDataBuffers(),
43      mActiveBuffers(),
44      mCacheCapacity(0),
45      mIsProtectedBuffer(false),
46      mTransform(PLANE_TRANSFORM_0),
47      mPlaneAlpha(0),
48      mCurrentDataBuffer(0),
49      mUpdateMasks(0)
50{
51    CTRACE();
52    memset(&mPosition, 0, sizeof(mPosition));
53    memset(&mSrcCrop, 0, sizeof(mSrcCrop));
54}
55
56DisplayPlane::~DisplayPlane()
57{
58    WARN_IF_NOT_DEINIT();
59}
60
61bool DisplayPlane::initialize(uint32_t bufferCount)
62{
63    CTRACE();
64
65    if (bufferCount < MIN_DATA_BUFFER_COUNT) {
66        WTRACE("buffer count %d is too small", bufferCount);
67        bufferCount = MIN_DATA_BUFFER_COUNT;
68    }
69
70    // create buffer cache, adding few extra slots as buffer rendering is async
71    // buffer could still be queued in the display pipeline such that they
72    // can't be unmapped]
73    mCacheCapacity = bufferCount;
74    mDataBuffers.setCapacity(bufferCount);
75    mActiveBuffers.setCapacity(MIN_DATA_BUFFER_COUNT);
76    mInitialized = true;
77    return true;
78}
79
80void DisplayPlane::deinitialize()
81{
82    // invalidate cached data buffers
83    if (mDataBuffers.size()) {
84        // invalidateBufferCache will assert if object is not initialized
85        // so invoking it only there is buffer to invalidate.
86        invalidateBufferCache();
87    }
88
89    // invalidate active buffers
90    if (mActiveBuffers.size()) {
91        invalidateActiveBuffers();
92    }
93
94    mCurrentDataBuffer = 0;
95    mInitialized = false;
96}
97
98void DisplayPlane::checkPosition(int& x, int& y, int& w, int& h)
99{
100    Drm *drm = Hwcomposer::getInstance().getDrm();
101    drmModeModeInfo modeInfo;
102    if (!drm->getModeInfo(mDevice, modeInfo)) {
103        ETRACE("failed to get mode info");
104        return;
105    }
106    drmModeModeInfoPtr mode = &modeInfo;
107
108    if (x < 0)
109        x = 0;
110    if (y < 0)
111        y = 0;
112    if ((x + w) > mode->hdisplay)
113        w = mode->hdisplay - x;
114    if ((y + h) > mode->vdisplay)
115        h = mode->vdisplay - y;
116}
117
118void DisplayPlane::setPosition(int x, int y, int w, int h)
119{
120    ATRACE("Position = %d, %d - %dx%d", x, y, w, h);
121
122    if (mPosition.x != x || mPosition.y != y ||
123        mPosition.w != w || mPosition.h != h) {
124        mUpdateMasks |= PLANE_POSITION_CHANGED;
125        mPosition.x = x;
126        mPosition.y = y;
127        mPosition.w = w;
128        mPosition.h = h;
129    }
130}
131
132void DisplayPlane::setSourceCrop(int x, int y, int w, int h)
133{
134    ATRACE("Source crop = %d, %d - %dx%d", x, y, w, h);
135
136    if (mSrcCrop.x != x || mSrcCrop.y != y ||
137        mSrcCrop.w != w || mSrcCrop.h != h) {
138        mUpdateMasks |= PLANE_SOURCE_CROP_CHANGED;
139        mSrcCrop.x = x;
140        mSrcCrop.y = y;
141        mSrcCrop.w = w;
142        mSrcCrop.h = h;
143    }
144}
145
146void DisplayPlane::setTransform(int trans)
147{
148    ATRACE("transform = %d", trans);
149
150    if (mTransform == trans) {
151        return;
152    }
153
154    switch (trans) {
155    case PLANE_TRANSFORM_90:
156    case PLANE_TRANSFORM_180:
157    case PLANE_TRANSFORM_270:
158        mTransform = trans;
159        break;
160    default:
161        mTransform = PLANE_TRANSFORM_0;
162        break;
163    }
164
165    mUpdateMasks |= PLANE_TRANSFORM_CHANGED;
166}
167
168void DisplayPlane::setPlaneAlpha(uint8_t alpha)
169{
170    ATRACE("plane alpha = 0x%x", alpha);
171
172    if (mPlaneAlpha != alpha) {
173        mPlaneAlpha = alpha;
174    }
175}
176
177bool DisplayPlane::setDataBuffer(uint32_t handle)
178{
179    DataBuffer *buffer;
180    BufferMapper *mapper;
181    ssize_t index;
182    bool ret;
183    bool isCompression;
184    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
185
186    RETURN_FALSE_IF_NOT_INIT();
187    ATRACE("handle = %#x", handle);
188
189    if (!handle) {
190        WTRACE("invalid buffer handle");
191        return false;
192    }
193
194    // do not need to update the buffer handle
195    if (mCurrentDataBuffer != handle)
196        mUpdateMasks |= PLANE_BUFFER_CHANGED;
197
198    // if no update then do Not need set data buffer
199    if (!mUpdateMasks)
200        return true;
201
202    buffer = bm->lockDataBuffer(handle);
203    if (!buffer) {
204        ETRACE("failed to get buffer");
205        return false;
206    }
207
208    mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
209    isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer);
210
211    // map buffer if it's not in cache
212    index = mDataBuffers.indexOfKey(buffer->getKey());
213    if (index < 0) {
214        VTRACE("unmapped buffer, mapping...");
215        mapper = mapBuffer(buffer);
216        if (!mapper) {
217            ETRACE("failed to map buffer %#x", handle);
218            bm->unlockDataBuffer(buffer);
219            return false;
220        }
221    } else {
222        VTRACE("got mapper in saved data buffers and update source Crop");
223        mapper = mDataBuffers.valueAt(index);
224    }
225
226    // always update source crop to mapper
227    mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);
228
229    mapper->setIsCompression(isCompression);
230
231    // unlock buffer after getting mapper
232    bm->unlockDataBuffer(buffer);
233    buffer = NULL;
234
235    ret = setDataBuffer(*mapper);
236    if (ret) {
237        mCurrentDataBuffer = handle;
238        // update active buffers
239        updateActiveBuffers(mapper);
240    }
241    return ret;
242}
243
244BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer)
245{
246    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
247
248    // invalidate buffer cache  if cache is full
249    if ((int)mDataBuffers.size() >= mCacheCapacity) {
250        invalidateBufferCache();
251    }
252
253    BufferMapper *mapper = bm->map(*buffer);
254    if (!mapper) {
255        ETRACE("failed to map buffer");
256        return NULL;
257    }
258
259    // add it to data buffers
260    ssize_t index = mDataBuffers.add(buffer->getKey(), mapper);
261    if (index < 0) {
262        ETRACE("failed to add mapper");
263        bm->unmap(mapper);
264        return NULL;
265    }
266
267    return mapper;
268}
269
270bool DisplayPlane::isActiveBuffer(BufferMapper *mapper)
271{
272    for (size_t i = 0; i < mActiveBuffers.size(); i++) {
273        BufferMapper *activeMapper = mActiveBuffers.itemAt(i);
274        if (!activeMapper)
275            continue;
276        if (activeMapper->getKey() == mapper->getKey())
277            return true;
278    }
279
280    return false;
281}
282
283void DisplayPlane::updateActiveBuffers(BufferMapper *mapper)
284{
285    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
286
287    // unmap the first entry (oldest buffer)
288    if (mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) {
289        BufferMapper *oldest = mActiveBuffers.itemAt(0);
290        bm->unmap(oldest);
291        mActiveBuffers.removeAt(0);
292    }
293
294    // queue it to active buffers
295    if (!isActiveBuffer(mapper)) {
296        mapper->incRef();
297        mActiveBuffers.push_back(mapper);
298    }
299}
300
301void DisplayPlane::invalidateActiveBuffers()
302{
303    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
304    BufferMapper* mapper;
305
306    RETURN_VOID_IF_NOT_INIT();
307
308    VTRACE("invalidating active buffers");
309
310    for (size_t i = 0; i < mActiveBuffers.size(); i++) {
311        mapper = mActiveBuffers.itemAt(i);
312        // unmap it
313        bm->unmap(mapper);
314    }
315
316    // clear recorded data buffers
317    mActiveBuffers.clear();
318}
319
320void DisplayPlane::invalidateBufferCache()
321{
322    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
323    BufferMapper* mapper;
324
325    RETURN_VOID_IF_NOT_INIT();
326
327    for (size_t i = 0; i < mDataBuffers.size(); i++) {
328        mapper = mDataBuffers.valueAt(i);
329        bm->unmap(mapper);
330    }
331
332    mDataBuffers.clear();
333    // reset current buffer
334    mCurrentDataBuffer = 0;
335}
336
337bool DisplayPlane::assignToDevice(int disp)
338{
339    RETURN_FALSE_IF_NOT_INIT();
340    ATRACE("disp = %d", disp);
341
342    mDevice = disp;
343    return true;
344}
345
346bool DisplayPlane::flip(void *ctx)
347{
348    RETURN_FALSE_IF_NOT_INIT();
349
350    // always flip
351    return true;
352}
353
354void DisplayPlane::postFlip()
355{
356    mUpdateMasks = 0;
357}
358
359bool 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
373void DisplayPlane::setZOrder(int zorder)
374{
375    mZOrder = zorder;
376}
377
378int DisplayPlane::getZOrder() const
379{
380    return mZOrder;
381}
382
383} // namespace intel
384} // namespace android
385