/* * Copyright 2016 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "cros_gralloc_helpers.h" #include #include /* Define to match AIDL BufferUsage::VIDEO_DECODER. */ #define BUFFER_USAGE_VIDEO_DECODER (1 << 22) /* Define to match AIDL BufferUsage::GPU_DATA_BUFFER. */ #define BUFFER_USAGE_GPU_DATA_BUFFER (1 << 24) uint32_t cros_gralloc_convert_format(int format) { /* * Conversion from HAL to fourcc-based DRV formats based on * platform_android.c in mesa. */ switch (format) { case HAL_PIXEL_FORMAT_RGBA_8888: return DRM_FORMAT_ABGR8888; case HAL_PIXEL_FORMAT_RGBX_8888: return DRM_FORMAT_XBGR8888; case HAL_PIXEL_FORMAT_RGB_888: return DRM_FORMAT_BGR888; /* * Confusingly, HAL_PIXEL_FORMAT_RGB_565 is defined as: * * "16-bit packed format that has 5-bit R, 6-bit G, and 5-bit B components, in that * order, from the most-sigfinicant bits to the least-significant bits." * * so the order of the components is intentionally not flipped between the pixel * format and the DRM format. */ case HAL_PIXEL_FORMAT_RGB_565: return DRM_FORMAT_RGB565; case HAL_PIXEL_FORMAT_BGRA_8888: return DRM_FORMAT_ARGB8888; case HAL_PIXEL_FORMAT_RAW16: return DRM_FORMAT_R16; /* * Choose DRM_FORMAT_R8 because requires the buffers * with a format HAL_PIXEL_FORMAT_BLOB have a height of 1, and width * equal to their size in bytes. */ case HAL_PIXEL_FORMAT_BLOB: return DRM_FORMAT_R8; case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: return DRM_FORMAT_FLEX_IMPLEMENTATION_DEFINED; case HAL_PIXEL_FORMAT_YCbCr_420_888: return DRM_FORMAT_FLEX_YCbCr_420_888; case HAL_PIXEL_FORMAT_Y8: return DRM_FORMAT_R8; case HAL_PIXEL_FORMAT_Y16: return DRM_FORMAT_R16; case HAL_PIXEL_FORMAT_YV12: return DRM_FORMAT_YVU420_ANDROID; #if ANDROID_API_LEVEL >= 29 case HAL_PIXEL_FORMAT_RGBA_FP16: return DRM_FORMAT_ABGR16161616F; case HAL_PIXEL_FORMAT_RGBA_1010102: return DRM_FORMAT_ABGR2101010; #endif #if ANDROID_API_LEVEL >= 30 case HAL_PIXEL_FORMAT_YCBCR_P010: return DRM_FORMAT_P010; #endif } return DRM_FORMAT_NONE; } static inline void handle_usage(uint64_t *gralloc_usage, uint64_t gralloc_mask, uint64_t *bo_use_flags, uint64_t bo_mask) { if ((*gralloc_usage) & gralloc_mask) { (*gralloc_usage) &= ~gralloc_mask; (*bo_use_flags) |= bo_mask; } } uint64_t cros_gralloc_convert_usage(uint64_t usage) { uint64_t use_flags = BO_USE_NONE; /* * GRALLOC_USAGE_SW_READ_OFTEN contains GRALLOC_USAGE_SW_READ_RARELY, thus OFTEN must be * handled first. The same applies to GRALLOC_USAGE_SW_WRITE_OFTEN. */ handle_usage(&usage, GRALLOC_USAGE_SW_READ_OFTEN, &use_flags, BO_USE_SW_READ_OFTEN); handle_usage(&usage, GRALLOC_USAGE_SW_READ_RARELY, &use_flags, BO_USE_SW_READ_RARELY); handle_usage(&usage, GRALLOC_USAGE_SW_WRITE_OFTEN, &use_flags, BO_USE_SW_WRITE_OFTEN); handle_usage(&usage, GRALLOC_USAGE_SW_WRITE_RARELY, &use_flags, BO_USE_SW_WRITE_RARELY); handle_usage(&usage, GRALLOC_USAGE_HW_TEXTURE, &use_flags, BO_USE_TEXTURE); handle_usage(&usage, GRALLOC_USAGE_HW_RENDER, &use_flags, BO_USE_RENDERING); handle_usage(&usage, GRALLOC_USAGE_HW_2D, &use_flags, BO_USE_RENDERING); /* HWC wants to use display hardware, but can defer to OpenGL. */ handle_usage(&usage, GRALLOC_USAGE_HW_COMPOSER, &use_flags, BO_USE_SCANOUT | BO_USE_TEXTURE); handle_usage(&usage, GRALLOC_USAGE_HW_FB, &use_flags, BO_USE_NONE); /* * This flag potentially covers external display for the normal drivers (i915/rockchip) and * usb monitors (evdi/udl). It's complicated so ignore it. */ handle_usage(&usage, GRALLOC_USAGE_EXTERNAL_DISP, &use_flags, BO_USE_NONE); /* Map PROTECTED to linear until real HW protection is available on Android. */ handle_usage(&usage, GRALLOC_USAGE_PROTECTED, &use_flags, BO_USE_LINEAR); handle_usage(&usage, GRALLOC_USAGE_CURSOR, &use_flags, BO_USE_NONE); /* HACK: See b/30054495 for BO_USE_SW_READ_OFTEN. */ handle_usage(&usage, GRALLOC_USAGE_HW_VIDEO_ENCODER, &use_flags, BO_USE_HW_VIDEO_ENCODER | BO_USE_SW_READ_OFTEN); handle_usage(&usage, GRALLOC_USAGE_HW_CAMERA_WRITE, &use_flags, BO_USE_CAMERA_WRITE); handle_usage(&usage, GRALLOC_USAGE_HW_CAMERA_READ, &use_flags, BO_USE_CAMERA_READ); handle_usage(&usage, GRALLOC_USAGE_RENDERSCRIPT, &use_flags, BO_USE_RENDERSCRIPT); handle_usage(&usage, BUFFER_USAGE_VIDEO_DECODER, &use_flags, BO_USE_HW_VIDEO_DECODER); handle_usage(&usage, BUFFER_USAGE_GPU_DATA_BUFFER, &use_flags, BO_USE_GPU_DATA_BUFFER); handle_usage(&usage, BUFFER_USAGE_FRONT_RENDERING, &use_flags, BO_USE_FRONT_RENDERING); if (usage) { drv_log("Unhandled gralloc usage: %llx\n", (unsigned long long)usage); return BO_USE_NONE; } return use_flags; } uint32_t cros_gralloc_convert_map_usage(uint64_t usage) { uint32_t map_flags = BO_MAP_NONE; if (usage & GRALLOC_USAGE_SW_READ_MASK) map_flags |= BO_MAP_READ; if (usage & GRALLOC_USAGE_SW_WRITE_MASK) map_flags |= BO_MAP_WRITE; return map_flags; } cros_gralloc_handle_t cros_gralloc_convert_handle(buffer_handle_t handle) { auto hnd = reinterpret_cast(handle); if (!hnd || hnd->magic != cros_gralloc_magic) return nullptr; return hnd; } int32_t cros_gralloc_sync_wait(int32_t fence, bool close_fence) { if (fence < 0) return 0; /* * Wait initially for 1000 ms, and then wait indefinitely. The SYNC_IOC_WAIT * documentation states the caller waits indefinitely on the fence if timeout < 0. */ int err = sync_wait(fence, 1000); if (err < 0) { drv_log("Timed out on sync wait, err = %s\n", strerror(errno)); err = sync_wait(fence, -1); if (err < 0) { drv_log("sync wait error = %s\n", strerror(errno)); return -errno; } } if (close_fence) { err = close(fence); if (err) { drv_log("Unable to close fence fd, err = %s\n", strerror(errno)); return -errno; } } return 0; } std::string get_drm_format_string(uint32_t drm_format) { char *sequence = (char *)&drm_format; std::string s(sequence, 4); return "DRM_FOURCC_" + s; }