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 <common/base/Drm.h>
18#include <common/base/HwcLayer.h>
19#include <Hwcomposer.h>
20#include <GraphicBuffer.h>
21#include <IDisplayDevice.h>
22#include <DisplayQuery.h>
23#include <PlaneCapabilities.h>
24
25
26namespace android {
27namespace intel {
28
29inline bool operator==(const hwc_rect_t& x, const hwc_rect_t& y)
30{
31    return (x.top == y.top &&
32            x.bottom == y.bottom &&
33            x.left == y.left &&
34            x.right == y.right);
35}
36
37inline bool operator !=(const hwc_rect_t& x, const hwc_rect_t& y)
38{
39    return !operator==(x, y);
40}
41
42inline bool operator ==(const hwc_frect_t& x, const hwc_frect_t& y)
43{
44    return (x.top == y.top &&
45            x.bottom == y.bottom &&
46            x.left == y.left &&
47            x.right == y.right);
48}
49
50inline bool operator !=(const hwc_frect_t& x, const hwc_frect_t& y)
51{
52    return !operator==(x, y);
53}
54
55HwcLayer::HwcLayer(int index, hwc_layer_1_t *layer)
56    : mIndex(index),
57      mZOrder(index + 1),  // 0 is reserved for frame buffer target
58      mDevice(0),
59      mLayer(layer),
60      mPlane(0),
61      mFormat(DataBuffer::FORMAT_INVALID),
62      mWidth(0),
63      mHeight(0),
64      mUsage(0),
65      mHandle(0),
66      mIsProtected(false),
67      mType(LAYER_FB),
68      mPriority(0),
69      mTransform(0),
70      mUpdated(false)
71{
72    memset(&mSourceCropf, 0, sizeof(mSourceCropf));
73    memset(&mDisplayFrame, 0, sizeof(mDisplayFrame));
74    memset(&mStride, 0, sizeof(mStride));
75
76    mPlaneCandidate = false;
77    setupAttributes();
78}
79
80HwcLayer::~HwcLayer()
81{
82    if (mPlane) {
83        WLOGTRACE("HwcLayer is not cleaned up");
84    }
85
86    mLayer = NULL;
87    mPlane = NULL;
88}
89
90bool HwcLayer::attachPlane(DisplayPlane* plane, int device)
91{
92    if (mPlane) {
93        ELOGTRACE("failed to attach plane, plane exists");
94        return false;
95    }
96
97    if (!plane) {
98        ELOGTRACE("Invalid plane");
99        return false;
100    }
101
102    mDevice = device;
103    //plane->setZOrder(mIndex);
104    plane->assignToDevice(device);
105    mPlane = plane;
106    return true;
107}
108
109DisplayPlane* HwcLayer::detachPlane()
110{
111    // reset plane's z order
112    if (mPlane)
113        mPlane->setZOrder(-1);
114    DisplayPlane *plane = mPlane;
115    mPlane = 0;
116    mDevice = 0;
117    return plane;
118}
119
120void HwcLayer::setType(uint32_t type)
121{
122    if (!mLayer)
123        return;
124
125    switch (type) {
126    case LAYER_OVERLAY:
127    case LAYER_SKIPPED:
128        mLayer->compositionType = HWC_OVERLAY;
129        mLayer->hints |= HWC_HINT_CLEAR_FB;
130        break;
131    // NOTE: set compositionType to HWC_FRAMEBUFFER here so that we have
132    // a chance to submit the primary changes to HW.
133    // Upper layer HWComposer will reset the compositionType automatically.
134    case LAYER_FB:
135    case LAYER_FORCE_FB:
136        mLayer->compositionType = HWC_FRAMEBUFFER;
137        break;
138    case LAYER_SIDEBAND:
139        mLayer->compositionType = HWC_SIDEBAND;
140        break;
141    case LAYER_CURSOR_OVERLAY:
142        mLayer->compositionType = HWC_CURSOR_OVERLAY;
143        break;
144    default:
145        break;
146    }
147
148    mType = type;
149}
150
151uint32_t HwcLayer::getType() const
152{
153    return mType;
154}
155
156void HwcLayer::setCompositionType(int32_t type)
157{
158    mLayer->compositionType = type;
159}
160
161int32_t HwcLayer::getCompositionType() const
162{
163    return mLayer->compositionType;
164}
165
166int HwcLayer::getIndex() const
167{
168    return mIndex;
169}
170
171int HwcLayer::getZOrder() const
172{
173    return mZOrder;
174}
175
176uint32_t HwcLayer::getFormat() const
177{
178    return mFormat;
179}
180
181uint32_t HwcLayer::getBufferWidth() const
182{
183    return mWidth;
184}
185
186uint32_t HwcLayer::getBufferHeight() const
187{
188    return mHeight;
189}
190
191const stride_t& HwcLayer::getBufferStride() const
192{
193    return mStride;
194}
195
196uint32_t HwcLayer::getUsage() const
197{
198    return mUsage;
199}
200
201uint32_t HwcLayer::getHandle() const
202{
203    return mHandle;
204}
205
206uint32_t HwcLayer::getTransform() const
207{
208    return mTransform;
209}
210
211bool HwcLayer::isProtected() const
212{
213    return mIsProtected;
214}
215
216hwc_layer_1_t* HwcLayer::getLayer() const
217{
218    return mLayer;
219}
220
221DisplayPlane* HwcLayer::getPlane() const
222{
223    return mPlane;
224}
225
226void HwcLayer::setPriority(uint32_t priority)
227{
228    mPriority = priority;
229}
230
231uint32_t HwcLayer::getPriority() const
232{
233    return mPriority;
234}
235
236bool HwcLayer::update(hwc_layer_1_t *layer)
237{
238    // update layer
239    mLayer = layer;
240    setupAttributes();
241
242    // if not a FB layer & a plane was attached update plane's data buffer
243    if (mPlane) {
244        mPlane->setPosition(layer->displayFrame.left,
245                            layer->displayFrame.top,
246                            layer->displayFrame.right - layer->displayFrame.left,
247                            layer->displayFrame.bottom - layer->displayFrame.top);
248        mPlane->setSourceCrop(layer->sourceCropf.left,
249                              layer->sourceCropf.top,
250                              layer->sourceCropf.right - layer->sourceCropf.left,
251                              layer->sourceCropf.bottom - layer->sourceCropf.top);
252        mPlane->setTransform(layer->transform);
253        mPlane->setPlaneAlpha(layer->planeAlpha, layer->blending);
254        bool ret = mPlane->setDataBuffer((uint32_t)layer->handle);
255        if (ret == true) {
256            return true;
257        }
258        DLOGTRACE("failed to set data buffer, reset handle to 0!!");
259        mHandle = 0;
260        if (!mIsProtected) {
261            // typical case: rotated buffer is not ready or handle is null
262            return false;
263        } else {
264            // protected video has to be rendered using overlay.
265            // if buffer is not ready overlay will still be attached to this layer
266            // but rendering needs to be skipped.
267            WLOGTRACE("ignoring result of data buffer setting for protected video");
268            return true;
269        }
270    }
271
272    return true;
273}
274
275bool HwcLayer::isUpdated()
276{
277    return mUpdated;
278}
279
280void HwcLayer::postFlip()
281{
282    mUpdated = false;
283    if (mPlane) {
284        mPlane->postFlip();
285    }
286}
287
288void HwcLayer::setupAttributes()
289{
290    if ((mLayer->flags & HWC_SKIP_LAYER) ||
291        mTransform != mLayer->transform ||
292        mSourceCropf != mLayer->sourceCropf ||
293        mDisplayFrame != mLayer->displayFrame ||
294        mHandle != (uint32_t)mLayer->handle ||
295        DisplayQuery::isVideoFormat(mFormat)) {
296        // TODO: same handle does not mean there is always no update
297        mUpdated = true;
298    }
299
300    // update handle always as it can become "NULL"
301    // if the given layer is not ready
302    mTransform = mLayer->transform;
303    mSourceCropf = mLayer->sourceCropf;
304    mDisplayFrame = mLayer->displayFrame;
305    mHandle = (uint32_t)mLayer->handle;
306
307    if (mFormat != DataBuffer::FORMAT_INVALID) {
308        // other attributes have been set.
309        return;
310    }
311
312    if (mLayer->handle == NULL) {
313        VLOGTRACE("invalid handle");
314        return;
315    }
316
317    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
318    if (bm == NULL) {
319        // TODO: this check is redundant
320        return;
321    }
322
323    DataBuffer *buffer = bm->lockDataBuffer((uint32_t)mLayer->handle);
324     if (!buffer) {
325         ELOGTRACE("failed to get buffer");
326     } else {
327        mFormat = buffer->getFormat();
328        mWidth = buffer->getWidth();
329        mHeight = buffer->getHeight();
330        mStride = buffer->getStride();
331        mPriority = (mSourceCropf.right - mSourceCropf.left) * (mSourceCropf.bottom - mSourceCropf.top);
332        mPriority <<= LAYER_PRIORITY_SIZE_OFFSET;
333        mPriority |= mIndex;
334        GraphicBuffer *gBuffer = (GraphicBuffer*)buffer;
335        mUsage = gBuffer->getUsage();
336        mIsProtected = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
337        if (mIsProtected) {
338            mPriority |= LAYER_PRIORITY_PROTECTED;
339        } else if (PlaneCapabilities::isFormatSupported(DisplayPlane::PLANE_OVERLAY, this)) {
340            mPriority |= LAYER_PRIORITY_OVERLAY;
341        }
342        bm->unlockDataBuffer(buffer);
343    }
344}
345
346} // namespace intel
347} // namespace android
348