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