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