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;