1 /*
2 * Copyright (C) 2012 The Android Open Source Project
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 "ExynosHWCHelper.h"
17
18 #include <android-base/properties.h>
19 #include <linux/videodev2.h>
20 #include <linux/videodev2_exynos_media.h>
21 #include <png.h>
22 #include <sync/sync.h>
23 #include <sys/mman.h>
24 #include <utils/CallStack.h>
25 #include <utils/Errors.h>
26
27 #include <iomanip>
28
29 #include "ExynosHWC.h"
30 #include "ExynosHWCDebug.h"
31 #include "ExynosLayer.h"
32 #include "ExynosResourceRestriction.h"
33 #include "VendorVideoAPI.h"
34 #include "exynos_sync.h"
35
36 using vendor::graphics::BufferUsage;
37 using vendor::graphics::VendorGraphicBufferUsage;
38 using vendor::graphics::VendorGraphicBufferMeta;
39 using namespace SOC_VERSION;
40
41 #define AFBC_MAGIC 0xafbc
42
43 #define FT_LOGD(msg, ...) \
44 {\
45 if (exynosHWCControl.fenceTracer >= 2) \
46 ALOGD("[FenceTracer]::" msg, ##__VA_ARGS__); \
47 }
48 #define FT_LOGE(msg, ...) \
49 {\
50 if (exynosHWCControl.fenceTracer > 0) \
51 ALOGE("[FenceTracer]::" msg, ##__VA_ARGS__); \
52 }
53 #define FT_LOGW(msg, ...) \
54 {\
55 if (exynosHWCControl.fenceTracer >= 1) \
56 ALOGD("[FenceTracer]::" msg, ##__VA_ARGS__); \
57 }
58
59 extern struct exynos_hwc_control exynosHWCControl;
60 extern char fence_names[FENCE_MAX][32];
61
getHWC1CompType(int32_t type)62 uint32_t getHWC1CompType(int32_t type) {
63
64 uint32_t cType = HWC_FRAMEBUFFER;
65
66 switch(type) {
67 case HWC2_COMPOSITION_DEVICE:
68 case HWC2_COMPOSITION_EXYNOS:
69 cType = HWC_OVERLAY;
70 break;
71 case HWC2_COMPOSITION_SOLID_COLOR:
72 cType = HWC_BACKGROUND;
73 break;
74 case HWC2_COMPOSITION_CURSOR:
75 cType = HWC_CURSOR_OVERLAY;
76 break;
77 case HWC2_COMPOSITION_SIDEBAND:
78 cType = HWC_SIDEBAND;
79 break;
80 case HWC2_COMPOSITION_CLIENT:
81 case HWC2_COMPOSITION_INVALID:
82 default:
83 cType = HWC_FRAMEBUFFER;
84 break;
85 }
86
87 return cType;
88 }
89
getDrmMode(uint64_t flags)90 uint32_t getDrmMode(uint64_t flags)
91 {
92 if (flags & BufferUsage::PROTECTED) {
93 if (flags & VendorGraphicBufferUsage::PRIVATE_NONSECURE)
94 return NORMAL_DRM;
95 else
96 return SECURE_DRM;
97 }
98 return NO_DRM;
99 }
100
getDrmMode(const buffer_handle_t handle)101 uint32_t getDrmMode(const buffer_handle_t handle)
102 {
103 uint64_t usage = VendorGraphicBufferMeta::get_usage(handle);
104 if (usage & BufferUsage::PROTECTED) {
105 if (usage & VendorGraphicBufferUsage::PRIVATE_NONSECURE)
106 return NORMAL_DRM;
107 else
108 return SECURE_DRM;
109 }
110
111 return NO_DRM;
112 }
113
isNarrowRgb(int format,android_dataspace data_space)114 unsigned int isNarrowRgb(int format, android_dataspace data_space)
115 {
116 if (format == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL)
117 return 0;
118 else {
119 if (isFormatRgb(format))
120 return 0;
121 else {
122 uint32_t data_space_range = (data_space & HAL_DATASPACE_RANGE_MASK);
123 if (data_space_range == HAL_DATASPACE_RANGE_UNSPECIFIED) {
124 return 1;
125 } else if (data_space_range == HAL_DATASPACE_RANGE_FULL) {
126 return 0;
127 } else {
128 return 1;
129 }
130 }
131 }
132 }
133
halFormatToExynosFormat(int inHalFormat,uint32_t inCompressType)134 const format_description_t* halFormatToExynosFormat(int inHalFormat, uint32_t inCompressType) {
135 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
136 const int descHalFormat = exynos_format_desc[i].halFormat;
137
138 if ((inHalFormat == descHalFormat) &&
139 exynos_format_desc[i].isCompressionSupported(inCompressType)) {
140 return &exynos_format_desc[i];
141 }
142 }
143 return nullptr;
144 }
145
formatToBpp(int format)146 uint8_t formatToBpp(int format)
147 {
148 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
149 if (exynos_format_desc[i].halFormat == format)
150 return exynos_format_desc[i].bpp;
151 }
152
153 ALOGW("unrecognized pixel format %u", format);
154 return 0;
155 }
156
DpuFormatToBpp(decon_pixel_format format)157 uint8_t DpuFormatToBpp(decon_pixel_format format)
158 {
159 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
160 if (exynos_format_desc[i].s3cFormat == format)
161 return exynos_format_desc[i].bpp;
162 }
163 ALOGW("unrecognized decon format %u", format);
164 return 0;
165 }
166
isFormatRgb(int format)167 bool isFormatRgb(int format)
168 {
169 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
170 if (exynos_format_desc[i].halFormat == format) {
171 if (exynos_format_desc[i].type & RGB)
172 return true;
173 else
174 return false;
175 }
176 }
177 return false;
178 }
179
isFormatYUV(int format)180 bool isFormatYUV(int format)
181 {
182 if (isFormatRgb(format))
183 return false;
184 return true;
185 }
186
isFormatSBWC(int format)187 bool isFormatSBWC(int format)
188 {
189 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
190 if (exynos_format_desc[i].halFormat == format) {
191 if (exynos_format_desc[i].type & COMP_TYPE_SBWC)
192 return true;
193 else
194 return false;
195 }
196 }
197 return false;
198 }
199
isFormatYUV420(int format)200 bool isFormatYUV420(int format)
201 {
202 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
203 if (exynos_format_desc[i].halFormat == format) {
204 if (exynos_format_desc[i].type & YUV420)
205 return true;
206 else
207 return false;
208 }
209 }
210 return false;
211 }
212
isFormatYUV8_2(int format)213 bool isFormatYUV8_2(int format)
214 {
215 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
216 if (exynos_format_desc[i].halFormat == format) {
217 if ((exynos_format_desc[i].type & YUV420) &&
218 (exynos_format_desc[i].type & BIT8_2))
219 return true;
220 else
221 return false;
222 }
223 }
224 return false;
225 }
226
isFormat10BitYUV420(int format)227 bool isFormat10BitYUV420(int format)
228 {
229 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
230 if (exynos_format_desc[i].halFormat == format) {
231 if ((exynos_format_desc[i].type & YUV420) &&
232 (exynos_format_desc[i].type & BIT10))
233 return true;
234 else
235 return false;
236 }
237 }
238 return false;
239 }
240
isFormatYUV422(int format)241 bool isFormatYUV422(int format)
242 {
243 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
244 if (exynos_format_desc[i].halFormat == format) {
245 if (exynos_format_desc[i].type & YUV422)
246 return true;
247 else
248 return false;
249 }
250 }
251 return false;
252 }
253
isFormatP010(int format)254 bool isFormatP010(int format)
255 {
256 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
257 if (exynos_format_desc[i].halFormat == format) {
258 if (exynos_format_desc[i].type & P010)
259 return true;
260 else
261 return false;
262 }
263 }
264 return false;
265 }
266
isFormat10Bit(int format)267 bool isFormat10Bit(int format) {
268 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
269 if (exynos_format_desc[i].halFormat == format) {
270 if ((exynos_format_desc[i].type & BIT_MASK) == BIT10)
271 return true;
272 else
273 return false;
274 }
275 }
276 return false;
277 }
278
isFormat8Bit(int format)279 bool isFormat8Bit(int format) {
280 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
281 if (exynos_format_desc[i].halFormat == format) {
282 if ((exynos_format_desc[i].type & BIT_MASK) == BIT8)
283 return true;
284 else
285 return false;
286 }
287 }
288 return false;
289 }
290
isFormatYCrCb(int format)291 bool isFormatYCrCb(int format)
292 {
293 return format == HAL_PIXEL_FORMAT_EXYNOS_YV12_M;
294 }
295
isFormatLossy(int format)296 bool isFormatLossy(int format)
297 {
298 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
299 if (exynos_format_desc[i].halFormat == format) {
300 uint32_t sbwcType = exynos_format_desc[i].type & FORMAT_SBWC_MASK;
301 if (sbwcType && sbwcType != SBWC_LOSSLESS)
302 return true;
303 else
304 return false;
305 }
306 }
307 return false;
308 }
309
formatHasAlphaChannel(int format)310 bool formatHasAlphaChannel(int format)
311 {
312 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
313 if (exynos_format_desc[i].halFormat == format) {
314 return exynos_format_desc[i].hasAlpha;
315 }
316 }
317 return false;
318 }
319
isAFBCCompressed(const buffer_handle_t handle)320 bool isAFBCCompressed(const buffer_handle_t handle) {
321 if (handle != NULL) {
322 return VendorGraphicBufferMeta::is_afbc(handle);
323 }
324
325 return false;
326 }
327
isSBWCCompressed(const buffer_handle_t handle)328 bool isSBWCCompressed(const buffer_handle_t handle) {
329 if (handle != NULL) {
330 return VendorGraphicBufferMeta::is_sbwc(handle);
331 }
332
333 return false;
334 }
335
getFormat(const buffer_handle_t handle)336 uint32_t getFormat(const buffer_handle_t handle) {
337 if (handle != NULL) {
338 return VendorGraphicBufferMeta::get_format(handle);
339 }
340
341 return 0;
342 }
343
getFormatModifier(const buffer_handle_t handle)344 uint64_t getFormatModifier(const buffer_handle_t handle) {
345 if (handle != NULL) {
346 return VendorGraphicBufferMeta::get_format_modifier(handle);
347 }
348
349 return 0;
350 }
351
getCompressionType(const buffer_handle_t handle)352 uint32_t getCompressionType(const buffer_handle_t handle) {
353 if (handle == NULL) return COMP_TYPE_NONE;
354
355 if (isAFBCCompressed(handle)) {
356 return COMP_TYPE_AFBC;
357 } else if (isSBWCCompressed(handle)) {
358 return COMP_TYPE_SBWC;
359 }
360
361 return COMP_TYPE_NONE;
362 }
363
getCompressionInfo(buffer_handle_t handle)364 CompressionInfo getCompressionInfo(buffer_handle_t handle) {
365 CompressionInfo compressionInfo = {COMP_TYPE_NONE, 0};
366
367 if (handle == NULL) return compressionInfo;
368
369 if (isAFBCCompressed(handle)) {
370 compressionInfo.type = COMP_TYPE_AFBC;
371 compressionInfo.modifier = getFormatModifier(handle);
372 } else if (isSBWCCompressed(handle)) {
373 compressionInfo.type = COMP_TYPE_SBWC;
374
375 uint32_t format = getFormat(handle);
376 if (isFormat10BitYUV420(format))
377 compressionInfo.modifier = SBWC_FORMAT_MOD_BLOCK_SIZE_32x5;
378 else
379 compressionInfo.modifier = SBWC_FORMAT_MOD_BLOCK_SIZE_32x4;
380 } else {
381 compressionInfo.type = COMP_TYPE_NONE;
382 }
383
384 return compressionInfo;
385 }
386
getCompressionStr(CompressionInfo compression)387 String8 getCompressionStr(CompressionInfo compression) {
388 String8 result;
389 if (compression.type == COMP_TYPE_NONE)
390 result.append("None");
391 else if (compression.type == COMP_TYPE_AFBC)
392 result.appendFormat("AFBC(mod:0x%" PRIx64 ")", compression.modifier);
393 else if (compression.type == COMP_TYPE_SBWC)
394 result.appendFormat("SBWC(mod:0x%" PRIx64 ")", compression.modifier);
395 else
396 result.append("Unknown");
397 return result;
398 }
399
isAFBC32x8(CompressionInfo compression)400 bool isAFBC32x8(CompressionInfo compression) {
401 return (compression.type == COMP_TYPE_AFBC) &&
402 ((compression.modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) ==
403 AFBC_FORMAT_MOD_BLOCK_SIZE_32x8);
404 }
405
halDataSpaceToV4L2ColorSpace(android_dataspace data_space)406 uint32_t halDataSpaceToV4L2ColorSpace(android_dataspace data_space)
407 {
408 uint32_t standard_data_space = (data_space & HAL_DATASPACE_STANDARD_MASK);
409 switch (standard_data_space) {
410 case HAL_DATASPACE_STANDARD_BT2020:
411 case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
412 return V4L2_COLORSPACE_BT2020;
413 case HAL_DATASPACE_STANDARD_DCI_P3:
414 return V4L2_COLORSPACE_DCI_P3;
415 case HAL_DATASPACE_STANDARD_BT709:
416 return V4L2_COLORSPACE_REC709;
417 default:
418 return V4L2_COLORSPACE_DEFAULT;
419 }
420 return V4L2_COLORSPACE_DEFAULT;
421 }
422
halFormatToDpuFormat(int format,uint32_t compressType)423 enum decon_pixel_format halFormatToDpuFormat(int format, uint32_t compressType) {
424 auto exynosFormat = halFormatToExynosFormat(format, compressType);
425 return (exynosFormat != nullptr) ? exynosFormat->s3cFormat : DECON_PIXEL_FORMAT_MAX;
426 }
427
DpuFormatToHalFormat(int format,uint32_t)428 uint32_t DpuFormatToHalFormat(int format, uint32_t /*compressType*/) {
429 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
430 if (exynos_format_desc[i].s3cFormat == static_cast<decon_pixel_format>(format))
431 return exynos_format_desc[i].halFormat;
432 }
433 return HAL_PIXEL_FORMAT_EXYNOS_UNDEFINED;
434 }
435
halFormatToDrmFormat(int format,uint32_t compressType)436 int halFormatToDrmFormat(int format, uint32_t compressType)
437 {
438 auto exynosFormat = halFormatToExynosFormat(format, compressType);
439 return (exynosFormat != nullptr) ? exynosFormat->drmFormat : DRM_FORMAT_UNDEFINED;
440 }
441
drmFormatToHalFormats(int format,std::vector<uint32_t> * halFormats)442 int32_t drmFormatToHalFormats(int format, std::vector<uint32_t> *halFormats)
443 {
444 if (halFormats == NULL)
445 return -EINVAL;
446
447 halFormats->clear();
448 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
449 if (exynos_format_desc[i].drmFormat == format) {
450 halFormats->push_back(exynos_format_desc[i].halFormat);
451 }
452 }
453 return NO_ERROR;
454 }
455
drmFormatToHalFormat(int format)456 int drmFormatToHalFormat(int format)
457 {
458 for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
459 if (exynos_format_desc[i].drmFormat == format)
460 return exynos_format_desc[i].halFormat;
461 }
462 return HAL_PIXEL_FORMAT_EXYNOS_UNDEFINED;
463 }
464
colorModeToDataspace(android_color_mode_t mode)465 android_dataspace colorModeToDataspace(android_color_mode_t mode)
466 {
467 android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
468 switch (mode) {
469 case HAL_COLOR_MODE_STANDARD_BT601_625:
470 dataSpace = HAL_DATASPACE_STANDARD_BT601_625;
471 break;
472 case HAL_COLOR_MODE_STANDARD_BT601_625_UNADJUSTED:
473 dataSpace = HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED;
474 break;
475 case HAL_COLOR_MODE_STANDARD_BT601_525:
476 dataSpace = HAL_DATASPACE_STANDARD_BT601_525;
477 break;
478 case HAL_COLOR_MODE_STANDARD_BT601_525_UNADJUSTED:
479 dataSpace = HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED;
480 break;
481 case HAL_COLOR_MODE_STANDARD_BT709:
482 dataSpace = HAL_DATASPACE_STANDARD_BT709;
483 break;
484 case HAL_COLOR_MODE_DCI_P3:
485 dataSpace = HAL_DATASPACE_DCI_P3;
486 break;
487 case HAL_COLOR_MODE_ADOBE_RGB:
488 dataSpace = HAL_DATASPACE_ADOBE_RGB;
489 break;
490 case HAL_COLOR_MODE_DISPLAY_P3:
491 dataSpace = HAL_DATASPACE_DISPLAY_P3;
492 break;
493 case HAL_COLOR_MODE_SRGB:
494 dataSpace = HAL_DATASPACE_V0_SRGB;
495 break;
496 case HAL_COLOR_MODE_NATIVE:
497 dataSpace = HAL_DATASPACE_UNKNOWN;
498 break;
499 default:
500 break;
501 }
502 return dataSpace;
503 }
504
halTransformToDrmRot(uint32_t halTransform)505 uint64_t halTransformToDrmRot(uint32_t halTransform)
506 {
507 switch (halTransform) {
508 case HAL_TRANSFORM_FLIP_H:
509 return DRM_MODE_REFLECT_Y|DRM_MODE_ROTATE_0;
510 case HAL_TRANSFORM_FLIP_V:
511 return DRM_MODE_REFLECT_X|DRM_MODE_ROTATE_0;
512 case HAL_TRANSFORM_ROT_180:
513 return DRM_MODE_ROTATE_180;
514 case HAL_TRANSFORM_ROT_90:
515 return DRM_MODE_ROTATE_90;
516 case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
517 /*
518 * HAL: HAL_TRANSFORM_FLIP_H -> HAL_TRANSFORM_ROT_90
519 * DPP: ROT_90 -> XFLIP
520 */
521 return (DRM_MODE_ROTATE_90|DRM_MODE_REFLECT_X);
522 case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V):
523 /*
524 * HAL: HAL_TRANSFORM_FLIP_V -> HAL_TRANSFORM_ROT_90
525 * DPP: ROT_90 -> YFLIP
526 */
527 return (DRM_MODE_ROTATE_90|DRM_MODE_REFLECT_Y);
528 case HAL_TRANSFORM_ROT_270:
529 return DRM_MODE_ROTATE_270;
530 default:
531 return DRM_MODE_ROTATE_0;
532 }
533 }
534
dumpHandle(uint32_t type,buffer_handle_t h)535 void dumpHandle(uint32_t type, buffer_handle_t h)
536 {
537 if (h == NULL)
538 return;
539
540 VendorGraphicBufferMeta gmeta(h);
541
542 HDEBUGLOGD(type, "\t\tformat = %d, width = %u, height = %u, stride = %u, vstride = %u",
543 gmeta.format, gmeta.width, gmeta.height, gmeta.stride, gmeta.vstride);
544 }
545
dumpExynosImage(uint32_t type,exynos_image & img)546 void dumpExynosImage(uint32_t type, exynos_image &img)
547 {
548 if (!hwcCheckDebugMessages(type))
549 return;
550
551 String8 result;
552 dumpExynosImage(result, img);
553
554 ALOGD("%s", result.string());
555 }
556
dumpExynosImage(String8 & result,exynos_image & img)557 void dumpExynosImage(String8& result, exynos_image &img)
558 {
559 result.appendFormat("\tbufferHandle: %p, fullWidth: %d, fullHeight: %d, x: %d, y: %d, w: %d, "
560 "h: %d, format: %s\n",
561 img.bufferHandle, img.fullWidth, img.fullHeight, img.x, img.y, img.w, img.h,
562 getFormatStr(img.format, img.compressionInfo.type).string());
563 result.appendFormat("\tusageFlags: 0x%" PRIx64 ", layerFlags: 0x%8x, acquireFenceFd: %d, releaseFenceFd: %d\n",
564 img.usageFlags, img.layerFlags, img.acquireFenceFd, img.releaseFenceFd);
565 result.appendFormat("\tdataSpace(%d), blending(%d), transform(0x%2x), compression: %s\n",
566 img.dataSpace, img.blending, img.transform,
567 getCompressionStr(img.compressionInfo).string());
568 if (img.bufferHandle != NULL) {
569 VendorGraphicBufferMeta gmeta(img.bufferHandle);
570 result.appendFormat("\tbuffer's stride: %d, %d\n", gmeta.stride, gmeta.vstride);
571 }
572 }
573
printExynosLayer(const ExynosLayer * layer)574 void printExynosLayer(const ExynosLayer* layer) {
575 if (layer == nullptr) {
576 return;
577 }
578
579 const_cast<ExynosLayer*>(layer)->printLayer();
580 }
581
isSrcCropFloat(hwc_frect & frect)582 bool isSrcCropFloat(hwc_frect &frect)
583 {
584 return (frect.left != (int)frect.left) ||
585 (frect.top != (int)frect.top) ||
586 (frect.right != (int)frect.right) ||
587 (frect.bottom != (int)frect.bottom);
588 }
589
isScaled(exynos_image & src,exynos_image & dst)590 bool isScaled(exynos_image &src, exynos_image &dst)
591 {
592 uint32_t srcW = src.w;
593 uint32_t srcH = src.h;
594 uint32_t dstW = dst.w;
595 uint32_t dstH = dst.h;
596
597 if (!!(src.transform & HAL_TRANSFORM_ROT_90)) {
598 dstW = dst.h;
599 dstH = dst.w;
600 }
601
602 return ((srcW != dstW) || (srcH != dstH));
603 }
604
isScaledDown(exynos_image & src,exynos_image & dst)605 bool isScaledDown(exynos_image &src, exynos_image &dst)
606 {
607 uint32_t srcW = src.w;
608 uint32_t srcH = src.h;
609 uint32_t dstW = dst.w;
610 uint32_t dstH = dst.h;
611
612 if (!!(src.transform & HAL_TRANSFORM_ROT_90)) {
613 dstW = dst.h;
614 dstH = dst.w;
615 }
616
617 return ((srcW > dstW) || (srcH > dstH));
618 }
619
hasHdrInfo(const exynos_image & img)620 bool hasHdrInfo(const exynos_image& img) {
621 uint32_t dataSpace = img.dataSpace;
622
623 /* By reference Layer's dataspace */
624 uint32_t standard = (dataSpace & HAL_DATASPACE_STANDARD_MASK);
625 uint32_t transfer = (dataSpace & HAL_DATASPACE_TRANSFER_MASK);
626
627 if ((standard == HAL_DATASPACE_STANDARD_BT2020) ||
628 (standard == HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE) ||
629 (standard == HAL_DATASPACE_STANDARD_DCI_P3)) {
630 if ((transfer == HAL_DATASPACE_TRANSFER_ST2084) ||
631 (transfer == HAL_DATASPACE_TRANSFER_HLG))
632 return true;
633 else
634 return false;
635 }
636
637 return false;
638 }
639
hasHdrInfo(android_dataspace dataSpace)640 bool hasHdrInfo(android_dataspace dataSpace) {
641 exynos_image img;
642 img.dataSpace = dataSpace;
643 return hasHdrInfo(img);
644 }
645
hasHdr10Plus(exynos_image & img)646 bool hasHdr10Plus(exynos_image &img) {
647 /* TODO Check layer has hdr10 and dynamic metadata here */
648 return (img.metaType & VIDEO_INFO_TYPE_HDR_DYNAMIC) ? true : false;
649 }
650
getFormatStr(int format,uint32_t compressType)651 String8 getFormatStr(int format, uint32_t compressType) {
652 auto exynosFormat = halFormatToExynosFormat(format, compressType);
653
654 if (exynosFormat != nullptr) {
655 return exynosFormat->name;
656 }
657
658 String8 result;
659 result.appendFormat("? %08x", format);
660 return result;
661 }
662
adjustRect(hwc_rect_t & rect,int32_t width,int32_t height)663 void adjustRect(hwc_rect_t &rect, int32_t width, int32_t height)
664 {
665 if (rect.left < 0)
666 rect.left = 0;
667 if (rect.left > width)
668 rect.left = width;
669 if (rect.top < 0)
670 rect.top = 0;
671 if (rect.top > height)
672 rect.top = height;
673 if (rect.right < rect.left)
674 rect.right = rect.left;
675 if (rect.right > width)
676 rect.right = width;
677 if (rect.bottom < rect.top)
678 rect.bottom = rect.top;
679 if (rect.bottom > height)
680 rect.bottom = height;
681 }
682
getBufferNumOfFormat(int format,uint32_t compressType)683 uint32_t getBufferNumOfFormat(int format, uint32_t compressType) {
684 auto exynosFormat = halFormatToExynosFormat(format, compressType);
685 return (exynosFormat != nullptr) ? exynosFormat->bufferNum : 0;
686 }
687
getPlaneNumOfFormat(int format,uint32_t compressType)688 uint32_t getPlaneNumOfFormat(int format, uint32_t compressType) {
689 auto exynosFormat = halFormatToExynosFormat(format, compressType);
690 return (exynosFormat != nullptr) ? exynosFormat->planeNum : 0;
691 }
692
getBytePerPixelOfPrimaryPlane(int format)693 uint32_t getBytePerPixelOfPrimaryPlane(int format) {
694 if (isFormatRgb(format))
695 return (formatToBpp(format) / 8);
696 else if (isFormat10BitYUV420(format))
697 return 2;
698 else if (isFormatYUV420(format))
699 return 1;
700 else
701 return 0;
702 }
703
setFenceName(int fenceFd,HwcFenceType fenceType)704 void setFenceName(int fenceFd, HwcFenceType fenceType) {
705 if (fenceFd >= 3)
706 ioctl(fenceFd, SYNC_IOC_FENCE_NAME, fence_names[fenceType]);
707 else if (fenceFd == -1) {
708 HDEBUGLOGD(eDebugFence, "%s : fence (type %d) is -1", __func__, (int)fenceType);
709 }
710 else {
711 ALOGW("%s : fence (type %d) is less than 3", __func__, (int)fenceType);
712 hwc_print_stack();
713 }
714 }
715
716 // TODO(b/273890355): remove this function and get buffer size from gralloc
getExynosBufferYLength(uint32_t width,uint32_t height,int format)717 uint32_t getExynosBufferYLength(uint32_t width, uint32_t height, int format)
718 {
719 switch (format) {
720 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
721 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
722 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
723 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
724 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
725 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
726 return NV12M_Y_SIZE(width, height);
727 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
728 HDEBUGLOGD(eDebugMPP, "8bit size(Y) : %d, extra size : %d", NV12M_Y_SIZE(width, height), NV12M_Y_2B_SIZE(width, height));
729 return NV12M_Y_SIZE(width, height) + NV12M_Y_2B_SIZE(width, height);
730 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
731 return NV12N_10B_Y_8B_SIZE(width, height) + NV12N_10B_Y_2B_SIZE(width, height);
732 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
733 HDEBUGLOGD(eDebugMPP, "size(Y) : %d", P010M_Y_SIZE(width, height));
734 return P010M_Y_SIZE(width, height);
735 case HAL_PIXEL_FORMAT_YCBCR_P010:
736 HDEBUGLOGD(eDebugMPP, "size(Y) : %d", P010_Y_SIZE(width, height));
737 return P010_Y_SIZE(width, height);
738 case MALI_GRALLOC_FORMAT_INTERNAL_P010:
739 return 2 * __ALIGN_UP(width, 32) * __ALIGN_UP(height, 2);
740 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
741 return NV12N_Y_SIZE(width, height);
742 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN:
743 return 2 * __ALIGN_UP(width, 64) * __ALIGN_UP(height, 16);
744 case HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B:
745 return 2 * __ALIGN_UP(width, 64) * __ALIGN_UP(height, 16);
746 case HAL_PIXEL_FORMAT_GOOGLE_NV12_SP:
747 return __ALIGN_UP(width, 64) * __ALIGN_UP(height, 16);
748 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
749 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
750 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
751 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
752 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
753 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
754 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
755 return SBWC_8B_Y_SIZE(width, height) +
756 SBWC_8B_Y_HEADER_SIZE(width, height);
757 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
758 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
759 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
760 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
761 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
762 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
763 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
764 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
765 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
766 return SBWC_10B_Y_SIZE(width, height) +
767 SBWC_10B_Y_HEADER_SIZE(width, height);
768 case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
769 return __ALIGN_UP(width, 64) * __ALIGN_UP(height, 2);
770 }
771
772 return NV12M_Y_SIZE(width, height) + ((width % 128) == 0 ? 0 : 256);
773 }
774
775 // TODO(b/273890355): no one is using this function. It can be removed.
getExynosBufferCbCrLength(uint32_t width,uint32_t height,int format)776 uint32_t getExynosBufferCbCrLength(uint32_t width, uint32_t height, int format)
777 {
778 switch (format) {
779 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
780 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
781 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
782 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
783 case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
784 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
785 return NV12M_CBCR_SIZE(width, height);
786 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
787 HDEBUGLOGD(eDebugMPP, "8bit size(CbCr) : %d, extra size : %d",NV12M_CBCR_SIZE(width, height), NV12M_CBCR_2B_SIZE(width, height));
788 return NV12M_CBCR_SIZE(width, height) + NV12M_CBCR_2B_SIZE(width, height);
789 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
790 HDEBUGLOGD(eDebugMPP, "size(CbCr) : %d", P010M_CBCR_SIZE(width, height));
791 return P010M_CBCR_SIZE(width, height);
792 case HAL_PIXEL_FORMAT_YCBCR_P010:
793 HDEBUGLOGD(eDebugMPP, "size(CbCr) : %d", P010_CBCR_SIZE(width, height));
794 return P010_CBCR_SIZE(width, height);
795 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_SPN:
796 return __ALIGN_UP(width, 64) * __ALIGN_UP(height, 16);
797 case HAL_PIXEL_FORMAT_GOOGLE_NV12_SP_10B:
798 return __ALIGN_UP(width, 64) * __ALIGN_UP(height, 16);
799 case HAL_PIXEL_FORMAT_GOOGLE_NV12_SP:
800 return __ALIGN_UP(width, 64) * __ALIGN_UP(height, 16) / 2;
801 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC:
802 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L50:
803 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_SBWC_L75:
804 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC:
805 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L50:
806 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_SBWC_L75:
807 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_SBWC:
808 return SBWC_8B_CBCR_SIZE(width, height) +
809 SBWC_8B_CBCR_HEADER_SIZE(width, height);
810 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC:
811 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L40:
812 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L60:
813 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_10B_SBWC_L80:
814 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC:
815 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L40:
816 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L60:
817 case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_10B_SBWC_L80:
818 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_10B_SBWC:
819 return SBWC_10B_CBCR_SIZE(width, height) +
820 SBWC_10B_CBCR_HEADER_SIZE(width, height);
821 }
822
823 return NV12M_CBCR_SIZE(width, height);
824 }
825
getBufLength(buffer_handle_t handle,uint32_t planerNum,size_t * length,int format,uint32_t width,uint32_t height)826 int getBufLength(buffer_handle_t handle, uint32_t planerNum, size_t *length, int format, uint32_t width, uint32_t height)
827 {
828 uint32_t bufferNumber = getBufferNumOfFormat(format, getCompressionType(handle));
829 if ((bufferNumber == 0) || (bufferNumber > planerNum))
830 return -EINVAL;
831
832 VendorGraphicBufferMeta gmeta(handle);
833
834 switch (bufferNumber) {
835 case 1:
836 length[0] = gmeta.size;
837 break;
838 case 2:
839 HDEBUGLOGD(eDebugMPP, "-- %s x : %d y : %d format : %d",__func__, width, height, format);
840 length[0] = gmeta.size;
841 length[1] = gmeta.size1;
842 HDEBUGLOGD(eDebugMPP, "Y size : %zu CbCr size : %zu", length[0], length[1]);
843 break;
844 case 3:
845 length[0] = width * height;
846 length[1]= (length[0]/4);
847 length[2]= (length[0]/4);
848 break;
849 }
850 return NO_ERROR;
851 }
852
fence_close(int fence,ExynosDisplay * display,HwcFdebugFenceType type,HwcFdebugIpType ip)853 int fence_close(int fence, ExynosDisplay* display, HwcFdebugFenceType type, HwcFdebugIpType ip) {
854 if (display != NULL) setFenceInfo(fence, display, type, ip, HwcFenceDirection::CLOSE);
855 return hwcFdClose(fence);
856 }
857
fence_valid(int fence)858 bool fence_valid(int fence) {
859 if (fence == -1){
860 HDEBUGLOGD(eDebugFence, "%s : fence is -1", __func__);
861 return false;
862 } else if (fence < 3) {
863 ALOGW("%s : fence (fd:%d) is less than 3", __func__, fence);
864 hwc_print_stack();
865 return true;
866 }
867 return true;
868 }
869
hwcFdClose(int fd)870 int hwcFdClose(int fd) {
871 if (fd>= 3)
872 close(fd);
873 else if (fd == -1){
874 HDEBUGLOGD(eDebugFence, "%s : Fd is -1", __func__);
875 } else {
876 ALOGW("%s : Fd:%d is less than 3", __func__, fd);
877 hwc_print_stack();
878 }
879 return -1;
880 }
881
hwc_dup(int fd,ExynosDisplay * display,HwcFdebugFenceType type,HwcFdebugIpType ip,bool pendingAllowed)882 int hwc_dup(int fd, ExynosDisplay* display, HwcFdebugFenceType type, HwcFdebugIpType ip,
883 bool pendingAllowed) {
884 int dup_fd = -1;
885
886 if (fd>= 3)
887 dup_fd = dup(fd);
888 else if (fd == -1){
889 HDEBUGLOGD(eDebugFence, "%s : Fd is -1", __func__);
890 } else {
891 ALOGW("%s : Fd:%d is less than 3", __func__, fd);
892 hwc_print_stack();
893 }
894
895 if ((dup_fd < 3) && (dup_fd != -1)) {
896 ALOGW("%s : Dupulicated Fd:%d is less than 3 : %d", __func__, fd, dup_fd);
897 hwc_print_stack();
898 }
899
900 setFenceInfo(dup_fd, display, type, ip, HwcFenceDirection::DUP, pendingAllowed, fd);
901 FT_LOGD("duplicated %d from %d", dup_fd, fd);
902
903 return dup_fd;
904 }
905
hwc_print_stack()906 int hwc_print_stack() {
907 /* CallStack stack; */
908 /* stack.update(); */
909 /* stack.log("HWCException", ANDROID_LOG_ERROR, "HWCException"); */
910 return 0;
911 }
912
getLocalTimeStr(struct timeval tv)913 String8 getLocalTimeStr(struct timeval tv) {
914 struct tm* localTime = (struct tm*)localtime((time_t*)&tv.tv_sec);
915 return String8::format("%02d-%02d %02d:%02d:%02d.%03lu(%lu)", localTime->tm_mon + 1,
916 localTime->tm_mday, localTime->tm_hour, localTime->tm_min,
917 localTime->tm_sec, tv.tv_usec / 1000,
918 ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)));
919 }
920
setFenceInfo(uint32_t fd,const ExynosDisplay * display,HwcFdebugFenceType type,HwcFdebugIpType ip,HwcFenceDirection direction,bool pendingAllowed,int32_t dupFrom)921 void setFenceInfo(uint32_t fd, const ExynosDisplay *display, HwcFdebugFenceType type,
922 HwcFdebugIpType ip, HwcFenceDirection direction, bool pendingAllowed,
923 int32_t dupFrom) {
924 if (!fence_valid(fd) || display == NULL) return;
925
926 ExynosDevice* device = display->mDevice;
927 device->mFenceTracker.updateFenceInfo(fd, display, type, ip, direction, pendingAllowed,
928 dupFrom);
929 }
930
updateFenceInfo(uint32_t fd,const ExynosDisplay * display,HwcFdebugFenceType type,HwcFdebugIpType ip,HwcFenceDirection direction,bool pendingAllowed,int32_t dupFrom)931 void FenceTracker::updateFenceInfo(uint32_t fd, const ExynosDisplay *display,
932 HwcFdebugFenceType type, HwcFdebugIpType ip,
933 HwcFenceDirection direction, bool pendingAllowed,
934 int32_t dupFrom) {
935 std::scoped_lock lock(mFenceMutex);
936 HwcFenceInfo &info = mFenceInfos[fd];
937 info.displayId = display->mDisplayId;
938
939 if (info.leaking) {
940 return;
941 }
942
943 switch (direction) {
944 case HwcFenceDirection::FROM:
945 info.usage++;
946 break;
947 case HwcFenceDirection::TO:
948 info.usage--;
949 break;
950 case HwcFenceDirection::DUP:
951 info.usage++;
952 info.dupFrom = dupFrom;
953 break;
954 case HwcFenceDirection::CLOSE:
955 info.usage--;
956 if (info.usage < 0) info.usage = 0;
957 break;
958 case HwcFenceDirection::UPDATE:
959 break;
960 default:
961 ALOGE("Fence trace : Undefined direction!");
962 break;
963 }
964
965 if (info.usage == 0) {
966 mFenceInfos.erase(fd);
967 return;
968 } else if (info.usage < 0) {
969 ALOGE("%s : Invalid negative usage (%d) for Fence FD:%d", __func__, info.usage, fd);
970 printLastFenceInfoLocked(fd);
971 }
972
973 HwcFenceTrace trace = {.direction = direction, .type = type, .ip = ip, .time = {0, 0}};
974
975 gettimeofday(&trace.time, NULL);
976
977 info.traces.push_back(trace);
978
979 FT_LOGW("FD : %d, direction : %d, type : %d, ip : %d", fd, direction, type, ip);
980
981 // Fence's usage count shuld be zero at end of frame(present done).
982 // This flag means usage count of the fence can be pended over frame.
983 info.pendingAllowed = pendingAllowed;
984 }
985
printLastFenceInfoLocked(uint32_t fd)986 void FenceTracker::printLastFenceInfoLocked(uint32_t fd) {
987 if (!fence_valid(fd)) return;
988
989 auto it = mFenceInfos.find(fd);
990 if (it == mFenceInfos.end()) return;
991 HwcFenceInfo &info = it->second;
992 FT_LOGD("---- Fence FD : %d, Display(%d) ----", fd, info.displayId);
993 FT_LOGD("usage: %d, dupFrom: %d, pendingAllowed: %d, leaking: %d", info.usage, info.dupFrom,
994 info.pendingAllowed, info.leaking);
995
996 for (const auto &trace : info.traces) {
997 FT_LOGD("> dir: %d, type: %d, ip: %d, time:%s", trace.direction, trace.type, trace.ip,
998 getLocalTimeStr(trace.time).string());
999 }
1000 }
1001
dumpFenceInfoLocked(int32_t count)1002 void FenceTracker::dumpFenceInfoLocked(int32_t count) {
1003 FT_LOGD("Dump fence (up to %d fences) ++", count);
1004 for (const auto &[fd, info] : mFenceInfos) {
1005 if (info.pendingAllowed) continue;
1006 if (count-- <= 0) break;
1007 printLastFenceInfoLocked(fd);
1008 }
1009 FT_LOGD("Dump fence --");
1010 }
1011
printLeakFdsLocked()1012 void FenceTracker::printLeakFdsLocked() {
1013 auto reportLeakFdsLocked = [&fenceInfos = mFenceInfos](int sign) REQUIRES(mFenceMutex) {
1014 String8 errString;
1015 errString.appendFormat("Leak Fds (%d) :\n", sign);
1016
1017 int cnt = 0;
1018 for (const auto &[fd, info] : fenceInfos) {
1019 if (!info.leaking) continue;
1020 if (info.usage * sign > 0) {
1021 errString.appendFormat("%d,", fd);
1022 if ((++cnt % 10) == 0) {
1023 errString.append("\n");
1024 }
1025 }
1026 }
1027
1028 FT_LOGW("%s", errString.string());
1029 };
1030
1031 reportLeakFdsLocked(+1);
1032 reportLeakFdsLocked(-1);
1033 }
1034
dumpNCheckLeakLocked()1035 void FenceTracker::dumpNCheckLeakLocked() {
1036 FT_LOGD("Dump leaking fence ++");
1037 for (auto &[fd, info] : mFenceInfos) {
1038 if (!info.pendingAllowed) {
1039 // leak is occurred in this frame first
1040 if (!info.leaking) {
1041 info.leaking = true;
1042 printLastFenceInfoLocked(fd);
1043 }
1044 }
1045 }
1046
1047 int priv = exynosHWCControl.fenceTracer;
1048 exynosHWCControl.fenceTracer = 3;
1049 printLeakFdsLocked();
1050 exynosHWCControl.fenceTracer = priv;
1051
1052 FT_LOGD("Dump leaking fence --");
1053 }
1054
fenceWarnLocked(uint32_t threshold)1055 bool FenceTracker::fenceWarnLocked(uint32_t threshold) {
1056 uint32_t cnt = mFenceInfos.size();
1057
1058 if (cnt > threshold) {
1059 ALOGE("Fence leak! -- the number of fences(%d) exceeds threshold(%d)", cnt, threshold);
1060 int priv = exynosHWCControl.fenceTracer;
1061 exynosHWCControl.fenceTracer = 3;
1062 dumpFenceInfoLocked(10);
1063 exynosHWCControl.fenceTracer = priv;
1064 }
1065
1066 return (cnt > threshold);
1067 }
1068
validateFencePerFrameLocked(const ExynosDisplay * display)1069 bool FenceTracker::validateFencePerFrameLocked(const ExynosDisplay *display) {
1070 bool ret = true;
1071
1072 for (const auto &[fd, info] : mFenceInfos) {
1073 if (info.displayId != display->mDisplayId) continue;
1074 if ((!info.pendingAllowed) && (!info.leaking)) {
1075 ret = false;
1076 break;
1077 }
1078 }
1079
1080 if (!ret) {
1081 int priv = exynosHWCControl.fenceTracer;
1082 exynosHWCControl.fenceTracer = 3;
1083 dumpNCheckLeakLocked();
1084 exynosHWCControl.fenceTracer = priv;
1085 }
1086
1087 return ret;
1088 }
1089
validateFences(ExynosDisplay * display)1090 bool FenceTracker::validateFences(ExynosDisplay *display) {
1091 std::scoped_lock lock(mFenceMutex);
1092
1093 if (!validateFencePerFrameLocked(display)) {
1094 ALOGE("You should doubt fence leak!");
1095 saveFenceTraceLocked(display);
1096 return false;
1097 }
1098
1099 if (fenceWarnLocked(MAX_FENCE_THRESHOLD)) {
1100 printLeakFdsLocked();
1101 saveFenceTraceLocked(display);
1102 return false;
1103 }
1104
1105 if (exynosHWCControl.doFenceFileDump) {
1106 ALOGD("Fence file dump !");
1107 saveFenceTraceLocked(display);
1108 exynosHWCControl.doFenceFileDump = false;
1109 }
1110
1111 return true;
1112 }
1113
saveFenceTraceLocked(ExynosDisplay * display)1114 int32_t FenceTracker::saveFenceTraceLocked(ExynosDisplay *display) {
1115 int32_t ret = NO_ERROR;
1116 auto &fileWriter = display->mFenceFileWriter;
1117
1118 if (!fileWriter.chooseOpenedFile()) {
1119 return -1;
1120 }
1121
1122 String8 saveString;
1123
1124 struct timeval tv;
1125 gettimeofday(&tv, NULL);
1126 saveString.appendFormat("\n====== Fences at time:%s ======\n", getLocalTimeStr(tv).string());
1127
1128 for (const auto &[fd, info] : mFenceInfos) {
1129 saveString.appendFormat("---- Fence FD : %d, Display(%d) ----\n", fd, info.displayId);
1130 saveString.appendFormat("usage: %d, dupFrom: %d, pendingAllowed: %d, leaking: %d\n",
1131 info.usage, info.dupFrom, info.pendingAllowed, info.leaking);
1132
1133 for (const auto &trace : info.traces) {
1134 saveString.appendFormat("> dir: %d, type: %d, ip: %d, time:%s\n", trace.direction,
1135 trace.type, trace.ip, getLocalTimeStr(trace.time).string());
1136 }
1137 }
1138
1139 fileWriter.write(saveString);
1140 fileWriter.flush();
1141 return ret;
1142 }
1143
getMPPStr(int typeId)1144 String8 getMPPStr(int typeId) {
1145 if (typeId < MPP_DPP_NUM){
1146 int cnt = sizeof(available_otf_mpp_units)/sizeof(exynos_mpp_t);
1147 for (int i = 0; i < cnt; i++){
1148 if (available_otf_mpp_units[i].physicalType == typeId)
1149 return String8(available_otf_mpp_units[i].name);
1150 }
1151 } else {
1152 int cnt = sizeof(AVAILABLE_M2M_MPP_UNITS)/sizeof(exynos_mpp_t);
1153 for (int i = 0; i < cnt; i++){
1154 if (AVAILABLE_M2M_MPP_UNITS[i].physicalType == typeId)
1155 return String8(AVAILABLE_M2M_MPP_UNITS[i].name);
1156 }
1157 }
1158 String8 result;
1159 result.appendFormat("? %08x", typeId);
1160 return result;
1161 }
1162
hasPPC(uint32_t physicalType,uint32_t formatIndex,uint32_t rotIndex)1163 bool hasPPC(uint32_t physicalType, uint32_t formatIndex, uint32_t rotIndex) {
1164 if (ppc_table_map.find(PPC_IDX(physicalType, formatIndex, rotIndex)) !=
1165 ppc_table_map.end()) {
1166 return true;
1167 }
1168 return false;
1169 }
1170
add(const std::string & key,const uint64_t & value,bool toHex)1171 TableBuilder& TableBuilder::add(const std::string& key, const uint64_t& value, bool toHex) {
1172 std::stringstream v;
1173 if (toHex)
1174 v << "0x" << std::hex << value;
1175 else
1176 v << value;
1177 data.emplace_back(std::make_pair(key, v.str()));
1178 return *this;
1179 }
1180
add(const std::string & key,const std::vector<uint64_t> & values,bool toHex)1181 TableBuilder& TableBuilder::add(const std::string& key, const std::vector<uint64_t>& values,
1182 bool toHex) {
1183 std::stringstream value;
1184 for (int i = 0; i < values.size(); i++) {
1185 if (i) value << ", ";
1186
1187 if (toHex)
1188 value << "0x" << std::hex << values[i];
1189 else
1190 value << values[i];
1191 }
1192
1193 data.emplace_back(std::make_pair(key, value.str()));
1194 return *this;
1195 }
1196
build()1197 std::string TableBuilder::build() {
1198 std::stringstream splitter, header, content;
1199 splitter << "+";
1200 header << "|";
1201 content << "|";
1202 for (const auto& [key, value] : data) {
1203 int size = std::max(key.size(), value.size()) + 2 /* for spaces around the string */;
1204 splitter << std::string(size, '-') << "+";
1205 header << buildPaddedString(key, size) << "|";
1206 content << buildPaddedString(value, size) << "|";
1207 }
1208
1209 std::string output = splitter.str() + "\n" +
1210 header.str() + "\n" +
1211 splitter.str() + "\n" +
1212 content.str() + "\n" +
1213 splitter.str() + "\n";
1214 return output;
1215 }
1216
buildPaddedString(const std::string & str,int size)1217 std::string TableBuilder::buildPaddedString(const std::string& str, int size) {
1218 int totalPadding = size - str.size();
1219 int leftPadding = totalPadding / 2.0;
1220 int rightPadding = (totalPadding / 2.0) + 0.6; // Poor person's ceil
1221
1222 return std::string(leftPadding, ' ') + str + std::string(rightPadding, ' ');
1223 }
1224
writeFileNode(FILE * fd,int value)1225 void writeFileNode(FILE* fd, int value) {
1226 constexpr uint32_t kMaxWriteFileLen = 16;
1227 char val[kMaxWriteFileLen] = {0};
1228
1229 if (fd == nullptr) {
1230 ALOGE("invalid fd pass to %s!", __func__);
1231 return;
1232 }
1233
1234 if (int32_t ret = snprintf(val, kMaxWriteFileLen, "%d", value) <= 0) {
1235 ALOGE("failed to write file node, ret =%d", ret);
1236 } else {
1237 fwrite(val, sizeof(val), 1, fd);
1238 if (ferror(fd)) {
1239 ALOGE("write failed: %s", strerror(errno));
1240 clearerr(fd);
1241 }
1242 rewind(fd);
1243 }
1244 }
1245
writeIntToFile(const char * file,uint32_t value)1246 int32_t writeIntToFile(const char* file, uint32_t value) {
1247 FILE* fd = fopen(file, "w+");
1248 if (fd == nullptr) {
1249 ALOGE("%s open failed! %s", file, strerror(errno));
1250 return -EINVAL;
1251 }
1252 writeFileNode(fd, value);
1253 fclose(fd);
1254 return 0;
1255 }
1256
load_png_image(const char * filepath,buffer_handle_t buffer)1257 int32_t load_png_image(const char* filepath, buffer_handle_t buffer) {
1258 png_structp png_ptr;
1259 png_infop info_ptr;
1260 int width, height, bpp, color_type;
1261
1262 VendorGraphicBufferMeta gmeta(buffer);
1263
1264 FILE* fp = fopen(filepath, "rb");
1265 if (fp == NULL) {
1266 ALOGE("%s open failed ", filepath);
1267 return -ENOENT;
1268 }
1269
1270 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
1271 if (png_ptr == NULL) {
1272 fclose(fp);
1273 return -ENOMEM;
1274 }
1275
1276 info_ptr = png_create_info_struct(png_ptr);
1277 if (info_ptr == NULL) {
1278 fclose(fp);
1279 png_destroy_read_struct(&png_ptr, NULL, NULL);
1280 return -ENOMEM;
1281 }
1282
1283 if (setjmp(png_jmpbuf(png_ptr))) {
1284 fclose(fp);
1285 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1286 return -EIO;
1287 }
1288
1289 png_init_io(png_ptr, fp);
1290
1291 png_set_sig_bytes(png_ptr, 0);
1292 png_read_info(png_ptr, info_ptr);
1293
1294 width = png_get_image_width(png_ptr, info_ptr);
1295 height = png_get_image_height(png_ptr, info_ptr);
1296 if (width != gmeta.width || height != gmeta.height) {
1297 fclose(fp);
1298 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1299 return -EINVAL;
1300 }
1301
1302 bpp = png_get_bit_depth(png_ptr, info_ptr) * png_get_channels(png_ptr, info_ptr);
1303 color_type = png_get_color_type(png_ptr, info_ptr);
1304 if (color_type != PNG_COLOR_TYPE_RGB_ALPHA || bpp != formatToBpp(gmeta.format)) {
1305 fclose(fp);
1306 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1307 return -EINVAL;
1308 }
1309
1310 size_t bufferHandleSize = gmeta.stride * gmeta.vstride * formatToBpp(gmeta.format) / 8;
1311 size_t png_size = png_get_rowbytes(png_ptr, info_ptr) * height;
1312 if (bufferHandleSize > gmeta.size || (bufferHandleSize < png_size)) {
1313 fclose(fp);
1314 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1315 return -EINVAL;
1316 }
1317 void* bufferHandleData =
1318 mmap(0, bufferHandleSize, PROT_READ | PROT_WRITE, MAP_SHARED, gmeta.fd, 0);
1319
1320 if (bufferHandleData != MAP_FAILED && bufferHandleData != NULL) {
1321 int strideBytes = gmeta.stride * (formatToBpp(gmeta.format) / 8);
1322 png_bytep row_ptr = (png_bytep)bufferHandleData;
1323 for (int y = 0; y < height; ++y) {
1324 png_read_row(png_ptr, row_ptr, NULL);
1325 row_ptr += strideBytes;
1326 }
1327 munmap(bufferHandleData, bufferHandleSize);
1328 }
1329
1330 fclose(fp);
1331 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1332
1333 return 0;
1334 }
1335
readLineFromFile(const std::string & filename,std::string & out,char delim)1336 int readLineFromFile(const std::string &filename, std::string &out, char delim) {
1337 std::ifstream in(filename);
1338
1339 if (!in) {
1340 return -ENOENT;
1341 }
1342 std::getline(in, out, delim);
1343 if (!in) {
1344 return -EIO;
1345 }
1346
1347 return android::OK;
1348 }
1349
waitForPropertyValue(const std::string & property,int64_t timeoutMs)1350 std::optional<std::string> waitForPropertyValue(const std::string& property, int64_t timeoutMs) {
1351 if (!android::base::WaitForPropertyCreation(property, std::chrono::milliseconds(timeoutMs))) {
1352 return std::nullopt;
1353 }
1354 std::string out = android::base::GetProperty(property, "unknown");
1355 if (out == "unknown") {
1356 return std::nullopt;
1357 }
1358 return std::make_optional(out);
1359 }
1360
rectSize(const hwc_rect_t & rect)1361 uint32_t rectSize(const hwc_rect_t& rect) {
1362 auto width = rect.right - rect.left;
1363 auto height = rect.bottom - rect.top;
1364
1365 if (width <= 0 || height <= 0) return 0;
1366
1367 return width * height;
1368 }
1369
assign(decon_win_rect & win_rect,uint32_t left,uint32_t right,uint32_t width,uint32_t height)1370 void assign(decon_win_rect& win_rect, uint32_t left, uint32_t right, uint32_t width,
1371 uint32_t height) {
1372 win_rect.x = left;
1373 win_rect.y = right;
1374 win_rect.w = std::max(0U, width);
1375 win_rect.h = std::max(0U, height);
1376 }
1377