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