diff options
author | 2023-12-08 11:30:37 -0500 | |
---|---|---|
committer | 2023-12-14 17:49:59 -0500 | |
commit | d727e9c78f799534ea606e3793d50fc73a4566d7 (patch) | |
tree | 2abe6c45f46c40daabeb348bc7377eb446c7706c | |
parent | 1fcaffe2ed5f7312ea0bcbf9abd2d3617bd70bd0 (diff) |
Add AHB_allocate2 + get/setDataSpace
Also fix that some ADataSpace enum values were not prefixed
with ADATASPACE_*
Test: atest AHardwareBufferTest
Bug: 315475131
Change-Id: Ie92f416a209501fa8fdc9b3593ea6d3bb68eaa48
24 files changed, 618 insertions, 141 deletions
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp index e7b2195056..745b6f30cc 100644 --- a/libs/nativewindow/AHardwareBuffer.cpp +++ b/libs/nativewindow/AHardwareBuffer.cpp @@ -113,6 +113,22 @@ static_assert( AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM, "HAL and AHardwareBuffer pixel format don't match"); +static enum AHardwareBufferStatus filterStatus(status_t status) { + switch (status) { + case STATUS_OK: + return AHARDWAREBUFFER_STATUS_OK; + case STATUS_NO_MEMORY: + return AHARDWAREBUFFER_STATUS_NO_MEMORY; + case STATUS_BAD_VALUE: + return AHARDWAREBUFFER_STATUS_BAD_VALUE; + case STATUS_UNKNOWN_TRANSACTION: + case STATUS_INVALID_OPERATION: + return AHARDWAREBUFFER_STATUS_UNSUPPORTED; + default: + return AHARDWAREBUFFER_STATUS_UNKNOWN_ERROR; + } +} + // ---------------------------------------------------------------------------- // Public functions // ---------------------------------------------------------------------------- @@ -511,6 +527,24 @@ binder_status_t AHardwareBuffer_writeToParcel(const AHardwareBuffer* _Nonnull bu return AParcel_viewPlatformParcel(parcel)->write(*gb); } +ADataSpace AHardwareBuffer_getDataSpace(const AHardwareBuffer* _Nonnull buffer) { + const GraphicBuffer* gb = AHardwareBuffer_to_GraphicBuffer(buffer); + if (!gb) return ADATASPACE_UNKNOWN; + ui::Dataspace dataspace = ui::Dataspace::UNKNOWN; + status_t status = gb->getDataspace(&dataspace); + if (status != OK) { + return ADATASPACE_UNKNOWN; + } + return static_cast<ADataSpace>(dataspace); +} + +enum AHardwareBufferStatus AHardwareBuffer_setDataSpace(AHardwareBuffer* buffer, + ADataSpace dataspace) { + GraphicBuffer* gb = AHardwareBuffer_to_GraphicBuffer(buffer); + auto& mapper = GraphicBufferMapper::get(); + return filterStatus(mapper.setDataspace(gb->handle, static_cast<ui::Dataspace>(dataspace))); +} + // ---------------------------------------------------------------------------- // VNDK functions // ---------------------------------------------------------------------------- @@ -552,6 +586,56 @@ int AHardwareBuffer_createFromHandle(const AHardwareBuffer_Desc* desc, return NO_ERROR; } +enum AHardwareBufferStatus AHardwareBuffer_allocate2( + const AHardwareBuffer_Desc* desc, const AHardwareBufferLongOptions* additionalOptions, + size_t additionalOptionsSize, AHardwareBuffer** outBuffer) { + (void)additionalOptions; + (void)additionalOptionsSize; + if (!outBuffer || !desc) return AHARDWAREBUFFER_STATUS_BAD_VALUE; + if (!AHardwareBuffer_isValidDescription(desc, /*log=*/true)) { + return AHARDWAREBUFFER_STATUS_BAD_VALUE; + } + + int format = AHardwareBuffer_convertToPixelFormat(desc->format); + uint64_t usage = AHardwareBuffer_convertToGrallocUsageBits(desc->usage); + + std::vector<GraphicBufferAllocator::AdditionalOptions> extras; + extras.reserve(additionalOptionsSize); + for (size_t i = 0; i < additionalOptionsSize; i++) { + extras.push_back(GraphicBufferAllocator::AdditionalOptions{additionalOptions[i].name, + additionalOptions[i].value}); + } + + const auto extrasCount = extras.size(); + auto gbuffer = sp<GraphicBuffer>::make(GraphicBufferAllocator::AllocationRequest{ + .importBuffer = true, + .width = desc->width, + .height = desc->height, + .format = format, + .layerCount = desc->layers, + .usage = usage, + .requestorName = std::string("AHardwareBuffer pid [") + std::to_string(getpid()) + "]", + .extras = std::move(extras), + }); + + status_t err = gbuffer->initCheck(); + if (err != 0 || gbuffer->handle == nullptr) { + if (err == NO_MEMORY) { + GraphicBuffer::dumpAllocationsToSystemLog(); + } + ALOGE("GraphicBuffer(w=%u, h=%u, lc=%u, extrasCount=%zd) failed (%s), handle=%p", + desc->width, desc->height, desc->layers, extrasCount, strerror(-err), + gbuffer->handle); + return filterStatus(err == 0 ? UNKNOWN_ERROR : err); + } + + *outBuffer = AHardwareBuffer_from_GraphicBuffer(gbuffer.get()); + + // Ensure the buffer doesn't get destroyed when the sp<> goes away. + AHardwareBuffer_acquire(*outBuffer); + return AHARDWAREBUFFER_STATUS_OK; +} + // ---------------------------------------------------------------------------- // Helpers implementation // ---------------------------------------------------------------------------- @@ -652,12 +736,9 @@ uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t ahardwarebuffer_format) { return ahardwarebuffer_format; } +// TODO: Remove, this is just to make an overly aggressive ABI checker happy int32_t AHardwareBuffer_getDataSpace(AHardwareBuffer* buffer) { - GraphicBuffer* gb = AHardwareBuffer_to_GraphicBuffer(buffer); - auto& mapper = GraphicBufferMapper::get(); - ui::Dataspace dataspace = ui::Dataspace::UNKNOWN; - mapper.getDataspace(gb->handle, &dataspace); - return static_cast<int32_t>(dataspace); + return ::AHardwareBuffer_getDataSpace(buffer); } uint64_t AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage) { diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp index dd5958de28..f97eed5db3 100644 --- a/libs/nativewindow/ANativeWindow.cpp +++ b/libs/nativewindow/ANativeWindow.cpp @@ -152,31 +152,56 @@ int32_t ANativeWindow_setBuffersTransform(ANativeWindow* window, int32_t transfo int32_t ANativeWindow_setBuffersDataSpace(ANativeWindow* window, int32_t dataSpace) { static_assert(static_cast<int>(ADATASPACE_UNKNOWN) == static_cast<int>(HAL_DATASPACE_UNKNOWN)); - static_assert(static_cast<int>(STANDARD_MASK) == static_cast<int>(HAL_DATASPACE_STANDARD_MASK)); - static_assert(static_cast<int>(STANDARD_UNSPECIFIED) == static_cast<int>(HAL_DATASPACE_STANDARD_UNSPECIFIED)); - static_assert(static_cast<int>(STANDARD_BT709) == static_cast<int>(HAL_DATASPACE_STANDARD_BT709)); - static_assert(static_cast<int>(STANDARD_BT601_625) == static_cast<int>(HAL_DATASPACE_STANDARD_BT601_625)); - static_assert(static_cast<int>(STANDARD_BT601_625_UNADJUSTED) == static_cast<int>(HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED)); - static_assert(static_cast<int>(STANDARD_BT601_525) == static_cast<int>(HAL_DATASPACE_STANDARD_BT601_525)); - static_assert(static_cast<int>(STANDARD_BT601_525_UNADJUSTED) == static_cast<int>(HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED)); - static_assert(static_cast<int>(STANDARD_BT470M) == static_cast<int>(HAL_DATASPACE_STANDARD_BT470M)); - static_assert(static_cast<int>(STANDARD_FILM) == static_cast<int>(HAL_DATASPACE_STANDARD_FILM)); - static_assert(static_cast<int>(STANDARD_DCI_P3) == static_cast<int>(HAL_DATASPACE_STANDARD_DCI_P3)); - static_assert(static_cast<int>(STANDARD_ADOBE_RGB) == static_cast<int>(HAL_DATASPACE_STANDARD_ADOBE_RGB)); - static_assert(static_cast<int>(TRANSFER_MASK) == static_cast<int>(HAL_DATASPACE_TRANSFER_MASK)); - static_assert(static_cast<int>(TRANSFER_UNSPECIFIED) == static_cast<int>(HAL_DATASPACE_TRANSFER_UNSPECIFIED)); - static_assert(static_cast<int>(TRANSFER_LINEAR) == static_cast<int>(HAL_DATASPACE_TRANSFER_LINEAR)); - static_assert(static_cast<int>(TRANSFER_SMPTE_170M) == static_cast<int>(HAL_DATASPACE_TRANSFER_SMPTE_170M)); - static_assert(static_cast<int>(TRANSFER_GAMMA2_2) == static_cast<int>(HAL_DATASPACE_TRANSFER_GAMMA2_2)); - static_assert(static_cast<int>(TRANSFER_GAMMA2_6) == static_cast<int>(HAL_DATASPACE_TRANSFER_GAMMA2_6)); - static_assert(static_cast<int>(TRANSFER_GAMMA2_8) == static_cast<int>(HAL_DATASPACE_TRANSFER_GAMMA2_8)); - static_assert(static_cast<int>(TRANSFER_ST2084) == static_cast<int>(HAL_DATASPACE_TRANSFER_ST2084)); - static_assert(static_cast<int>(TRANSFER_HLG) == static_cast<int>(HAL_DATASPACE_TRANSFER_HLG)); - static_assert(static_cast<int>(RANGE_MASK) == static_cast<int>(HAL_DATASPACE_RANGE_MASK)); - static_assert(static_cast<int>(RANGE_UNSPECIFIED) == static_cast<int>(HAL_DATASPACE_RANGE_UNSPECIFIED)); - static_assert(static_cast<int>(RANGE_FULL) == static_cast<int>(HAL_DATASPACE_RANGE_FULL)); - static_assert(static_cast<int>(RANGE_LIMITED) == static_cast<int>(HAL_DATASPACE_RANGE_LIMITED)); - static_assert(static_cast<int>(RANGE_EXTENDED) == static_cast<int>(HAL_DATASPACE_RANGE_EXTENDED)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_MASK) == + static_cast<int>(HAL_DATASPACE_STANDARD_MASK)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_UNSPECIFIED) == + static_cast<int>(HAL_DATASPACE_STANDARD_UNSPECIFIED)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_BT709) == + static_cast<int>(HAL_DATASPACE_STANDARD_BT709)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_BT601_625) == + static_cast<int>(HAL_DATASPACE_STANDARD_BT601_625)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_BT601_625_UNADJUSTED) == + static_cast<int>(HAL_DATASPACE_STANDARD_BT601_625_UNADJUSTED)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_BT601_525) == + static_cast<int>(HAL_DATASPACE_STANDARD_BT601_525)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_BT601_525_UNADJUSTED) == + static_cast<int>(HAL_DATASPACE_STANDARD_BT601_525_UNADJUSTED)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_BT470M) == + static_cast<int>(HAL_DATASPACE_STANDARD_BT470M)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_FILM) == + static_cast<int>(HAL_DATASPACE_STANDARD_FILM)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_DCI_P3) == + static_cast<int>(HAL_DATASPACE_STANDARD_DCI_P3)); + static_assert(static_cast<int>(ADATASPACE_STANDARD_ADOBE_RGB) == + static_cast<int>(HAL_DATASPACE_STANDARD_ADOBE_RGB)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_MASK) == + static_cast<int>(HAL_DATASPACE_TRANSFER_MASK)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_UNSPECIFIED) == + static_cast<int>(HAL_DATASPACE_TRANSFER_UNSPECIFIED)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_LINEAR) == + static_cast<int>(HAL_DATASPACE_TRANSFER_LINEAR)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_SMPTE_170M) == + static_cast<int>(HAL_DATASPACE_TRANSFER_SMPTE_170M)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_GAMMA2_2) == + static_cast<int>(HAL_DATASPACE_TRANSFER_GAMMA2_2)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_GAMMA2_6) == + static_cast<int>(HAL_DATASPACE_TRANSFER_GAMMA2_6)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_GAMMA2_8) == + static_cast<int>(HAL_DATASPACE_TRANSFER_GAMMA2_8)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_ST2084) == + static_cast<int>(HAL_DATASPACE_TRANSFER_ST2084)); + static_assert(static_cast<int>(ADATASPACE_TRANSFER_HLG) == + static_cast<int>(HAL_DATASPACE_TRANSFER_HLG)); + static_assert(static_cast<int>(ADATASPACE_RANGE_MASK) == + static_cast<int>(HAL_DATASPACE_RANGE_MASK)); + static_assert(static_cast<int>(ADATASPACE_RANGE_UNSPECIFIED) == + static_cast<int>(HAL_DATASPACE_RANGE_UNSPECIFIED)); + static_assert(static_cast<int>(ADATASPACE_RANGE_FULL) == + static_cast<int>(HAL_DATASPACE_RANGE_FULL)); + static_assert(static_cast<int>(ADATASPACE_RANGE_LIMITED) == + static_cast<int>(HAL_DATASPACE_RANGE_LIMITED)); + static_assert(static_cast<int>(ADATASPACE_RANGE_EXTENDED) == + static_cast<int>(HAL_DATASPACE_RANGE_EXTENDED)); static_assert(static_cast<int>(ADATASPACE_SRGB) == static_cast<int>(HAL_DATASPACE_V0_SRGB)); static_assert(static_cast<int>(ADATASPACE_SCRGB) == static_cast<int>(HAL_DATASPACE_V0_SCRGB)); static_assert(static_cast<int>(ADATASPACE_DISPLAY_P3) == static_cast<int>(HAL_DATASPACE_DISPLAY_P3)); diff --git a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h index 880c694934..f145a2f7c2 100644 --- a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h +++ b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h @@ -27,8 +27,8 @@ #include <stdint.h> -struct AHardwareBuffer; -struct AHardwareBuffer_Desc; +#include <vndk/hardware_buffer.h> + struct ANativeWindowBuffer; namespace android { @@ -46,11 +46,6 @@ uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format); // convert HAL format to AHardwareBuffer format (note: this is a no-op) uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format); -// retrieves a dataspace from the AHardwareBuffer metadata, if the device -// support gralloc metadata. Returns UNKNOWN if gralloc metadata is not -// supported. -int32_t AHardwareBuffer_getDataSpace(AHardwareBuffer* buffer); - // convert AHardwareBuffer usage bits to HAL usage bits (note: this is a no-op) uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t usage); diff --git a/libs/nativewindow/include/android/data_space.h b/libs/nativewindow/include/android/data_space.h index eab21fbdf1..d4278bedf3 100644 --- a/libs/nativewindow/include/android/data_space.h +++ b/libs/nativewindow/include/android/data_space.h @@ -37,7 +37,7 @@ __BEGIN_DECLS /** * ADataSpace. */ -enum ADataSpace { +enum ADataSpace : int32_t { /** * Default-assumption data space, when not explicitly specified. * @@ -63,7 +63,7 @@ enum ADataSpace { * Defines the chromaticity coordinates of the source primaries in terms of * the CIE 1931 definition of x and y specified in ISO 11664-1. */ - STANDARD_MASK = 63 << 16, + ADATASPACE_STANDARD_MASK = 63 << 16, /** * Chromacity coordinates are unknown or are determined by the application. @@ -78,7 +78,7 @@ enum ADataSpace { * For all other formats standard is undefined, and implementations should use * an appropriate standard for the data represented. */ - STANDARD_UNSPECIFIED = 0 << 16, + ADATASPACE_STANDARD_UNSPECIFIED = 0 << 16, /** * <pre> @@ -91,7 +91,7 @@ enum ADataSpace { * Use the unadjusted KR = 0.2126, KB = 0.0722 luminance interpretation * for RGB conversion. */ - STANDARD_BT709 = 1 << 16, + ADATASPACE_STANDARD_BT709 = 1 << 16, /** * <pre> @@ -106,7 +106,7 @@ enum ADataSpace { * to minimize the color shift into RGB space that uses BT.709 * primaries. */ - STANDARD_BT601_625 = 2 << 16, + ADATASPACE_STANDARD_BT601_625 = 2 << 16, /** * <pre> @@ -119,7 +119,7 @@ enum ADataSpace { * Use the unadjusted KR = 0.222, KB = 0.071 luminance interpretation * for RGB conversion. */ - STANDARD_BT601_625_UNADJUSTED = 3 << 16, + ADATASPACE_STANDARD_BT601_625_UNADJUSTED = 3 << 16, /** * <pre> @@ -134,7 +134,7 @@ enum ADataSpace { * to minimize the color shift into RGB space that uses BT.709 * primaries. */ - STANDARD_BT601_525 = 4 << 16, + ADATASPACE_STANDARD_BT601_525 = 4 << 16, /** * <pre> @@ -147,7 +147,7 @@ enum ADataSpace { * Use the unadjusted KR = 0.212, KB = 0.087 luminance interpretation * for RGB conversion (as in SMPTE 240M). */ - STANDARD_BT601_525_UNADJUSTED = 5 << 16, + ADATASPACE_STANDARD_BT601_525_UNADJUSTED = 5 << 16, /** * <pre> @@ -160,7 +160,7 @@ enum ADataSpace { * Use the unadjusted KR = 0.2627, KB = 0.0593 luminance interpretation * for RGB conversion. */ - STANDARD_BT2020 = 6 << 16, + ADATASPACE_STANDARD_BT2020 = 6 << 16, /** * <pre> @@ -173,7 +173,7 @@ enum ADataSpace { * Use the unadjusted KR = 0.2627, KB = 0.0593 luminance interpretation * for RGB conversion using the linear domain. */ - STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << 16, + ADATASPACE_STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << 16, /** * <pre> @@ -186,7 +186,7 @@ enum ADataSpace { * Use the unadjusted KR = 0.30, KB = 0.11 luminance interpretation * for RGB conversion. */ - STANDARD_BT470M = 8 << 16, + ADATASPACE_STANDARD_BT470M = 8 << 16, /** * <pre> @@ -199,7 +199,7 @@ enum ADataSpace { * Use the unadjusted KR = 0.254, KB = 0.068 luminance interpretation * for RGB conversion. */ - STANDARD_FILM = 9 << 16, + ADATASPACE_STANDARD_FILM = 9 << 16, /** * SMPTE EG 432-1 and SMPTE RP 431-2. (DCI-P3) @@ -210,7 +210,7 @@ enum ADataSpace { * red 0.680 0.320 * white (D65) 0.3127 0.3290</pre> */ - STANDARD_DCI_P3 = 10 << 16, + ADATASPACE_STANDARD_DCI_P3 = 10 << 16, /** * Adobe RGB @@ -221,7 +221,7 @@ enum ADataSpace { * red 0.640 0.330 * white (D65) 0.3127 0.3290</pre> */ - STANDARD_ADOBE_RGB = 11 << 16, + ADATASPACE_STANDARD_ADOBE_RGB = 11 << 16, /** * Transfer aspect @@ -236,7 +236,7 @@ enum ADataSpace { * component. Implementation may apply the transfer function in RGB space * for all pixel formats if desired. */ - TRANSFER_MASK = 31 << 22, + ADATASPACE_TRANSFER_MASK = 31 << 22, /** * Transfer characteristics are unknown or are determined by the @@ -244,13 +244,13 @@ enum ADataSpace { * * Implementations should use the following transfer functions: * - * For YCbCr formats: use TRANSFER_SMPTE_170M - * For RGB formats: use TRANSFER_SRGB + * For YCbCr formats: use ADATASPACE_TRANSFER_SMPTE_170M + * For RGB formats: use ADATASPACE_TRANSFER_SRGB * * For all other formats transfer function is undefined, and implementations * should use an appropriate standard for the data represented. */ - TRANSFER_UNSPECIFIED = 0 << 22, + ADATASPACE_TRANSFER_UNSPECIFIED = 0 << 22, /** * Linear transfer. @@ -260,7 +260,7 @@ enum ADataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal</pre> */ - TRANSFER_LINEAR = 1 << 22, + ADATASPACE_TRANSFER_LINEAR = 1 << 22, /** * sRGB transfer. @@ -271,7 +271,7 @@ enum ADataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal</pre> */ - TRANSFER_SRGB = 2 << 22, + ADATASPACE_TRANSFER_SRGB = 2 << 22, /** * SMPTE 170M transfer. @@ -282,7 +282,7 @@ enum ADataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal</pre> */ - TRANSFER_SMPTE_170M = 3 << 22, + ADATASPACE_TRANSFER_SMPTE_170M = 3 << 22, /** * Display gamma 2.2. @@ -292,7 +292,7 @@ enum ADataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal</pre> */ - TRANSFER_GAMMA2_2 = 4 << 22, + ADATASPACE_TRANSFER_GAMMA2_2 = 4 << 22, /** * Display gamma 2.6. @@ -302,7 +302,7 @@ enum ADataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal</pre> */ - TRANSFER_GAMMA2_6 = 5 << 22, + ADATASPACE_TRANSFER_GAMMA2_6 = 5 << 22, /** * Display gamma 2.8. @@ -312,7 +312,7 @@ enum ADataSpace { * L - luminance of image 0 <= L <= 1 for conventional colorimetry * E - corresponding electrical signal</pre> */ - TRANSFER_GAMMA2_8 = 6 << 22, + ADATASPACE_TRANSFER_GAMMA2_8 = 6 << 22, /** * SMPTE ST 2084 (Dolby Perceptual Quantizer). @@ -328,7 +328,7 @@ enum ADataSpace { * L = 1 corresponds to 10000 cd/m2 * E - corresponding electrical signal</pre> */ - TRANSFER_ST2084 = 7 << 22, + ADATASPACE_TRANSFER_ST2084 = 7 << 22, /** * ARIB STD-B67 Hybrid Log Gamma. @@ -344,7 +344,7 @@ enum ADataSpace { * to reference white level of 100 cd/m2 * E - corresponding electrical signal</pre> */ - TRANSFER_HLG = 8 << 22, + ADATASPACE_TRANSFER_HLG = 8 << 22, /** * Range aspect @@ -352,7 +352,7 @@ enum ADataSpace { * Defines the range of values corresponding to the unit range of 0-1. * This is defined for YCbCr only, but can be expanded to RGB space. */ - RANGE_MASK = 7 << 27, + ADATASPACE_RANGE_MASK = 7 << 27, /** * Range is unknown or are determined by the application. Implementations @@ -365,13 +365,13 @@ enum ADataSpace { * For all other formats range is undefined, and implementations should use * an appropriate range for the data represented. */ - RANGE_UNSPECIFIED = 0 << 27, + ADATASPACE_RANGE_UNSPECIFIED = 0 << 27, /** * Full range uses all values for Y, Cb and Cr from * 0 to 2^b-1, where b is the bit depth of the color format. */ - RANGE_FULL = 1 << 27, + ADATASPACE_RANGE_FULL = 1 << 27, /** * Limited range uses values 16/256*2^b to 235/256*2^b for Y, and @@ -386,7 +386,7 @@ enum ADataSpace { * Luma (Y) samples should range from 64 to 940, inclusive * Chroma (Cb, Cr) samples should range from 64 to 960, inclusive */ - RANGE_LIMITED = 2 << 27, + ADATASPACE_RANGE_LIMITED = 2 << 27, /** * Extended range is used for scRGB. Intended for use with @@ -395,7 +395,7 @@ enum ADataSpace { * color outside the sRGB gamut. * Used to blend / merge multiple dataspaces on a single display. */ - RANGE_EXTENDED = 3 << 27, + ADATASPACE_RANGE_EXTENDED = 3 << 27, /** * scRGB linear encoding @@ -410,7 +410,8 @@ enum ADataSpace { * * Uses extended range, linear transfer and BT.709 standard. */ - ADATASPACE_SCRGB_LINEAR = 406913024, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_EXTENDED + ADATASPACE_SCRGB_LINEAR = 406913024, // ADATASPACE_STANDARD_BT709 | ADATASPACE_TRANSFER_LINEAR | + // ADATASPACE_RANGE_EXTENDED /** * sRGB gamma encoding @@ -425,7 +426,8 @@ enum ADataSpace { * * Uses full range, sRGB transfer BT.709 standard. */ - ADATASPACE_SRGB = 142671872, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_FULL + ADATASPACE_SRGB = 142671872, // ADATASPACE_STANDARD_BT709 | ADATASPACE_TRANSFER_SRGB | + // ADATASPACE_RANGE_FULL /** * scRGB @@ -440,14 +442,16 @@ enum ADataSpace { * * Uses extended range, sRGB transfer and BT.709 standard. */ - ADATASPACE_SCRGB = 411107328, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_EXTENDED + ADATASPACE_SCRGB = 411107328, // ADATASPACE_STANDARD_BT709 | ADATASPACE_TRANSFER_SRGB | + // ADATASPACE_RANGE_EXTENDED /** * Display P3 * * Uses full range, sRGB transfer and D65 DCI-P3 standard. */ - ADATASPACE_DISPLAY_P3 = 143261696, // STANDARD_DCI_P3 | TRANSFER_SRGB | RANGE_FULL + ADATASPACE_DISPLAY_P3 = 143261696, // ADATASPACE_STANDARD_DCI_P3 | ADATASPACE_TRANSFER_SRGB | + // ADATASPACE_RANGE_FULL /** * ITU-R Recommendation 2020 (BT.2020) @@ -456,7 +460,8 @@ enum ADataSpace { * * Uses full range, SMPTE 2084 (PQ) transfer and BT2020 standard. */ - ADATASPACE_BT2020_PQ = 163971072, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_FULL + ADATASPACE_BT2020_PQ = 163971072, // ADATASPACE_STANDARD_BT2020 | ADATASPACE_TRANSFER_ST2084 | + // ADATASPACE_RANGE_FULL /** * ITU-R Recommendation 2020 (BT.2020) @@ -465,7 +470,8 @@ enum ADataSpace { * * Uses limited range, SMPTE 2084 (PQ) transfer and BT2020 standard. */ - ADATASPACE_BT2020_ITU_PQ = 298188800, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED + ADATASPACE_BT2020_ITU_PQ = 298188800, // ADATASPACE_STANDARD_BT2020 | ADATASPACE_TRANSFER_ST2084 + // | ADATASPACE_RANGE_LIMITED /** * Adobe RGB @@ -475,7 +481,8 @@ enum ADataSpace { * Note: Application is responsible for gamma encoding the data as * a 2.2 gamma encoding is not supported in HW. */ - ADATASPACE_ADOBE_RGB = 151715840, // STANDARD_ADOBE_RGB | TRANSFER_GAMMA2_2 | RANGE_FULL + ADATASPACE_ADOBE_RGB = 151715840, // ADATASPACE_STANDARD_ADOBE_RGB | + // ADATASPACE_TRANSFER_GAMMA2_2 | ADATASPACE_RANGE_FULL /** * JPEG File Interchange Format (JFIF) @@ -484,7 +491,8 @@ enum ADataSpace { * * Uses full range, SMPTE 170M transfer and BT.601_625 standard. */ - ADATASPACE_JFIF = 146931712, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_FULL + ADATASPACE_JFIF = 146931712, // ADATASPACE_STANDARD_BT601_625 | ADATASPACE_TRANSFER_SMPTE_170M | + // ADATASPACE_RANGE_FULL /** * ITU-R Recommendation 601 (BT.601) - 625-line @@ -493,7 +501,8 @@ enum ADataSpace { * * Uses limited range, SMPTE 170M transfer and BT.601_625 standard. */ - ADATASPACE_BT601_625 = 281149440, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED + ADATASPACE_BT601_625 = 281149440, // ADATASPACE_STANDARD_BT601_625 | + // ADATASPACE_TRANSFER_SMPTE_170M | ADATASPACE_RANGE_LIMITED /** * ITU-R Recommendation 601 (BT.601) - 525-line @@ -502,7 +511,8 @@ enum ADataSpace { * * Uses limited range, SMPTE 170M transfer and BT.601_525 standard. */ - ADATASPACE_BT601_525 = 281280512, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED + ADATASPACE_BT601_525 = 281280512, // ADATASPACE_STANDARD_BT601_525 | + // ADATASPACE_TRANSFER_SMPTE_170M | ADATASPACE_RANGE_LIMITED /** * ITU-R Recommendation 2020 (BT.2020) @@ -511,7 +521,8 @@ enum ADataSpace { * * Uses full range, SMPTE 170M transfer and BT2020 standard. */ - ADATASPACE_BT2020 = 147193856, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_FULL + ADATASPACE_BT2020 = 147193856, // ADATASPACE_STANDARD_BT2020 | ADATASPACE_TRANSFER_SMPTE_170M | + // ADATASPACE_RANGE_FULL /** * ITU-R Recommendation 709 (BT.709) @@ -520,7 +531,8 @@ enum ADataSpace { * * Uses limited range, SMPTE 170M transfer and BT.709 standard. */ - ADATASPACE_BT709 = 281083904, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED + ADATASPACE_BT709 = 281083904, // ADATASPACE_STANDARD_BT709 | ADATASPACE_TRANSFER_SMPTE_170M | + // ADATASPACE_RANGE_LIMITED /** * SMPTE EG 432-1 and SMPTE RP 431-2 @@ -532,7 +544,8 @@ enum ADataSpace { * Note: Application is responsible for gamma encoding the data as * a 2.6 gamma encoding is not supported in HW. */ - ADATASPACE_DCI_P3 = 155844608, // STANDARD_DCI_P3 | TRANSFER_GAMMA2_6 | RANGE_FULL + ADATASPACE_DCI_P3 = 155844608, // ADATASPACE_STANDARD_DCI_P3 | ADATASPACE_TRANSFER_GAMMA2_6 | + // ADATASPACE_RANGE_FULL /** * sRGB linear encoding @@ -546,21 +559,24 @@ enum ADataSpace { * * Uses full range, linear transfer and BT.709 standard. */ - ADATASPACE_SRGB_LINEAR = 138477568, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL + ADATASPACE_SRGB_LINEAR = 138477568, // ADATASPACE_STANDARD_BT709 | ADATASPACE_TRANSFER_LINEAR | + // ADATASPACE_RANGE_FULL /** * Hybrid Log Gamma encoding * * Uses full range, hybrid log gamma transfer and BT2020 standard. */ - ADATASPACE_BT2020_HLG = 168165376, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_FULL + ADATASPACE_BT2020_HLG = 168165376, // ADATASPACE_STANDARD_BT2020 | ADATASPACE_TRANSFER_HLG | + // ADATASPACE_RANGE_FULL /** * ITU Hybrid Log Gamma encoding * * Uses limited range, hybrid log gamma transfer and BT2020 standard. */ - ADATASPACE_BT2020_ITU_HLG = 302383104, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_LIMITED + ADATASPACE_BT2020_ITU_HLG = 302383104, // ADATASPACE_STANDARD_BT2020 | ADATASPACE_TRANSFER_HLG | + // ADATASPACE_RANGE_LIMITED /** * Depth @@ -574,7 +590,37 @@ enum ADataSpace { * * Embedded depth metadata following the dynamic depth specification. */ - ADATASPACE_DYNAMIC_DEPTH = 4098 + ADATASPACE_DYNAMIC_DEPTH = 4098, + +#ifndef ADATASPACE_SKIP_LEGACY_DEFINES + STANDARD_MASK = ADATASPACE_STANDARD_MASK, + STANDARD_UNSPECIFIED = ADATASPACE_STANDARD_UNSPECIFIED, + STANDARD_BT709 = ADATASPACE_STANDARD_BT709, + STANDARD_BT601_625 = ADATASPACE_STANDARD_BT601_625, + STANDARD_BT601_625_UNADJUSTED = ADATASPACE_STANDARD_BT601_625_UNADJUSTED, + STANDARD_BT601_525 = ADATASPACE_STANDARD_BT601_525, + STANDARD_BT601_525_UNADJUSTED = ADATASPACE_STANDARD_BT601_525_UNADJUSTED, + STANDARD_BT470M = ADATASPACE_STANDARD_BT470M, + STANDARD_BT2020 = ADATASPACE_STANDARD_BT2020, + STANDARD_FILM = ADATASPACE_STANDARD_FILM, + STANDARD_DCI_P3 = ADATASPACE_STANDARD_DCI_P3, + STANDARD_ADOBE_RGB = ADATASPACE_STANDARD_ADOBE_RGB, + TRANSFER_MASK = ADATASPACE_TRANSFER_MASK, + TRANSFER_UNSPECIFIED = ADATASPACE_TRANSFER_UNSPECIFIED, + TRANSFER_LINEAR = ADATASPACE_TRANSFER_LINEAR, + TRANSFER_SMPTE_170M = ADATASPACE_TRANSFER_SMPTE_170M, + TRANSFER_GAMMA2_2 = ADATASPACE_TRANSFER_GAMMA2_2, + TRANSFER_GAMMA2_6 = ADATASPACE_TRANSFER_GAMMA2_6, + TRANSFER_GAMMA2_8 = ADATASPACE_TRANSFER_GAMMA2_8, + TRANSFER_SRGB = ADATASPACE_TRANSFER_SRGB, + TRANSFER_ST2084 = ADATASPACE_TRANSFER_ST2084, + TRANSFER_HLG = ADATASPACE_TRANSFER_HLG, + RANGE_MASK = ADATASPACE_RANGE_MASK, + RANGE_UNSPECIFIED = ADATASPACE_RANGE_UNSPECIFIED, + RANGE_FULL = ADATASPACE_RANGE_FULL, + RANGE_LIMITED = ADATASPACE_RANGE_LIMITED, + RANGE_EXTENDED = ADATASPACE_RANGE_EXTENDED, +#endif }; __END_DECLS diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h index 21798d0e29..e0e30c3283 100644 --- a/libs/nativewindow/include/android/hardware_buffer.h +++ b/libs/nativewindow/include/android/hardware_buffer.h @@ -46,6 +46,9 @@ #define ANDROID_HARDWARE_BUFFER_H #include <android/rect.h> +#define ADATASPACE_SKIP_LEGACY_DEFINES +#include <android/data_space.h> +#undef ADATASPACE_SKIP_LEGACY_DEFINES #include <inttypes.h> #include <sys/cdefs.h> diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h index 21931bb553..491860125f 100644 --- a/libs/nativewindow/include/vndk/hardware_buffer.h +++ b/libs/nativewindow/include/vndk/hardware_buffer.h @@ -21,6 +21,7 @@ #include <android/hardware_buffer.h> #include <cutils/native_handle.h> +#include <errno.h> __BEGIN_DECLS @@ -105,6 +106,76 @@ enum { AHARDWAREBUFFER_USAGE_CAMERA_MASK = 6UL << 16, }; +/** + * Additional options for AHardwareBuffer_allocate2. These correspond to + * android.hardware.graphics.common.ExtendableType + */ +typedef struct { + const char* _Nonnull name; + int64_t value; +} AHardwareBufferLongOptions; + +enum AHardwareBufferStatus : int32_t { + /* Success, no error */ + AHARDWAREBUFFER_STATUS_OK = 0, + /* There's insufficient memory to satisfy the request */ + AHARDWAREBUFFER_STATUS_NO_MEMORY = -ENOMEM, + /* The given argument is invalid */ + AHARDWAREBUFFER_STATUS_BAD_VALUE = -EINVAL, + /* The requested operation is not supported by the device */ + AHARDWAREBUFFER_STATUS_UNSUPPORTED = -ENOSYS, + /* An unknown error occurred */ + AHARDWAREBUFFER_STATUS_UNKNOWN_ERROR = (-2147483647 - 1), +}; + +/** + * Allocates a buffer that matches the passed AHardwareBuffer_Desc with additional options + * + * If allocation succeeds, the buffer can be used according to the + * usage flags specified in its description. If a buffer is used in ways + * not compatible with its usage flags, the results are undefined and + * may include program termination. + * + * @param desc The AHardwareBuffer_Desc that describes the allocation to request. Note that `stride` + * is ignored. + * @param additionalOptions A pointer to an array of AHardwareBufferLongOptions with additional + * string key + long value options that may be specified. May be null if + * `additionalOptionsSize` is 0 + * @param additionalOptionsSize The number of additional options to pass + * @param outBuffer The resulting buffer allocation + * @return AHARDWAREBUFFER_STATUS_OK on success + * AHARDWAREBUFFER_STATUS_NO_MEMORY if there's insufficient resources for the allocation + * AHARDWAREBUFFER_STATUS_BAD_VALUE if the provided description & options are not supported + * by the device + * AHARDWAREBUFFER_STATUS_UNKNOWN_ERROR for any other error + * any reason. The returned buffer has a reference count of 1. + */ +enum AHardwareBufferStatus AHardwareBuffer_allocate2( + const AHardwareBuffer_Desc* _Nonnull desc, + const AHardwareBufferLongOptions* _Nullable additionalOptions, size_t additionalOptionsSize, + AHardwareBuffer* _Nullable* _Nonnull outBuffer) __INTRODUCED_IN(__ANDROID_API_V__); + +/** + * Queries the dataspace of the given AHardwareBuffer. + * + * @param buffer The non-null buffer for which to query the Dataspace + * @return The dataspace of the buffer, or ADATASPACE_UNKNOWN if one hasn't been set + */ +enum ADataSpace AHardwareBuffer_getDataSpace(const AHardwareBuffer* _Nonnull buffer) + __INTRODUCED_IN(__ANDROID_API_V__); + +/** + * Sets the dataspace of the given AHardwareBuffer + * @param buffer The non-null buffer for which to set the dataspace + * @param dataSpace The dataspace to set + * @return AHARDWAREBUFFER_STATUS_OK on success, + * AHARDWAREBUFFER_STATUS_UNSUPPORTED if the device doesn't support setting the dataspace, + * AHARDWAREBUFFER_STATUS_UNKNOWN_ERROR for any other failure. + */ +enum AHardwareBufferStatus AHardwareBuffer_setDataSpace(AHardwareBuffer* _Nonnull buffer, + enum ADataSpace dataSpace) + __INTRODUCED_IN(__ANDROID_API_V__); + __END_DECLS #endif /* ANDROID_VNDK_NATIVEWINDOW_AHARDWAREBUFFER_H */ diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt index dcb506815c..a185a59fca 100644 --- a/libs/nativewindow/libnativewindow.map.txt +++ b/libs/nativewindow/libnativewindow.map.txt @@ -2,6 +2,7 @@ LIBNATIVEWINDOW { global: AHardwareBuffer_acquire; AHardwareBuffer_allocate; + AHardwareBuffer_allocate2; # llndk # systemapi AHardwareBuffer_createFromHandle; # llndk # systemapi AHardwareBuffer_describe; AHardwareBuffer_getId; # introduced=31 @@ -16,6 +17,8 @@ LIBNATIVEWINDOW { AHardwareBuffer_unlock; AHardwareBuffer_readFromParcel; # introduced=34 AHardwareBuffer_writeToParcel; # introduced=34 + AHardwareBuffer_getDataSpace; # llndk # systemapi + AHardwareBuffer_setDataSpace; # llndk # systemapi ANativeWindowBuffer_getHardwareBuffer; # llndk ANativeWindow_OemStorageGet; # llndk ANativeWindow_OemStorageSet; # llndk diff --git a/libs/nativewindow/tests/AHardwareBufferTest.cpp b/libs/nativewindow/tests/AHardwareBufferTest.cpp index ef863b6d67..1f0128a48e 100644 --- a/libs/nativewindow/tests/AHardwareBufferTest.cpp +++ b/libs/nativewindow/tests/AHardwareBufferTest.cpp @@ -17,6 +17,8 @@ #define LOG_TAG "AHardwareBuffer_test" //#define LOG_NDEBUG 0 +#include <android-base/properties.h> +#include <android/data_space.h> #include <android/hardware/graphics/common/1.0/types.h> #include <gtest/gtest.h> #include <private/android/AHardwareBufferHelpers.h> @@ -26,6 +28,10 @@ using namespace android; using android::hardware::graphics::common::V1_0::BufferUsage; +static bool IsCuttlefish() { + return ::android::base::GetProperty("ro.product.board", "") == "cutf"; +} + static ::testing::AssertionResult BuildHexFailureMessage(uint64_t expected, uint64_t actual, const char* type) { std::ostringstream ss; @@ -170,3 +176,83 @@ TEST(AHardwareBufferTest, GetIdTest) { EXPECT_NE(id1, id2); } + +TEST(AHardwareBufferTest, Allocate2NoExtras) { + AHardwareBuffer_Desc desc{ + .width = 64, + .height = 1, + .layers = 1, + .format = AHARDWAREBUFFER_FORMAT_BLOB, + .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, + .stride = 0, + }; + + AHardwareBuffer* buffer = nullptr; + ASSERT_EQ(0, AHardwareBuffer_allocate2(&desc, nullptr, 0, &buffer)); + uint64_t id = 0; + EXPECT_EQ(0, AHardwareBuffer_getId(buffer, &id)); + EXPECT_NE(0, id); + AHardwareBuffer_Desc desc2{}; + AHardwareBuffer_describe(buffer, &desc2); + EXPECT_EQ(desc.width, desc2.width); + EXPECT_EQ(desc.height, desc2.height); + EXPECT_GE(desc2.stride, desc2.width); + + AHardwareBuffer_release(buffer); +} + +TEST(AHardwareBufferTest, Allocate2WithExtras) { + if (!IsCuttlefish()) { + GTEST_SKIP() << "Unknown gralloc HAL, cannot test extras"; + } + + AHardwareBuffer_Desc desc{ + .width = 64, + .height = 48, + .layers = 1, + .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, + .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, + .stride = 0, + }; + + AHardwareBuffer* buffer = nullptr; + std::array<AHardwareBufferLongOptions, 1> extras = {{ + {.name = "android.hardware.graphics.common.Dataspace", ADATASPACE_DISPLAY_P3}, + }}; + ASSERT_EQ(0, AHardwareBuffer_allocate2(&desc, extras.data(), extras.size(), &buffer)); + uint64_t id = 0; + EXPECT_EQ(0, AHardwareBuffer_getId(buffer, &id)); + EXPECT_NE(0, id); + AHardwareBuffer_Desc desc2{}; + AHardwareBuffer_describe(buffer, &desc2); + EXPECT_EQ(desc.width, desc2.width); + EXPECT_EQ(desc.height, desc2.height); + EXPECT_GE(desc2.stride, desc2.width); + + EXPECT_EQ(ADATASPACE_DISPLAY_P3, AHardwareBuffer_getDataSpace(buffer)); + + AHardwareBuffer_release(buffer); +} + +TEST(AHardwareBufferTest, GetSetDataspace) { + AHardwareBuffer_Desc desc{ + .width = 64, + .height = 48, + .layers = 1, + .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, + .usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, + .stride = 0, + }; + + AHardwareBuffer* buffer = nullptr; + ASSERT_EQ(0, AHardwareBuffer_allocate(&desc, &buffer)); + + EXPECT_EQ(ADATASPACE_UNKNOWN, AHardwareBuffer_getDataSpace(buffer)); + AHardwareBufferStatus status = AHardwareBuffer_setDataSpace(buffer, ADATASPACE_DISPLAY_P3); + if (status != AHARDWAREBUFFER_STATUS_UNSUPPORTED) { + EXPECT_EQ(0, status); + EXPECT_EQ(ADATASPACE_DISPLAY_P3, AHardwareBuffer_getDataSpace(buffer)); + } + + AHardwareBuffer_release(buffer); +}
\ No newline at end of file diff --git a/libs/nativewindow/tests/Android.bp b/libs/nativewindow/tests/Android.bp index 30737c1bf6..d7c7eb3153 100644 --- a/libs/nativewindow/tests/Android.bp +++ b/libs/nativewindow/tests/Android.bp @@ -31,6 +31,7 @@ cc_test { "device-tests", ], shared_libs: [ + "libbase", "libgui", "liblog", "libnativewindow", @@ -44,5 +45,8 @@ cc_test { "ANativeWindowTest.cpp", "c_compatibility.c", ], - cflags: ["-Wall", "-Werror"], + cflags: [ + "-Wall", + "-Werror", + ], } diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp index e9b5decee8..a5aca9912f 100644 --- a/libs/ui/Gralloc2.cpp +++ b/libs/ui/Gralloc2.cpp @@ -384,8 +384,8 @@ std::string Gralloc2Allocator::dumpDebugInfo(bool /*less*/) const { status_t Gralloc2Allocator::allocate(std::string /*requestorName*/, uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage, - uint32_t bufferCount, uint32_t* outStride, - buffer_handle_t* outBufferHandles, bool importBuffers) const { + uint32_t* outStride, buffer_handle_t* outBufferHandles, + bool importBuffers) const { IMapper::BufferDescriptorInfo descriptorInfo = {}; descriptorInfo.width = width; descriptorInfo.height = height; @@ -400,6 +400,8 @@ status_t Gralloc2Allocator::allocate(std::string /*requestorName*/, uint32_t wid return error; } + constexpr auto bufferCount = 1; + auto ret = mAllocator->allocate(descriptor, bufferCount, [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) { diff --git a/libs/ui/Gralloc3.cpp b/libs/ui/Gralloc3.cpp index 474d381dbb..152b35a505 100644 --- a/libs/ui/Gralloc3.cpp +++ b/libs/ui/Gralloc3.cpp @@ -371,7 +371,7 @@ std::string Gralloc3Allocator::dumpDebugInfo(bool /*less*/) const { status_t Gralloc3Allocator::allocate(std::string /*requestorName*/, uint32_t width, uint32_t height, android::PixelFormat format, uint32_t layerCount, - uint64_t usage, uint32_t bufferCount, uint32_t* outStride, + uint64_t usage, uint32_t* outStride, buffer_handle_t* outBufferHandles, bool importBuffers) const { IMapper::BufferDescriptorInfo descriptorInfo; sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo); @@ -383,6 +383,8 @@ status_t Gralloc3Allocator::allocate(std::string /*requestorName*/, uint32_t wid return error; } + constexpr auto bufferCount = 1; + auto ret = mAllocator->allocate(descriptor, bufferCount, [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) { diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp index 03ff58a76c..d6970e0477 100644 --- a/libs/ui/Gralloc4.cpp +++ b/libs/ui/Gralloc4.cpp @@ -1069,7 +1069,7 @@ std::string Gralloc4Allocator::dumpDebugInfo(bool less) const { status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height, android::PixelFormat format, uint32_t layerCount, - uint64_t usage, uint32_t bufferCount, uint32_t* outStride, + uint64_t usage, uint32_t* outStride, buffer_handle_t* outBufferHandles, bool importBuffers) const { IMapper::BufferDescriptorInfo descriptorInfo; if (auto error = sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage, @@ -1084,6 +1084,8 @@ status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, return error; } + constexpr auto bufferCount = 1; + if (mAidlAllocator) { AllocationResult result; #pragma clang diagnostic push diff --git a/libs/ui/Gralloc5.cpp b/libs/ui/Gralloc5.cpp index 2ec6d18fda..b07e15534a 100644 --- a/libs/ui/Gralloc5.cpp +++ b/libs/ui/Gralloc5.cpp @@ -19,6 +19,7 @@ #include <ui/Gralloc5.h> +#include <aidl/android/hardware/graphics/allocator/AllocationError.h> #include <aidlcommonsupport/NativeHandle.h> #include <android/binder_manager.h> #include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h> @@ -215,55 +216,75 @@ std::string Gralloc5Allocator::dumpDebugInfo(bool less) const { status_t Gralloc5Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height, android::PixelFormat format, uint32_t layerCount, - uint64_t usage, uint32_t bufferCount, uint32_t *outStride, - buffer_handle_t *outBufferHandles, bool importBuffers) const { - auto descriptorInfo = makeDescriptor(requestorName, width, height, format, layerCount, usage); + uint64_t usage, uint32_t* outStride, + buffer_handle_t* outBufferHandles, bool importBuffers) const { + auto result = allocate(GraphicBufferAllocator::AllocationRequest{ + .importBuffer = importBuffers, + .width = width, + .height = height, + .format = format, + .layerCount = layerCount, + .usage = usage, + .requestorName = requestorName, + }); + + *outStride = result.stride; + outBufferHandles[0] = result.handle; + return result.status; +} + +GraphicBufferAllocator::AllocationResult Gralloc5Allocator::allocate( + const GraphicBufferAllocator::AllocationRequest& request) const { + auto descriptorInfo = makeDescriptor(request.requestorName, request.width, request.height, + request.format, request.layerCount, request.usage); if (!descriptorInfo) { - return BAD_VALUE; + return GraphicBufferAllocator::AllocationResult{BAD_VALUE}; + } + + descriptorInfo->additionalOptions.reserve(request.extras.size()); + for (const auto& option : request.extras) { + ExtendableType type; + type.name = option.name; + type.value = option.value; + descriptorInfo->additionalOptions.push_back(std::move(type)); } AllocationResult result; - auto status = mAllocator->allocate2(*descriptorInfo, bufferCount, &result); + auto status = mAllocator->allocate2(*descriptorInfo, 1, &result); if (!status.isOk()) { auto error = status.getExceptionCode(); if (error == EX_SERVICE_SPECIFIC) { - error = status.getServiceSpecificError(); - } - if (error == OK) { - error = UNKNOWN_ERROR; + switch (static_cast<AllocationError>(status.getServiceSpecificError())) { + case AllocationError::BAD_DESCRIPTOR: + error = BAD_VALUE; + break; + case AllocationError::NO_RESOURCES: + error = NO_MEMORY; + break; + default: + error = UNKNOWN_ERROR; + break; + } } - return error; + return GraphicBufferAllocator::AllocationResult{error}; } - if (importBuffers) { - for (uint32_t i = 0; i < bufferCount; i++) { - auto handle = makeFromAidl(result.buffers[i]); - auto error = mMapper.importBuffer(handle, &outBufferHandles[i]); - native_handle_delete(handle); - if (error != NO_ERROR) { - for (uint32_t j = 0; j < i; j++) { - mMapper.freeBuffer(outBufferHandles[j]); - outBufferHandles[j] = nullptr; - } - return error; - } + GraphicBufferAllocator::AllocationResult ret{OK}; + if (request.importBuffer) { + auto handle = makeFromAidl(result.buffers[0]); + auto error = mMapper.importBuffer(handle, &ret.handle); + native_handle_delete(handle); + if (error != NO_ERROR) { + return GraphicBufferAllocator::AllocationResult{error}; } } else { - for (uint32_t i = 0; i < bufferCount; i++) { - outBufferHandles[i] = dupFromAidl(result.buffers[i]); - if (!outBufferHandles[i]) { - for (uint32_t j = 0; j < i; j++) { - auto buffer = const_cast<native_handle_t *>(outBufferHandles[j]); - native_handle_close(buffer); - native_handle_delete(buffer); - outBufferHandles[j] = nullptr; - } - return NO_MEMORY; - } + ret.handle = dupFromAidl(result.buffers[0]); + if (!ret.handle) { + return GraphicBufferAllocator::AllocationResult{NO_MEMORY}; } } - *outStride = result.stride; + ret.stride = result.stride; // Release all the resources held by AllocationResult (specifically any remaining FDs) result = {}; @@ -272,7 +293,7 @@ status_t Gralloc5Allocator::allocate(std::string requestorName, uint32_t width, // is marked apex_available (b/214400477) and libbinder isn't (which of course is correct) // IPCThreadState::self()->flushCommands(); - return OK; + return ret; } void Gralloc5Mapper::preload() { diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 429760ffe0..c007fdb587 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -106,6 +106,26 @@ GraphicBuffer::GraphicBuffer(const native_handle_t* inHandle, HandleWrapMethod m inUsage, inStride); } +GraphicBuffer::GraphicBuffer(const GraphicBufferAllocator::AllocationRequest& request) + : GraphicBuffer() { + GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); + auto result = allocator.allocate(request); + mInitCheck = result.status; + if (result.status == NO_ERROR) { + handle = result.handle; + stride = result.stride; + + mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts); + + width = static_cast<int>(request.width); + height = static_cast<int>(request.height); + format = request.format; + layerCount = request.layerCount; + usage = request.usage; + usage_deprecated = int(usage); + } +} + GraphicBuffer::~GraphicBuffer() { ATRACE_CALL(); @@ -143,6 +163,10 @@ ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const const_cast<GraphicBuffer*>(this)); } +status_t GraphicBuffer::getDataspace(ui::Dataspace* outDataspace) const { + return mBufferMapper.getDataspace(handle, outDataspace); +} + status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage) { diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp index eb0bd4ed0a..98082fb81e 100644 --- a/libs/ui/GraphicBufferAllocator.cpp +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -113,6 +113,79 @@ void GraphicBufferAllocator::dumpToSystemLog(bool less) { ALOGD("%s", s.c_str()); } +auto GraphicBufferAllocator::allocate(const AllocationRequest& request) -> AllocationResult { + ATRACE_CALL(); + if (!request.width || !request.height) { + return AllocationResult(BAD_VALUE); + } + + const auto width = request.width; + const auto height = request.height; + + const uint32_t bpp = bytesPerPixel(request.format); + if (std::numeric_limits<size_t>::max() / width / height < static_cast<size_t>(bpp)) { + ALOGE("Failed to allocate (%u x %u) layerCount %u format %d " + "usage %" PRIx64 ": Requesting too large a buffer size", + request.width, request.height, request.layerCount, request.format, request.usage); + return AllocationResult(BAD_VALUE); + } + + if (request.layerCount < 1) { + return AllocationResult(BAD_VALUE); + } + + auto result = mAllocator->allocate(request); + if (result.status == UNKNOWN_TRANSACTION) { + if (!request.extras.empty()) { + ALOGE("Failed to allocate with additional options, allocator version mis-match? " + "gralloc version = %d", + (int)mMapper.getMapperVersion()); + return result; + } + // If there's no additional options, fall back to previous allocate version + result.status = mAllocator->allocate(request.requestorName, request.width, request.height, + request.format, request.layerCount, request.usage, + &result.stride, &result.handle, request.importBuffer); + } + + if (result.status != NO_ERROR) { + ALOGE("Failed to allocate (%u x %u) layerCount %u format %d " + "usage %" PRIx64 ": %d", + request.width, request.height, request.layerCount, request.format, request.usage, + result.status); + return result; + } + + if (!request.importBuffer) { + return result; + } + size_t bufSize; + + // if stride has no meaning or is too large, + // approximate size with the input width instead + if ((result.stride) != 0 && + std::numeric_limits<size_t>::max() / height / (result.stride) < static_cast<size_t>(bpp)) { + bufSize = static_cast<size_t>(width) * height * bpp; + } else { + bufSize = static_cast<size_t>((result.stride)) * height * bpp; + } + + Mutex::Autolock _l(sLock); + KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); + alloc_rec_t rec; + rec.width = width; + rec.height = height; + rec.stride = result.stride; + rec.format = request.format; + rec.layerCount = request.layerCount; + rec.usage = request.usage; + rec.size = bufSize; + rec.requestorName = request.requestorName; + list.add(result.handle, rec); + + return result; +} + status_t GraphicBufferAllocator::allocateHelper(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage, buffer_handle_t* handle, uint32_t* stride, @@ -141,7 +214,7 @@ status_t GraphicBufferAllocator::allocateHelper(uint32_t width, uint32_t height, usage &= ~static_cast<uint64_t>((1 << 10) | (1 << 13)); status_t error = mAllocator->allocate(requestorName, width, height, format, layerCount, usage, - 1, stride, handle, importBuffer); + stride, handle, importBuffer); if (error != NO_ERROR) { ALOGE("Failed to allocate (%u x %u) layerCount %u format %d " "usage %" PRIx64 ": %d", diff --git a/libs/ui/include/ui/Gralloc.h b/libs/ui/include/ui/Gralloc.h index 496ba57789..e6015e0b5e 100644 --- a/libs/ui/include/ui/Gralloc.h +++ b/libs/ui/include/ui/Gralloc.h @@ -23,6 +23,7 @@ #include <ui/PixelFormat.h> #include <ui/Rect.h> #include <utils/StrongPointer.h> +#include "GraphicBufferAllocator.h" #include <string> @@ -218,9 +219,13 @@ public: */ virtual status_t allocate(std::string requestorName, uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage, - uint32_t bufferCount, uint32_t* outStride, - buffer_handle_t* outBufferHandles, + uint32_t* outStride, buffer_handle_t* outBufferHandles, bool importBuffers = true) const = 0; + + virtual GraphicBufferAllocator::AllocationResult allocate( + const GraphicBufferAllocator::AllocationRequest&) const { + return GraphicBufferAllocator::AllocationResult(UNKNOWN_TRANSACTION); + } }; } // namespace android diff --git a/libs/ui/include/ui/Gralloc2.h b/libs/ui/include/ui/Gralloc2.h index a7b6f49206..e50bb3af3e 100644 --- a/libs/ui/include/ui/Gralloc2.h +++ b/libs/ui/include/ui/Gralloc2.h @@ -81,9 +81,8 @@ public: std::string dumpDebugInfo(bool less = true) const override; status_t allocate(std::string requestorName, uint32_t width, uint32_t height, - PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t bufferCount, - uint32_t* outStride, buffer_handle_t* outBufferHandles, - bool importBuffers = true) const override; + PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t* outStride, + buffer_handle_t* outBufferHandles, bool importBuffers = true) const override; private: const Gralloc2Mapper& mMapper; diff --git a/libs/ui/include/ui/Gralloc3.h b/libs/ui/include/ui/Gralloc3.h index 7367549964..035684abcd 100644 --- a/libs/ui/include/ui/Gralloc3.h +++ b/libs/ui/include/ui/Gralloc3.h @@ -82,9 +82,8 @@ public: std::string dumpDebugInfo(bool less = true) const override; status_t allocate(std::string requestorName, uint32_t width, uint32_t height, - PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t bufferCount, - uint32_t* outStride, buffer_handle_t* outBufferHandles, - bool importBuffers = true) const override; + PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t* outStride, + buffer_handle_t* outBufferHandles, bool importBuffers = true) const override; private: const Gralloc3Mapper& mMapper; diff --git a/libs/ui/include/ui/Gralloc4.h b/libs/ui/include/ui/Gralloc4.h index df43be87cd..0f469c0b7e 100644 --- a/libs/ui/include/ui/Gralloc4.h +++ b/libs/ui/include/ui/Gralloc4.h @@ -174,9 +174,8 @@ public: std::string dumpDebugInfo(bool less = true) const override; status_t allocate(std::string requestorName, uint32_t width, uint32_t height, - PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t bufferCount, - uint32_t* outStride, buffer_handle_t* outBufferHandles, - bool importBuffers = true) const override; + PixelFormat format, uint32_t layerCount, uint64_t usage, uint32_t* outStride, + buffer_handle_t* outBufferHandles, bool importBuffers = true) const override; private: const Gralloc4Mapper& mMapper; diff --git a/libs/ui/include/ui/Gralloc5.h b/libs/ui/include/ui/Gralloc5.h index 44b97d1a6f..f9e8f5e9fd 100644 --- a/libs/ui/include/ui/Gralloc5.h +++ b/libs/ui/include/ui/Gralloc5.h @@ -172,10 +172,12 @@ public: [[nodiscard]] status_t allocate(std::string requestorName, uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage, - uint32_t bufferCount, uint32_t *outStride, - buffer_handle_t *outBufferHandles, + uint32_t* outStride, buffer_handle_t* outBufferHandles, bool importBuffers) const override; + [[nodiscard]] GraphicBufferAllocator::AllocationResult allocate( + const GraphicBufferAllocator::AllocationRequest&) const override; + private: const Gralloc5Mapper &mMapper; std::shared_ptr<aidl::android::hardware::graphics::allocator::IAllocator> mAllocator; diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h index f859848b0c..652d8ba709 100644 --- a/libs/ui/include/ui/GraphicBuffer.h +++ b/libs/ui/include/ui/GraphicBuffer.h @@ -26,6 +26,7 @@ #include <android/hardware_buffer.h> #include <ui/ANativeObjectBase.h> +#include <ui/GraphicBufferAllocator.h> #include <ui/GraphicBufferMapper.h> #include <ui/PixelFormat.h> #include <ui/Rect.h> @@ -103,6 +104,8 @@ public: uint32_t inLayerCount, uint64_t inUsage, std::string requestorName = "<Unknown>"); + GraphicBuffer(const GraphicBufferAllocator::AllocationRequest&); + // Create a GraphicBuffer from an existing handle. enum HandleWrapMethod : uint8_t { // Wrap and use the handle directly. It assumes the handle has been @@ -169,6 +172,8 @@ public: mGenerationNumber = generation; } + status_t getDataspace(ui::Dataspace* outDataspace) const; + // This function is privileged. It requires access to the allocator // device or service, which usually involves adding suitable selinux // rules. diff --git a/libs/ui/include/ui/GraphicBufferAllocator.h b/libs/ui/include/ui/GraphicBufferAllocator.h index 3ed988c4c2..8f461e193b 100644 --- a/libs/ui/include/ui/GraphicBufferAllocator.h +++ b/libs/ui/include/ui/GraphicBufferAllocator.h @@ -22,6 +22,7 @@ #include <memory> #include <string> +#include <vector> #include <cutils/native_handle.h> @@ -42,6 +43,35 @@ class GraphicBufferAllocator : public Singleton<GraphicBufferAllocator> public: static inline GraphicBufferAllocator& get() { return getInstance(); } + struct AdditionalOptions { + const char* name; + int64_t value; + }; + + struct AllocationRequest { + bool importBuffer; + uint32_t width; + uint32_t height; + PixelFormat format; + uint32_t layerCount; + uint64_t usage; + std::string requestorName; + std::vector<AdditionalOptions> extras; + }; + + struct AllocationResult { + status_t status; + buffer_handle_t handle = nullptr; + uint32_t stride = 0; + + explicit AllocationResult(status_t status) : status(status) {} + + explicit AllocationResult(buffer_handle_t handle, uint32_t stride) + : status(OK), handle(handle), stride(stride) {} + }; + + AllocationResult allocate(const AllocationRequest&); + /** * Allocates and imports a gralloc buffer. * diff --git a/libs/ui/tests/GraphicBufferAllocator_test.cpp b/libs/ui/tests/GraphicBufferAllocator_test.cpp index f4c0afa71b..efca083e6e 100644 --- a/libs/ui/tests/GraphicBufferAllocator_test.cpp +++ b/libs/ui/tests/GraphicBufferAllocator_test.cpp @@ -51,7 +51,7 @@ public: std::cout << "Setting expected stride to " << stride << std::endl; EXPECT_CALL(*(reinterpret_cast<const mock::MockGrallocAllocator*>(mAllocator.get())), allocate) - .WillOnce(DoAll(SetArgPointee<7>(stride), Return(err))); + .WillOnce(DoAll(SetArgPointee<6>(stride), Return(err))); } std::unique_ptr<const GrallocAllocator>& getAllocator() { return mAllocator; } }; diff --git a/libs/ui/tests/mock/MockGrallocAllocator.h b/libs/ui/tests/mock/MockGrallocAllocator.h index d62e3e2192..d02b3873e0 100644 --- a/libs/ui/tests/mock/MockGrallocAllocator.h +++ b/libs/ui/tests/mock/MockGrallocAllocator.h @@ -35,7 +35,7 @@ public: MOCK_METHOD(std::string, dumpDebugInfo, (bool less), (const, override)); MOCK_METHOD(status_t, allocate, (std::string requestorName, uint32_t width, uint32_t height, PixelFormat format, - uint32_t layerCount, uint64_t usage, uint32_t bufferCount, uint32_t* outStride, + uint32_t layerCount, uint64_t usage, uint32_t* outStride, buffer_handle_t* outBufferHandles, bool less), (const, override)); }; |