• 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 <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 
27 namespace android {
28 namespace intel {
29 
operator ==(const hwc_rect_t & x,const hwc_rect_t & y)30 inline 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 
operator !=(const hwc_rect_t & x,const hwc_rect_t & y)38 inline bool operator !=(const hwc_rect_t& x, const hwc_rect_t& y)
39 {
40     return !operator==(x, y);
41 }
42 
operator ==(const hwc_frect_t & x,const hwc_frect_t & y)43 inline 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 
operator !=(const hwc_frect_t & x,const hwc_frect_t & y)51 inline bool operator !=(const hwc_frect_t& x, const hwc_frect_t& y)
52 {
53     return !operator==(x, y);
54 }
55 
HwcLayer(int index,hwc_layer_1_t * layer)56 HwcLayer::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 
~HwcLayer()96 HwcLayer::~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 
attachPlane(DisplayPlane * plane,int device)110 bool 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 
detachPlane()129 DisplayPlane* 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 
setType(uint32_t type)140 void 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 
getType() const171 uint32_t HwcLayer::getType() const
172 {
173     return mType;
174 }
175 
setCompositionType(int32_t type)176 void HwcLayer::setCompositionType(int32_t type)
177 {
178     mLayer->compositionType = type;
179 }
180 
getCompositionType() const181 int32_t HwcLayer::getCompositionType() const
182 {
183     return mLayer->compositionType;
184 }
185 
getIndex() const186 int HwcLayer::getIndex() const
187 {
188     return mIndex;
189 }
190 
getZOrder() const191 int HwcLayer::getZOrder() const
192 {
193     return mZOrder;
194 }
195 
getFormat() const196 uint32_t HwcLayer::getFormat() const
197 {
198     return mFormat;
199 }
200 
getBufferWidth() const201 uint32_t HwcLayer::getBufferWidth() const
202 {
203     return mWidth;
204 }
205 
getBufferHeight() const206 uint32_t HwcLayer::getBufferHeight() const
207 {
208     return mHeight;
209 }
210 
getBufferStride() const211 const stride_t& HwcLayer::getBufferStride() const
212 {
213     return mStride;
214 }
215 
getUsage() const216 uint32_t HwcLayer::getUsage() const
217 {
218     return mUsage;
219 }
220 
getHandle() const221 buffer_handle_t HwcLayer::getHandle() const
222 {
223     return mHandle;
224 }
225 
getTransform() const226 uint32_t HwcLayer::getTransform() const
227 {
228     return mTransform;
229 }
230 
isProtected() const231 bool HwcLayer::isProtected() const
232 {
233     return mIsProtected;
234 }
235 
getLayer() const236 hwc_layer_1_t* HwcLayer::getLayer() const
237 {
238     return mLayer;
239 }
240 
getPlane() const241 DisplayPlane* HwcLayer::getPlane() const
242 {
243     return mPlane;
244 }
245 
setPriority(uint32_t priority)246 void HwcLayer::setPriority(uint32_t priority)
247 {
248     mPriority = priority;
249 }
250 
getPriority() const251 uint32_t HwcLayer::getPriority() const
252 {
253     return mPriority;
254 }
255 
update(hwc_layer_1_t * layer)256 bool 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 
isUpdated()317 bool HwcLayer::isUpdated()
318 {
319     return mUpdated;
320 }
321 
getStaticCount()322 uint32_t HwcLayer::getStaticCount()
323 {
324     return mStaticCount;
325 }
326 
postFlip()327 void 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 
setupAttributes()345 void 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