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