Add layered image support to gralloc1 hal.
Bug: 31686534
Test: manual
Change-Id: I6442413072cef2a19abd3aacddf964ca1f4e7481
diff --git a/graphics/allocator/2.0/IAllocator.hal b/graphics/allocator/2.0/IAllocator.hal
index 8accb82..ff08a7e 100644
--- a/graphics/allocator/2.0/IAllocator.hal
+++ b/graphics/allocator/2.0/IAllocator.hal
@@ -26,11 +26,16 @@
* is supported.
*/
TEST_ALLOCATE = 1,
+
+ /*
+ * layerCount must be 1 unless this capability is supported.
+ */
+ LAYERED_BUFFERS = 2,
};
struct BufferDescriptorInfo {
/*
- * The width specifies how many columns of pixels should be in the
+ * The width specifies how many columns of pixels must be in the
* allocated buffer, but does not necessarily represent the offset in
* columns between the same column in adjacent rows. The rows may be
* padded.
@@ -38,11 +43,16 @@
uint32_t width;
/*
- * The height specifies how many rows of pixels should be in the
+ * 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.
+ */
+ uint32_t layerCount;
+
/* Buffer pixel format. */
PixelFormat format;
diff --git a/graphics/allocator/2.0/default/Gralloc.cpp b/graphics/allocator/2.0/default/Gralloc.cpp
index a7fc6c1..8a74661 100644
--- a/graphics/allocator/2.0/default/Gralloc.cpp
+++ b/graphics/allocator/2.0/default/Gralloc.cpp
@@ -74,6 +74,7 @@
GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
GRALLOC1_PFN_SET_FORMAT setFormat;
+ GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount;
GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
GRALLOC1_PFN_ALLOCATE allocate;
@@ -135,6 +136,10 @@
GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR);
initDispatch(mDispatch.setDimensions, GRALLOC1_FUNCTION_SET_DIMENSIONS);
initDispatch(mDispatch.setFormat, GRALLOC1_FUNCTION_SET_FORMAT);
+ if (hasCapability(Capability::LAYERED_BUFFERS)) {
+ initDispatch(
+ mDispatch.setLayerCount, GRALLOC1_FUNCTION_SET_LAYER_COUNT);
+ }
initDispatch(mDispatch.setConsumerUsage,
GRALLOC1_FUNCTION_SET_CONSUMER_USAGE);
initDispatch(mDispatch.setProducerUsage,
@@ -191,6 +196,11 @@
err = mDispatch.setFormat(mDevice, descriptor,
static_cast<int32_t>(descriptorInfo.format));
}
+ if (err == GRALLOC1_ERROR_NONE &&
+ hasCapability(Capability::LAYERED_BUFFERS)) {
+ err = mDispatch.setLayerCount(mDevice, descriptor,
+ descriptorInfo.layerCount);
+ }
if (err == GRALLOC1_ERROR_NONE) {
uint64_t producerUsageMask = descriptorInfo.producerUsageMask;
if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) {
diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp
index eeca5c7..2af1d2c 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.cpp
+++ b/graphics/mapper/2.0/default/GrallocMapper.cpp
@@ -15,10 +15,13 @@
#define LOG_TAG "GrallocMapperPassthrough"
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <hardware/gralloc1.h>
#include <log/log.h>
+#include <unordered_set>
+
namespace android {
namespace hardware {
namespace graphics {
@@ -26,6 +29,8 @@
namespace V2_0 {
namespace implementation {
+using Capability = allocator::V2_0::IAllocator::Capability;
+
class GrallocDevice : public Device {
public:
GrallocDevice();
@@ -38,6 +43,8 @@
uint32_t* outWidth, uint32_t* outHeight);
Error getFormat(const native_handle_t* bufferHandle,
PixelFormat* outFormat);
+ Error getLayerCount(const native_handle_t* bufferHandle,
+ uint32_t* outLayerCount);
Error getProducerUsageMask(const native_handle_t* bufferHandle,
uint64_t* outUsageMask);
Error getConsumerUsageMask(const native_handle_t* bufferHandle,
@@ -58,15 +65,21 @@
int32_t* outReleaseFence);
private:
+ void initCapabilities();
+
void initDispatch();
+ bool hasCapability(Capability capability) const;
gralloc1_device_t* mDevice;
+ std::unordered_set<Capability> mCapabilities;
+
struct {
GRALLOC1_PFN_RETAIN retain;
GRALLOC1_PFN_RELEASE release;
GRALLOC1_PFN_GET_DIMENSIONS getDimensions;
GRALLOC1_PFN_GET_FORMAT getFormat;
+ GRALLOC1_PFN_GET_LAYER_COUNT getLayerCount;
GRALLOC1_PFN_GET_PRODUCER_USAGE getProducerUsage;
GRALLOC1_PFN_GET_CONSUMER_USAGE getConsumerUsage;
GRALLOC1_PFN_GET_BACKING_STORE getBackingStore;
@@ -96,6 +109,7 @@
LOG_ALWAYS_FATAL("failed to open gralloc1 device");
}
+ initCapabilities();
initDispatch();
}
@@ -104,6 +118,19 @@
gralloc1_close(mDevice);
}
+void GrallocDevice::initCapabilities()
+{
+ uint32_t count;
+ mDevice->getCapabilities(mDevice, &count, nullptr);
+
+ std::vector<Capability> caps(count);
+ mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
+ std::underlying_type<Capability>::type*>(caps.data()));
+ caps.resize(count);
+
+ mCapabilities.insert(caps.cbegin(), caps.cend());
+}
+
void GrallocDevice::initDispatch()
{
#define CHECK_FUNC(func, desc) do { \
@@ -118,6 +145,9 @@
CHECK_FUNC(release, GRALLOC1_FUNCTION_RELEASE);
CHECK_FUNC(getDimensions, GRALLOC1_FUNCTION_GET_DIMENSIONS);
CHECK_FUNC(getFormat, GRALLOC1_FUNCTION_GET_FORMAT);
+ if (hasCapability(Capability::LAYERED_BUFFERS)) {
+ CHECK_FUNC(getLayerCount, GRALLOC1_FUNCTION_GET_LAYER_COUNT);
+ }
CHECK_FUNC(getProducerUsage, GRALLOC1_FUNCTION_GET_PRODUCER_USAGE);
CHECK_FUNC(getConsumerUsage, GRALLOC1_FUNCTION_GET_CONSUMER_USAGE);
CHECK_FUNC(getBackingStore, GRALLOC1_FUNCTION_GET_BACKING_STORE);
@@ -130,6 +160,11 @@
#undef CHECK_FUNC
}
+bool GrallocDevice::hasCapability(Capability capability) const
+{
+ return (mCapabilities.count(capability) > 0);
+}
+
Error GrallocDevice::retain(const native_handle_t* bufferHandle)
{
int32_t error = mDispatch.retain(mDevice, bufferHandle);
@@ -158,6 +193,19 @@
return static_cast<Error>(error);
}
+Error GrallocDevice::getLayerCount(const native_handle_t* bufferHandle,
+ uint32_t* outLayerCount)
+{
+ if (hasCapability(Capability::LAYERED_BUFFERS)) {
+ int32_t error = mDispatch.getLayerCount(mDevice, bufferHandle,
+ outLayerCount);
+ return static_cast<Error>(error);
+ } else {
+ *outLayerCount = 1;
+ return Error::NONE;
+ }
+}
+
Error GrallocDevice::getProducerUsageMask(const native_handle_t* bufferHandle,
uint64_t* outUsageMask)
{
@@ -238,6 +286,7 @@
.release = release,
.getDimensions = getDimensions,
.getFormat = getFormat,
+ .getLayerCount = getLayerCount,
.getProducerUsageMask = getProducerUsageMask,
.getConsumerUsageMask = getConsumerUsageMask,
.getBackingStore = getBackingStore,
@@ -296,6 +345,12 @@
return cast(device)->getFormat(bufferHandle, outFormat);
}
+ static Error getLayerCount(Device* device,
+ const native_handle_t* bufferHandle, uint32_t* outLayerCount)
+ {
+ return cast(device)->getLayerCount(bufferHandle, outLayerCount);
+ }
+
static Error getProducerUsageMask(Device* device,
const native_handle_t* bufferHandle, uint64_t* outUsageMask)
{
diff --git a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h b/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h
index 23faa80..ac8ec45 100644
--- a/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h
+++ b/graphics/mapper/2.0/include/android/hardware/graphics/mapper/2.0/IMapper.h
@@ -128,6 +128,21 @@
PixelFormat* outFormat);
/*
+ * Gets the number of layers of the buffer.
+ *
+ * See IAllocator::BufferDescriptorInfo for more information.
+ *
+ * @param device is the mapper device.
+ * @param bufferHandle is the buffer from which to get format.
+ * @return error is NONE upon success. Otherwise,
+ * BAD_BUFFER when the buffer handle is invalid.
+ * @return layerCount is the number of layers of the buffer.
+ */
+ typedef Error (*getLayerCount)(Device* device,
+ const native_handle_t* bufferHandle,
+ uint32_t* outLayerCount);
+
+ /*
* Gets the producer usage flags which were used to allocate this buffer.
*
* See IAllocator::BufferDescriptorInfo for more information.
@@ -364,6 +379,7 @@
Device::release release;
Device::getDimensions getDimensions;
Device::getFormat getFormat;
+ Device::getLayerCount getLayerCount;
Device::getProducerUsageMask getProducerUsageMask;
Device::getConsumerUsageMask getConsumerUsageMask;
Device::getBackingStore getBackingStore;