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 <cutils/properties.h>
20 #include <linux/videodev2.h>
21 #include <linux/videodev2_exynos_media.h>
22 #include <png.h>
23 #include <sync/sync.h>
24 #include <sys/mman.h>
25 #include <utils/CallStack.h>
26 #include <utils/Errors.h>
27 
28 #include <iomanip>
29 
30 #include "ExynosHWC.h"
31 #include "ExynosHWCDebug.h"
32 #include "ExynosLayer.h"
33 #include "ExynosResourceRestriction.h"
34 #include "VendorVideoAPI.h"
35 #include "exynos_sync.h"
36 
37 using vendor::graphics::BufferUsage;
38 using vendor::graphics::VendorGraphicBufferUsage;
39 using vendor::graphics::VendorGraphicBufferMeta;
40 using namespace SOC_VERSION;
41 
42 #define AFBC_MAGIC  0xafbc
43 
44 #define FT_LOGD(msg, ...) \
45     {\
46         if (exynosHWCControl.fenceTracer >= 2) \
47             ALOGD("[FenceTracer]::" msg, ##__VA_ARGS__); \
48     }
49 #define FT_LOGE(msg, ...) \
50     {\
51         if (exynosHWCControl.fenceTracer > 0) \
52             ALOGE("[FenceTracer]::" msg, ##__VA_ARGS__); \
53     }
54 #define FT_LOGW(msg, ...) \
55     {\
56         if (exynosHWCControl.fenceTracer >= 1) \
57             ALOGD("[FenceTracer]::" msg, ##__VA_ARGS__); \
58     }
59 
60 extern struct exynos_hwc_control exynosHWCControl;
61 extern char fence_names[FENCE_MAX][32];
62 
getHWC1CompType(int32_t type)63 uint32_t getHWC1CompType(int32_t type) {
64 
65     uint32_t cType = HWC_FRAMEBUFFER;
66 
67     switch(type) {
68     case HWC2_COMPOSITION_DEVICE:
69     case HWC2_COMPOSITION_EXYNOS:
70         cType = HWC_OVERLAY;
71         break;
72     case HWC2_COMPOSITION_SOLID_COLOR:
73         cType = HWC_BACKGROUND;
74         break;
75     case HWC2_COMPOSITION_CURSOR:
76         cType = HWC_CURSOR_OVERLAY;
77         break;
78     case HWC2_COMPOSITION_SIDEBAND:
79         cType = HWC_SIDEBAND;
80         break;
81     case HWC2_COMPOSITION_CLIENT:
82     case HWC2_COMPOSITION_INVALID:
83     default:
84         cType = HWC_FRAMEBUFFER;
85         break;
86     }
87 
88     return cType;
89 }
90 
getDrmMode(uint64_t flags)91 uint32_t getDrmMode(uint64_t flags)
92 {
93     if (flags & BufferUsage::PROTECTED) {
94         if (flags & VendorGraphicBufferUsage::PRIVATE_NONSECURE)
95             return NORMAL_DRM;
96         else
97             return SECURE_DRM;
98     }
99     return NO_DRM;
100 }
101 
getDrmMode(const buffer_handle_t handle)102 uint32_t getDrmMode(const buffer_handle_t handle)
103 {
104     uint64_t usage = VendorGraphicBufferMeta::get_usage(handle);
105     if (usage & BufferUsage::PROTECTED) {
106         if (usage & VendorGraphicBufferUsage::PRIVATE_NONSECURE)
107             return NORMAL_DRM;
108         else
109             return SECURE_DRM;
110     }
111 
112     return NO_DRM;
113 }
114 
isNarrowRgb(int format,android_dataspace data_space)115 unsigned int isNarrowRgb(int format, android_dataspace data_space)
116 {
117     if (format == HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL)
118         return 0;
119     else {
120         if (isFormatRgb(format))
121             return 0;
122         else {
123             uint32_t data_space_range = (data_space & HAL_DATASPACE_RANGE_MASK);
124             if (data_space_range == HAL_DATASPACE_RANGE_UNSPECIFIED) {
125                 return 1;
126             } else if (data_space_range == HAL_DATASPACE_RANGE_FULL) {
127                 return 0;
128             } else {
129                 return 1;
130             }
131         }
132     }
133 }
134 
halFormatToExynosFormat(int inHalFormat,uint32_t inCompressType)135 const format_description_t* halFormatToExynosFormat(int inHalFormat, uint32_t inCompressType) {
136     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
137         const int descHalFormat = exynos_format_desc[i].halFormat;
138 
139         if ((inHalFormat == descHalFormat) &&
140             exynos_format_desc[i].isCompressionSupported(inCompressType)) {
141             return &exynos_format_desc[i];
142         }
143     }
144     return nullptr;
145 }
146 
formatToBpp(int format)147 uint8_t formatToBpp(int format)
148 {
149     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
150         if (exynos_format_desc[i].halFormat == format)
151             return exynos_format_desc[i].bpp;
152     }
153 
154     ALOGW("unrecognized pixel format %u", format);
155     return 0;
156 }
157 
DpuFormatToBpp(decon_pixel_format format)158 uint8_t DpuFormatToBpp(decon_pixel_format format)
159 {
160     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
161         if (exynos_format_desc[i].s3cFormat == format)
162             return exynos_format_desc[i].bpp;
163     }
164     ALOGW("unrecognized decon format %u", format);
165     return 0;
166 }
167 
isFormatRgb(int format)168 bool isFormatRgb(int format)
169 {
170     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
171         if (exynos_format_desc[i].halFormat == format) {
172             if (exynos_format_desc[i].type & RGB)
173                 return true;
174             else
175                 return false;
176         }
177     }
178     return false;
179 }
180 
isFormatYUV(int format)181 bool isFormatYUV(int format)
182 {
183     if (isFormatRgb(format))
184         return false;
185     return true;
186 }
187 
isFormatSBWC(int format)188 bool isFormatSBWC(int format)
189 {
190     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
191         if (exynos_format_desc[i].halFormat == format) {
192             if (exynos_format_desc[i].type & COMP_TYPE_SBWC)
193                 return true;
194             else
195                 return false;
196         }
197     }
198     return false;
199 }
200 
isFormatYUV420(int format)201 bool isFormatYUV420(int format)
202 {
203     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
204         if (exynos_format_desc[i].halFormat == format) {
205             if (exynos_format_desc[i].type & YUV420)
206                 return true;
207             else
208                 return false;
209         }
210     }
211     return false;
212 }
213 
isFormatYUV8_2(int format)214 bool isFormatYUV8_2(int format)
215 {
216     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
217         if (exynos_format_desc[i].halFormat == format) {
218             if ((exynos_format_desc[i].type & YUV420) &&
219                 (exynos_format_desc[i].type & BIT8_2))
220                 return true;
221             else
222                 return false;
223         }
224     }
225     return false;
226 }
227 
isFormat10BitYUV420(int format)228 bool isFormat10BitYUV420(int format)
229 {
230     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
231         if (exynos_format_desc[i].halFormat == format) {
232             if ((exynos_format_desc[i].type & YUV420) &&
233                 (exynos_format_desc[i].type & BIT10))
234                 return true;
235             else
236                 return false;
237         }
238     }
239     return false;
240 }
241 
isFormatYUV422(int format)242 bool isFormatYUV422(int format)
243 {
244     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
245         if (exynos_format_desc[i].halFormat == format) {
246             if (exynos_format_desc[i].type & YUV422)
247                 return true;
248             else
249                 return false;
250         }
251     }
252     return false;
253 }
254 
isFormatP010(int format)255 bool isFormatP010(int format)
256 {
257     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
258         if (exynos_format_desc[i].halFormat == format) {
259             if (exynos_format_desc[i].type & P010)
260                 return true;
261             else
262                 return false;
263         }
264     }
265     return false;
266 }
267 
isFormat10Bit(int format)268 bool isFormat10Bit(int format) {
269     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
270         if (exynos_format_desc[i].halFormat == format) {
271             if ((exynos_format_desc[i].type & BIT_MASK) == BIT10)
272                 return true;
273             else
274                 return false;
275         }
276     }
277     return false;
278 }
279 
isFormat8Bit(int format)280 bool isFormat8Bit(int format) {
281     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
282         if (exynos_format_desc[i].halFormat == format) {
283             if ((exynos_format_desc[i].type & BIT_MASK) == BIT8)
284                 return true;
285             else
286                 return false;
287         }
288     }
289     return false;
290 }
291 
isFormatYCrCb(int format)292 bool isFormatYCrCb(int format)
293 {
294     return format == HAL_PIXEL_FORMAT_EXYNOS_YV12_M;
295 }
296 
isFormatLossy(int format)297 bool isFormatLossy(int format)
298 {
299     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
300         if (exynos_format_desc[i].halFormat == format) {
301             uint32_t sbwcType = exynos_format_desc[i].type & FORMAT_SBWC_MASK;
302             if (sbwcType && sbwcType != SBWC_LOSSLESS)
303                 return true;
304             else
305                 return false;
306         }
307     }
308     return false;
309 }
310 
formatHasAlphaChannel(int format)311 bool formatHasAlphaChannel(int format)
312 {
313     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++) {
314         if (exynos_format_desc[i].halFormat == format) {
315             return exynos_format_desc[i].hasAlpha;
316         }
317     }
318     return false;
319 }
320 
isAFBCCompressed(const buffer_handle_t handle)321 bool isAFBCCompressed(const buffer_handle_t handle) {
322     if (handle != NULL) {
323         return VendorGraphicBufferMeta::is_afbc(handle);
324     }
325 
326     return false;
327 }
328 
isSBWCCompressed(const buffer_handle_t handle)329 bool isSBWCCompressed(const buffer_handle_t handle) {
330     if (handle != NULL) {
331         return VendorGraphicBufferMeta::is_sbwc(handle);
332     }
333 
334     return false;
335 }
336 
getFormat(const buffer_handle_t handle)337 uint32_t getFormat(const buffer_handle_t handle) {
338     if (handle != NULL) {
339         return VendorGraphicBufferMeta::get_format(handle);
340     }
341 
342     return 0;
343 }
344 
getFormatModifier(const buffer_handle_t handle)345 uint64_t getFormatModifier(const buffer_handle_t handle) {
346     if (handle != NULL) {
347         return VendorGraphicBufferMeta::get_format_modifier(handle);
348     }
349 
350     return 0;
351 }
352 
getCompressionType(const buffer_handle_t handle)353 uint32_t getCompressionType(const buffer_handle_t handle) {
354     if (handle == NULL) return COMP_TYPE_NONE;
355 
356     if (isAFBCCompressed(handle)) {
357         return COMP_TYPE_AFBC;
358     } else if (isSBWCCompressed(handle)) {
359         return COMP_TYPE_SBWC;
360     }
361 
362     return COMP_TYPE_NONE;
363 }
364 
getCompressionInfo(buffer_handle_t handle)365 CompressionInfo getCompressionInfo(buffer_handle_t handle) {
366     CompressionInfo compressionInfo = {COMP_TYPE_NONE, 0};
367 
368     if (handle == NULL) return compressionInfo;
369 
370     if (isAFBCCompressed(handle)) {
371         compressionInfo.type = COMP_TYPE_AFBC;
372         compressionInfo.modifier = getFormatModifier(handle);
373     } else if (isSBWCCompressed(handle)) {
374         compressionInfo.type = COMP_TYPE_SBWC;
375 
376         uint32_t format = getFormat(handle);
377         if (isFormat10BitYUV420(format))
378             compressionInfo.modifier = SBWC_FORMAT_MOD_BLOCK_SIZE_32x5;
379         else
380             compressionInfo.modifier = SBWC_FORMAT_MOD_BLOCK_SIZE_32x4;
381     } else {
382         compressionInfo.type = COMP_TYPE_NONE;
383     }
384 
385     return compressionInfo;
386 }
387 
getCompressionStr(CompressionInfo compression)388 String8 getCompressionStr(CompressionInfo compression) {
389     String8 result;
390     if (compression.type == COMP_TYPE_NONE)
391         result.append("None");
392     else if (compression.type == COMP_TYPE_AFBC)
393         result.appendFormat("AFBC(mod:0x%" PRIx64 ")", compression.modifier);
394     else if (compression.type == COMP_TYPE_SBWC)
395         result.appendFormat("SBWC(mod:0x%" PRIx64 ")", compression.modifier);
396     else
397         result.append("Unknown");
398     return result;
399 }
400 
isAFBC32x8(CompressionInfo compression)401 bool isAFBC32x8(CompressionInfo compression) {
402     return (compression.type == COMP_TYPE_AFBC) &&
403             ((compression.modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) ==
404              AFBC_FORMAT_MOD_BLOCK_SIZE_32x8);
405 }
406 
halDataSpaceToV4L2ColorSpace(android_dataspace data_space)407 uint32_t halDataSpaceToV4L2ColorSpace(android_dataspace data_space)
408 {
409     uint32_t standard_data_space = (data_space & HAL_DATASPACE_STANDARD_MASK);
410     switch (standard_data_space) {
411     case HAL_DATASPACE_STANDARD_BT2020:
412     case HAL_DATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE:
413         return V4L2_COLORSPACE_BT2020;
414     case HAL_DATASPACE_STANDARD_DCI_P3:
415         return V4L2_COLORSPACE_DCI_P3;
416     case HAL_DATASPACE_STANDARD_BT709:
417         return V4L2_COLORSPACE_REC709;
418     default:
419         return V4L2_COLORSPACE_DEFAULT;
420     }
421     return V4L2_COLORSPACE_DEFAULT;
422 }
423 
halFormatToDpuFormat(int format,uint32_t compressType)424 enum decon_pixel_format halFormatToDpuFormat(int format, uint32_t compressType) {
425     auto exynosFormat = halFormatToExynosFormat(format, compressType);
426     return (exynosFormat != nullptr) ? exynosFormat->s3cFormat : DECON_PIXEL_FORMAT_MAX;
427 }
428 
DpuFormatToHalFormat(int format,uint32_t)429 uint32_t DpuFormatToHalFormat(int format, uint32_t /*compressType*/) {
430     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
431         if (exynos_format_desc[i].s3cFormat == static_cast<decon_pixel_format>(format))
432             return exynos_format_desc[i].halFormat;
433     }
434     return HAL_PIXEL_FORMAT_EXYNOS_UNDEFINED;
435 }
436 
halFormatToDrmFormat(int format,uint32_t compressType)437 int halFormatToDrmFormat(int format, uint32_t compressType)
438 {
439     auto exynosFormat = halFormatToExynosFormat(format, compressType);
440     return (exynosFormat != nullptr) ? exynosFormat->drmFormat : DRM_FORMAT_UNDEFINED;
441 }
442 
drmFormatToHalFormats(int format,std::vector<uint32_t> * halFormats)443 int32_t drmFormatToHalFormats(int format, std::vector<uint32_t> *halFormats)
444 {
445     if (halFormats == NULL)
446         return -EINVAL;
447 
448     halFormats->clear();
449     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
450         if (exynos_format_desc[i].drmFormat == format) {
451             halFormats->push_back(exynos_format_desc[i].halFormat);
452         }
453     }
454     return NO_ERROR;
455 }
456 
drmFormatToHalFormat(int format)457 int drmFormatToHalFormat(int format)
458 {
459     for (unsigned int i = 0; i < FORMAT_MAX_CNT; i++){
460         if (exynos_format_desc[i].drmFormat == format)
461             return exynos_format_desc[i].halFormat;
462     }
463     return HAL_PIXEL_FORMAT_EXYNOS_UNDEFINED;
464 }
465 
colorModeToDataspace(android_color_mode_t mode)466 android_dataspace colorModeToDataspace(android_color_mode_t mode)
467 {
468     android_dataspace dataSpace = HAL_DATASPACE_UNKNOWN;
469     switch (mode) {
470         case HAL_COLOR_MODE_STANDARD_BT601_625:
471             dataSpace = HAL_DATASPACE_STANDARD_BT601_625;
472             break;
473         case HAL_COLOR_MODE_STANDARD_BT601_625_UNADJUSTED:
474             dataSpace = HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED;
475             break;
476         case HAL_COLOR_MODE_STANDARD_BT601_525:
477             dataSpace = HAL_DATASPACE_STANDARD_BT601_525;
478             break;
479         case HAL_COLOR_MODE_STANDARD_BT601_525_UNADJUSTED:
480             dataSpace = HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED;
481             break;
482         case HAL_COLOR_MODE_STANDARD_BT709:
483             dataSpace = HAL_DATASPACE_STANDARD_BT709;
484             break;
485         case HAL_COLOR_MODE_DCI_P3:
486             dataSpace = HAL_DATASPACE_DCI_P3;
487             break;
488         case HAL_COLOR_MODE_ADOBE_RGB:
489             dataSpace = HAL_DATASPACE_ADOBE_RGB;
490             break;
491         case HAL_COLOR_MODE_DISPLAY_P3:
492             dataSpace = HAL_DATASPACE_DISPLAY_P3;
493             break;
494         case HAL_COLOR_MODE_SRGB:
495             dataSpace = HAL_DATASPACE_V0_SRGB;
496             break;
497         case HAL_COLOR_MODE_NATIVE:
498             dataSpace = HAL_DATASPACE_UNKNOWN;
499             break;
500         default:
501             break;
502     }
503     return dataSpace;
504 }
505 
halTransformToDrmRot(uint32_t halTransform)506 uint64_t halTransformToDrmRot(uint32_t halTransform)
507 {
508     switch (halTransform) {
509     case HAL_TRANSFORM_FLIP_H:
510         return DRM_MODE_REFLECT_Y|DRM_MODE_ROTATE_0;
511     case HAL_TRANSFORM_FLIP_V:
512         return DRM_MODE_REFLECT_X|DRM_MODE_ROTATE_0;
513     case HAL_TRANSFORM_ROT_180:
514         return DRM_MODE_ROTATE_180;
515     case HAL_TRANSFORM_ROT_90:
516         return DRM_MODE_ROTATE_90;
517     case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_H):
518         /*
519          * HAL: HAL_TRANSFORM_FLIP_H -> HAL_TRANSFORM_ROT_90
520          * DPP: ROT_90 -> XFLIP
521          */
522         return (DRM_MODE_ROTATE_90|DRM_MODE_REFLECT_X);
523     case (HAL_TRANSFORM_ROT_90|HAL_TRANSFORM_FLIP_V):
524         /*
525          * HAL: HAL_TRANSFORM_FLIP_V -> HAL_TRANSFORM_ROT_90
526          * DPP: ROT_90 -> YFLIP
527          */
528         return (DRM_MODE_ROTATE_90|DRM_MODE_REFLECT_Y);
529     case HAL_TRANSFORM_ROT_270:
530         return DRM_MODE_ROTATE_270;
531     default:
532         return DRM_MODE_ROTATE_0;
533     }
534 }
535 
dumpHandle(uint32_t type,buffer_handle_t h)536 void dumpHandle(uint32_t type, buffer_handle_t h)
537 {
538     if (h == NULL)
539         return;
540 
541     VendorGraphicBufferMeta gmeta(h);
542 
543     HDEBUGLOGD(type, "\t\tformat = %d, width = %u, height = %u, stride = %u, vstride = %u",
544             gmeta.format, gmeta.width, gmeta.height, gmeta.stride, gmeta.vstride);
545 }
546 
dumpExynosImage(uint32_t type,exynos_image & img)547 void dumpExynosImage(uint32_t type, exynos_image &img)
548 {
549     if (!hwcCheckDebugMessages(type))
550         return;
551 
552     String8 result;
553     dumpExynosImage(result, img);
554 
555     ALOGD("%s", result.c_str());
556 }
557 
dumpExynosImage(String8 & result,const exynos_image & img)558 void dumpExynosImage(String8& result, const exynos_image& img) {
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).c_str());
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).c_str());
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).c_str());
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.c_str());
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).c_str());
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).c_str());
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         ALOGE("%s png_ptr create failed", filepath);
1273         fclose(fp);
1274         return -ENOMEM;
1275     }
1276 
1277     info_ptr = png_create_info_struct(png_ptr);
1278     if (info_ptr == NULL) {
1279         ALOGE("%s info_ptr create failed", filepath);
1280         fclose(fp);
1281         png_destroy_read_struct(&png_ptr, NULL, NULL);
1282         return -ENOMEM;
1283     }
1284 
1285     if (setjmp(png_jmpbuf(png_ptr))) {
1286         ALOGE("%s setjmp failed", filepath);
1287         fclose(fp);
1288         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1289         return -EIO;
1290     }
1291 
1292     png_init_io(png_ptr, fp);
1293 
1294     png_set_sig_bytes(png_ptr, 0);
1295     png_read_info(png_ptr, info_ptr);
1296 
1297     width = png_get_image_width(png_ptr, info_ptr);
1298     height = png_get_image_height(png_ptr, info_ptr);
1299     if (width != gmeta.width || height != gmeta.height) {
1300         ALOGE("%s source width/height (%dx%d) doesn't match with buffer (%dx%d)", filepath, width,
1301               height, gmeta.width, gmeta.height);
1302         fclose(fp);
1303         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1304         return -EINVAL;
1305     }
1306 
1307     bpp = png_get_bit_depth(png_ptr, info_ptr) * png_get_channels(png_ptr, info_ptr);
1308     color_type = png_get_color_type(png_ptr, info_ptr);
1309     if (color_type != PNG_COLOR_TYPE_RGB_ALPHA || bpp != formatToBpp(gmeta.format)) {
1310         ALOGE("%s color_type (%d) isn't rgb alpha (%d), or source bpp (%d) doesn't match with "
1311               "buffer (%d)",
1312               filepath, color_type, PNG_COLOR_TYPE_RGB_ALPHA, bpp, formatToBpp(gmeta.format));
1313         fclose(fp);
1314         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1315         return -EINVAL;
1316     }
1317 
1318     size_t bufferHandleSize = gmeta.stride * gmeta.vstride * formatToBpp(gmeta.format) / 8;
1319     size_t png_size = png_get_rowbytes(png_ptr, info_ptr) * height;
1320     if (bufferHandleSize > gmeta.size || (bufferHandleSize < png_size)) {
1321         ALOGE("%s buffer handle size isn't within [png_size, gmeta.size]: %d vs [%d, %d]", filepath,
1322               (int)bufferHandleSize, (int)png_size, gmeta.size);
1323         fclose(fp);
1324         png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1325         return -EINVAL;
1326     }
1327     void* bufferHandleData =
1328             mmap(0, bufferHandleSize, PROT_READ | PROT_WRITE, MAP_SHARED, gmeta.fd, 0);
1329 
1330     if (bufferHandleData != MAP_FAILED && bufferHandleData != NULL) {
1331         int strideBytes = gmeta.stride * (formatToBpp(gmeta.format) / 8);
1332         png_bytep row_ptr = (png_bytep)bufferHandleData;
1333 
1334         for (int y = 0; y < height; ++y) {
1335             png_read_row(png_ptr, row_ptr + strideBytes * y, NULL);
1336         }
1337 
1338         const bool premultiplied =
1339                 static_cast<bool>(property_get_bool("vendor.display.png.premultiplied", 0));
1340         ALOGD("premultiplied=%s", premultiplied ? "true" : "false");
1341         if (premultiplied) {
1342             const auto& premul = [](int a, int v) { return (unsigned char)(v * a / 255.0 + 0.5); };
1343             for (int i = 0; i + 3 < height * strideBytes; i += 4) {
1344                 row_ptr[i + 0] = premul(row_ptr[i + 3], row_ptr[i + 0]);
1345                 row_ptr[i + 1] = premul(row_ptr[i + 3], row_ptr[i + 1]);
1346                 row_ptr[i + 2] = premul(row_ptr[i + 3], row_ptr[i + 2]);
1347             }
1348         }
1349 
1350         munmap(bufferHandleData, bufferHandleSize);
1351     }
1352 
1353     fclose(fp);
1354     png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1355 
1356     return 0;
1357 }
1358 
readLineFromFile(const std::string & filename,std::string & out,char delim)1359 int readLineFromFile(const std::string &filename, std::string &out, char delim) {
1360     std::ifstream in(filename);
1361 
1362     if (!in) {
1363         return -ENOENT;
1364     }
1365     std::getline(in, out, delim);
1366     if (!in) {
1367         return -EIO;
1368     }
1369 
1370     return android::OK;
1371 }
1372 
waitForPropertyValue(const std::string & property,int64_t timeoutMs)1373 std::optional<std::string> waitForPropertyValue(const std::string& property, int64_t timeoutMs) {
1374     if (!android::base::WaitForPropertyCreation(property, std::chrono::milliseconds(timeoutMs))) {
1375         return std::nullopt;
1376     }
1377     std::string out = android::base::GetProperty(property, "unknown");
1378     if (out == "unknown") {
1379         return std::nullopt;
1380     }
1381     return std::make_optional(out);
1382 }
1383 
rectSize(const hwc_rect_t & rect)1384 uint32_t rectSize(const hwc_rect_t& rect) {
1385     auto width = rect.right - rect.left;
1386     auto height = rect.bottom - rect.top;
1387 
1388     if (width <= 0 || height <= 0) return 0;
1389 
1390     return width * height;
1391 }
1392 
assign(decon_win_rect & win_rect,uint32_t left,uint32_t right,uint32_t width,uint32_t height)1393 void assign(decon_win_rect& win_rect, uint32_t left, uint32_t right, uint32_t width,
1394             uint32_t height) {
1395     win_rect.x = left;
1396     win_rect.y = right;
1397     win_rect.w = std::max(0U, width);
1398     win_rect.h = std::max(0U, height);
1399 }
1400 
nanoSec2Hz(uint64_t ns)1401 uint32_t nanoSec2Hz(uint64_t ns) {
1402     if (ns == 0) return 0;
1403     constexpr auto nsecsPerSec = std::chrono::nanoseconds(1s).count();
1404     return round(static_cast<float>(nsecsPerSec) / ns);
1405 };
1406