From f13f2213ee1071bd5602b95f110c1072671cfff8 Mon Sep 17 00:00:00 2001 From: Naseer Ahmed Date: Tue, 22 Nov 2016 20:05:16 -0500 Subject: [PATCH] gralloc1: Add remaining functionality * Use private_0 flag * Add some legacy flags to be used during transition * Fix gralloc module version * Adjust makefiles for gralloc1 * Add support for dump, num flex planes and lock flex. * Use a unique ID for buffer descriptors * Do not delete buffer handle, fix after verifying framework fix. * Current gralloc1 clients do not conform to the lock() requirement in the gralloc1 header. Tracked in b/33588773 * Add perform APIs to get the buffer size and allocate a buffer for use by SDM * Fix reference counting * Add a unique buffer ID * Some cleanup in private_handle * Create a wrapper class of private_handle to do refcounting * Resolve implementation defined formats At allocation time, update buffer descriptors to replace implementation defined formats with the ones we mean to allocate * Defer ion handle release * Remove unused drm code. * Add legacy constructor for private_handle_t used by some clients * Add FP16 support * Add Dump() in buffer manager * Use handle as map key * Drop ZSL check CRs-Fixed: 2007391 Change-Id: Iaf843d93c031839d90403cc2e6927b516aedd354 --- msm8996/Android.mk | 6 +- msm8996/libcopybit/Android.mk | 4 +- msm8996/libgralloc1/gr_adreno_info.cpp | 12 +- msm8996/libgralloc1/gr_adreno_info.h | 17 +- msm8996/libgralloc1/gr_allocator.cpp | 177 ++++----- msm8996/libgralloc1/gr_allocator.h | 21 +- msm8996/libgralloc1/gr_buf_descriptor.h | 24 +- msm8996/libgralloc1/gr_buf_mgr.cpp | 465 ++++++++++++++++++------ msm8996/libgralloc1/gr_buf_mgr.h | 90 ++++- msm8996/libgralloc1/gr_device_impl.cpp | 226 ++++++------ msm8996/libgralloc1/gr_device_impl.h | 39 +- msm8996/libgralloc1/gr_ion_alloc.cpp | 50 +-- msm8996/libgralloc1/gr_ion_alloc.h | 8 +- msm8996/libgralloc1/gr_priv_handle.h | 105 +++--- msm8996/libgralloc1/gr_utils.cpp | 4 + msm8996/libgralloc1/gralloc_priv.h | 83 +++-- msm8996/sdm/libs/hwc2/Android.mk | 8 +- 17 files changed, 830 insertions(+), 509 deletions(-) diff --git a/msm8996/Android.mk b/msm8996/Android.mk index 5f260f18..b5961ad0 100644 --- a/msm8996/Android.mk +++ b/msm8996/Android.mk @@ -1,5 +1,9 @@ display-hals := libcopybit liblight libmemtrack libqservice libqdutils -display-hals += libgralloc +ifneq ($(TARGET_USES_GRALLOC1), true) + display-hals += libgralloc +else + display-hals += libgralloc1 +endif display-hals += hdmi_cec sdm-libs := sdm/libs diff --git a/msm8996/libcopybit/Android.mk b/msm8996/libcopybit/Android.mk index a5a62776..41ee9e90 100644 --- a/msm8996/libcopybit/Android.mk +++ b/msm8996/libcopybit/Android.mk @@ -21,12 +21,13 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) include $(BUILD_HEADER_LIBRARY) include $(CLEAR_VARS) +ifneq ($(TARGET_USES_GRALLOC1), true) LOCAL_MODULE := copybit.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_PROPRIETARY_MODULE := true LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes) -LOCAL_SHARED_LIBRARIES := $(common_libs) libdl libmemalloc +LOCAL_SHARED_LIBRARIES := $(common_libs) libdl LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdcopybit\" -Wno-sign-conversion LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) LOCAL_CLANG := true @@ -48,3 +49,4 @@ else endif endif endif +endif diff --git a/msm8996/libgralloc1/gr_adreno_info.cpp b/msm8996/libgralloc1/gr_adreno_info.cpp index adb59f08..0692ca6c 100644 --- a/msm8996/libgralloc1/gr_adreno_info.cpp +++ b/msm8996/libgralloc1/gr_adreno_info.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -47,8 +47,6 @@ bool AdrenoMemInfo::Init() { ::dlsym(libadreno_utils_, "compute_aligned_width_and_height"); *reinterpret_cast(&LINK_adreno_compute_padding) = ::dlsym(libadreno_utils_, "compute_surface_padding"); - *reinterpret_cast(&LINK_adreno_isMacroTilingSupportedByGpu) = - ::dlsym(libadreno_utils_, "isMacroTilingSupportedByGpu"); *reinterpret_cast(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) = ::dlsym(libadreno_utils_, "compute_compressedfmt_aligned_width_and_height"); *reinterpret_cast(&LINK_adreno_isUBWCSupportedByGpu) = @@ -84,14 +82,6 @@ AdrenoMemInfo::~AdrenoMemInfo() { } } -bool AdrenoMemInfo::IsMacroTilingSupportedByGPU() { - if (LINK_adreno_isMacroTilingSupportedByGpu) { - return LINK_adreno_isMacroTilingSupportedByGpu(); - } - - return false; -} - void AdrenoMemInfo::AlignUnCompressedRGB(int width, int height, int format, int tile_enabled, unsigned int *aligned_w, unsigned int *aligned_h) { *aligned_w = (unsigned int)ALIGN(width, 32); diff --git a/msm8996/libgralloc1/gr_adreno_info.h b/msm8996/libgralloc1/gr_adreno_info.h index 7b053ad6..7ad68017 100644 --- a/msm8996/libgralloc1/gr_adreno_info.h +++ b/msm8996/libgralloc1/gr_adreno_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -30,13 +30,7 @@ #ifndef __GR_ADRENO_INFO_H__ #define __GR_ADRENO_INFO_H__ -#ifdef VENUS_COLOR_FORMAT #include -#else -#define VENUS_Y_STRIDE(args...) 0 -#define VENUS_Y_SCANLINES(args...) 0 -#define VENUS_BUFFER_SIZE(args...) 0 -#endif namespace gralloc1 { @@ -111,14 +105,6 @@ class AdrenoMemInfo { */ uint32_t GetGpuPixelAlignment(); - /* - * Function to return whether GPU support MacroTile feature - * - * @return >0 : supported - * 0 : not supported - */ - bool IsMacroTilingSupportedByGPU(); - /* * Function to query whether GPU supports UBWC for given HAL format * @return > 0 : supported @@ -139,7 +125,6 @@ class AdrenoMemInfo { int tile_mode, int raster_mode, int padding_threshold, int *aligned_w, int *aligned_h) = NULL; - int (*LINK_adreno_isMacroTilingSupportedByGpu)(void) = NULL; void (*LINK_adreno_compute_compressedfmt_aligned_width_and_height)( int width, int height, int format, int tile_mode, int raster_mode, int padding_threshold, int *aligned_w, int *aligned_h, int *bpp) = NULL; diff --git a/msm8996/libgralloc1/gr_allocator.cpp b/msm8996/libgralloc1/gr_allocator.cpp index b8331b64..9a461152 100644 --- a/msm8996/libgralloc1/gr_allocator.cpp +++ b/msm8996/libgralloc1/gr_allocator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,6 +29,7 @@ #include #include +#include #include "gr_utils.h" #include "gr_allocator.h" @@ -48,18 +49,29 @@ #define ION_FLAG_ALLOW_NON_CONTIG 0 #endif +#ifndef ION_FLAG_CP_CAMERA_PREVIEW +#define ION_FLAG_CP_CAMERA_PREVIEW 0 +#endif + #ifdef MASTER_SIDE_CP #define CP_HEAP_ID ION_SECURE_HEAP_ID #define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL) #define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY) +#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA) +#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW) #else // SLAVE_SIDE_CP #define CP_HEAP_ID ION_CP_MM_HEAP_ID #define SD_HEAP_ID CP_HEAP_ID #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG) #define ION_SD_FLAGS ION_SECURE +#define ION_SC_FLAGS ION_SECURE +#define ION_SC_PREVIEW_FLAGS ION_SECURE #endif +using std::vector; +using std::shared_ptr; + namespace gralloc1 { Allocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) { @@ -76,11 +88,6 @@ bool Allocator::Init() { return false; } - gpu_support_macrotile = adreno_helper_->IsMacroTilingSupportedByGPU(); - int supports_macrotile = 0; - qdutils::querySDEInfo(qdutils::HAS_MACRO_TILE, &supports_macrotile); - display_support_macrotile = !!supports_macrotile; - return true; } @@ -114,43 +121,6 @@ int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod return ret; } -// Allocates buffer from width, height and format into a -// private_handle_t. It is the responsibility of the caller -// to free the buffer using the FreeBuffer function -int Allocator::AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd) { - AllocData data; - unsigned int aligned_w, aligned_h; - data.base = 0; - data.fd = -1; - data.offset = 0; - data.align = (unsigned int)getpagesize(); - int format = descriptor.GetFormat(); - gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage(); - gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage(); - GetBufferSizeAndDimensions(descriptor, &data.size, &aligned_w, &aligned_h); - - int err = AllocateMem(&data, prod_usage, cons_usage); - if (0 != err) { - ALOGE("%s: allocate failed", __FUNCTION__); - return -ENOMEM; - } - - if (IsUBwcEnabled(format, prod_usage, cons_usage)) { - data.alloc_type |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; - } - - // Metadata is not allocated. would be empty - private_handle_t *hnd = new private_handle_t( - data.fd, data.size, INT(data.alloc_type), 0, INT(format), INT(aligned_w), INT(aligned_h), -1, - 0, 0, descriptor.GetWidth(), descriptor.GetHeight(), prod_usage, cons_usage); - hnd->base = (uint64_t)data.base; - hnd->offset = data.offset; - hnd->gpuaddr = 0; - *pHnd = hnd; - - return 0; -} - int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) { if (ion_allocator_) { return ion_allocator_->MapBuffer(base, size, offset, fd); @@ -159,24 +129,33 @@ int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, in return -EINVAL; } -int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) { +int Allocator::ImportBuffer(int fd) { if (ion_allocator_) { - return ion_allocator_->FreeBuffer(base, size, offset, fd); + return ion_allocator_->ImportBuffer(fd); + } + return -EINVAL; +} + +int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, + int handle) { + if (ion_allocator_) { + return ion_allocator_->FreeBuffer(base, size, offset, fd, handle); } return -EINVAL; } -int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) { +int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) { if (ion_allocator_) { - return ion_allocator_->CleanBuffer(base, size, offset, fd, op); + return ion_allocator_->CleanBuffer(base, size, offset, handle, op); } return -EINVAL; } -bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors, - int *max_index) { +bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, + const vector>& descriptors, + ssize_t *max_index) { unsigned int cur_heap_id = 0, prev_heap_id = 0; unsigned int cur_alloc_type = 0, prev_alloc_type = 0; unsigned int cur_ion_flags = 0, prev_ion_flags = 0; @@ -187,8 +166,8 @@ bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDesc *max_index = -1; for (uint32_t i = 0; i < num_descriptors; i++) { // Check Cached vs non-cached and all the ION flags - cur_uncached = UseUncached(descriptors[i].GetProducerUsage()); - GetIonHeapInfo(descriptors[i].GetProducerUsage(), descriptors[i].GetConsumerUsage(), + cur_uncached = UseUncached(descriptors[i]->GetProducerUsage()); + GetIonHeapInfo(descriptors[i]->GetProducerUsage(), descriptors[i]->GetConsumerUsage(), &cur_heap_id, &cur_alloc_type, &cur_ion_flags); if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type || @@ -197,8 +176,8 @@ bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDesc } // For same format type, find the descriptor with bigger size - GetAlignedWidthAndHeight(descriptors[i], &alignedw, &alignedh); - unsigned int size = GetSize(descriptors[i], alignedw, alignedh); + GetAlignedWidthAndHeight(*descriptors[i], &alignedw, &alignedh); + unsigned int size = GetSize(*descriptors[i], alignedw, alignedh); if (max_size < size) { *max_index = INT(i); max_size = size; @@ -213,34 +192,6 @@ bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDesc return true; } -bool Allocator::IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage, - gralloc1_consumer_usage_t cons_usage) { - bool tile_enabled = false; - - // Check whether GPU & MDSS supports MacroTiling feature - if (!adreno_helper_->IsMacroTilingSupportedByGPU() || !display_support_macrotile) { - return tile_enabled; - } - - // check the format - switch (format) { - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGB_565: - case HAL_PIXEL_FORMAT_BGR_565: - if (!CpuCanAccess(prod_usage, cons_usage)) { - // not touched by CPU - tile_enabled = true; - } - break; - default: - break; - } - - return tile_enabled; -} - // helper function unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw, unsigned int alignedh) { @@ -272,8 +223,12 @@ unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int size = alignedw * alignedh * 2; break; case HAL_PIXEL_FORMAT_RAW10: + case HAL_PIXEL_FORMAT_RAW12: size = ALIGN(alignedw * alignedh, SIZE_4K); break; + case HAL_PIXEL_FORMAT_RAW8: + size = alignedw * alignedh * 1; + break; // adreno formats case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21 @@ -299,6 +254,9 @@ unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int case HAL_PIXEL_FORMAT_YCrCb_420_SP: size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K); break; + case HAL_PIXEL_FORMAT_YCbCr_420_P010: + size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K); + break; case HAL_PIXEL_FORMAT_YCbCr_422_SP: case HAL_PIXEL_FORMAT_YCrCb_422_SP: case HAL_PIXEL_FORMAT_YCbCr_422_I: @@ -350,22 +308,6 @@ void Allocator::GetBufferSizeAndDimensions(const BufferDescriptor &descriptor, u *size = GetSize(descriptor, *alignedw, *alignedh); } -void Allocator::GetBufferAttributes(const BufferDescriptor &descriptor, unsigned int *alignedw, - unsigned int *alignedh, int *tiled, unsigned int *size) { - int format = descriptor.GetFormat(); - gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage(); - gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage(); - - *tiled = false; - if (IsUBwcEnabled(format, prod_usage, cons_usage) || - IsMacroTileEnabled(format, prod_usage, cons_usage)) { - *tiled = true; - } - - GetAlignedWidthAndHeight(descriptor, alignedw, alignedh); - *size = GetSize(descriptor, *alignedw, *alignedh); -} - void Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format, struct android_ycbcr *ycbcr) { // UBWC buffer has these 4 planes in the following sequence: @@ -471,6 +413,7 @@ int Allocator::GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr case HAL_PIXEL_FORMAT_NV21_ZSL: case HAL_PIXEL_FORMAT_RAW16: case HAL_PIXEL_FORMAT_RAW10: + case HAL_PIXEL_FORMAT_RAW8: GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); std::swap(ycbcr->cb, ycbcr->cr); break; @@ -511,10 +454,13 @@ int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage, gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC; } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) { gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12 - } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL) { - gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21 ZSL } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) { - gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21 + if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) { + // 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 (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) { if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21 @@ -590,7 +536,7 @@ void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, unsigned int *alloc_type, unsigned int *ion_flags) { unsigned int heap_id = 0; unsigned int type = 0; - int flags = 0; + uint32_t flags = 0; if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) { if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) { heap_id = ION_HEAP(SD_HEAP_ID); @@ -598,10 +544,17 @@ void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, * There is currently no flag in ION for Secure Display * VM. Please add it to the define once available. */ - flags |= ION_SD_FLAGS; + flags |= UINT(ION_SD_FLAGS); + } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) { + heap_id = ION_HEAP(SD_HEAP_ID); + if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) { + flags |= UINT(ION_SC_PREVIEW_FLAGS); + } else { + flags |= UINT(ION_SC_FLAGS); + } } else { heap_id = ION_HEAP(CP_HEAP_ID); - flags |= ION_CP_FLAGS; + flags |= UINT(ION_CP_FLAGS); } } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) { // MM Heap is exclusively a secure heap. @@ -618,7 +571,7 @@ void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, heap_id |= ION_HEAP(ION_ADSP_HEAP_ID); } - if (flags & ION_SECURE) { + if (flags & UINT(ION_SECURE)) { type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER; } @@ -628,7 +581,7 @@ void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, } *alloc_type = type; - *ion_flags = (unsigned int)flags; + *ion_flags = flags; *ion_heap_id = heap_id; return; @@ -670,6 +623,11 @@ void Allocator::GetYuvUBwcWidthAndHeight(int width, int height, int format, unsi *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width); *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height); break; + case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: + // The macro returns the stride which is 4/3 times the width, hence * 3/4 + *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4; + *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height); + break; default: ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); *aligned_w = 0; @@ -797,7 +755,7 @@ void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, uns // Currently surface padding is only computed for RGB* surfaces. bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage); - int tile = ubwc_enabled || IsMacroTileEnabled(format, prod_usage, cons_usage); + int tile = ubwc_enabled; if (IsUncompressedRGBFormat(format)) { adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh); @@ -831,9 +789,15 @@ void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, uns case HAL_PIXEL_FORMAT_RAW16: aligned_w = ALIGN(width, 16); break; + case HAL_PIXEL_FORMAT_RAW12: + aligned_w = ALIGN(width * 12 / 8, 8); + break; case HAL_PIXEL_FORMAT_RAW10: aligned_w = ALIGN(width * 10 / 8, 8); break; + case HAL_PIXEL_FORMAT_RAW8: + aligned_w = ALIGN(width, 8); + break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: aligned_w = ALIGN(width, 128); break; @@ -842,6 +806,7 @@ void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, uns case HAL_PIXEL_FORMAT_YCrCb_422_SP: case HAL_PIXEL_FORMAT_YCbCr_422_I: case HAL_PIXEL_FORMAT_YCrCb_422_I: + case HAL_PIXEL_FORMAT_YCbCr_420_P010: aligned_w = ALIGN(width, 16); break; case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: diff --git a/msm8996/libgralloc1/gr_allocator.h b/msm8996/libgralloc1/gr_allocator.h index 583b2d7e..df1a30ce 100644 --- a/msm8996/libgralloc1/gr_allocator.h +++ b/msm8996/libgralloc1/gr_allocator.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -36,6 +36,8 @@ #define SECURE_ALIGN SZ_1M #endif +#include + #include "gralloc_priv.h" #include "gr_buf_descriptor.h" #include "gr_adreno_info.h" @@ -48,17 +50,16 @@ class Allocator { Allocator(); ~Allocator(); bool Init(); - int AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd); int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd); - int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd); - int CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op); + int ImportBuffer(int fd); + int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, int handle); + int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op); int AllocateMem(AllocData *data, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage); - bool IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage, - gralloc1_consumer_usage_t cons_usage); // @return : index of the descriptor with maximum buffer size req - bool CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors, - int *max_index); + bool CheckForBufferSharing(uint32_t num_descriptors, + const std::vector>& descriptors, + ssize_t *max_index); int GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage, int format); unsigned int GetSize(const BufferDescriptor &d, unsigned int alignedw, unsigned int alignedh); @@ -68,8 +69,6 @@ class Allocator { unsigned int *alignedw, unsigned int *alignedh); void GetAlignedWidthAndHeight(const BufferDescriptor &d, unsigned int *aligned_w, unsigned int *aligned_h); - void GetBufferAttributes(const BufferDescriptor &d, unsigned int *alignedw, - unsigned int *alignedh, int *tiled, unsigned int *size); int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr); int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data); bool UseUncached(gralloc1_producer_usage_t usage); @@ -92,8 +91,6 @@ class Allocator { void GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id, unsigned int *alloc_type, unsigned int *ion_flags); - bool gpu_support_macrotile = false; - bool display_support_macrotile = false; IonAlloc *ion_allocator_ = NULL; AdrenoMemInfo *adreno_helper_ = NULL; }; diff --git a/msm8996/libgralloc1/gr_buf_descriptor.h b/msm8996/libgralloc1/gr_buf_descriptor.h index 1c3572db..95386fa3 100644 --- a/msm8996/libgralloc1/gr_buf_descriptor.h +++ b/msm8996/libgralloc1/gr_buf_descriptor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -32,18 +32,18 @@ #include -#define BUF_DESCRIPTOR(exp) reinterpret_cast(exp) - +namespace gralloc1 { class BufferDescriptor { public: - BufferDescriptor() {} + BufferDescriptor() : id_(next_id_++) {} BufferDescriptor(int w, int h, int f) : width_(w), height_(h), format_(f), producer_usage_(GRALLOC1_PRODUCER_USAGE_NONE), - consumer_usage_(GRALLOC1_CONSUMER_USAGE_NONE) {} + consumer_usage_(GRALLOC1_CONSUMER_USAGE_NONE), + id_(next_id_++) {} BufferDescriptor(int w, int h, int f, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) @@ -51,9 +51,8 @@ class BufferDescriptor { height_(h), format_(f), producer_usage_(prod_usage), - consumer_usage_(cons_usage) {} - - bool IsValid() { return (magic == kMagic); } + consumer_usage_(cons_usage), + id_(next_id_++) {} void SetConsumerUsage(gralloc1_consumer_usage_t usage) { consumer_usage_ = usage; } @@ -76,15 +75,16 @@ class BufferDescriptor { int GetFormat() const { return format_; } - private: - static const int kMagic = 'gr1d'; + gralloc1_buffer_descriptor_t GetId() const { return id_; } - int magic = kMagic; + private: int width_ = -1; int height_ = -1; int format_ = -1; gralloc1_producer_usage_t producer_usage_ = GRALLOC1_PRODUCER_USAGE_NONE; gralloc1_consumer_usage_t consumer_usage_ = GRALLOC1_CONSUMER_USAGE_NONE; + const gralloc1_buffer_descriptor_t id_; + static std::atomic next_id_; }; - +}; // namespace gralloc1 #endif // __GR_BUF_DESCRIPTOR_H__ diff --git a/msm8996/libgralloc1/gr_buf_mgr.cpp b/msm8996/libgralloc1/gr_buf_mgr.cpp index 33abd401..6432820f 100644 --- a/msm8996/libgralloc1/gr_buf_mgr.cpp +++ b/msm8996/libgralloc1/gr_buf_mgr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. * Not a Contribution * * Copyright (C) 2010 The Android Open Source Project @@ -17,7 +17,11 @@ * limitations under the License. */ +#define DEBUG 0 +#include #include +#include +#include #include "qd_utils.h" #include "gr_priv_handle.h" @@ -27,8 +31,9 @@ #include "qdMetaData.h" namespace gralloc1 { +std::atomic BufferDescriptor::next_id_(1); -BufferManager::BufferManager() { +BufferManager::BufferManager() : next_id_(0) { char property[PROPERTY_VALUE_MAX]; // Map framebuffer memory @@ -46,6 +51,29 @@ BufferManager::BufferManager() { } handles_map_.clear(); + allocator_ = new Allocator(); + allocator_->Init(); +} + + +gralloc1_error_t BufferManager::CreateBufferDescriptor( + gralloc1_buffer_descriptor_t *descriptor_id) { + std::lock_guard lock(locker_); + auto descriptor = std::make_shared(); + descriptors_map_.emplace(descriptor->GetId(), descriptor); + *descriptor_id = descriptor->GetId(); + return GRALLOC1_ERROR_NONE; +} + +gralloc1_error_t BufferManager::DestroyBufferDescriptor( + gralloc1_buffer_descriptor_t descriptor_id) { + std::lock_guard lock(locker_); + const auto descriptor = descriptors_map_.find(descriptor_id); + if (descriptor == descriptors_map_.end()) { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; + } + descriptors_map_.erase(descriptor); + return GRALLOC1_ERROR_NONE; } BufferManager::~BufferManager() { @@ -54,14 +82,8 @@ BufferManager::~BufferManager() { } } -bool BufferManager::Init() { - allocator_ = new Allocator(); - - return allocator_->Init(); -} - gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors, - const BufferDescriptor *descriptors, + const gralloc1_buffer_descriptor_t *descriptor_ids, buffer_handle_t *out_buffers) { bool shared = true; gralloc1_error_t status = GRALLOC1_ERROR_NONE; @@ -70,10 +92,28 @@ gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors, // client can ask to test the allocation by passing NULL out_buffers bool test_allocate = !out_buffers; + // Validate descriptors + std::vector> descriptors; + for (uint32_t i = 0; i < num_descriptors; i++) { + const auto map_descriptor = descriptors_map_.find(descriptor_ids[i]); + if (map_descriptor == descriptors_map_.end()) { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; + } else { + descriptors.push_back(map_descriptor->second); + } + } + + // Resolve implementation defined formats + for (auto &descriptor : descriptors) { + descriptor->SetColorFormat(allocator_->GetImplDefinedFormat(descriptor->GetProducerUsage(), + descriptor->GetConsumerUsage(), + descriptor->GetFormat())); + } + // Check if input descriptors can be supported AND // Find out if a single buffer can be shared for all the given input descriptors uint32_t i = 0; - int max_buf_index = -1; + ssize_t max_buf_index = -1; shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index); if (test_allocate) { @@ -83,7 +123,7 @@ gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors, if (shared && (max_buf_index >= 0)) { // Allocate one and duplicate/copy the handles for each descriptor - if (AllocateBuffer(descriptors[max_buf_index], &out_buffers[max_buf_index])) { + if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) { return GRALLOC1_ERROR_NO_RESOURCES; } @@ -92,20 +132,14 @@ gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors, // Current assumption is even MetaData memory would be same // Need to revisit if there is a need for own metadata memory if (i != UINT(max_buf_index)) { - CreateSharedHandle(out_buffers[max_buf_index], descriptors[i], &out_buffers[i]); - - // since we just created handle out of existing handle add it to map - locker_.lock(); - handles_map_.insert(std::pair( - reinterpret_cast(out_buffers[i]), 1)); - locker_.unlock(); + CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]); } } } else { // Buffer sharing is not feasible. - // Allocate seperate buffer for each descriptor + // Allocate separate buffer for each descriptor for (i = 0; i < num_descriptors; i++) { - if (AllocateBuffer(descriptors[i], &out_buffers[i])) { + if (AllocateBuffer(*descriptors[i], &out_buffers[i])) { return GRALLOC1_ERROR_NO_RESOURCES; } } @@ -121,6 +155,7 @@ gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors, void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor, buffer_handle_t *outbuffer) { + // TODO(user): This path is not verified private_handle_t const *input = reinterpret_cast(inbuffer); // Get Buffer attributes or dimension @@ -133,34 +168,82 @@ void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDes int buffer_type = GetBufferType(descriptor.GetFormat()); // Duplicate the fds - private_handle_t *out_hnd = new private_handle_t( - dup(input->fd), input->size, flags, buffer_type, descriptor.GetFormat(), INT(alignedw), - INT(alignedh), dup(input->fd_metadata), input->offset_metadata, input->base_metadata, - descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetProducerUsage(), - descriptor.GetConsumerUsage()); - + // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions? + private_handle_t *out_hnd = new private_handle_t(dup(input->fd), + dup(input->fd_metadata), + flags, + INT(alignedw), + INT(alignedh), + descriptor.GetWidth(), + descriptor.GetHeight(), + descriptor.GetFormat(), + buffer_type, + input->size, + descriptor.GetProducerUsage(), + descriptor.GetConsumerUsage()); + out_hnd->id = ++next_id_; + // TODO(user): Base address of shared handle and ion handles + RegisterHandle(out_hnd, -1, -1); *outbuffer = out_hnd; } -gralloc1_error_t BufferManager::FreeBuffer(private_handle_t const *hnd) { +gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr buf) { + auto hnd = buf->handle; if (allocator_->FreeBuffer(reinterpret_cast(hnd->base), hnd->size, hnd->offset, - hnd->fd) != 0) { + hnd->fd, buf->ion_handle_main) != 0) { return GRALLOC1_ERROR_BAD_HANDLE; } unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE); if (allocator_->FreeBuffer(reinterpret_cast(hnd->base_metadata), meta_size, - hnd->offset_metadata, hnd->fd_metadata) != 0) { + hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) { return GRALLOC1_ERROR_BAD_HANDLE; } - // delete handle also - private_handle_t *handle = const_cast(hnd); - delete handle; - + // TODO(user): delete handle once framework bug around this is confirmed + // to be resolved. This is tracked in bug 36355756 + private_handle_t * handle = const_cast(hnd); + handle->fd = -1; + handle->fd_metadata = -1; return GRALLOC1_ERROR_NONE; } +void BufferManager::RegisterHandle(const private_handle_t *hnd, + int ion_handle, + int ion_handle_meta) { + auto buffer = std::make_shared(hnd, ion_handle, ion_handle_meta); + handles_map_.emplace(std::make_pair(hnd, buffer)); +} + +gralloc1_error_t BufferManager::ImportHandle(private_handle_t* hnd) { + int ion_handle = allocator_->ImportBuffer(hnd->fd); + if (ion_handle < 0) { + ALOGE("Failed to import ion buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, hnd->fd, hnd->id); + return GRALLOC1_ERROR_BAD_HANDLE; + } + int ion_handle_meta = allocator_->ImportBuffer(hnd->fd_metadata); + if (ion_handle_meta < 0) { + ALOGE("Failed to import ion metadata buffer: hnd: %p, fd:%d, id:%" PRIu64, hnd, + hnd->fd, hnd->id); + return GRALLOC1_ERROR_BAD_HANDLE; + } + // Set base pointers to NULL since the data here was received over binder + hnd->base = 0; + hnd->base_metadata = 0; + RegisterHandle(hnd, ion_handle, ion_handle_meta); + return GRALLOC1_ERROR_NONE; +} + +std::shared_ptr +BufferManager::GetBufferFromHandle(const private_handle_t *hnd) { + auto it = handles_map_.find(hnd); + if (it != handles_map_.end()) { + return it->second; + } else { + return nullptr; + } +} + gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) { private_handle_t *hnd = const_cast(handle); @@ -171,7 +254,7 @@ gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) { return GRALLOC1_ERROR_BAD_HANDLE; } - unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE); + unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), getpagesize()); if (allocator_->MapBuffer(reinterpret_cast(&hnd->base_metadata), size, hnd->offset_metadata, hnd->fd_metadata) != 0) { return GRALLOC1_ERROR_BAD_HANDLE; @@ -181,50 +264,44 @@ gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) { } gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) { - locker_.lock(); - - // find if this handle is already in map - auto it = handles_map_.find(hnd); - if (it != handles_map_.end()) { - // It's already in map, Just increment refcnt - // No need to mmap the memory. - it->second = it->second + 1; + std::lock_guard lock(locker_); + ALOGD_IF(DEBUG, "Retain buffer handle:%p id: %" PRIu64, hnd, hnd->id); + gralloc1_error_t err = GRALLOC1_ERROR_NONE; + auto buf = GetBufferFromHandle(hnd); + if (buf != nullptr) { + buf->IncRef(); } else { - // not present in the map. mmap and then add entry to map - if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) { - handles_map_.insert(std::pair(hnd, 1)); + private_handle_t *handle = const_cast(hnd); + err = ImportHandle(handle); + if (err == GRALLOC1_ERROR_NONE) { + // TODO(user): Do not map here, map should be in lock() + err = MapBuffer(hnd); } } - - locker_.unlock(); - return GRALLOC1_ERROR_NONE; + return err; } gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) { - locker_.lock(); - - // find if this handle is already in map - auto it = handles_map_.find(hnd); - if (it == handles_map_.end()) { - // Corrupt handle or map. - locker_.unlock(); + std::lock_guard lock(locker_); + ALOGD_IF(DEBUG, "Release buffer handle:%p id: %" PRIu64, hnd, hnd->id); + auto buf = GetBufferFromHandle(hnd); + if (buf == nullptr) { + ALOGE("Could not find handle: %p id: %" PRIu64, hnd, hnd->id); return GRALLOC1_ERROR_BAD_HANDLE; } else { - it->second = it->second - 1; + if (buf->DecRef()) { + handles_map_.erase(hnd); + // Unmap, close ion handle and close fd + FreeBuffer(buf); + } } - - if (!it->second) { - handles_map_.erase(it); - FreeBuffer(hnd); - } - - locker_.unlock(); return GRALLOC1_ERROR_NONE; } gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) { + std::lock_guard lock(locker_); gralloc1_error_t err = GRALLOC1_ERROR_NONE; // If buffer is not meant for CPU return err @@ -234,18 +311,23 @@ gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd, if (hnd->base == 0) { // we need to map for real - locker_.lock(); err = MapBuffer(hnd); - locker_.unlock(); + } + + auto buf = GetBufferFromHandle(hnd); + if (buf == nullptr) { + return GRALLOC1_ERROR_BAD_HANDLE; } // Invalidate if CPU reads in software and there are non-CPU // writers. No need to do this for the metadata buffer as it is // only read/written in software. + + // todo use handle here if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) && (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) { if (allocator_->CleanBuffer(reinterpret_cast(hnd->base), hnd->size, hnd->offset, - hnd->fd, CACHE_INVALIDATE)) { + buf->ion_handle_main, CACHE_INVALIDATE)) { return GRALLOC1_ERROR_BAD_HANDLE; } } @@ -260,32 +342,36 @@ gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd, } gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) { + std::lock_guard lock(locker_); gralloc1_error_t status = GRALLOC1_ERROR_NONE; - locker_.lock(); private_handle_t *hnd = const_cast(handle); + auto buf = GetBufferFromHandle(hnd); + if (buf == nullptr) { + return GRALLOC1_ERROR_BAD_HANDLE; + } if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { if (allocator_->CleanBuffer(reinterpret_cast(hnd->base), hnd->size, hnd->offset, - hnd->fd, CACHE_CLEAN) != 0) { + buf->ion_handle_main, CACHE_CLEAN) != 0) { status = GRALLOC1_ERROR_BAD_HANDLE; } hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; } - locker_.unlock(); return status; } -int BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage, +uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) { - int align = getpagesize(); + uint32_t align = UINT(getpagesize()); if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) { align = 8192; } if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) { - if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) { + if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) || + (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) { // The alignment here reflects qsee mmu V7L/V8L requirement align = SZ_2M; } else { @@ -331,10 +417,6 @@ int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usa flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY; } - if (allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage)) { - flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED; - } - if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) { flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; } @@ -361,65 +443,68 @@ int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usa return flags; } -int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int real_w, - int real_h, int format, int bufferType, +int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w, + int unaligned_h, int format, int bufferType, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) { + auto page_size = UINT(getpagesize()); int err = 0; int flags = 0; - size = ALIGN(size, PAGE_SIZE); AllocData data; - data.align = (unsigned int)GetDataAlignment(format, prod_usage, cons_usage); - size = ALIGN(size, data.align); - data.size = size; + data.align = GetDataAlignment(format, prod_usage, cons_usage); + data.size = ALIGN(size, data.align); data.handle = (uintptr_t)handle; - - // Allocate memory data.uncached = allocator_->UseUncached(prod_usage); + + // Allocate buffer memory err = allocator_->AllocateMem(&data, prod_usage, cons_usage); if (err) { ALOGE("gralloc failed to allocate err=%s", strerror(-err)); - *handle = 0; return err; } - // allocate memory for MetaData + // Allocate memory for MetaData AllocData e_data; - e_data.size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE); + e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size); e_data.handle = data.handle; - e_data.align = (unsigned int)getpagesize(); - - ColorSpace_t colorSpace = ITU_R_601; - if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) { - colorSpace = ITU_R_601_FR; - } + e_data.align = page_size; err = allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE); - ALOGE_IF(err, "gralloc failed for e_daata error=%s", strerror(-err)); + if (err) { + ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err)); + return err; + } flags = GetHandleFlags(format, prod_usage, cons_usage); flags |= data.alloc_type; // Create handle - uint64_t eBaseAddr = (uint64_t)(e_data.base) + e_data.offset; - private_handle_t *hnd = new private_handle_t(data.fd, size, flags, bufferType, format, aligned_w, - aligned_h, e_data.fd, e_data.offset, eBaseAddr, - real_w, real_h, prod_usage, cons_usage); + private_handle_t *hnd = new private_handle_t(data.fd, + e_data.fd, + flags, + aligned_w, + aligned_h, + unaligned_w, + unaligned_h, + format, + bufferType, + size, + prod_usage, + cons_usage); - hnd->offset = data.offset; - hnd->base = (uint64_t)(data.base) + data.offset; - hnd->gpuaddr = 0; + hnd->id = ++next_id_; + hnd->base = reinterpret_cast(data.base); + hnd->base_metadata = reinterpret_cast(e_data.base); + ColorSpace_t colorSpace = ITU_R_601; setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast(&colorSpace)); - *handle = hnd; - - // we have just allocated the buffer & mmapped. Add to map - locker_.lock(); - handles_map_.insert(std::pair(hnd, 1)); - locker_.unlock(); - + RegisterHandle(hnd, data.ion_handle, e_data.ion_handle); + ALOGD_IF(DEBUG, "Allocated buffer handle: %p id: %" PRIu64, hnd, hnd->id); + if (DEBUG) { + private_handle_t::Dump(hnd); + } return err; } @@ -493,6 +578,7 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) { private_handle_t *hnd = reinterpret_cast( native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts())); if (hnd) { + unsigned int alignedw = 0, alignedh = 0; hnd->magic = private_handle_t::kMagic; hnd->fd = fd; hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION; @@ -500,8 +586,12 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) { hnd->offset = offset; hnd->base = uint64_t(base) + offset; hnd->gpuaddr = 0; - hnd->width = width; - hnd->height = height; + BufferDescriptor descriptor(width, height, format); + allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh); + hnd->unaligned_width = width; + hnd->unaligned_height = height; + hnd->width = INT(alignedw); + hnd->height = INT(alignedh); hnd->format = format; *handle = reinterpret_cast(hnd); } @@ -567,8 +657,7 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) { int *tile_enabled = va_arg(args, int *); unsigned int alignedw, alignedh; BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage); - *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage) || - allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage); + *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage); allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh); *aligned_width = INT(alignedw); @@ -582,7 +671,27 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) { return GRALLOC1_ERROR_BAD_HANDLE; } MetaData_t *metadata = reinterpret_cast(hnd->base_metadata); - if (metadata && metadata->operation & UPDATE_COLOR_SPACE) { + if (!metadata) { + return GRALLOC1_ERROR_BAD_HANDLE; +#ifdef USE_COLOR_METADATA + } else if (metadata->operation & COLOR_METADATA) { + ColorMetaData *colorMetadata = &metadata->color; + switch (colorMetadata->colorPrimaries) { + case ColorPrimaries_BT709_5: + *color_space = HAL_CSC_ITU_R_709; + break; + case ColorPrimaries_BT601_6_525: + *color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601); + break; + case ColorPrimaries_BT2020: + *color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020; + break; + default: + ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries); + break; + } +#endif + } else if (metadata->operation & UPDATE_COLOR_SPACE) { *color_space = metadata->colorSpace; } } break; @@ -631,11 +740,139 @@ gralloc1_error_t BufferManager::Perform(int operation, va_list args) { } } break; + case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: { + int width = va_arg(args, int); + int height = va_arg(args, int); + int format = va_arg(args, int); + uint64_t p_usage = va_arg(args, uint64_t); + uint64_t c_usage = va_arg(args, uint64_t); + gralloc1_producer_usage_t producer_usage = static_cast(p_usage); + gralloc1_consumer_usage_t consumer_usage = static_cast(c_usage); + uint32_t *aligned_width = va_arg(args, uint32_t *); + uint32_t *aligned_height = va_arg(args, uint32_t *); + uint32_t *size = va_arg(args, uint32_t *); + auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage); + allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height); + // Align size + auto align = GetDataAlignment(format, producer_usage, consumer_usage); + *size = ALIGN(*size, align); + } break; + + // TODO(user): Break out similar functionality, preferably moving to a common lib. + + case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: { + int width = va_arg(args, int); + int height = va_arg(args, int); + int format = va_arg(args, int); + uint64_t p_usage = va_arg(args, uint64_t); + uint64_t c_usage = va_arg(args, uint64_t); + buffer_handle_t *hnd = va_arg(args, buffer_handle_t*); + gralloc1_producer_usage_t producer_usage = static_cast(p_usage); + gralloc1_consumer_usage_t consumer_usage = static_cast(c_usage); + BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage); + unsigned int size; + unsigned int alignedw, alignedh; + allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh); + AllocateBuffer(descriptor, hnd, size); + } break; + default: break; } - return GRALLOC1_ERROR_NONE; } +static bool IsYuvFormat(const private_handle_t *hnd) { + switch (hnd->format) { + case HAL_PIXEL_FORMAT_YCbCr_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_422_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: + case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS + case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCrCb_422_SP: + case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: + case HAL_PIXEL_FORMAT_NV21_ZSL: + case HAL_PIXEL_FORMAT_RAW16: + case HAL_PIXEL_FORMAT_RAW12: + case HAL_PIXEL_FORMAT_RAW10: + case HAL_PIXEL_FORMAT_YV12: + return true; + default: + return false; + } +} + +gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd, + uint32_t *out_num_planes) { + if (!IsYuvFormat(hnd)) { + return GRALLOC1_ERROR_UNSUPPORTED; + } else { + *out_num_planes = 3; + } + return GRALLOC1_ERROR_NONE; +} + +gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd, + struct android_flex_layout *layout) { + if (!IsYuvFormat(hnd)) { + return GRALLOC1_ERROR_UNSUPPORTED; + } + + android_ycbcr ycbcr; + int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr); + + if (err != 0) { + return GRALLOC1_ERROR_BAD_HANDLE; + } + + layout->format = FLEX_FORMAT_YCbCr; + layout->num_planes = 3; + + for (uint32_t i = 0; i < layout->num_planes; i++) { + layout->planes[i].bits_per_component = 8; + layout->planes[i].bits_used = 8; + layout->planes[i].h_increment = 1; + layout->planes[i].v_increment = 1; + layout->planes[i].h_subsampling = 2; + layout->planes[i].v_subsampling = 2; + } + + layout->planes[0].top_left = static_cast(ycbcr.y); + layout->planes[0].component = FLEX_COMPONENT_Y; + layout->planes[0].v_increment = static_cast(ycbcr.ystride); + + layout->planes[1].top_left = static_cast(ycbcr.cb); + layout->planes[1].component = FLEX_COMPONENT_Cb; + layout->planes[1].h_increment = static_cast(ycbcr.chroma_step); + layout->planes[1].v_increment = static_cast(ycbcr.cstride); + + layout->planes[2].top_left = static_cast(ycbcr.cr); + layout->planes[2].component = FLEX_COMPONENT_Cr; + layout->planes[2].h_increment = static_cast(ycbcr.chroma_step); + layout->planes[2].v_increment = static_cast(ycbcr.cstride); + return GRALLOC1_ERROR_NONE; +} + +gralloc1_error_t BufferManager::Dump(std::ostringstream *os) { + for (auto it : handles_map_) { + auto buf = it.second; + auto hnd = buf->handle; + *os << "handle id: " << std::setw(4) << hnd->id; + *os << " fd: " << std::setw(3) << hnd->fd; + *os << " fd_meta: " << std::setw(3) << hnd->fd_metadata; + *os << " wxh: " << std::setw(4) << hnd->width <<" x " << std::setw(4) << hnd->height; + *os << " uwxuh: " << std::setw(4) << hnd->unaligned_width << " x "; + *os << std::setw(4) << hnd->unaligned_height; + *os << " size: " << std::setw(9) << hnd->size; + *os << std::hex << std::setfill('0'); + *os << " priv_flags: " << "0x" << std::setw(8) << hnd->flags; + *os << " prod_usage: " << "0x" << std::setw(8) << hnd->producer_usage; + *os << " cons_usage: " << "0x" << std::setw(8) << hnd->consumer_usage; + // TODO(user): get format string from qdutils + *os << " format: " << "0x" << std::setw(8) << hnd->format; + *os << std::dec << std::setfill(' ') << std::endl; + } + return GRALLOC1_ERROR_NONE; +} } // namespace gralloc1 diff --git a/msm8996/libgralloc1/gr_buf_mgr.h b/msm8996/libgralloc1/gr_buf_mgr.h index d3c0e675..0677d961 100644 --- a/msm8996/libgralloc1/gr_buf_mgr.h +++ b/msm8996/libgralloc1/gr_buf_mgr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Not a Contribution * * Copyright (C) 2008 The Android Open Source Project @@ -22,48 +22,116 @@ #include #include +#include +#include #include #include "gralloc_priv.h" #include "gr_allocator.h" +#include "gr_buf_descriptor.h" namespace gralloc1 { class BufferManager { public: - BufferManager(); ~BufferManager(); - bool Init(); - gralloc1_error_t AllocateBuffers(uint32_t numDescriptors, const BufferDescriptor *descriptors, - buffer_handle_t *outBuffers); + gralloc1_error_t CreateBufferDescriptor(gralloc1_buffer_descriptor_t *descriptor_id); + gralloc1_error_t DestroyBufferDescriptor(gralloc1_buffer_descriptor_t descriptor_id); + gralloc1_error_t AllocateBuffers(uint32_t num_descriptors, + const gralloc1_buffer_descriptor_t *descriptor_ids, + buffer_handle_t *out_buffers); gralloc1_error_t RetainBuffer(private_handle_t const *hnd); gralloc1_error_t ReleaseBuffer(private_handle_t const *hnd); gralloc1_error_t LockBuffer(const private_handle_t *hnd, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage); gralloc1_error_t UnlockBuffer(const private_handle_t *hnd); gralloc1_error_t Perform(int operation, va_list args); + gralloc1_error_t GetFlexLayout(const private_handle_t *hnd, struct android_flex_layout *layout); + gralloc1_error_t GetNumFlexPlanes(const private_handle_t *hnd, uint32_t *out_num_planes); + gralloc1_error_t Dump(std::ostringstream *os); + + template + gralloc1_error_t CallBufferDescriptorFunction(gralloc1_buffer_descriptor_t descriptor_id, + void (BufferDescriptor::*member)(Args...), + Args... args) { + std::lock_guard lock(locker_); + const auto map_descriptor = descriptors_map_.find(descriptor_id); + if (map_descriptor == descriptors_map_.end()) { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; + } + const auto descriptor = map_descriptor->second; + (descriptor.get()->*member)(std::forward(args)...); + return GRALLOC1_ERROR_NONE; + } + + static BufferManager* GetInstance() { + static BufferManager *instance = new BufferManager(); + return instance; + } private: + BufferManager(); gralloc1_error_t MapBuffer(private_handle_t const *hnd); - gralloc1_error_t FreeBuffer(private_handle_t const *hnd); int GetBufferType(int format); int AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle, unsigned int bufferSize = 0); - int AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int real_w, int real_h, - int format, int bufferType, gralloc1_producer_usage_t prod_usage, - gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle); - int GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage, + int AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w, + int unaligned_h, int format, int bufferType, + gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage, + buffer_handle_t *handle); + uint32_t GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage); int GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage); void CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor, buffer_handle_t *out_buffer); + // Imports the ion fds into the current process. Returns an error for invalid handles + gralloc1_error_t ImportHandle(private_handle_t* hnd); + + // Creates a Buffer from the valid private handle and adds it to the map + void RegisterHandle(const private_handle_t *hnd, int ion_handle, int ion_handle_meta); + + // Wrapper structure over private handle + // Values associated with the private handle + // that do not need to go over IPC can be placed here + // This structure is also not expected to be ABI stable + // unlike private_handle_t + struct Buffer { + const private_handle_t *handle = nullptr; + int ref_count = 1; + // Hold the main and metadata ion handles + // Freed from the allocator process + // and unused in the mapping process + int ion_handle_main = -1; + int ion_handle_meta = -1; + + Buffer() = delete; + explicit Buffer(const private_handle_t* h, int ih_main = -1, int ih_meta = -1): + handle(h), + ion_handle_main(ih_main), + ion_handle_meta(ih_meta) { + } + void IncRef() { ++ref_count; } + bool DecRef() { return --ref_count == 0; } + }; + + gralloc1_error_t FreeBuffer(std::shared_ptr buf); + + // Get the wrapper Buffer object from the handle, returns nullptr if handle is not found + std::shared_ptr GetBufferFromHandle(const private_handle_t *hnd); + bool map_fb_mem_ = false; bool ubwc_for_fb_ = false; Allocator *allocator_ = NULL; std::mutex locker_; - std::unordered_map handles_map_ = {}; + // TODO(user): The private_handle_t is used as a key because the unique ID generated + // from next_id_ is not unique across processes. The correct way to resolve this would + // be to use the allocator over hwbinder + std::unordered_map> handles_map_ = {}; + std::unordered_map> descriptors_map_ = {}; + std::atomic next_id_; }; } // namespace gralloc1 diff --git a/msm8996/libgralloc1/gr_device_impl.cpp b/msm8996/libgralloc1/gr_device_impl.cpp index 62589413..3649111f 100644 --- a/msm8996/libgralloc1/gr_device_impl.cpp +++ b/msm8996/libgralloc1/gr_device_impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -29,6 +29,9 @@ #include #include +#include +#include +#include #include "gr_device_impl.h" #include "gr_buf_descriptor.h" @@ -43,13 +46,11 @@ int gralloc_device_close(struct hw_device_t *device); static struct hw_module_methods_t gralloc_module_methods = {.open = gralloc_device_open}; -struct hw_module_t gralloc_module = {}; - -struct private_module_t HAL_MODULE_INFO_SYM = { - .base = { +struct gralloc_module_t HAL_MODULE_INFO_SYM = { + .common = { .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, + .module_api_version = GRALLOC_MODULE_API_VERSION_1_0, + .hal_api_version = HARDWARE_HAL_API_VERSION, .id = GRALLOC_HARDWARE_MODULE_ID, .name = "Graphics Memory Module", .author = "Code Aurora Forum", @@ -62,62 +63,51 @@ struct private_module_t HAL_MODULE_INFO_SYM = { int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device) { int status = -EINVAL; if (!strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) { - const private_module_t *m = reinterpret_cast(module); - gralloc1::GrallocImpl * /*gralloc1_device_t*/ dev = new gralloc1::GrallocImpl(m); + gralloc1::GrallocImpl * /*gralloc1_device_t*/ dev = gralloc1::GrallocImpl::GetInstance(module); *device = reinterpret_cast(dev); - - if (dev->Init()) { + if (dev) { status = 0; } else { - ALOGE(" Error in opening gralloc1 device"); - return status; + ALOGE("Fatal error opening gralloc1 device"); } } - return status; } namespace gralloc1 { -GrallocImpl::GrallocImpl(const private_module_t *module) { +GrallocImpl::GrallocImpl(const hw_module_t *module) { common.tag = HARDWARE_DEVICE_TAG; - common.version = 1; // TODO(user): cross check version - common.module = const_cast(&module->base); + common.version = GRALLOC_MODULE_API_VERSION_1_0; + common.module = const_cast(module); common.close = CloseDevice; getFunction = GetFunction; getCapabilities = GetCapabilities; + + initalized_ = Init(); } bool GrallocImpl::Init() { - buf_mgr_ = new BufferManager(); - - return buf_mgr_->Init(); + buf_mgr_ = BufferManager::GetInstance(); + return buf_mgr_ != nullptr; } GrallocImpl::~GrallocImpl() { - if (buf_mgr_) { - delete buf_mgr_; - } } -int GrallocImpl::CloseDevice(hw_device_t *device) { - GrallocImpl *impl = reinterpret_cast(device); - delete impl; - +int GrallocImpl::CloseDevice(hw_device_t *device __unused) { + // No-op since the gralloc device is a singleton return 0; } void GrallocImpl::GetCapabilities(struct gralloc1_device *device, uint32_t *out_count, - int32_t /*gralloc1_capability_t*/ *out_capabilities) { - if (!device) { - // Need to plan for adding more capabilities - if (out_capabilities == NULL) { - *out_count = 1; - } else { - *out_capabilities = GRALLOC1_CAPABILITY_TEST_ALLOCATE; + int32_t /*gralloc1_capability_t*/ *out_capabilities) { + if (device != nullptr) { + if (out_capabilities != nullptr && *out_count > 0) { + out_capabilities[0] = GRALLOC1_CAPABILITY_TEST_ALLOCATE; } + *out_count = 1; } - return; } @@ -127,6 +117,8 @@ gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, } switch (function) { + case GRALLOC1_FUNCTION_DUMP: + return reinterpret_cast(Dump); case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR: return reinterpret_cast(CreateBufferDescriptor); case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR: @@ -157,17 +149,12 @@ gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, return reinterpret_cast(RetainBuffer); case GRALLOC1_FUNCTION_RELEASE: return reinterpret_cast(ReleaseBuffer); - /* TODO(user) :definition of flex plane is not known yet - * Need to implement after clarification from Google. - * case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES: - return reinterpret_cast (; */ + case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES: + return reinterpret_cast(GetNumFlexPlanes); case GRALLOC1_FUNCTION_LOCK: return reinterpret_cast(LockBuffer); - /* TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure is not known yet. - * Need to implement after clarification from Google. - case GRALLOC1_PFN_LOCK_FLEX: - return reinterpret_cast (LockYCbCrBuffer; - */ + case GRALLOC1_FUNCTION_LOCK_FLEX: + return reinterpret_cast(LockFlex); case GRALLOC1_FUNCTION_UNLOCK: return reinterpret_cast(UnlockBuffer); case GRALLOC1_FUNCTION_PERFORM: @@ -180,12 +167,26 @@ gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, return NULL; } -gralloc1_error_t GrallocImpl::CheckDeviceAndDescriptor(gralloc1_device_t *device, - gralloc1_buffer_descriptor_t descriptor) { - if (!device || !BUF_DESCRIPTOR(descriptor)->IsValid()) { - ALOGE("Gralloc Error : device=%p, descriptor=%p", (void *)device, (void *)descriptor); +gralloc1_error_t GrallocImpl::Dump(gralloc1_device_t *device, uint32_t *out_size, + char *out_buffer) { + if (!device) { + ALOGE("Gralloc Error : device=%p", (void *)device); return GRALLOC1_ERROR_BAD_DESCRIPTOR; } + const size_t max_dump_size = 8192; + if (out_buffer == nullptr) { + *out_size = max_dump_size; + } else { + std::ostringstream os; + os << "-------------------------------" << std::endl; + os << "QTI gralloc dump:" << std::endl; + os << "-------------------------------" << std::endl; + GrallocImpl const *dev = GRALLOC_IMPL(device); + dev->buf_mgr_->Dump(&os); + os << "-------------------------------" << std::endl; + auto copied = os.str().copy(out_buffer, std::min(os.str().size(), max_dump_size), 0); + *out_size = UINT(copied); + } return GRALLOC1_ERROR_NONE; } @@ -206,69 +207,66 @@ gralloc1_error_t GrallocImpl::CreateBufferDescriptor(gralloc1_device_t *device, if (!device) { return GRALLOC1_ERROR_BAD_DESCRIPTOR; } - - BufferDescriptor *descriptor = new BufferDescriptor(); - if (descriptor == NULL) { - return GRALLOC1_ERROR_NO_RESOURCES; - } - - *out_descriptor = reinterpret_cast(descriptor); - - return GRALLOC1_ERROR_NONE; + GrallocImpl const *dev = GRALLOC_IMPL(device); + return dev->buf_mgr_->CreateBufferDescriptor(out_descriptor); } gralloc1_error_t GrallocImpl::DestroyBufferDescriptor(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor) { - gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor); - if (status == GRALLOC1_ERROR_NONE) { - delete reinterpret_cast(descriptor); + if (!device) { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; } - - return status; + GrallocImpl const *dev = GRALLOC_IMPL(device); + return dev->buf_mgr_->DestroyBufferDescriptor(descriptor); } gralloc1_error_t GrallocImpl::SetConsumerUsage(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, gralloc1_consumer_usage_t usage) { - gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor); - if (status == GRALLOC1_ERROR_NONE) { - BUF_DESCRIPTOR(descriptor)->SetConsumerUsage(usage); + if (!device) { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; + } else { + GrallocImpl const *dev = GRALLOC_IMPL(device); + return dev->buf_mgr_->CallBufferDescriptorFunction(descriptor, + &BufferDescriptor::SetConsumerUsage, usage); } - - return status; } gralloc1_error_t GrallocImpl::SetBufferDimensions(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, uint32_t width, uint32_t height) { - gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor); - if (status == GRALLOC1_ERROR_NONE) { - BUF_DESCRIPTOR(descriptor)->SetDimensions(INT(width), INT(height)); + if (!device) { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; + } else { + GrallocImpl const *dev = GRALLOC_IMPL(device); + return dev->buf_mgr_->CallBufferDescriptorFunction(descriptor, + &BufferDescriptor::SetDimensions, + INT(width), INT(height)); } - - return status; } gralloc1_error_t GrallocImpl::SetColorFormat(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, int32_t format) { - gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor); - if (status == GRALLOC1_ERROR_NONE) { - BUF_DESCRIPTOR(descriptor)->SetColorFormat(format); + if (!device) { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; + } else { + GrallocImpl const *dev = GRALLOC_IMPL(device); + return dev->buf_mgr_->CallBufferDescriptorFunction(descriptor, + &BufferDescriptor::SetColorFormat, format); } - - return status; } gralloc1_error_t GrallocImpl::SetProducerUsage(gralloc1_device_t *device, gralloc1_buffer_descriptor_t descriptor, gralloc1_producer_usage_t usage) { - gralloc1_error_t status = CheckDeviceAndDescriptor(device, descriptor); - if (status == GRALLOC1_ERROR_NONE) { - BUF_DESCRIPTOR(descriptor)->SetProducerUsage(usage); + if (!device) { + return GRALLOC1_ERROR_BAD_DESCRIPTOR; + } else { + GrallocImpl const *dev = GRALLOC_IMPL(device); + return dev->buf_mgr_->CallBufferDescriptorFunction(descriptor, + &BufferDescriptor::SetProducerUsage, usage); } - - return status; } gralloc1_error_t GrallocImpl::GetBackingStore(gralloc1_device_t *device, buffer_handle_t buffer, @@ -298,8 +296,8 @@ gralloc1_error_t GrallocImpl::GetBufferDimensions(gralloc1_device_t *device, buf gralloc1_error_t status = CheckDeviceAndHandle(device, buffer); if (status == GRALLOC1_ERROR_NONE) { const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer); - *outWidth = UINT(hnd->GetRealWidth()); - *outHeight = UINT(hnd->GetRealHeight()); + *outWidth = UINT(hnd->GetUnalignedWidth()); + *outHeight = UINT(hnd->GetUnalignedHeight()); } return status; @@ -336,16 +334,16 @@ gralloc1_error_t GrallocImpl::GetBufferStride(gralloc1_device_t *device, buffer_ return status; } -gralloc1_error_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_t num_dptors, - const gralloc1_buffer_descriptor_t *dptors, - buffer_handle_t *outBuffers) { - if (!num_dptors || !dptors) { +gralloc1_error_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_t num_descriptors, + const gralloc1_buffer_descriptor_t *descriptors, + buffer_handle_t *out_buffers) { + if (!num_descriptors || !descriptors) { return GRALLOC1_ERROR_BAD_DESCRIPTOR; } GrallocImpl const *dev = GRALLOC_IMPL(device); - const BufferDescriptor *descriptors = reinterpret_cast(dptors); - gralloc1_error_t status = dev->buf_mgr_->AllocateBuffers(num_dptors, descriptors, outBuffers); + gralloc1_error_t status = dev->buf_mgr_->AllocateBuffers(num_descriptors, descriptors, + out_buffers); return status; } @@ -372,6 +370,17 @@ gralloc1_error_t GrallocImpl::ReleaseBuffer(gralloc1_device_t *device, buffer_ha return status; } +gralloc1_error_t GrallocImpl::GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer, + uint32_t *out_num_planes) { + gralloc1_error_t status = CheckDeviceAndHandle(device, buffer); + if (status == GRALLOC1_ERROR_NONE) { + GrallocImpl const *dev = GRALLOC_IMPL(device); + const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer); + status = dev->buf_mgr_->GetNumFlexPlanes(hnd, out_num_planes); + } + return status; +} + gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage, @@ -392,14 +401,16 @@ gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handl // Either producer usage or consumer usage must be *_USAGE_NONE if ((prod_usage != GRALLOC1_PRODUCER_USAGE_NONE) && (cons_usage != GRALLOC1_CONSUMER_USAGE_NONE)) { - return GRALLOC1_ERROR_BAD_VALUE; + // Current gralloc1 clients do not satisfy this restriction. + // See b/33588773 for details + // return GRALLOC1_ERROR_BAD_VALUE; } // currently we ignore the region/rect client wants to lock if (region == NULL) { return GRALLOC1_ERROR_BAD_VALUE; } - + // TODO(user): Need to check if buffer was allocated with the same flags status = dev->buf_mgr_->LockBuffer(hnd, prod_usage, cons_usage); *out_data = reinterpret_cast(hnd->base); @@ -407,27 +418,24 @@ gralloc1_error_t GrallocImpl::LockBuffer(gralloc1_device_t *device, buffer_handl return status; } -/* TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure definition is not known yet. - * Need to implement after clarification from Google. -gralloc1_error_t GrallocImpl::LockYCbCrBuffer(gralloc1_device_t* device, buffer_handle_t buffer, - gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage, - const gralloc1_rect_t* region, struct android_ycbcr* outYCbCr, int32_t* outAcquireFence) { - gralloc1_error_t status = CheckDeviceAndHandle(device, buffer); - - if (status == GRALLOC1_ERROR_NONE) { - void **outData = 0; - status = LockBuffer(device, buffer, prod_usage, cons_usage, region, outData, outAcquireFence); - } - - if (status == GRALLOC1_ERROR_NONE) { - const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer); - GrallocImpl const *dev = GRALLOC_IMPL(device); - dev->allocator_->GetYUVPlaneInfo(hnd, outYCbCr); +gralloc1_error_t GrallocImpl::LockFlex(gralloc1_device_t *device, buffer_handle_t buffer, + gralloc1_producer_usage_t prod_usage, + gralloc1_consumer_usage_t cons_usage, + const gralloc1_rect_t *region, + struct android_flex_layout *out_flex_layout, + int32_t acquire_fence) { + void *out_data; + gralloc1_error_t status = GrallocImpl::LockBuffer(device, buffer, prod_usage, cons_usage, region, + &out_data, acquire_fence); + if (status != GRALLOC1_ERROR_NONE) { + return status; } + GrallocImpl const *dev = GRALLOC_IMPL(device); + const private_handle_t *hnd = PRIV_HANDLE_CONST(buffer); + dev->buf_mgr_->GetFlexLayout(hnd, out_flex_layout); return status; } - */ gralloc1_error_t GrallocImpl::UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer, int32_t *release_fence) { diff --git a/msm8996/libgralloc1/gr_device_impl.h b/msm8996/libgralloc1/gr_device_impl.h index 4fc8e3c8..5a3e7e9f 100644 --- a/msm8996/libgralloc1/gr_device_impl.h +++ b/msm8996/libgralloc1/gr_device_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -44,18 +44,24 @@ namespace gralloc1 { class GrallocImpl : public gralloc1_device_t { public: - explicit GrallocImpl(const private_module_t *module); - ~GrallocImpl(); - bool Init(); static int CloseDevice(hw_device_t *device); static void GetCapabilities(struct gralloc1_device *device, uint32_t *out_count, int32_t * /*gralloc1_capability_t*/ out_capabilities); static gralloc1_function_pointer_t GetFunction( struct gralloc1_device *device, int32_t /*gralloc1_function_descriptor_t*/ descriptor); + static GrallocImpl* GetInstance(const struct hw_module_t *module) { + static GrallocImpl *instance = new GrallocImpl(module); + if (instance->IsInitialized()) { + return instance; + } else { + return nullptr; + } + } + private: - static inline gralloc1_error_t CheckDeviceAndDescriptor(gralloc1_device_t *device, - gralloc1_buffer_descriptor_t descriptor); + static inline gralloc1_error_t Dump(gralloc1_device_t *device, uint32_t *out_size, + char *out_buffer); static inline gralloc1_error_t CheckDeviceAndHandle(gralloc1_device_t *device, buffer_handle_t buffer); static gralloc1_error_t CreateBufferDescriptor(gralloc1_device_t *device, @@ -90,30 +96,31 @@ class GrallocImpl : public gralloc1_device_t { buffer_handle_t *out_buffers); static gralloc1_error_t RetainBuffer(gralloc1_device_t *device, buffer_handle_t buffer); static gralloc1_error_t ReleaseBuffer(gralloc1_device_t *device, buffer_handle_t buffer); - static gralloc1_error_t getNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer, + static gralloc1_error_t GetNumFlexPlanes(gralloc1_device_t *device, buffer_handle_t buffer, uint32_t *out_num_planes); static gralloc1_error_t LockBuffer(gralloc1_device_t *device, buffer_handle_t buffer, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage, - const gralloc1_rect_t *access_region, void **out_data, + const gralloc1_rect_t *region, void **out_data, int32_t acquire_fence); static gralloc1_error_t LockFlex(gralloc1_device_t *device, buffer_handle_t buffer, gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage, - const gralloc1_rect_t *access_region, + const gralloc1_rect_t *region, struct android_flex_layout *out_flex_layout, - int32_t acquireFence); - /* TODO(user) : LOCK_YCBCR changed to LOCK_FLEX but structure is not known yet. - * Need to implement after clarification from Google. - static gralloc1_error_t LockYCbCrBuffer(gralloc1_device_t* device, buffer_handle_t buffer, - gralloc1_producer_usage_t producerUsage, gralloc1_consumer_usage_t consumerUsage, - const gralloc1_rect_t* Region, struct android_ycbcr* outYCbCr, int32_t* outAcquireFence); - */ + int32_t acquire_fence); + static gralloc1_error_t UnlockBuffer(gralloc1_device_t *device, buffer_handle_t buffer, int32_t *release_fence); static gralloc1_error_t Gralloc1Perform(gralloc1_device_t *device, int operation, ...); + explicit GrallocImpl(const hw_module_t *module); + ~GrallocImpl(); + bool Init(); + bool IsInitialized() const { return initalized_; } + BufferManager *buf_mgr_ = NULL; + bool initalized_ = false; }; } // namespace gralloc1 diff --git a/msm8996/libgralloc1/gr_ion_alloc.cpp b/msm8996/libgralloc1/gr_ion_alloc.cpp index ca93a632..25792e58 100644 --- a/msm8996/libgralloc1/gr_ion_alloc.cpp +++ b/msm8996/libgralloc1/gr_ion_alloc.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -106,23 +106,30 @@ int IonAlloc::AllocBuffer(AllocData *data) { data->base = base; data->fd = fd_data.fd; - ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data); - ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d", data->base, ion_alloc_data.len, - data->fd); + data->ion_handle = handle_data.handle; + ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d handle:0x%x", data->base, + ion_alloc_data.len, data->fd, data->ion_handle); return 0; } -int IonAlloc::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) { +int IonAlloc::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, + int ion_handle) { ATRACE_CALL(); int err = 0; - ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%u fd:%d", base, size, fd); + ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%u fd:%d handle:0x%x", base, size, fd, + ion_handle); if (base) { err = UnmapBuffer(base, size, offset); } - close(fd); + if (ion_handle > 0) { + struct ion_handle_data handle_data; + handle_data.handle = ion_handle; + ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data); + } + close(fd); return err; } @@ -145,6 +152,18 @@ int IonAlloc::MapBuffer(void **base, unsigned int size, unsigned int offset, int return err; } +int IonAlloc::ImportBuffer(int fd) { + struct ion_fd_data fd_data; + int err = 0; + fd_data.fd = fd; + if (ioctl(ion_dev_fd_, INT(ION_IOC_IMPORT), &fd_data)) { + err = -errno; + ALOGE("%s: ION_IOC_IMPORT failed with error - %s", __FUNCTION__, strerror(errno)); + return err; + } + return fd_data.handle; +} + int IonAlloc::UnmapBuffer(void *base, unsigned int size, unsigned int /*offset*/) { ATRACE_CALL(); ALOGD_IF(DEBUG, "ion: Unmapping buffer base:%p size:%u", base, size); @@ -158,23 +177,13 @@ int IonAlloc::UnmapBuffer(void *base, unsigned int size, unsigned int /*offset*/ return err; } -int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) { +int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op) { ATRACE_CALL(); ATRACE_INT("operation id", op); struct ion_flush_data flush_data; - struct ion_fd_data fd_data; - struct ion_handle_data handle_data; int err = 0; - fd_data.fd = fd; - if (ioctl(ion_dev_fd_, INT(ION_IOC_IMPORT), &fd_data)) { - err = -errno; - ALOGE("%s: ION_IOC_IMPORT failed with error - %s", __FUNCTION__, strerror(errno)); - return err; - } - - handle_data.handle = fd_data.handle; - flush_data.handle = fd_data.handle; + flush_data.handle = handle; flush_data.vaddr = base; // offset and length are unsigned int flush_data.offset = offset; @@ -197,12 +206,9 @@ int IonAlloc::CleanBuffer(void *base, unsigned int size, unsigned int offset, in if (ioctl(ion_dev_fd_, INT(ION_IOC_CUSTOM), &d)) { err = -errno; ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s", __FUNCTION__, strerror(errno)); - ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data); return err; } - ioctl(ion_dev_fd_, INT(ION_IOC_FREE), &handle_data); - return 0; } diff --git a/msm8996/libgralloc1/gr_ion_alloc.h b/msm8996/libgralloc1/gr_ion_alloc.h index baef8aa8..b25f509b 100644 --- a/msm8996/libgralloc1/gr_ion_alloc.h +++ b/msm8996/libgralloc1/gr_ion_alloc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -45,6 +45,7 @@ enum { struct AllocData { void *base = NULL; int fd = -1; + int ion_handle = -1; unsigned int offset = 0; unsigned int size = 0; unsigned int align = 1; @@ -63,10 +64,11 @@ class IonAlloc { bool Init(); int AllocBuffer(AllocData *data); - int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd); + int FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd, int ion_handle); int MapBuffer(void **base, unsigned int size, unsigned int offset, int fd); + int ImportBuffer(int fd); int UnmapBuffer(void *base, unsigned int size, unsigned int offset); - int CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op); + int CleanBuffer(void *base, unsigned int size, unsigned int offset, int handle, int op); private: const char *kIonDevice = "/dev/ion"; diff --git a/msm8996/libgralloc1/gr_priv_handle.h b/msm8996/libgralloc1/gr_priv_handle.h index 444fc800..227bcd67 100644 --- a/msm8996/libgralloc1/gr_priv_handle.h +++ b/msm8996/libgralloc1/gr_priv_handle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Not a Contribution * * Copyright (C) 2008 The Android Open Source Project @@ -22,6 +22,8 @@ #include #include +#include +#include #define GRALLOC1_FUNCTION_PERFORM 0x00001000 @@ -29,20 +31,15 @@ typedef gralloc1_error_t (*GRALLOC1_PFN_PERFORM)(gralloc1_device_t *device, int operation, ...); -typedef int BackStoreFd; - #define PRIV_HANDLE_CONST(exp) static_cast(exp) struct private_handle_t : public native_handle_t { - // TODO(user): Moving PRIV_FLAGS to #defs & check for each PRIV_FLAG and remove unused. enum { PRIV_FLAGS_FRAMEBUFFER = 0x00000001, PRIV_FLAGS_USES_ION = 0x00000008, - PRIV_FLAGS_USES_ASHMEM = 0x00000010, PRIV_FLAGS_NEEDS_FLUSH = 0x00000020, PRIV_FLAGS_INTERNAL_ONLY = 0x00000040, PRIV_FLAGS_NON_CPU_WRITER = 0x00000080, - PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100, PRIV_FLAGS_CACHED = 0x00000200, PRIV_FLAGS_SECURE_BUFFER = 0x00000400, PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000, @@ -59,35 +56,30 @@ struct private_handle_t : public native_handle_t { PRIV_FLAGS_TILE_RENDERED = 0x02000000, PRIV_FLAGS_CPU_RENDERED = 0x04000000, PRIV_FLAGS_UBWC_ALIGNED = 0x08000000, - PRIV_FLAGS_DISP_CONSUMER = 0x10000000 + PRIV_FLAGS_DISP_CONSUMER = 0x10000000, + PRIV_FLAGS_CLIENT_ALLOCATED = 0x20000000, // Ion buffer allocated outside of gralloc }; - // file-descriptors + // file-descriptors dup'd over IPC int fd; int fd_metadata; - // ints + // values sent over IPC int magic; int flags; + int width; // holds width of the actual buffer allocated + int height; // holds height of the actual buffer allocated + int unaligned_width; // holds width client asked to allocate + int unaligned_height; // holds height client asked to allocate + int format; + int buffer_type; unsigned int size; unsigned int offset; - int buffer_type; - uint64_t base __attribute__((aligned(8))); unsigned int offset_metadata; - - // The gpu address mapped into the mmu. - uint64_t gpuaddr __attribute__((aligned(8))); - - int format; - int width; // holds width of the actual buffer allocated - int height; // holds height of the actual buffer allocated - - int stride; - uint64_t base_metadata __attribute__((aligned(8))); - - // added for gralloc1 - int real_width; // holds width client asked to allocate - int real_height; // holds height client asked to allocate// holds width client asked to allocate + uint64_t base __attribute__((aligned(8))); + uint64_t base_metadata __attribute__((aligned(8))); + uint64_t gpuaddr __attribute__((aligned(8))); + uint64_t id __attribute__((aligned(8))); gralloc1_producer_usage_t producer_usage __attribute__((aligned(8))); gralloc1_consumer_usage_t consumer_usage __attribute__((aligned(8))); @@ -95,30 +87,39 @@ struct private_handle_t : public native_handle_t { static const int kMagic = 'gmsm'; static inline int NumInts() { - return ((sizeof(private_handle_t) - sizeof(native_handle_t)) / sizeof(int)) - kNumFds; + return ((sizeof(private_handle_t) - sizeof(native_handle_t)) / sizeof(int)) + - kNumFds; } - private_handle_t(int fd, unsigned int size, int flags, int buf_type, int format, int width, - int height, int meta_fd = -1, unsigned int meta_offset = 0, - uint64_t meta_base = 0, int rw = 0, int rh = 0, + private_handle_t(int fd, + int meta_fd, + int flags, + int width, + int height, + int uw, + int uh, + int format, + int buf_type, + unsigned int size, gralloc1_producer_usage_t prod_usage = GRALLOC1_PRODUCER_USAGE_NONE, gralloc1_consumer_usage_t cons_usage = GRALLOC1_CONSUMER_USAGE_NONE) : fd(fd), fd_metadata(meta_fd), magic(kMagic), flags(flags), - size(size), - offset(0), - buffer_type(buf_type), - base(0), - offset_metadata(meta_offset), - gpuaddr(0), - format(format), width(width), height(height), - base_metadata(meta_base), - real_width(rw), - real_height(rh), + unaligned_width(uw), + unaligned_height(uh), + format(format), + buffer_type(buf_type), + size(size), + offset(0), + offset_metadata(0), + base(0), + base_metadata(0), + gpuaddr(0), + id(0), producer_usage(prod_usage), consumer_usage(cons_usage) { version = static_cast(sizeof(native_handle)); @@ -126,9 +127,16 @@ struct private_handle_t : public native_handle_t { numFds = kNumFds; } +// Legacy constructor used by some clients + private_handle_t(int fd, unsigned int size, int usage, int buf_type, int format, int w, int h) + : private_handle_t(fd, -1, PRIV_FLAGS_CLIENT_ALLOCATED, w, h, 0, 0, format, buf_type, size, + static_cast(usage), + static_cast(usage)) { + } + ~private_handle_t() { magic = 0; - ALOGE_IF(DBG_HANDLE, "deleting buffer handle %p", this); + ALOGE_IF(DBG_HANDLE, "Deleting buffer handle %p", this); } static int validate(const native_handle *h) { @@ -151,15 +159,22 @@ struct private_handle_t : public native_handle_t { return 0; } - int GetRealWidth() const { return real_width; } + static void Dump(const private_handle_t *hnd) { + ALOGD("handle id:%" PRIu64 " wxh:%dx%d uwxuh:%dx%d size: %d fd:%d fd_meta:%d flags:0x%x" + "prod_usage:0x%" PRIx64" cons_usage:0x%" PRIx64 "format:0x%x", + hnd->id, hnd->width, hnd->height, hnd->unaligned_width, hnd->unaligned_height, hnd->size, + hnd->fd, hnd->fd_metadata, hnd->flags, hnd->producer_usage, hnd->consumer_usage, + hnd->format); + } - int GetRealHeight() const { return real_height; } + int GetUnalignedWidth() const { return unaligned_width; } + + int GetUnalignedHeight() const { return unaligned_height; } int GetColorFormat() const { return format; } int GetStride() const { - // In handle we are storing aligned width after allocation. - // Why GetWidth & GetStride?? Are we supposed to maintain unaligned values?? + // In handle we currently store aligned width after allocation. return width; } @@ -167,7 +182,7 @@ struct private_handle_t : public native_handle_t { gralloc1_producer_usage_t GetProducerUsage() const { return producer_usage; } - BackStoreFd GetBackingstore() const { return fd; } + uint64_t GetBackingstore() const { return id; } }; #endif // __GR_PRIV_HANDLE_H__ diff --git a/msm8996/libgralloc1/gr_utils.cpp b/msm8996/libgralloc1/gr_utils.cpp index 98b68896..f3c4ba8f 100644 --- a/msm8996/libgralloc1/gr_utils.cpp +++ b/msm8996/libgralloc1/gr_utils.cpp @@ -52,6 +52,7 @@ bool IsUncompressedRGBFormat(int format) { case HAL_PIXEL_FORMAT_ABGR_2101010: case HAL_PIXEL_FORMAT_BGRX_1010102: case HAL_PIXEL_FORMAT_XBGR_2101010: + case HAL_PIXEL_FORMAT_RGBA_FP16: return true; default: break; @@ -101,6 +102,9 @@ bool IsCompressedRGBFormat(int format) { uint32_t GetBppForUncompressedRGB(int format) { uint32_t bpp = 0; switch (format) { + case HAL_PIXEL_FORMAT_RGBA_FP16: + bpp = 8; + break; case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_BGRA_8888: diff --git a/msm8996/libgralloc1/gralloc_priv.h b/msm8996/libgralloc1/gralloc_priv.h index 64cb1f5e..b558975f 100644 --- a/msm8996/libgralloc1/gralloc_priv.h +++ b/msm8996/libgralloc1/gralloc_priv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. * Not a Contribution * * Copyright (C) 2008 The Android Open Source Project @@ -20,50 +20,68 @@ #ifndef __GRALLOC_PRIV_H__ #define __GRALLOC_PRIV_H__ +#include #include "gr_priv_handle.h" -#define ROUND_UP_PAGESIZE(x) ((((unsigned int)(x)) + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1))) +#define ROUND_UP_PAGESIZE(x) roundUpToPageSize(x) +inline int roundUpToPageSize(int x) { + return (x + (getpagesize()-1)) & ~(getpagesize()-1); +} /* Gralloc usage bits indicating the type of allocation that should be used */ /* Refer gralloc1_producer_usage_t & gralloc1_consumer_usage-t in gralloc1.h */ -/* GRALLOC_USAGE_PRIVATE_0 is unused */ - +/* Producer flags */ /* Non linear, Universal Bandwidth Compression */ -#define GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC GRALLOC1_PRODUCER_USAGE_PRIVATE_1 - -/* IOMMU heap comes from manually allocated pages, can be cached/uncached, is not secured */ -#define GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_2 - -/* MM heap is a carveout heap for video, can be secured */ -#define GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_3 - -/* ADSP heap is a carveout heap, is not secured */ -#define GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_4 - -/* CAMERA heap is a carveout heap for camera, is not secured */ -#define GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_5 +#define GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC GRALLOC1_PRODUCER_USAGE_PRIVATE_0 /* Set this for allocating uncached memory (using O_DSYNC), * cannot be used with noncontiguous heaps */ -#define GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED GRALLOC1_PRODUCER_USAGE_PRIVATE_6 +#define GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED GRALLOC1_PRODUCER_USAGE_PRIVATE_1 -#define GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL GRALLOC1_PRODUCER_USAGE_PRIVATE_7 +/* CAMERA heap is a carveout heap for camera, is not secured */ +#define GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_2 -/* Buffer content should be displayed on a primary display only */ -#define GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY GRALLOC1_CONSUMER_USAGE_PRIVATE_1 +/* ADSP heap is a carveout heap, is not secured */ +#define GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_3 -/* Buffer content should be displayed on an external display only */ -#define GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY GRALLOC1_CONSUMER_USAGE_PRIVATE_2 +/* IOMMU heap comes from manually allocated pages, can be cached/uncached, is not secured */ +#define GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_4 +/* MM heap is a carveout heap for video, can be secured */ +#define GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_5 + +/* Use legacy ZSL definition until we know the correct usage on gralloc1 */ +#define GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL GRALLOC_USAGE_HW_CAMERA_ZSL + + +/* Consumer flags */ +/* TODO(user): Fix when producer and consumer flags are actually separated */ /* This flag is set for WFD usecase */ -#define GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD GRALLOC1_CONSUMER_USAGE_PRIVATE_3 +#define GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD 0x00200000 /* This flag is used for SECURE display usecase */ -#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY GRALLOC1_CONSUMER_USAGE_PRIVATE_4 +#define GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY 0x00800000 + +/* Buffer content should be displayed on a primary display only */ +#define GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY 0x04000000 + +/* Buffer content should be displayed on an external display only */ +#define GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY 0x08000000 + + +/* Legacy gralloc0.x definitions */ +/* Some clients may still be using the old flags */ +#define GRALLOC_USAGE_PRIVATE_ALLOC_UBWC GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC +#define GRALLOC_USAGE_PRIVATE_UNCACHED GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED +#define GRALLOC_USAGE_PRIVATE_IOMMU_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_IOMMU_HEAP +#define GRALLOC_USAGE_PRIVATE_WFD GRALLOC1_CONSUMER_USAGE_PRIVATE_WFD +#define GRALLOC_USAGE_PRIVATE_CAMERA_HEAP GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP +#define GRALLOC_USAGE_PRIVATE_MM_HEAP 0x0 + + // for PERFORM API : -// TODO(user): Move it to enum if it's ookay for gfx #define GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER 1 #define GRALLOC_MODULE_PERFORM_GET_STRIDE 2 #define GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE 3 @@ -77,6 +95,8 @@ #define GRALLOC_MODULE_PERFORM_GET_IGC 11 #define GRALLOC_MODULE_PERFORM_SET_IGC 12 #define GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE 13 +#define GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS 14 +#define GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER 15 // OEM specific HAL formats #define HAL_PIXEL_FORMAT_RGBA_5551 6 @@ -96,9 +116,9 @@ #define HAL_PIXEL_FORMAT_NV21_ZSL 0x113 #define HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS 0x114 #define HAL_PIXEL_FORMAT_BGR_565 0x115 +#define HAL_PIXEL_FORMAT_RAW8 0x123 // 10 bit -#define HAL_PIXEL_FORMAT_RGBA_1010102 0x116 #define HAL_PIXEL_FORMAT_ARGB_2101010 0x117 #define HAL_PIXEL_FORMAT_RGBX_1010102 0x118 #define HAL_PIXEL_FORMAT_XRGB_2101010 0x119 @@ -107,7 +127,6 @@ #define HAL_PIXEL_FORMAT_BGRX_1010102 0x11C #define HAL_PIXEL_FORMAT_XBGR_2101010 0x11D #define HAL_PIXEL_FORMAT_YCbCr_420_P010 0x11F -#define HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC 0x120 #define HAL_PIXEL_FORMAT_INTERLACE 0x180 @@ -120,6 +139,7 @@ // UBWC aligned Venus format #define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC 0x7FA30C06 +#define HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC 0x7FA30C09 // Khronos ASTC formats #define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 @@ -155,6 +175,13 @@ #define HAL_IGC_NOT_SPECIFIED 0 #define HAL_IGC_s_RGB 1 +/* Color Space: Values maps to ColorSpace_t in qdMetadata.h */ +#define HAL_CSC_ITU_R_601 0 +#define HAL_CSC_ITU_R_601_FR 1 +#define HAL_CSC_ITU_R_709 2 +#define HAL_CSC_ITU_R_2020 3 +#define HAL_CSC_ITU_R_2020_FR 4 + /* possible formats for 3D content*/ enum { HAL_NO_3D = 0x0, diff --git a/msm8996/sdm/libs/hwc2/Android.mk b/msm8996/sdm/libs/hwc2/Android.mk index 7559f2c0..d9dc1087 100644 --- a/msm8996/sdm/libs/hwc2/Android.mk +++ b/msm8996/sdm/libs/hwc2/Android.mk @@ -17,8 +17,12 @@ LOCAL_CFLAGS := -Wno-missing-field-initializers -Wno-unused-par LOCAL_CLANG := true LOCAL_SHARED_LIBRARIES := libsdmcore libqservice libbinder libhardware libhardware_legacy \ - libutils liblog libcutils libsync libmemalloc libqdutils libdl \ - libpowermanager libsdmutils libc++ + libutils libcutils libsync libqdutils libdl \ + libpowermanager libsdmutils libc++ liblog + +ifneq ($(TARGET_USES_GRALLOC1), true) + LOCAL_SHARED_LIBRARIES += libmemalloc +endif LOCAL_SRC_FILES := hwc_session.cpp \ hwc_display.cpp \