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 <HwcTrace.h>
17#include <Drm.h>
18#include <HwcLayer.h>
19#include <Hwcomposer.h>
20#include <GraphicBuffer.h>
21#include <IDisplayDevice.h>
22#include <DisplayQuery.h>
23#include <PlaneCapabilities.h>
24#include <cutils/properties.h>
25
26
27namespace android {
28namespace intel {
29
30inline bool operator==(const hwc_rect_t& x, const hwc_rect_t& y)
31{
32    return (x.top == y.top &&
33            x.bottom == y.bottom &&
34            x.left == y.left &&
35            x.right == y.right);
36}
37
38inline bool operator !=(const hwc_rect_t& x, const hwc_rect_t& y)
39{
40    return !operator==(x, y);
41}
42
43inline bool operator ==(const hwc_frect_t& x, const hwc_frect_t& y)
44{
45    return (x.top == y.top &&
46            x.bottom == y.bottom &&
47            x.left == y.left &&
48            x.right == y.right);
49}
50
51inline bool operator !=(const hwc_frect_t& x, const hwc_frect_t& y)
52{
53    return !operator==(x, y);
54}
55
56HwcLayer::HwcLayer(int index, hwc_layer_1_t *layer)
57    : mIndex(index),
58      mZOrder(index + 1),  // 0 is reserved for frame buffer target
59      mDevice(0),
60      mLayer(layer),
61      mPlane(0),
62      mFormat(DataBuffer::FORMAT_INVALID),
63      mWidth(0),
64      mHeight(0),
65      mUsage(0),
66      mHandle(0),
67      mIsProtected(false),
68      mType(LAYER_FB),
69      mPriority(0),
70      mTransform(0),
71      mStaticCount(0),
72      mUpdated(false)
73{
74    memset(&mSourceCropf, 0, sizeof(mSourceCropf));
75    memset(&mDisplayFrame, 0, sizeof(mDisplayFrame));
76    memset(&mStride, 0, sizeof(mStride));
77
78    mPlaneCandidate = false;
79    setupAttributes();
80
81#ifdef HWC_TRACE_FPS
82    mTraceFps = false;
83    char prop[PROPERTY_VALUE_MAX];
84    if (property_get("debug.hwc.fps_trace.enable", prop, "0") > 0) {
85        mTraceFps = atoi(prop);
86    }
87    mLastHandle = NULL;
88
89    if (mTraceFps) {
90        // holding up to 6 seconds of samples at 60Hz
91        mFrames.setCapacity(6 * 60);
92    }
93#endif
94}
95
96HwcLayer::~HwcLayer()
97{
98    if (mPlane) {
99        WTRACE("HwcLayer is not cleaned up");
100    }
101
102    mLayer = NULL;
103    mPlane = NULL;
104
105#ifdef HWC_TRACE_FPS
106    mFrames.clear();
107#endif
108}
109
110bool HwcLayer::attachPlane(DisplayPlane* plane, int device)
111{
112    if (mPlane) {
113        ETRACE("failed to attach plane, plane exists");
114        return false;
115    }
116
117    if (!plane) {
118        ETRACE("Invalid plane");
119        return false;
120    }
121
122    mDevice = device;
123    //plane->setZOrder(mIndex);
124    plane->assignToDevice(device);
125    mPlane = plane;
126    return true;
127}
128
129DisplayPlane* HwcLayer::detachPlane()
130{
131    // reset plane's z order
132    if (mPlane)
133        mPlane->setZOrder(-1);
134    DisplayPlane *plane = mPlane;
135    mPlane = 0;
136    mDevice = 0;
137    return plane;
138}
139
140void HwcLayer::setType(uint32_t type)
141{
142    if (!mLayer)
143        return;
144
145    switch (type) {
146    case LAYER_OVERLAY:
147    case LAYER_SKIPPED:
148        mLayer->compositionType = HWC_OVERLAY;
149        mLayer->hints |= HWC_HINT_CLEAR_FB;
150        break;
151    // NOTE: set compositionType to HWC_FRAMEBUFFER here so that we have
152    // a chance to submit the primary changes to HW.
153    // Upper layer HWComposer will reset the compositionType automatically.
154    case LAYER_FB:
155    case LAYER_FORCE_FB:
156        mLayer->compositionType = HWC_FRAMEBUFFER;
157        break;
158    case LAYER_SIDEBAND:
159        mLayer->compositionType = HWC_SIDEBAND;
160        break;
161    case LAYER_CURSOR_OVERLAY:
162        mLayer->compositionType = HWC_CURSOR_OVERLAY;
163        break;
164    default:
165        break;
166    }
167
168    mType = type;
169}
170
171uint32_t HwcLayer::getType() const
172{
173    return mType;
174}
175
176void HwcLayer::setCompositionType(int32_t type)
177{
178    mLayer->compositionType = type;
179}
180
181int32_t HwcLayer::getCompositionType() const
182{
183    return mLayer->compositionType;
184}
185
186int HwcLayer::getIndex() const
187{
188    return mIndex;
189}
190
191int HwcLayer::getZOrder() const
192{
193    return mZOrder;
194}
195
196uint32_t HwcLayer::getFormat() const
197{
198    return mFormat;
199}
200
201uint32_t HwcLayer::getBufferWidth() const
202{
203    return mWidth;
204}
205
206uint32_t HwcLayer::getBufferHeight() const
207{
208    return mHeight;
209}
210
211const stride_t& HwcLayer::getBufferStride() const
212{
213    return mStride;
214}
215
216uint32_t HwcLayer::getUsage() const
217{
218    return mUsage;
219}
220
221buffer_handle_t HwcLayer::getHandle() const
222{
223    return mHandle;
224}
225
226uint32_t HwcLayer::getTransform() const
227{
228    return mTransform;
229}
230
231bool HwcLayer::isProtected() const
232{
233    return mIsProtected;
234}
235
236hwc_layer_1_t* HwcLayer::getLayer() const
237{
238    return mLayer;
239}
240
241DisplayPlane* HwcLayer::getPlane() const
242{
243    return mPlane;
244}
245
246void HwcLayer::setPriority(uint32_t priority)
247{
248    mPriority = priority;
249}
250
251uint32_t HwcLayer::getPriority() const
252{
253    return mPriority;
254}
255
256bool HwcLayer::update(hwc_layer_1_t *layer)
257{
258    // update layer
259    mLayer = layer;
260    setupAttributes();
261
262#ifdef HWC_TRACE_FPS
263    if (mTraceFps && mLayer && mLayer->compositionType != HWC_FRAMEBUFFER_TARGET ) {
264        // 1 second = 1000000000 nano seconds
265        uint64_t now = systemTime(CLOCK_MONOTONIC);
266        if (mLastHandle != mHandle) {
267            mLastHandle = mHandle;
268            mFrames.push(now);
269        }
270        // calculate fps in 5-second time window
271        int frames = mFrames.size();
272        while (frames && now - mFrames[0] > 5000000000LL) {
273            mFrames.removeItemsAt(0);
274            frames--;
275        }
276        double fps = 0;
277        if (frames > 1) {
278            fps = frames * 1000000000.0/ (now - mFrames[0]);
279        }
280        ITRACE("fps of layer %d is %.1f", mIndex, fps);
281    }
282#endif
283
284    // if not a FB layer & a plane was attached update plane's data buffer
285    if (mPlane) {
286        mPlane->setPosition(layer->displayFrame.left,
287                            layer->displayFrame.top,
288                            layer->displayFrame.right - layer->displayFrame.left,
289                            layer->displayFrame.bottom - layer->displayFrame.top);
290        mPlane->setSourceCrop(layer->sourceCropf.left,
291                              layer->sourceCropf.top,
292                              layer->sourceCropf.right - layer->sourceCropf.left,
293                              layer->sourceCropf.bottom - layer->sourceCropf.top);
294        mPlane->setTransform(layer->transform);
295        mPlane->setPlaneAlpha(layer->planeAlpha, layer->blending);
296        bool ret = mPlane->setDataBuffer(layer->handle);
297        if (ret == true) {
298            return true;
299        }
300        DTRACE("failed to set data buffer, reset handle to 0!!");
301        mHandle = 0;
302        if (!mIsProtected) {
303            // typical case: rotated buffer is not ready or handle is null
304            return false;
305        } else {
306            // protected video has to be rendered using overlay.
307            // if buffer is not ready overlay will still be attached to this layer
308            // but rendering needs to be skipped.
309            WTRACE("ignoring result of data buffer setting for protected video");
310            return true;
311        }
312    }
313
314    return true;
315}
316
317bool HwcLayer::isUpdated()
318{
319    return mUpdated;
320}
321
322uint32_t HwcLayer::getStaticCount()
323{
324    return mStaticCount;
325}
326
327void HwcLayer::postFlip()
328{
329    mUpdated = false;
330    if (mPlane) {
331        mPlane->postFlip();
332
333        // flip frame buffer target once in video extended mode to refresh screen,
334        // then mark type as LAYER_SKIPPED so it will not be flipped again.
335        // by doing this pipe for primary device can enter idle state
336        if (mDevice == IDisplayDevice::DEVICE_PRIMARY &&
337            mType == LAYER_FRAMEBUFFER_TARGET &&
338            Hwcomposer::getInstance().getDisplayAnalyzer()->isVideoExtModeActive()) {
339            DTRACE("Skipping frame buffer target...");
340            mType = LAYER_SKIPPED;
341        }
342    }
343}
344
345void HwcLayer::setupAttributes()
346{
347    if ((mLayer->flags & HWC_SKIP_LAYER) ||
348        mTransform != mLayer->transform ||
349        mSourceCropf != mLayer->sourceCropf ||
350        mDisplayFrame != mLayer->displayFrame ||
351        mHandle != mLayer->handle ||
352        DisplayQuery::isVideoFormat(mFormat)) {
353        // TODO: same handle does not mean there is always no update
354        mUpdated = true;
355        mStaticCount = 0;
356    } else {
357        // protect it from exceeding its max
358        if (++mStaticCount > 1000)
359            mStaticCount = LAYER_STATIC_THRESHOLD + 1;
360    }
361
362    // update handle always as it can become "NULL"
363    // if the given layer is not ready
364    mTransform = mLayer->transform;
365    mSourceCropf = mLayer->sourceCropf;
366    mDisplayFrame = mLayer->displayFrame;
367    mHandle = mLayer->handle;
368
369    if (mFormat != DataBuffer::FORMAT_INVALID) {
370        // other attributes have been set.
371        return;
372    }
373
374    if (mLayer->handle == NULL) {
375        VTRACE("invalid handle");
376        return;
377    }
378
379    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
380    if (bm == NULL) {
381        // TODO: this check is redundant
382        return;
383    }
384
385    DataBuffer *buffer = bm->lockDataBuffer(mLayer->handle);
386     if (!buffer) {
387         ETRACE("failed to get buffer");
388     } else {
389        mFormat = buffer->getFormat();
390        mWidth = buffer->getWidth();
391        mHeight = buffer->getHeight();
392        mStride = buffer->getStride();
393        mPriority = (mSourceCropf.right - mSourceCropf.left) * (mSourceCropf.bottom - mSourceCropf.top);
394        mPriority <<= LAYER_PRIORITY_SIZE_OFFSET;
395        mPriority |= mIndex;
396        GraphicBuffer *gBuffer = (GraphicBuffer*)buffer;
397        mUsage = gBuffer->getUsage();
398        mIsProtected = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
399        if (mIsProtected) {
400            mPriority |= LAYER_PRIORITY_PROTECTED;
401        } else if (PlaneCapabilities::isFormatSupported(DisplayPlane::PLANE_OVERLAY, this)) {
402            mPriority |= LAYER_PRIORITY_OVERLAY;
403        }
404        bm->unlockDataBuffer(buffer);
405    }
406}
407
408} // namespace intel
409} // namespace android
410