blob: c0bf38eded3b1ef740ca3e3771b174d77c468025
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 | // This file is modified by Amlogic, Inc. 2017.01.17. |
17 | */ |
18 | |
19 | #include <inttypes.h> |
20 | #include <HwcTrace.h> |
21 | #include <HwcLayer.h> |
22 | #include <Hwcomposer.h> |
23 | #include <IDisplayDevice.h> |
24 | #include <cutils/properties.h> |
25 | #include <sync/sync.h> |
26 | #include <AmVideo.h> |
27 | |
28 | |
29 | namespace android { |
30 | namespace amlogic { |
31 | |
32 | HwcLayer::HwcLayer(hwc2_display_t& dpy) |
33 | : mDisplayId(dpy), |
34 | mBlendMode(0), |
35 | mCompositionType(0), |
36 | mAcquireFence(-1), |
37 | mDataSpace(HAL_DATASPACE_UNKNOWN), |
38 | mPlaneAlpha(0.0f), |
39 | mTransform(0), |
40 | mZ(0), |
41 | mBufferHnd(NULL), |
42 | mInitialized(false) |
43 | { |
44 | // initial layer's state. |
45 | mColor.r = 0; |
46 | mColor.g = 0; |
47 | mColor.b = 0; |
48 | mColor.a = 0; |
49 | |
50 | mSourceCrop.left = 0.0f; |
51 | mSourceCrop.top = 0.0f; |
52 | mSourceCrop.right = 0.0f; |
53 | mSourceCrop.bottom = 0.0f; |
54 | |
55 | mDisplayFrame.left = 0; |
56 | mDisplayFrame.top = 0; |
57 | mDisplayFrame.right = 0; |
58 | mDisplayFrame.bottom = 0; |
59 | |
60 | mDamageRegion.numRects = 0; |
61 | mVisibleRegion.numRects = 0; |
62 | } |
63 | |
64 | HwcLayer::~HwcLayer() |
65 | { |
66 | |
67 | } |
68 | |
69 | bool HwcLayer::initialize() { |
70 | Mutex::Autolock _l(mLock); |
71 | |
72 | mInitialized = true; |
73 | return true; |
74 | } |
75 | |
76 | void HwcLayer::deinitialize() { |
77 | Mutex::Autolock _l(mLock); |
78 | |
79 | mInitialized = false; |
80 | } |
81 | |
82 | void HwcLayer::resetAcquireFence() { |
83 | Mutex::Autolock _l(mLock); |
84 | |
85 | HwcFenceControl::closeFd(mAcquireFence); |
86 | mAcquireFence = -1; |
87 | } |
88 | |
89 | bool HwcLayer::isCropped() { |
90 | bool rtn = true; |
91 | private_handle_t const* buffer = private_handle_t::dynamicCast(mBufferHnd); |
92 | |
93 | if (buffer && buffer->width && buffer->height) { |
94 | float widthCmp = (mSourceCrop.right - mSourceCrop.left) / buffer->width; |
95 | float heightCmp = (mSourceCrop.bottom - mSourceCrop.top) / buffer->height; |
96 | |
97 | if (Utils::abs(widthCmp - 1.0f) <= 0.01f |
98 | && Utils::abs(heightCmp - 1.0f) <= 0.01f) { |
99 | rtn = false; |
100 | } |
101 | } |
102 | |
103 | DTRACE("chkIsCropped %d", rtn); |
104 | return rtn; |
105 | } |
106 | |
107 | bool HwcLayer::isScaled() { |
108 | bool rtn = true; |
109 | float sourceWidth = mSourceCrop.right - mSourceCrop.left; |
110 | float sourceHeight = mSourceCrop.bottom - mSourceCrop.top; |
111 | int displayWidth = mDisplayFrame.right - mDisplayFrame.left; |
112 | int displayHeight = mDisplayFrame.bottom - mDisplayFrame.top; |
113 | |
114 | if (displayWidth > 0 && displayHeight > 0) { |
115 | float widthCmp = sourceWidth / displayWidth; |
116 | float heightCmp = sourceHeight / displayHeight; |
117 | |
118 | if (Utils::abs(widthCmp - 1.0f) <= 0.01f |
119 | && Utils::abs(heightCmp - 1.0f) <= 0.01f) { |
120 | rtn = false; |
121 | } |
122 | } |
123 | |
124 | DTRACE("chkIsScaled %d", rtn); |
125 | return rtn; |
126 | } |
127 | |
128 | bool HwcLayer::isOffset() { |
129 | bool rtn = false; |
130 | if (mDisplayFrame.left != 0 || mDisplayFrame.top != 0) |
131 | rtn = true; |
132 | |
133 | DTRACE("chkIsOffset %d", rtn); |
134 | return rtn; |
135 | } |
136 | |
137 | bool HwcLayer::isBlended() { |
138 | DTRACE("chkIsBlended %d", mBlendMode); |
139 | return mBlendMode != HWC2_BLEND_MODE_INVALID; |
140 | } |
141 | |
142 | bool HwcLayer::haveColor() { |
143 | DTRACE("[%d, %d, %d, %d]", mColor.r, mColor.g, mColor.b, mColor.a); |
144 | return !(0 == mColor.r && 0 == mColor.g && 0 == mColor.b && 0 == mColor.a); |
145 | } |
146 | |
147 | bool HwcLayer::havePlaneAlpha() { |
148 | DTRACE("mPlaneAlpha: %d", mPlaneAlpha); |
149 | return mPlaneAlpha > 0.0f && mPlaneAlpha < 1.0f; |
150 | } |
151 | |
152 | bool HwcLayer::haveDataspace() { |
153 | DTRACE("mDataSpace: %d", mDataSpace); |
154 | return mDataSpace != HAL_DATASPACE_UNKNOWN; |
155 | } |
156 | |
157 | void HwcLayer::reverseScaledFrame(const float& scaleX, const float& scaleY) { |
158 | if (mScaleReversed) |
159 | return; |
160 | |
161 | mDisplayFrame.left = mDisplayFrame.left * scaleX; |
162 | mDisplayFrame.top = mDisplayFrame.top * scaleY; |
163 | mDisplayFrame.right = mDisplayFrame.right * scaleX; |
164 | mDisplayFrame.bottom = mDisplayFrame.bottom * scaleY; |
165 | mScaleReversed = true; |
166 | } |
167 | |
168 | int32_t HwcLayer::setBuffer(buffer_handle_t buffer, int32_t acquireFence) { |
169 | Mutex::Autolock _l(mLock); |
170 | resetLayerBuffer(); |
171 | |
172 | // Bad parameter |
173 | if (!private_handle_t::dynamicCast(buffer)) { |
174 | DTRACE("Layer buffer is null! no need to update this layer."); |
175 | return HWC2_ERROR_BAD_PARAMETER; |
176 | } |
177 | |
178 | mBufferHnd = buffer; |
179 | mAcquireFence = acquireFence; |
180 | return HWC2_ERROR_NONE; |
181 | } |
182 | |
183 | int32_t HwcLayer::setSurfaceDamage(hwc_region_t damage) { |
184 | Mutex::Autolock _l(mLock); |
185 | |
186 | // TODO: still have some work to do here. |
187 | mDamageRegion = damage; |
188 | return HWC2_ERROR_NONE; |
189 | } |
190 | |
191 | // HWC2 Layer state functions |
192 | int32_t HwcLayer::setBlendMode(int32_t mode) { |
193 | Mutex::Autolock _l(mLock); |
194 | |
195 | // TODO: still have some work to do. |
196 | mBlendMode = mode; |
197 | return HWC2_ERROR_NONE; |
198 | } |
199 | |
200 | int32_t HwcLayer::setColor(hwc_color_t color) { |
201 | Mutex::Autolock _l(mLock); |
202 | |
203 | // TODO: still have some work to do. |
204 | mColor = color; |
205 | return HWC2_ERROR_NONE; |
206 | } |
207 | |
208 | int32_t HwcLayer::setCompositionType(int32_t type) { |
209 | // Mutex::Autolock _l(mLock); |
210 | |
211 | mCompositionType = type; |
212 | return HWC2_ERROR_NONE; |
213 | } |
214 | |
215 | int32_t HwcLayer::setDataspace(int32_t dataspace) { |
216 | Mutex::Autolock _l(mLock); |
217 | |
218 | // TODO: still have some work to do. |
219 | mDataSpace = dataspace; |
220 | return HWC2_ERROR_NONE; |
221 | } |
222 | |
223 | int32_t HwcLayer::setDisplayFrame(hwc_rect_t frame) { |
224 | Mutex::Autolock _l(mLock); |
225 | |
226 | // TODO: still have some work to do. |
227 | mDisplayFrame = frame; |
228 | mScaleReversed = false; |
229 | return HWC2_ERROR_NONE; |
230 | } |
231 | |
232 | int32_t HwcLayer::setPlaneAlpha(float alpha) { |
233 | Mutex::Autolock _l(mLock); |
234 | |
235 | // TODO: still have some work to do. |
236 | mPlaneAlpha = alpha; |
237 | return HWC2_ERROR_NONE; |
238 | } |
239 | |
240 | int32_t HwcLayer::setSidebandStream(const native_handle_t* stream) { |
241 | Mutex::Autolock _l(mLock); |
242 | resetLayerBuffer(); |
243 | |
244 | // Bad parameter. |
245 | if (NULL == stream) { |
246 | return HWC2_ERROR_BAD_PARAMETER; |
247 | } |
248 | mSidebandStream = stream; |
249 | return HWC2_ERROR_NONE; |
250 | } |
251 | |
252 | int32_t HwcLayer::setSourceCrop(hwc_frect_t crop) { |
253 | Mutex::Autolock _l(mLock); |
254 | |
255 | // TODO: still have some work to do. |
256 | mSourceCrop = crop; |
257 | return HWC2_ERROR_NONE; |
258 | } |
259 | |
260 | int32_t HwcLayer::setTransform(int32_t transform) { |
261 | Mutex::Autolock _l(mLock); |
262 | |
263 | mTransform = transform; |
264 | return HWC2_ERROR_NONE; |
265 | } |
266 | |
267 | int32_t HwcLayer::setVisibleRegion(hwc_region_t visible) { |
268 | Mutex::Autolock _l(mLock); |
269 | |
270 | // TODO: still have some work to do. |
271 | mVisibleRegion = visible; |
272 | return HWC2_ERROR_NONE; |
273 | } |
274 | |
275 | int32_t HwcLayer::setZ(uint32_t z) { |
276 | Mutex::Autolock _l(mLock); |
277 | |
278 | // TODO: still have some work to do. |
279 | mZ = z; |
280 | return HWC2_ERROR_NONE; |
281 | } |
282 | |
283 | void HwcLayer::resetLayerBuffer() { |
284 | mSidebandStream = NULL; |
285 | mBufferHnd = NULL; |
286 | HwcFenceControl::closeFd(mAcquireFence); |
287 | mAcquireFence = -1; |
288 | } |
289 | |
290 | #if WITH_LIBPLAYER_MODULE |
291 | void HwcLayer::presentOverlay(bool bPresent) { |
292 | int32_t angle = 0; |
293 | bool vpp_changed = false; |
294 | bool axis_changed = false; |
295 | bool mode_changed = false; |
296 | bool free_scale_changed = false; |
297 | bool window_axis_changed =false; |
298 | hwc_rect_t* displayframe = &mDisplayFrame; |
299 | |
300 | AmVideo::getInstance()->presentVideo(bPresent); |
301 | |
302 | if (Utils::checkBoolProp("ro.vout.dualdisplay4")) { |
303 | vpp_changed = Utils::checkSysfsStatus( |
304 | SYSFS_AMVIDEO_CURIDX, mLastVal, 32); |
305 | } |
306 | |
307 | mode_changed = Utils::checkSysfsStatus(SYSFS_DISPLAY_MODE, mLastMode, 32); |
308 | free_scale_changed = Utils::checkSysfsStatus(SYSFS_FB0_FREE_SCALE, mLastFreescale, 32); |
309 | axis_changed = Utils::checkSysfsStatus(SYSFS_VIDEO_AXIS, mLastAxis, 32); |
310 | window_axis_changed = Utils::checkSysfsStatus(SYSFS_WINDOW_AXIS, mLastWindowaxis, 50); |
311 | |
312 | if (mLastTransform == mTransform |
313 | && mLastDisplayFrame.left == displayframe->left |
314 | && mLastDisplayFrame.top == displayframe->top |
315 | && mLastDisplayFrame.right == displayframe->right |
316 | && mLastDisplayFrame.bottom== displayframe->bottom |
317 | && !vpp_changed && !mode_changed && !axis_changed |
318 | && !free_scale_changed && !window_axis_changed) { |
319 | return; |
320 | } |
321 | |
322 | switch (mTransform) { |
323 | case 0: |
324 | angle = 0; |
325 | break; |
326 | case HAL_TRANSFORM_ROT_90: |
327 | angle = 90; |
328 | break; |
329 | case HAL_TRANSFORM_ROT_180: |
330 | angle = 180; |
331 | break; |
332 | case HAL_TRANSFORM_ROT_270: |
333 | angle = 270; |
334 | break; |
335 | default: |
336 | return; |
337 | } |
338 | |
339 | amvideo_utils_set_virtual_position(displayframe->left, displayframe->top, |
340 | displayframe->right -displayframe->left, |
341 | displayframe->bottom - displayframe->top, |
342 | angle); |
343 | |
344 | /* the screen mode from Android framework should always be set to normal mode |
345 | * to match the relationship between the UI and video overlay window position. |
346 | */ |
347 | /*set screen_mode in amvideo_utils_set_virtual_position(),pls check in libplayer*/ |
348 | //amvideo_utils_set_screen_mode(0); |
349 | mLastTransform = mTransform; |
350 | mLastDisplayFrame.left = displayframe->left; |
351 | mLastDisplayFrame.top = displayframe->top; |
352 | mLastDisplayFrame.right = displayframe->right; |
353 | mLastDisplayFrame.bottom = displayframe->bottom; |
354 | |
355 | memset(mLastAxis, 0, sizeof(mLastAxis)); |
356 | if (Utils::getSysfsStr(SYSFS_VIDEO_AXIS, mLastAxis, sizeof(mLastAxis)) == 0) { |
357 | DTRACE("****last video axis is: %s", mLastAxis); |
358 | } |
359 | |
360 | } |
361 | #endif |
362 | |
363 | void HwcLayer::dump(Dump& d) { |
364 | Mutex::Autolock _l(mLock); |
365 | |
366 | static char const* compositionTypeName[] = { |
367 | "UNKNOWN", |
368 | "GLES", |
369 | "HWC", |
370 | "SOLID", |
371 | "HWC_CURSOR", |
372 | "SIDEBAND"}; |
373 | |
374 | d.append( |
375 | " %11s | %12" PRIxPTR " | %10d | %02x | %1.2f | %02x | %04x |%7.1f,%7.1f,%7.1f,%7.1f |%5d,%5d,%5d,%5d \n", |
376 | compositionTypeName[mCompositionType], intptr_t(mBufferHnd), |
377 | mZ, mDataSpace, mPlaneAlpha, mTransform, mBlendMode, |
378 | mSourceCrop.left, mSourceCrop.top, mSourceCrop.right, mSourceCrop.bottom, |
379 | mDisplayFrame.left, mDisplayFrame.top, mDisplayFrame.right, mDisplayFrame.bottom); |
380 | } |
381 | |
382 | |
383 | } // namespace amlogic |
384 | } // namespace android |
385 |