gralloc: add get and set BufferMetadata support
Add get and set functions that allow buffer metadata to be set
on the buffer.
This patch has been reviewed by vendors on AOSP. It is a combination of the
following patches. They have been squashed (and updated) to make them easier to
review. Two of the patches are proposals by ARM that have been incorporated into
this patch.
https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1107574
https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1109946
https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1124857
https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1126861
Bug: 141632767, 141631993
Test: VtsHalGraphicsMapperV4_0TargetTest
Change-Id: I0e79d73a7687f2f5b51828a7454888e6d8ff9460
diff --git a/graphics/common/aidl/Android.bp b/graphics/common/aidl/Android.bp
index 497c0f8..e0c7674 100644
--- a/graphics/common/aidl/Android.bp
+++ b/graphics/common/aidl/Android.bp
@@ -1,5 +1,6 @@
aidl_interface {
name: "vintf-graphics-common",
+ host_supported: true,
vendor_available: true,
vndk: {
enabled: true,
diff --git a/graphics/mapper/4.0/IMapper.hal b/graphics/mapper/4.0/IMapper.hal
index 640539f..a541382 100644
--- a/graphics/mapper/4.0/IMapper.hal
+++ b/graphics/mapper/4.0/IMapper.hal
@@ -35,18 +35,20 @@
*/
uint32_t width;
- /**
- * The height specifies how many rows of pixels must be in the
- * allocated buffer.
- */
+ /**
+ * The height specifies how many rows of pixels must be in the
+ * allocated buffer.
+ */
uint32_t height;
- /**
- * The number of image layers that must be in the allocated buffer.
- */
+ /**
+ * The number of image layers that must be in the allocated buffer.
+ */
uint32_t layerCount;
- /** Buffer pixel format. */
+ /**
+ * Buffer pixel format.
+ */
PixelFormat format;
/**
@@ -309,5 +311,209 @@
generates (Error error,
bool supported);
+
+ /**
+ * Description for get(...), set(...) and getFromBufferDescriptorInfo(...)
+ *
+ * ------------ Overview -----------------------------------
+ * Gralloc 4 adds support for getting and setting buffer metadata on a buffer.
+ *
+ * To get buffer metadata, the client passes in a buffer handle and a token that
+ * represents the type of buffer metadata they would like to get. IMapper returns
+ * a byte stream that contains the buffer metadata. To set the buffer metadata, the
+ * client passes in a buffer handle and a token that represents the type of buffer
+ * metadata they would like to set and a byte stream that contains the buffer metadata
+ * they are setting.
+ *
+ * Buffer metadata is global for a buffer. When the metadata is set on the buffer
+ * in a process, the updated metadata should be available to all other processes.
+ * Please see "Storing and Propagating Metadata" below for more details.
+ *
+ * The getter and setter functions have been optimized for easy vendor extension.
+ * They do not require a formal HIDL extension to add support for getting and setting
+ * vendor defined buffer metadata. In order to allow easy extension, the types used
+ * here are not typical HIDL types. See "Buffer Metadata Token" and
+ * "Buffer Metadata Stream" below for more details.
+ *
+ * ------------ Storing and Propagating Metadata -----------
+ * Buffer metadata must be global. Any changes to the metadata must be propagated
+ * to all other processes immediately. Vendors may chose how they would like support
+ * this functionality.
+ *
+ * We recommend supporting this functionality by allocating an extra page of shared
+ * memory and storing it in the buffer's native_handle_t. The buffer metadata can
+ * be stored in the extra page of shared memory. Set operations are automatically
+ * propagated to all other processes.
+ *
+ * ------------ Buffer Metadata Synchronization ------------
+ * There are no explicit buffer metadata synchronization primitives. Many devices
+ * before gralloc 4 already support getting and setting of global buffer metadata
+ * with no explicit synchronization primitives. Adding synchronization primitives
+ * would just add unnecessary complexity.
+ *
+ * The general rule is if a process has permission to write to a buffer, they
+ * have permission to write to the buffer's metadata. If a process has permission
+ * to read from a buffer, they have permission to read the buffer's metadata.
+ *
+ * There is one exception to this rule. Fences CANNOT be used to protect a buffer's
+ * metadata. A process should finish writing to a buffer's metadata before sending
+ * sending the buffer to another process that will read or write to the buffer.
+ * This exception is needed because sometimes userspace needs to read the
+ * buffer's metadata before the buffer's contents are ready.
+ *
+ * As a simple example: an app renders to a buffer and then displays the buffer.
+ * In this example when the app renders to the buffer, both the buffer and its
+ * metadata need to be updated. The app's process queues up its work on the GPU
+ * and gets back an acquire fence. The app's process must update the buffer's
+ * metadata before enqueuing the buffer to SurfaceFlinger. The app process CANNOT
+ * update the buffer's metadata after enqueuing the buffer. When HardwareComposer
+ * receives the buffer, it is immediately safe to read the buffer's metadata
+ * and use it to program the display driver. To read the buffer's contents,
+ * display driver must still wait on the acquire fence.
+ *
+ * ------------ Buffer Metadata Token ----------------------
+ * In order to allow arbitrary vendor defined metadata, we could not use a
+ * HIDL enum as the buffer metadata token. Extending a HIDL enum requires a full
+ * HIDL extension. We also could not use a simple non-HIDL enum because vendor
+ * defined enums from different vendors could collide. Instead we have defined
+ * a struct that has a string representing the enum type and an int that
+ * represents the enum value. The string protects different enum values from
+ * colliding.
+ *
+ * The token struct (MetadataType) is defined as a HIDL struct since it
+ * is passed into a HIDL function. The standard buffer metadata types are NOT
+ * defined as a HIDL enum because it would have required a new IMapper version
+ * just to add future standard buffer metadata types. By putting the enum in the
+ * stable AIDL (hardware/interfaces/graphics/common/aidl/android/hardware/
+ * graphics/common/StandardMetadataType.aidl), vendors will be able to optionally
+ * choose to support future standard buffer metadata types without upgrading
+ * HIDL versions. For more information see the description of "struct MetadataType".
+ *
+ * ------------ Buffer Metadata Stream ---------------------
+ * The buffer metadata is get and set as a byte stream (vec<uint8_t>). By getting
+ * and setting buffer metadata as a byte stream, vendors can use the standard
+ * getters and setter functions defined here. Vendors do NOT need to add their own
+ * getters and setter functions for each new type of buffer metadata.
+ *
+ * Converting buffer metadata into a byte stream can be non-trivial. For the standard
+ * buffer metadata types defined in StandardMetadataType.aidl, there are also
+ * support functions that will encode the buffer metadata into a byte stream
+ * and decode the buffer metadata from a byte stream. We STRONGLY recommend using
+ * these support functions. The framework will use them when getting and setting
+ * metadata. The support functions are defined in
+ * frameworks/native/libs/gralloc/types/include/gralloctypes/Gralloc4.h.
+ */
+
+ /**
+ * MetadataType represents the different types of buffer metadata that could be
+ * associated with a buffer. It is used by IMapper to help get and set buffer metadata
+ * on the buffer's native handle.
+ *
+ * Standard buffer metadata will have the name field set to
+ * "android.hardware.graphics.common.StandardMetadataType" and will contain values
+ * from StandardMetadataType.aidl.
+ *
+ * This struct should be "extended" by devices that use a proprietary or non-standard
+ * buffer metadata. To extend the struct, first create a custom @VendorStability vendor
+ * AIDL interface that defines the new type(s) you would like to support. Set the
+ * struct's name field to the custom aidl interface's name
+ * (eg. "vendor.mycompanyname.graphics.common.MetadataType"). Set the struct's value
+ * field to the custom @VendorStabilty vendor AIDL interface.
+ *
+ * Each company should create their own StandardMetadataType.aidl extension. The name
+ * field prevents values from different companies from colliding.
+ */
+ struct MetadataType {
+ string name;
+ int64_t value;
+ };
+
+ /**
+ * Gets the buffer metadata for a given MetadataType.
+ *
+ * Buffer metadata can be changed after allocation so clients should avoid "caching"
+ * the buffer metadata. For example, if the video resolution changes and the buffers
+ * are not reallocated, several buffer metadata values may change without warning.
+ * Clients should not expect the values to be constant. They should requery them every
+ * frame. The only exception is buffer metadata that is determined at allocation
+ * time. For StandardMetadataType values, only BUFFER_ID, NAME, WIDTH,
+ * HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and USAGE are safe to cache because
+ * they are determined at allocation time.
+ *
+ * @param buffer Buffer containing desired metadata
+ * @param metadataType MetadataType for the metadata value being queried
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * - `UNSUPPORTED` when metadataType is unknown/unsupported.
+ * IMapper must support getting all StandardMetadataType.aidl values defined
+ * at the time the device first launches.
+ * @return metadata Vector of bytes representing the buffer metadata associated with
+ * the MetadataType.
+ */
+ get(pointer buffer, MetadataType metadataType)
+ generates (Error error,
+ vec<uint8_t> metadata);
+
+ /**
+ * Sets the global value for a given MetadataType.
+ *
+ * Metadata fields are not required to be settable. This function can
+ * return Error::UNSUPPORTED whenever it doesn't support setting a
+ * particular Metadata field.
+ *
+ * The framework may attempt to set the following StandardMetadataType
+ * values: DATASPACE, PER_FRAME_METADATA, PER_FRAME_METADATA_BLOB and BLEND_MODE.
+ * We strongly encourage everyone to support setting as many of those fields as
+ * possible. If a device's Composer implementation supports a field, it should be
+ * supported here. Over time these metadata fields will be moved out of
+ * Composer/BufferQueue/etc. and into the buffer's Metadata fields.
+ * If a device's IMapper doesn't support setting those Metadata fields,
+ * eventually the device may not longer be able to support these fields.
+ *
+ * @param buffer Buffer receiving desired metadata
+ * @param metadataType MetadataType for the metadata value being set
+ * @param metadata Vector of bytes representing the value associated with
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_BUFFER` if the raw handle is invalid.
+ * - `BAD_VALUE` when the field is constant and can never be set (such as
+ * BUFFER_ID, NAME, WIDTH, HEIGHT, LAYER_COUNT, PIXEL_FORMAT_REQUESTED and
+ * USAGE)
+ * - `NO_RESOURCES` if the set cannot be fullfilled due to unavailability of
+ * resources.
+ * - `UNSUPPORTED` when metadataType is unknown/unsupported or setting
+ * it is unsupported. Unsupported should also be returned if the metadata
+ * is malformed.
+ */
+ set(pointer buffer, MetadataType metadataType, vec<uint8_t> metadata)
+ generates (Error error);
+
+ /**
+ * Given a BufferDescriptorInfo, gets the starting value of a given
+ * MetadataType. This can be used to query basic information about a buffer
+ * before the buffer is allocated.
+ *
+ * @param description Attributes of the descriptor.
+ * @param metadataType MetadataType for the metadata value being queried
+ * @return error Error status of the call, which may be
+ * - `NONE` upon success.
+ * - `BAD_VALUE` if any of the specified BufferDescriptorInfo attributes
+ * are invalid.
+ * - `NO_RESOURCES` if the get cannot be fullfilled due to unavailability of
+ * resources.
+ * - `UNSUPPORTED` when any of the description attributes are unsupported or
+ * if the metadataType is unknown/unsupported. This should also be
+ * returned if the requested metadata is not defined until a buffer has been
+ * allocated.
+ * @return metadata Vector of bytes representing the value associated with
+ * the MetadataType value.
+ */
+ getFromBufferDescriptorInfo(BufferDescriptorInfo description,
+ MetadataType metadataType)
+ generates (Error error,
+ vec<uint8_t> metadata);
};
diff --git a/graphics/mapper/4.0/utils/vts/Android.bp b/graphics/mapper/4.0/utils/vts/Android.bp
index e451584..56ff116 100644
--- a/graphics/mapper/4.0/utils/vts/Android.bp
+++ b/graphics/mapper/4.0/utils/vts/Android.bp
@@ -26,6 +26,9 @@
"android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.mapper@4.0",
],
+ shared_libs: [
+ "libgralloctypes",
+ ],
export_static_lib_headers: [
"android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.mapper@4.0",
diff --git a/graphics/mapper/4.0/utils/vts/MapperVts.cpp b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
index 056b7c9..531f311 100644
--- a/graphics/mapper/4.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/4.0/utils/vts/MapperVts.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <gralloctypes/Gralloc4.h>
#include <mapper-vts/4.0/MapperVts.h>
#include <VtsHalHidlTargetTestBase.h>
@@ -92,28 +93,39 @@
std::vector<const native_handle_t*> Gralloc::allocate(const BufferDescriptor& descriptor,
uint32_t count, bool import,
- uint32_t* outStride) {
+ bool allowFailure, uint32_t* outStride) {
std::vector<const native_handle_t*> bufferHandles;
bufferHandles.reserve(count);
- mAllocator->allocate(descriptor, count,
- [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
- ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
+ mAllocator->allocate(
+ descriptor, count,
+ [&](const auto& tmpError, const auto& tmpStride, const auto& tmpBuffers) {
+ ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
+ ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
- for (uint32_t i = 0; i < count; i++) {
- if (import) {
- ASSERT_NO_FATAL_FAILURE(
- bufferHandles.push_back(importBuffer(tmpBuffers[i])));
- } else {
- ASSERT_NO_FATAL_FAILURE(
- bufferHandles.push_back(cloneBuffer(tmpBuffers[i])));
- }
- }
+ for (uint32_t i = 0; i < count; i++) {
+ const native_handle_t* bufferHandle = nullptr;
+ if (import) {
+ if (allowFailure) {
+ bufferHandle = importBuffer(tmpBuffers[i]);
+ } else {
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = importBuffer(tmpBuffers[i]));
+ }
+ } else {
+ if (allowFailure) {
+ bufferHandle = cloneBuffer(tmpBuffers[i]);
+ } else {
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = cloneBuffer(tmpBuffers[i]));
+ }
+ }
+ if (bufferHandle) {
+ bufferHandles.push_back(bufferHandle);
+ }
+ }
- if (outStride) {
- *outStride = tmpStride;
- }
- });
+ if (outStride) {
+ *outStride = tmpStride;
+ }
+ });
if (::testing::Test::HasFatalFailure()) {
bufferHandles.clear();
@@ -123,17 +135,20 @@
}
const native_handle_t* Gralloc::allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
- bool import, uint32_t* outStride) {
+ bool import, bool allowFailure, uint32_t* outStride) {
BufferDescriptor descriptor = createDescriptor(descriptorInfo);
if (::testing::Test::HasFatalFailure()) {
return nullptr;
}
- auto buffers = allocate(descriptor, 1, import, outStride);
+ auto buffers = allocate(descriptor, 1, import, allowFailure, outStride);
if (::testing::Test::HasFatalFailure()) {
return nullptr;
}
+ if (buffers.size() != 1) {
+ return nullptr;
+ }
return buffers[0];
}
@@ -167,6 +182,10 @@
}
void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
+ if (bufferHandle == nullptr) {
+ return;
+ }
+
auto buffer = const_cast<native_handle_t*>(bufferHandle);
if (mImportedBuffers.erase(bufferHandle)) {
@@ -296,6 +315,35 @@
return supported;
}
+Error Gralloc::get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
+ hidl_vec<uint8_t>* outVec) {
+ Error err;
+ mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
+ [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
+ err = tmpError;
+ *outVec = tmpVec;
+ });
+ return err;
+}
+
+Error Gralloc::set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
+ const hidl_vec<uint8_t>& vec) {
+ return mMapper->set(const_cast<native_handle_t*>(bufferHandle), metadataType, vec);
+}
+
+Error Gralloc::getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const IMapper::MetadataType& metadataType,
+ hidl_vec<uint8_t>* outVec) {
+ Error err;
+ mMapper->getFromBufferDescriptorInfo(
+ descriptorInfo, metadataType,
+ [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
+ err = tmpError;
+ *outVec = tmpVec;
+ });
+ return err;
+}
+
} // namespace vts
} // namespace V4_0
} // namespace mapper
diff --git a/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h b/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
index 03ce764..28555fa 100644
--- a/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
+++ b/graphics/mapper/4.0/utils/vts/include/mapper-vts/4.0/MapperVts.h
@@ -51,9 +51,11 @@
//
// Either case, the returned buffers must be freed with freeBuffer.
std::vector<const native_handle_t*> allocate(const BufferDescriptor& descriptor, uint32_t count,
- bool import = true, uint32_t* outStride = nullptr);
+ bool import = true, bool allowFailure = false,
+ uint32_t* outStride = nullptr);
const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
- bool import = true, uint32_t* outStride = nullptr);
+ bool import = true, bool allowFailure = false,
+ uint32_t* outStride = nullptr);
// IMapper methods
@@ -81,6 +83,16 @@
bool isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo);
+ Error get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
+ hidl_vec<uint8_t>* outVec);
+
+ Error set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
+ const hidl_vec<uint8_t>& vec);
+
+ Error getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const IMapper::MetadataType& metadataType,
+ hidl_vec<uint8_t>* outVec);
+
private:
void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
diff --git a/graphics/mapper/4.0/vts/functional/Android.bp b/graphics/mapper/4.0/vts/functional/Android.bp
index a90ee0c..5a7548a 100644
--- a/graphics/mapper/4.0/vts/functional/Android.bp
+++ b/graphics/mapper/4.0/vts/functional/Android.bp
@@ -19,12 +19,16 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalGraphicsMapperV4_0TargetTest.cpp"],
static_libs: [
+ "android.hardware.graphics.mapper@4.0-vts",
+ ],
+ shared_libs: [
"android.hardware.graphics.allocator@4.0",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.common@1.1",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@4.0",
- "android.hardware.graphics.mapper@4.0-vts",
+ "libgralloctypes",
+ "vintf-graphics-common-ndk_platform",
],
test_suites: ["general-tests"],
}
diff --git a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
index 62ff613..1e8ec01 100644
--- a/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
+++ b/graphics/mapper/4.0/vts/functional/VtsHalGraphicsMapperV4_0TargetTest.cpp
@@ -22,6 +22,7 @@
#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
+#include <gralloctypes/Gralloc4.h>
#include <mapper-vts/4.0/MapperVts.h>
namespace android {
@@ -34,6 +35,15 @@
using android::hardware::graphics::common::V1_2::BufferUsage;
using android::hardware::graphics::common::V1_2::PixelFormat;
+using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
+using aidl::android::hardware::graphics::common::BlendMode;
+using aidl::android::hardware::graphics::common::Dataspace;
+using aidl::android::hardware::graphics::common::ExtendableType;
+using aidl::android::hardware::graphics::common::PlaneLayout;
+using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+
+using DecodeFunction = std::function<void(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const hidl_vec<uint8_t>& vec)>;
// Test environment for graphics.mapper.
class GraphicsMapperHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
@@ -57,6 +67,8 @@
mGralloc = std::make_unique<Gralloc>(
GraphicsMapperHidlEnvironment::Instance()->getServiceName<IAllocator>(),
GraphicsMapperHidlEnvironment::Instance()->getServiceName<IMapper>()));
+ ASSERT_NE(nullptr, mGralloc->getAllocator().get());
+ ASSERT_NE(nullptr, mGralloc->getMapper().get());
mDummyDescriptorInfo.name = "dummy";
mDummyDescriptorInfo.width = 64;
@@ -69,6 +81,85 @@
void TearDown() override {}
+ void testGet(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const MetadataType& metadataType, DecodeFunction decode) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(descriptorInfo, true));
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, metadataType, &vec));
+
+ ASSERT_NO_FATAL_FAILURE(decode(descriptorInfo, vec));
+ }
+
+ void testSet(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ const MetadataType& metadataType, const hidl_vec<uint8_t>& metadata,
+ DecodeFunction decode) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(descriptorInfo, true));
+
+ Error err = mGralloc->set(bufferHandle, metadataType, metadata);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, metadataType, &vec));
+
+ ASSERT_NO_FATAL_FAILURE(decode(descriptorInfo, vec));
+ }
+
+ void verifyDummyDescriptorInfoPlaneLayouts(const std::vector<PlaneLayout>& planeLayouts) {
+ ASSERT_EQ(1, planeLayouts.size());
+
+ const auto& planeLayout = planeLayouts.front();
+
+ ASSERT_EQ(4, planeLayout.components.size());
+
+ int64_t offsetInBitsR = -1;
+ int64_t offsetInBitsG = -1;
+ int64_t offsetInBitsB = -1;
+ int64_t offsetInBitsA = -1;
+
+ for (const auto& component : planeLayout.components) {
+ EXPECT_EQ(GRALLOC4_PLANE_LAYOUT_COMPONENT_TYPE, component.type.name);
+ EXPECT_EQ(8, component.sizeInBits);
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_R.value) {
+ offsetInBitsR = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_G.value) {
+ offsetInBitsG = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_B.value) {
+ offsetInBitsB = component.offsetInBits;
+ }
+ if (component.type.value == gralloc4::PlaneLayoutComponentType_A.value) {
+ offsetInBitsA = component.offsetInBits;
+ }
+ }
+
+ EXPECT_EQ(0, offsetInBitsR);
+ EXPECT_EQ(8, offsetInBitsG);
+ EXPECT_EQ(16, offsetInBitsB);
+ EXPECT_EQ(24, offsetInBitsA);
+
+ EXPECT_EQ(0, planeLayout.offsetInBytes);
+ EXPECT_EQ(8, planeLayout.sampleIncrementInBits);
+ // Skip testing stride because any stride is valid
+ EXPECT_EQ(mDummyDescriptorInfo.width, planeLayout.widthInSamples);
+ EXPECT_EQ(mDummyDescriptorInfo.height, planeLayout.heightInSamples);
+ EXPECT_LE(planeLayout.widthInSamples * planeLayout.heightInSamples * 4,
+ planeLayout.totalSizeInBytes);
+ EXPECT_EQ(1, planeLayout.horizontalSubsampling);
+ EXPECT_EQ(1, planeLayout.verticalSubsampling);
+
+ EXPECT_EQ(0, planeLayout.crop.left);
+ EXPECT_EQ(0, planeLayout.crop.top);
+ EXPECT_EQ(planeLayout.widthInSamples, planeLayout.crop.right);
+ EXPECT_EQ(planeLayout.heightInSamples, planeLayout.crop.bottom);
+ }
+
std::unique_ptr<Gralloc> mGralloc;
IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
};
@@ -90,8 +181,8 @@
for (uint32_t count = 0; count < 5; count++) {
std::vector<const native_handle_t*> bufferHandles;
uint32_t stride;
- ASSERT_NO_FATAL_FAILURE(bufferHandles =
- mGralloc->allocate(descriptor, count, false, &stride));
+ ASSERT_NO_FATAL_FAILURE(
+ bufferHandles = mGralloc->allocate(descriptor, count, false, false, &stride));
if (count >= 1) {
EXPECT_LE(mDummyDescriptorInfo.width, stride) << "invalid buffer stride";
@@ -293,7 +384,7 @@
const native_handle_t* bufferHandle;
uint32_t stride;
- ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride));
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, false, &stride));
// lock buffer for writing
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
@@ -354,7 +445,7 @@
const native_handle_t* bufferHandle;
uint32_t stride;
- ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, &stride));
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true, false, &stride));
// lock buffer for writing
const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
@@ -519,6 +610,987 @@
ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info));
}
+/**
+ * Test IMapper::get(BufferId)
+ */
+TEST_F(GraphicsMapperHidlTest, GetBufferId) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_BufferId,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t bufferId = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeBufferId(vec, &bufferId));
+ });
+}
+
+/**
+ * Test IMapper::get(Name)
+ */
+TEST_F(GraphicsMapperHidlTest, GetName) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Name,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ std::string name;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeName(vec, &name));
+ EXPECT_EQ(info.name, name);
+ });
+}
+
+/**
+ * Test IMapper::get(Width)
+ */
+TEST_F(GraphicsMapperHidlTest, GetWidth) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Width,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ uint64_t width = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeWidth(vec, &width));
+ EXPECT_EQ(info.width, width);
+ });
+}
+
+/**
+ * Test IMapper::get(Height)
+ */
+TEST_F(GraphicsMapperHidlTest, GetHeight) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Height,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ uint64_t height = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeHeight(vec, &height));
+ EXPECT_EQ(info.height, height);
+ });
+}
+
+/**
+ * Test IMapper::get(LayerCount)
+ */
+TEST_F(GraphicsMapperHidlTest, GetLayerCount) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_LayerCount,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ uint64_t layerCount = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeLayerCount(vec, &layerCount));
+ EXPECT_EQ(info.layerCount, layerCount);
+ });
+}
+
+/**
+ * Test IMapper::get(PixelFormatRequested)
+ */
+TEST_F(GraphicsMapperHidlTest, GetPixelFormatRequested) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatRequested,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ PixelFormat pixelFormatRequested = PixelFormat::BLOB;
+ ASSERT_EQ(NO_ERROR,
+ gralloc4::decodePixelFormatRequested(vec, &pixelFormatRequested));
+ EXPECT_EQ(info.format, pixelFormatRequested);
+ });
+}
+
+/**
+ * Test IMapper::get(PixelFormatFourCC)
+ */
+TEST_F(GraphicsMapperHidlTest, GetPixelFormatFourCC) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatFourCC,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint32_t pixelFormatFourCC = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatFourCC(vec, &pixelFormatFourCC));
+ });
+}
+
+/**
+ * Test IMapper::get(PixelFormatModifier)
+ */
+TEST_F(GraphicsMapperHidlTest, GetPixelFormatModifier) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatModifier,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t pixelFormatModifier = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatModifier(vec, &pixelFormatModifier));
+ });
+}
+
+/**
+ * Test IMapper::get(Usage)
+ */
+TEST_F(GraphicsMapperHidlTest, GetUsage) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Usage,
+ [](const IMapper::BufferDescriptorInfo& info, const hidl_vec<uint8_t>& vec) {
+ uint64_t usage = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &usage));
+ EXPECT_EQ(info.usage, usage);
+ });
+}
+
+/**
+ * Test IMapper::get(AllocationSize)
+ */
+TEST_F(GraphicsMapperHidlTest, GetAllocationSize) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_AllocationSize,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t allocationSize = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeAllocationSize(vec, &allocationSize));
+ });
+}
+
+/**
+ * Test IMapper::get(ProtectedContent)
+ */
+TEST_F(GraphicsMapperHidlTest, GetProtectedContent) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
+
+ const native_handle_t* bufferHandle = nullptr;
+ bufferHandle = mGralloc->allocate(info, true, true);
+ if (bufferHandle) {
+ GTEST_SUCCEED() << "unable to allocate protected content";
+ }
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_ProtectedContent, &vec));
+
+ uint64_t protectedContent = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeProtectedContent(vec, &protectedContent));
+ EXPECT_EQ(1, protectedContent);
+}
+
+/**
+ * Test IMapper::get(Compression)
+ */
+TEST_F(GraphicsMapperHidlTest, GetCompression) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+
+ testGet(info, gralloc4::MetadataType_Compression,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType compression = gralloc4::Compression_DisplayStreamCompression;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeCompression(vec, &compression));
+
+ EXPECT_EQ(gralloc4::Compression_None.name, compression.name);
+ EXPECT_EQ(gralloc4::Compression_None.value, compression.value);
+ });
+}
+
+/**
+ * Test IMapper::get(Interlaced)
+ */
+TEST_F(GraphicsMapperHidlTest, GetInterlaced) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Interlaced,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType interlaced = gralloc4::Interlaced_TopBottom;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeInterlaced(vec, &interlaced));
+
+ EXPECT_EQ(gralloc4::Interlaced_None.name, interlaced.name);
+ EXPECT_EQ(gralloc4::Interlaced_None.value, interlaced.value);
+ });
+}
+
+/**
+ * Test IMapper::get(ChromaSiting)
+ */
+TEST_F(GraphicsMapperHidlTest, GetChromaSiting) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_ChromaSiting,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType chromaSiting = gralloc4::ChromaSiting_Unknown;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeChromaSiting(vec, &chromaSiting));
+
+ EXPECT_EQ(gralloc4::ChromaSiting_None.name, chromaSiting.name);
+ EXPECT_EQ(gralloc4::ChromaSiting_None.value, chromaSiting.value);
+ });
+}
+
+/**
+ * Test IMapper::get(PlaneLayouts)
+ */
+TEST_F(GraphicsMapperHidlTest, GetPlaneLayouts) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
+
+ std::vector<PlaneLayout> planeLayouts;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
+
+ ASSERT_NO_FATAL_FAILURE(verifyDummyDescriptorInfoPlaneLayouts(planeLayouts));
+}
+
+/**
+ * Test IMapper::get(Dataspace)
+ */
+TEST_F(GraphicsMapperHidlTest, GetDataspace) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_Dataspace,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ Dataspace dataspace = Dataspace::DISPLAY_P3;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeDataspace(vec, &dataspace));
+ EXPECT_EQ(Dataspace::UNKNOWN, dataspace);
+ });
+}
+
+/**
+ * Test IMapper::get(BlendMode)
+ */
+TEST_F(GraphicsMapperHidlTest, GetBlendMode) {
+ testGet(mDummyDescriptorInfo, gralloc4::MetadataType_BlendMode,
+ [](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ BlendMode blendMode = BlendMode::NONE;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeBlendMode(vec, &blendMode));
+ EXPECT_EQ(BlendMode::INVALID, blendMode);
+ });
+}
+
+/**
+ * Test IMapper::get(metadata) with a bad buffer
+ */
+TEST_F(GraphicsMapperHidlTest, GetMetadataBadValue) {
+ const native_handle_t* bufferHandle = nullptr;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_BufferId, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->get(bufferHandle, gralloc4::MetadataType_Name, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->get(bufferHandle, gralloc4::MetadataType_Width, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->get(bufferHandle, gralloc4::MetadataType_Height, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_LayerCount, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->get(bufferHandle, gralloc4::MetadataType_Usage, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_AllocationSize, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_ProtectedContent, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_Compression, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_Interlaced, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_ChromaSiting, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_Dataspace, &vec));
+ ASSERT_EQ(0, vec.size());
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_BlendMode, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::get(metadata) for unsupported metadata
+ */
+TEST_F(GraphicsMapperHidlTest, GetUnsupportedMetadata) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ MetadataType metadataTypeFake = {"FAKE", 1};
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->get(bufferHandle, metadataTypeFake, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::get(metadata) for unsupported standard metadata
+ */
+TEST_F(GraphicsMapperHidlTest, GetUnsupportedStandardMetadata) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ MetadataType metadataTypeFake = {GRALLOC4_STANDARD_METADATA_TYPE, 9999};
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->get(bufferHandle, metadataTypeFake, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::set(PixelFormatFourCC)
+ */
+TEST_F(GraphicsMapperHidlTest, SetPixelFormatFourCC) {
+ uint32_t pixelFormatFourCC = 0x34324142; // DRM_FORMAT_BGRA8888
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatFourCC(pixelFormatFourCC, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatFourCC, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint32_t realPixelFormatFourCC = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatFourCC(vec, &realPixelFormatFourCC));
+ EXPECT_EQ(pixelFormatFourCC, realPixelFormatFourCC);
+ });
+}
+
+/**
+ * Test IMapper::set(PixelFormatModifier)
+ */
+TEST_F(GraphicsMapperHidlTest, SetPixelFormatModifier) {
+ uint64_t pixelFormatModifier = 10;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodePixelFormatModifier(pixelFormatModifier, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatModifier, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t realPixelFormatModifier = 0;
+ ASSERT_EQ(NO_ERROR,
+ gralloc4::decodePixelFormatModifier(vec, &realPixelFormatModifier));
+ EXPECT_EQ(pixelFormatModifier, realPixelFormatModifier);
+ });
+}
+
+/**
+ * Test IMapper::set(Usage) remove flag
+ */
+TEST_F(GraphicsMapperHidlTest, SetUsageRemoveBit) {
+ uint64_t usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN);
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeUsage(usage, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Usage, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t realUsage = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &realUsage));
+ EXPECT_EQ(usage, realUsage);
+ });
+}
+/**
+ * Test IMapper::set(Usage) add flag
+ */
+TEST_F(GraphicsMapperHidlTest, SetUsageAddBit) {
+ uint64_t usage = mDummyDescriptorInfo.usage | static_cast<uint64_t>(BufferUsage::GPU_TEXTURE);
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeUsage(usage, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Usage, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t realUsage = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &realUsage));
+ EXPECT_EQ(usage, realUsage);
+ });
+}
+
+/**
+ * Test IMapper::set(Usage) to test protected content
+ */
+TEST_F(GraphicsMapperHidlTest, SetUsageProtected) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+ info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
+
+ bufferHandle = mGralloc->allocate(info, true, true);
+ if (bufferHandle) {
+ GTEST_SUCCEED() << "unable to allocate protected content";
+ }
+
+ uint64_t usage = static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY);
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeUsage(usage, &vec));
+
+ Error err = mGralloc->set(bufferHandle, gralloc4::MetadataType_Usage, vec);
+ ASSERT_EQ(err, Error::UNSUPPORTED);
+ vec.resize(0);
+
+ uint64_t realUsage = 0;
+ ASSERT_EQ(Error::NONE, mGralloc->get(bufferHandle, gralloc4::MetadataType_Usage, &vec));
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &realUsage));
+ EXPECT_EQ(info.usage, realUsage);
+}
+
+/**
+ * Test IMapper::set(AllocationSize)
+ */
+TEST_F(GraphicsMapperHidlTest, SetAllocationSize) {
+ uint64_t allocationSize = 1000000;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeAllocationSize(allocationSize, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_AllocationSize, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ uint64_t realAllocationSize = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeAllocationSize(vec, &realAllocationSize));
+ EXPECT_EQ(allocationSize, realAllocationSize);
+ });
+}
+
+/**
+ * Test IMapper::set(ProtectedContent)
+ */
+TEST_F(GraphicsMapperHidlTest, SetProtectedContent) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+ info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
+
+ bufferHandle = mGralloc->allocate(info, true, true);
+ if (bufferHandle) {
+ GTEST_SUCCEED() << "unable to allocate protected content";
+ }
+
+ uint64_t protectedContent = 0;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeProtectedContent(protectedContent, &vec));
+
+ Error err = mGralloc->set(bufferHandle, gralloc4::MetadataType_ProtectedContent, vec);
+ ASSERT_EQ(err, Error::UNSUPPORTED);
+ vec.resize(0);
+
+ uint64_t realProtectedContent = 0;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->get(bufferHandle, gralloc4::MetadataType_ProtectedContent, &vec));
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeProtectedContent(vec, &realProtectedContent));
+ EXPECT_EQ(1, realProtectedContent);
+}
+
+/**
+ * Test IMapper::set(Compression)
+ */
+TEST_F(GraphicsMapperHidlTest, SetCompression) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+
+ ExtendableType compression = gralloc4::Compression_DisplayStreamCompression;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeCompression(compression, &vec));
+
+ testSet(info, gralloc4::MetadataType_Compression, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType realCompression = gralloc4::Compression_None;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeCompression(vec, &realCompression));
+
+ EXPECT_EQ(compression.name, realCompression.name);
+ EXPECT_EQ(compression.value, realCompression.value);
+ });
+}
+
+/**
+ * Test IMapper::set(Interlaced)
+ */
+TEST_F(GraphicsMapperHidlTest, SetInterlaced) {
+ ExtendableType interlaced = gralloc4::Interlaced_RightLeft;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeInterlaced(interlaced, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Interlaced, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType realInterlaced = gralloc4::Interlaced_None;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeInterlaced(vec, &realInterlaced));
+
+ EXPECT_EQ(interlaced.name, realInterlaced.name);
+ EXPECT_EQ(interlaced.value, realInterlaced.value);
+ });
+}
+
+/**
+ * Test IMapper::set(ChromaSiting)
+ */
+TEST_F(GraphicsMapperHidlTest, SetChromaSiting) {
+ ExtendableType chromaSiting = gralloc4::ChromaSiting_SitedInterstitial;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeChromaSiting(chromaSiting, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_ChromaSiting, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ ExtendableType realChromaSiting = gralloc4::ChromaSiting_None;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeChromaSiting(vec, &realChromaSiting));
+
+ EXPECT_EQ(chromaSiting.name, realChromaSiting.name);
+ EXPECT_EQ(chromaSiting.value, realChromaSiting.value);
+ });
+}
+
+/**
+ * Test IMapper::set(PlaneLayouts)
+ */
+TEST_F(GraphicsMapperHidlTest, SetPlaneLayouts) {
+ const native_handle_t* bufferHandle = nullptr;
+ auto info = mDummyDescriptorInfo;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(info, true));
+
+ std::vector<PlaneLayout> planeLayouts;
+ PlaneLayout planeLayoutA;
+ PlaneLayout planeLayoutRGB;
+ PlaneLayoutComponent component;
+
+ planeLayoutA.offsetInBytes = 0;
+ planeLayoutA.sampleIncrementInBits = 8;
+ planeLayoutA.strideInBytes = info.width + 20;
+ planeLayoutA.widthInSamples = info.width;
+ planeLayoutA.heightInSamples = info.height;
+ planeLayoutA.totalSizeInBytes = planeLayoutA.strideInBytes * info.height;
+ planeLayoutA.horizontalSubsampling = 1;
+ planeLayoutA.verticalSubsampling = 1;
+ planeLayoutA.crop.left = 0;
+ planeLayoutA.crop.top = 0;
+ planeLayoutA.crop.right = info.width;
+ planeLayoutA.crop.bottom = info.height;
+
+ component.type = gralloc4::PlaneLayoutComponentType_A;
+ component.offsetInBits = 0;
+ component.sizeInBits = 8;
+ planeLayoutA.components.push_back(component);
+
+ planeLayouts.push_back(planeLayoutA);
+
+ planeLayoutRGB.offsetInBytes = 0;
+ planeLayoutRGB.sampleIncrementInBits = 32;
+ planeLayoutRGB.strideInBytes = info.width + 20;
+ planeLayoutRGB.widthInSamples = info.width;
+ planeLayoutRGB.heightInSamples = info.height;
+ planeLayoutRGB.totalSizeInBytes = planeLayoutRGB.strideInBytes * info.height;
+ planeLayoutRGB.horizontalSubsampling = 1;
+ planeLayoutRGB.verticalSubsampling = 1;
+ planeLayoutRGB.crop.left = 0;
+ planeLayoutRGB.crop.top = 0;
+ planeLayoutRGB.crop.right = info.width;
+ planeLayoutRGB.crop.bottom = info.height;
+
+ component.type = gralloc4::PlaneLayoutComponentType_R;
+ planeLayoutRGB.components.push_back(component);
+ component.type = gralloc4::PlaneLayoutComponentType_G;
+ planeLayoutRGB.components.push_back(component);
+ component.type = gralloc4::PlaneLayoutComponentType_B;
+ planeLayoutRGB.components.push_back(component);
+
+ planeLayouts.push_back(planeLayoutRGB);
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodePlaneLayouts(planeLayouts, &vec));
+
+ Error err = mGralloc->set(bufferHandle, gralloc4::MetadataType_PlaneLayouts, vec);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ std::vector<PlaneLayout> realPlaneLayouts;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &realPlaneLayouts));
+
+ ASSERT_EQ(planeLayouts.size(), realPlaneLayouts.size());
+
+ for (int i = 0; i < realPlaneLayouts.size(); i++) {
+ const auto& planeLayout = planeLayouts[i];
+ const auto& realPlaneLayout = realPlaneLayouts[i];
+
+ EXPECT_EQ(planeLayout.offsetInBytes, realPlaneLayout.offsetInBytes);
+ EXPECT_EQ(planeLayout.sampleIncrementInBits, realPlaneLayout.sampleIncrementInBits);
+ EXPECT_EQ(planeLayout.strideInBytes, realPlaneLayout.strideInBytes);
+ EXPECT_EQ(planeLayout.widthInSamples, realPlaneLayout.widthInSamples);
+ EXPECT_EQ(planeLayout.heightInSamples, realPlaneLayout.heightInSamples);
+ EXPECT_LE(planeLayout.totalSizeInBytes, realPlaneLayout.totalSizeInBytes);
+ EXPECT_EQ(planeLayout.horizontalSubsampling, realPlaneLayout.horizontalSubsampling);
+ EXPECT_EQ(planeLayout.verticalSubsampling, realPlaneLayout.verticalSubsampling);
+
+ EXPECT_EQ(planeLayout.crop.left, realPlaneLayout.crop.left);
+ EXPECT_EQ(planeLayout.crop.top, realPlaneLayout.crop.top);
+ EXPECT_EQ(planeLayout.crop.right, realPlaneLayout.crop.right);
+ EXPECT_EQ(planeLayout.crop.bottom, realPlaneLayout.crop.bottom);
+
+ ASSERT_EQ(planeLayout.components.size(), realPlaneLayout.components.size());
+
+ for (int j = 0; j < realPlaneLayout.components.size(); j++) {
+ const auto& component = planeLayout.components[j];
+ const auto& realComponent = realPlaneLayout.components[j];
+
+ EXPECT_EQ(component.type.name, realComponent.type.name);
+ EXPECT_EQ(component.type.value, realComponent.type.value);
+ EXPECT_EQ(component.sizeInBits, realComponent.sizeInBits);
+ EXPECT_EQ(component.offsetInBits, realComponent.offsetInBits);
+ }
+ }
+}
+
+/**
+ * Test IMapper::set(Dataspace)
+ */
+TEST_F(GraphicsMapperHidlTest, SetDataspace) {
+ Dataspace dataspace = Dataspace::V0_SRGB_LINEAR;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeDataspace(dataspace, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_Dataspace, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ Dataspace realDataspace = Dataspace::UNKNOWN;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeDataspace(vec, &realDataspace));
+ EXPECT_EQ(dataspace, realDataspace);
+ });
+}
+
+/**
+ * Test IMapper::set(BlendMode)
+ */
+TEST_F(GraphicsMapperHidlTest, SetBlendMode) {
+ BlendMode blendMode = BlendMode::PREMULTIPLIED;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(NO_ERROR, gralloc4::encodeBlendMode(blendMode, &vec));
+
+ testSet(mDummyDescriptorInfo, gralloc4::MetadataType_BlendMode, vec,
+ [&](const IMapper::BufferDescriptorInfo& /*info*/, const hidl_vec<uint8_t>& vec) {
+ BlendMode realBlendMode = BlendMode::INVALID;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeBlendMode(vec, &realBlendMode));
+ EXPECT_EQ(blendMode, realBlendMode);
+ });
+}
+
+/**
+ * Test IMapper::set(metadata) with a bad buffer
+ */
+TEST_F(GraphicsMapperHidlTest, SetMetadataNullBuffer) {
+ const native_handle_t* bufferHandle = nullptr;
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_BufferId, vec));
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Name, vec));
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Width, vec));
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Height, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_LayerCount, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatRequested, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatModifier, vec));
+ ASSERT_EQ(Error::BAD_BUFFER, mGralloc->set(bufferHandle, gralloc4::MetadataType_Usage, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_AllocationSize, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_ProtectedContent, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Compression, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Interlaced, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_ChromaSiting, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PlaneLayouts, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Dataspace, vec));
+ ASSERT_EQ(Error::BAD_BUFFER,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_BlendMode, vec));
+}
+
+/**
+ * Test IMapper::set(metadata) for constant metadata
+ */
+TEST_F(GraphicsMapperHidlTest, SetConstantMetadata) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_BufferId, vec));
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_Name, vec));
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_Width, vec));
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_Height, vec));
+ ASSERT_EQ(Error::BAD_VALUE,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_LayerCount, vec));
+ ASSERT_EQ(Error::BAD_VALUE,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatRequested, vec));
+ ASSERT_EQ(Error::BAD_VALUE, mGralloc->set(bufferHandle, gralloc4::MetadataType_Usage, vec));
+}
+
+/**
+ * Test IMapper::set(metadata) for bad metadata
+ */
+TEST_F(GraphicsMapperHidlTest, SetBadMetadata) {
+ const native_handle_t* bufferHandle = nullptr;
+ ASSERT_NO_FATAL_FAILURE(bufferHandle = mGralloc->allocate(mDummyDescriptorInfo, true));
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_BufferId, vec));
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->set(bufferHandle, gralloc4::MetadataType_Name, vec));
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->set(bufferHandle, gralloc4::MetadataType_Width, vec));
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->set(bufferHandle, gralloc4::MetadataType_Height, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_LayerCount, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatRequested, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PixelFormatModifier, vec));
+ ASSERT_EQ(Error::UNSUPPORTED, mGralloc->set(bufferHandle, gralloc4::MetadataType_Usage, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_AllocationSize, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_ProtectedContent, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Compression, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Interlaced, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_ChromaSiting, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_PlaneLayouts, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_Dataspace, vec));
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->set(bufferHandle, gralloc4::MetadataType_BlendMode, vec));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(BufferId)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoBufferId) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+ gralloc4::MetadataType_BufferId, &vec));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Name)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoName) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Name, &vec));
+
+ std::string name;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeName(vec, &name));
+ EXPECT_EQ(mDummyDescriptorInfo.name, name);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Width)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoWidth) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Width, &vec));
+
+ uint64_t width = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeWidth(vec, &width));
+ EXPECT_EQ(mDummyDescriptorInfo.width, width);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Height)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoHeight) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Height, &vec));
+
+ uint64_t height = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeHeight(vec, &height));
+ EXPECT_EQ(mDummyDescriptorInfo.height, height);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(PixelFormatRequested)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatRequested) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatRequested, &vec));
+
+ PixelFormat pixelFormatRequested = PixelFormat::BLOB;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatRequested(vec, &pixelFormatRequested));
+ EXPECT_EQ(mDummyDescriptorInfo.format, pixelFormatRequested);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(PixelFormatFourCC)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatFourCC) {
+ hidl_vec<uint8_t> vec;
+ Error err = mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatFourCC, &vec);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ uint32_t pixelFormatFourCC = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatFourCC(vec, &pixelFormatFourCC));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(PixelFormatModifier)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPixelFormatModifier) {
+ hidl_vec<uint8_t> vec;
+ Error err = mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_PixelFormatModifier, &vec);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ uint64_t pixelFormatModifier = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePixelFormatModifier(vec, &pixelFormatModifier));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Usage)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUsage) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Usage, &vec));
+
+ uint64_t usage = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeUsage(vec, &usage));
+ EXPECT_EQ(mDummyDescriptorInfo.usage, usage);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(AllocationSize)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoAllocationSize) {
+ hidl_vec<uint8_t> vec;
+ Error err = mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+ gralloc4::MetadataType_AllocationSize, &vec);
+ if (err == Error::UNSUPPORTED) {
+ GTEST_SUCCEED() << "setting this metadata is unsupported";
+ }
+ ASSERT_EQ(err, Error::NONE);
+
+ uint64_t allocationSize = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeAllocationSize(vec, &allocationSize));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(ProtectedContent)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoProtectedContent) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY;
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ info, gralloc4::MetadataType_ProtectedContent, &vec));
+
+ uint64_t protectedContent = 0;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeProtectedContent(vec, &protectedContent));
+ EXPECT_EQ(1, protectedContent);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Compression)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoCompression) {
+ auto info = mDummyDescriptorInfo;
+ info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ info, gralloc4::MetadataType_Compression, &vec));
+
+ ExtendableType compression = gralloc4::Compression_DisplayStreamCompression;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeCompression(vec, &compression));
+
+ EXPECT_EQ(gralloc4::Compression_None.name, compression.name);
+ EXPECT_EQ(gralloc4::Compression_None.value, compression.value);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Interlaced)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoInterlaced) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Interlaced, &vec));
+
+ ExtendableType interlaced = gralloc4::Interlaced_TopBottom;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeInterlaced(vec, &interlaced));
+
+ EXPECT_EQ(gralloc4::Interlaced_None.name, interlaced.name);
+ EXPECT_EQ(gralloc4::Interlaced_None.value, interlaced.value);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(ChromaSiting)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoChromaSiting) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+ gralloc4::MetadataType_ChromaSiting, &vec));
+
+ ExtendableType chromaSiting = gralloc4::ChromaSiting_CositedHorizontal;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeChromaSiting(vec, &chromaSiting));
+
+ EXPECT_EQ(gralloc4::ChromaSiting_None.name, chromaSiting.name);
+ EXPECT_EQ(gralloc4::ChromaSiting_None.value, chromaSiting.value);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(PlaneLayouts)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoPlaneLayouts) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo,
+ gralloc4::MetadataType_PlaneLayouts, &vec));
+
+ std::vector<PlaneLayout> planeLayouts;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodePlaneLayouts(vec, &planeLayouts));
+ ASSERT_NO_FATAL_FAILURE(verifyDummyDescriptorInfoPlaneLayouts(planeLayouts));
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(Dataspace)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoDataspace) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_Dataspace, &vec));
+
+ Dataspace dataspace = Dataspace::DISPLAY_P3;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeDataspace(vec, &dataspace));
+ EXPECT_EQ(Dataspace::UNKNOWN, dataspace);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(BlendMode)
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoBlendMode) {
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::NONE, mGralloc->getFromBufferDescriptorInfo(
+ mDummyDescriptorInfo, gralloc4::MetadataType_BlendMode, &vec));
+
+ BlendMode blendMode = BlendMode::COVERAGE;
+ ASSERT_EQ(NO_ERROR, gralloc4::decodeBlendMode(vec, &blendMode));
+ EXPECT_EQ(BlendMode::INVALID, blendMode);
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(metadata) for unsupported metadata
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedMetadata) {
+ MetadataType metadataTypeFake = {"FAKE", 1};
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo, metadataTypeFake, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
+/**
+ * Test IMapper::getFromBufferDescriptorInfo(metadata) for unsupported standard metadata
+ */
+TEST_F(GraphicsMapperHidlTest, GetFromBufferDescriptorInfoUnsupportedStandardMetadata) {
+ MetadataType metadataTypeFake = {GRALLOC4_STANDARD_METADATA_TYPE, 9999};
+
+ hidl_vec<uint8_t> vec;
+ ASSERT_EQ(Error::UNSUPPORTED,
+ mGralloc->getFromBufferDescriptorInfo(mDummyDescriptorInfo, metadataTypeFake, &vec));
+ ASSERT_EQ(0, vec.size());
+}
+
} // namespace
} // namespace vts
} // namespace V4_0