Merge "gralloc: add get and set BufferMetadata support"
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