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