Gralloc: Implement getCustomFormatFlags API
Implement API to get custom format and private handle flags
based on a given combination of input format and usage flags.
Change-Id: Id87e9abe834fb17c6304262cc486a84131c8809a
CRs-Fixed: 2255171
diff --git a/gralloc/QtiMapper.cpp b/gralloc/QtiMapper.cpp
index 4ad6836..3848878 100644
--- a/gralloc/QtiMapper.cpp
+++ b/gralloc/QtiMapper.cpp
@@ -337,7 +337,12 @@
Return<void> QtiMapper::getCustomFormatFlags(int32_t format, uint64_t usage,
getCustomFormatFlags_cb hidl_cb) {
uint64_t priv_flags = 0;
- hidl_cb(Error::NONE, format, priv_flags);
+ auto err = Error::NONE;
+ int32_t custom_format = format;
+ if (gralloc::GetCustomFormatFlags(format, usage, &custom_format, &priv_flags) != 0) {
+ err = Error::UNSUPPORTED;
+ }
+ hidl_cb(err, custom_format, priv_flags);
return Void();
}
diff --git a/gralloc/gr_adreno_info.cpp b/gralloc/gr_adreno_info.cpp
index 1288d92..73f9ce0 100644
--- a/gralloc/gr_adreno_info.cpp
+++ b/gralloc/gr_adreno_info.cpp
@@ -267,4 +267,11 @@
LINK_adreno_get_aligned_gpu_buffer_size);
}
+bool AdrenoMemInfo::IsPISupportedByGPU(int format, uint64_t usage) {
+ if (LINK_adreno_isPISupportedByGpu) {
+ return LINK_adreno_isPISupportedByGpu(format, usage);
+ }
+ return false;
+}
+
} // namespace gralloc
diff --git a/gralloc/gr_adreno_info.h b/gralloc/gr_adreno_info.h
index eec7da4..07c4059 100644
--- a/gralloc/gr_adreno_info.h
+++ b/gralloc/gr_adreno_info.h
@@ -127,6 +127,10 @@
bool IsUBWCSupportedByGPU(int format);
/*
+ * Function to check if GPU supports PI or not
+ */
+ bool IsPISupportedByGPU(int format, uint64_t usage);
+ /*
* Function to get the corresponding Adreno format for given HAL format
*/
ADRENOPIXELFORMAT GetGpuPixelFormat(int hal_format);
@@ -185,6 +189,7 @@
ADRENOPIXELFORMAT format, int num_samples, surface_tile_mode_t tile_mode,
uint64_t usage, uint32_t num_planes) = NULL;
uint32_t (*LINK_adreno_get_aligned_gpu_buffer_size)(void* metadata_blob) = NULL;
+ int (*LINK_adreno_isPISupportedByGpu)(int format, uint64_t usage) = NULL;
bool gfx_ubwc_disable_ = false;
void *libadreno_utils_ = NULL;
diff --git a/gralloc/gr_allocator.cpp b/gralloc/gr_allocator.cpp
index e5ec78c..56b60bd 100644
--- a/gralloc/gr_allocator.cpp
+++ b/gralloc/gr_allocator.cpp
@@ -184,88 +184,6 @@
return true;
}
-int Allocator::GetImplDefinedFormat(uint64_t usage, int format) {
- int gr_format = format;
-
- // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
- // the usage bits, gralloc assigns a format.
- if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
- format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- if (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) {
- // Use of 10BIT_TP and 10BIT bits is supposed to be mutually exclusive.
- // Each bit maps to only one format. Here we will check one of the bits
- // and ignore the other.
- if (usage & GRALLOC_USAGE_PRIVATE_10BIT_TP) {
- gr_format = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
- } else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
- gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
- } else {
- gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
- }
- } else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
- gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS;
- } else if (usage & BufferUsage::VIDEO_ENCODER) {
- if (usage & GRALLOC_USAGE_PRIVATE_VIDEO_NV21_ENCODER) {
- gr_format = HAL_PIXEL_FORMAT_NV21_ENCODEABLE; // NV21
- } else {
- gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12
- }
- } else if (usage & BufferUsage::CAMERA_INPUT) {
- if (usage & BufferUsage::CAMERA_OUTPUT) {
- // Assumed ZSL if both producer and consumer camera flags set
- gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
- } else {
- gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21
- }
- } else if (usage & BufferUsage::CAMERA_OUTPUT) {
- if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
- } else {
- gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; // NV12 preview
- }
- } else if (usage & BufferUsage::COMPOSER_OVERLAY) {
- // XXX: If we still haven't set a format, default to RGBA8888
- gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
- } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- // If no other usage flags are detected, default the
- // flexible YUV format to NV21_ZSL
- gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
- }
- }
-
- return gr_format;
-}
-
-/* The default policy is to return cached buffers unless the client explicity
- * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
- * read or written in software. */
-bool Allocator::UseUncached(int format, uint64_t usage) {
- if ((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) || (usage & BufferUsage::PROTECTED)) {
- return true;
- }
-
- // CPU read rarely
- if ((usage & BufferUsage::CPU_READ_MASK) == static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) {
- return true;
- }
-
- // CPU write rarely
- if ((usage & BufferUsage::CPU_WRITE_MASK) ==
- static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) {
- return true;
- }
-
- if ((usage & BufferUsage::SENSOR_DIRECT_DATA) || (usage & BufferUsage::GPU_DATA_BUFFER)) {
- return true;
- }
-
- if (format && IsUBwcEnabled(format, usage)) {
- return true;
- }
-
- return false;
-}
-
void Allocator::GetIonHeapInfo(uint64_t usage, unsigned int *ion_heap_id, unsigned int *alloc_type,
unsigned int *ion_flags) {
unsigned int heap_id = 0;
diff --git a/gralloc/gr_allocator.h b/gralloc/gr_allocator.h
index 17fb0cb..36732c6 100644
--- a/gralloc/gr_allocator.h
+++ b/gralloc/gr_allocator.h
@@ -53,9 +53,6 @@
bool CheckForBufferSharing(uint32_t num_descriptors,
const std::vector<std::shared_ptr<BufferDescriptor>> &descriptors,
ssize_t *max_index);
- int GetImplDefinedFormat(uint64_t usage, int format);
- bool UseUncached(int format, uint64_t usage);
-
private:
void GetIonHeapInfo(uint64_t usage, unsigned int *ion_heap_id, unsigned int *alloc_type,
unsigned int *ion_flags);
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
index 12fd13f..7aa4b05 100644
--- a/gralloc/gr_buf_mgr.cpp
+++ b/gralloc/gr_buf_mgr.cpp
@@ -85,7 +85,7 @@
Error BufferManager::ValidateBufferSize(private_handle_t const *hnd, BufferInfo info) {
unsigned int size, alignedw, alignedh;
- info.format = allocator_->GetImplDefinedFormat(info.usage, info.format);
+ info.format = GetImplDefinedFormat(info.usage, info.format);
GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
auto ion_fd_size = static_cast<unsigned int>(lseek(hnd->fd, 0, SEEK_END));
if (size != ion_fd_size) {
@@ -254,52 +254,6 @@
return status;
}
-int BufferManager::GetHandleFlags(int format, uint64_t usage) {
- int flags = 0;
- if (usage & BufferUsage::VIDEO_ENCODER) {
- flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
- }
-
- if (usage & BufferUsage::CAMERA_OUTPUT) {
- flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
- }
-
- if (usage & BufferUsage::CAMERA_INPUT) {
- flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
- }
-
- if (usage & BufferUsage::COMPOSER_OVERLAY) {
- flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
- }
-
- if (usage & BufferUsage::GPU_TEXTURE) {
- flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
- }
-
- if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
- flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
- }
-
- if (IsUBwcEnabled(format, usage)) {
- flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
- }
-
- if (usage & (BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK)) {
- flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
- }
-
- if ((usage & (BufferUsage::VIDEO_ENCODER | BufferUsage::VIDEO_DECODER |
- BufferUsage::CAMERA_OUTPUT | BufferUsage::GPU_RENDER_TARGET))) {
- flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
- }
-
- if (!allocator_->UseUncached(format, usage)) {
- flags |= private_handle_t::PRIV_FLAGS_CACHED;
- }
-
- return flags;
-}
-
int BufferManager::GetBufferType(int inputFormat) {
int buffer_type = BUFFER_TYPE_UI;
if (IsYuvFormat(inputFormat)) {
@@ -317,7 +271,7 @@
std::lock_guard<std::mutex> buffer_lock(buffer_lock_);
uint64_t usage = descriptor.GetUsage();
- int format = allocator_->GetImplDefinedFormat(usage, descriptor.GetFormat());
+ int format = GetImplDefinedFormat(usage, descriptor.GetFormat());
uint32_t layer_count = descriptor.GetLayerCount();
unsigned int size;
@@ -340,13 +294,13 @@
size = (bufferSize >= size) ? bufferSize : size;
int err = 0;
- int flags = 0;
+ uint64_t flags = 0;
auto page_size = UINT(getpagesize());
AllocData data;
data.align = GetDataAlignment(format, usage);
data.size = size;
data.handle = (uintptr_t)handle;
- data.uncached = allocator_->UseUncached(format, usage);
+ data.uncached = UseUncached(format, usage);
// Allocate buffer memory
err = allocator_->AllocateMem(&data, usage, format);
@@ -372,7 +326,7 @@
// Create handle
private_handle_t *hnd = new private_handle_t(
- data.fd, e_data.fd, flags, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
+ data.fd, e_data.fd, INT(flags), INT(alignedw), INT(alignedh), descriptor.GetWidth(),
descriptor.GetHeight(), format, buffer_type, data.size, usage);
hnd->id = ++next_id_;
diff --git a/gralloc/gr_buf_mgr.h b/gralloc/gr_buf_mgr.h
index 9fcca1b..ca0c1b3 100644
--- a/gralloc/gr_buf_mgr.h
+++ b/gralloc/gr_buf_mgr.h
@@ -54,7 +54,6 @@
BufferManager();
Error MapBuffer(private_handle_t const *hnd);
int GetBufferType(int format);
- int GetHandleFlags(int format, uint64_t usage);
// Imports the ion fds into the current process. Returns an error for invalid handles
Error ImportHandleLocked(private_handle_t *hnd);
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
index a49f1ea..282bcc2 100644
--- a/gralloc/gr_utils.cpp
+++ b/gralloc/gr_utils.cpp
@@ -543,6 +543,28 @@
return false;
}
+bool IsUBwcPISupported(int format, uint64_t usage) {
+ if (usage & BufferUsage::COMPOSER_OVERLAY || !(usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI)) {
+ return false;
+ }
+
+ // As of now only two formats
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: {
+ if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
+ if (AdrenoMemInfo::GetInstance()) {
+ return AdrenoMemInfo::GetInstance()->IsPISupportedByGPU(format, usage);
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
bool IsUBwcEnabled(int format, uint64_t usage) {
// Allow UBWC, if client is using an explicitly defined UBWC pixel format.
if (IsUBwcFormat(format)) {
@@ -552,7 +574,8 @@
// Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
// support the format. OR if a non-OpenGL client like Rotator, sets UBWC
// usage flag and MDP supports the format.
- if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
+ if (((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) || (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI))
+ && IsUBwcSupported(format)) {
bool enable = true;
// Query GPU for UBWC only if buffer is intended to be used by GPU.
if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
@@ -983,4 +1006,142 @@
return false;
}
+bool UseUncached(int format, uint64_t usage) {
+ if ((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) || (usage & BufferUsage::PROTECTED)) {
+ return true;
+ }
+
+ // CPU read rarely
+ if ((usage & BufferUsage::CPU_READ_MASK) == static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) {
+ return true;
+ }
+
+ // CPU write rarely
+ if ((usage & BufferUsage::CPU_WRITE_MASK) ==
+ static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) {
+ return true;
+ }
+
+ if ((usage & BufferUsage::SENSOR_DIRECT_DATA) || (usage & BufferUsage::GPU_DATA_BUFFER)) {
+ return true;
+ }
+
+ if (format && IsUBwcEnabled(format, usage)) {
+ return true;
+ }
+
+ return false;
+}
+
+uint64_t GetHandleFlags(int format, uint64_t usage) {
+ uint64_t priv_flags = 0;
+
+ if (usage & BufferUsage::VIDEO_ENCODER) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
+ }
+
+ if (usage & BufferUsage::CAMERA_OUTPUT) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
+ }
+
+ if (usage & BufferUsage::CAMERA_INPUT) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
+ }
+
+ if (usage & BufferUsage::COMPOSER_OVERLAY) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
+ }
+
+ if (usage & BufferUsage::GPU_TEXTURE) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
+ }
+
+ if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
+ }
+
+ if (IsUBwcEnabled(format, usage)) {
+ if (IsUBwcPISupported(format, usage)) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI;
+ } else {
+ priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ }
+ }
+
+ if (usage & (BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK)) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
+ }
+
+ if ((usage & (BufferUsage::VIDEO_ENCODER | BufferUsage::VIDEO_DECODER |
+ BufferUsage::CAMERA_OUTPUT | BufferUsage::GPU_RENDER_TARGET))) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
+ }
+
+ if (!UseUncached(format, usage)) {
+ priv_flags |= private_handle_t::PRIV_FLAGS_CACHED;
+ }
+
+ return priv_flags;
+}
+
+int GetImplDefinedFormat(uint64_t usage, int format) {
+ int gr_format = format;
+
+ // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
+ // the usage bits, gralloc assigns a format.
+ if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+ format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ if (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC || usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI) {
+ // Use of 10BIT_TP and 10BIT bits is supposed to be mutually exclusive.
+ // Each bit maps to only one format. Here we will check one of the bits
+ // and ignore the other.
+ if (usage & GRALLOC_USAGE_PRIVATE_10BIT_TP) {
+ gr_format = HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC;
+ } else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
+ gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC;
+ } else {
+ gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
+ }
+ } else if (usage & GRALLOC_USAGE_PRIVATE_10BIT) {
+ gr_format = HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS;
+ } else if (usage & BufferUsage::VIDEO_ENCODER) {
+ if (usage & GRALLOC_USAGE_PRIVATE_VIDEO_NV21_ENCODER) {
+ gr_format = HAL_PIXEL_FORMAT_NV21_ENCODEABLE; // NV21
+ } else {
+ gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12
+ }
+ } else if (usage & BufferUsage::CAMERA_INPUT) {
+ if (usage & BufferUsage::CAMERA_OUTPUT) {
+ // Assumed ZSL if both producer and consumer camera flags set
+ gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
+ } else {
+ gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21
+ }
+ } else if (usage & BufferUsage::CAMERA_OUTPUT) {
+ if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
+ } else {
+ gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; // NV12 preview
+ }
+ } else if (usage & BufferUsage::COMPOSER_OVERLAY) {
+ // XXX: If we still haven't set a format, default to RGBA8888
+ gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
+ } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ // If no other usage flags are detected, default the
+ // flexible YUV format to NV21_ZSL
+ gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
+ }
+ }
+
+ return gr_format;
+}
+
+int GetCustomFormatFlags(int format, uint64_t usage,
+ int *custom_format, uint64_t *priv_flags) {
+ *custom_format = GetImplDefinedFormat(usage, format);
+ *priv_flags = GetHandleFlags(*custom_format, usage);
+
+ return 0;
+}
+
} // namespace gralloc
diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h
index fa62871..68f826f 100644
--- a/gralloc/gr_utils.h
+++ b/gralloc/gr_utils.h
@@ -86,6 +86,7 @@
int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data);
bool IsUBwcFormat(int format);
bool IsUBwcSupported(int format);
+bool IsUBwcPISupported(int format, uint64_t usage);
bool IsUBwcEnabled(int format, uint64_t usage);
void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
unsigned int *aligned_h);
@@ -102,11 +103,14 @@
int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
uint32_t *num_planes);
uint32_t GetDataAlignment(int format, uint64_t usage);
-
void GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
unsigned int *alignedw, unsigned int *alignedh,
GraphicsMetadata *graphics_metadata);
bool GetAdrenoSizeAPIStatus();
+bool UseUncached(int format, uint64_t usage);
+uint64_t GetHandleFlags(int format, uint64_t usage);
+int GetImplDefinedFormat(uint64_t usage, int format);
+int GetCustomFormatFlags(int format, uint64_t usage, int *custom_format, uint64_t *priv_flags);
} // namespace gralloc
#endif // __GR_UTILS_H__