graphics: revise gralloc interfaces

Revise IAllocator and IMapper to reduce IPC and to support gralloc0
devices.

Specifically, IAllocator is trimmed down to have essentially only

    allocate(BufferDescriptor descriptor, uint32_t count)
        generates (Error error,
                   uint32_t stride,
                   vec<handle> buffers);

The ability to allocate buffers with shared backing store is
removed.  ProducerUsage and ConsumerUsage are moved to the
graphics.common package and are merged and renamed to BufferUsage.
BufferUsage's bits follow gralloc0.

IMapper gains

    typedef vec<uint32_t> BufferDescriptor;
    createDescriptor(BufferDescriptorInfo descriptorInfo)
          generates (Error error,
                     BufferDescriptor descriptor);

where BufferDescriptor is an implementation-defined blob.  lockFlex
is replaced by lockYCbCr.  All getters are removed.

Reference counting with retain/release is replaced by
importBuffer/freeBuffer.

Most if not all gralloc1 features are not used by the runtime yet.
There is also not too much test written for them.  As such, they
tend to behave differently between implementations and cannot be
used reliably.

Bug: 36481301
Test: builds and boots on Pixel
Change-Id: I1d31105120517ea2c128c7a19297acf3bfd312bb
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 0baef89..6adfa71 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -3,7 +3,7 @@
     defaults: ["hidl_defaults"],
     proprietary: true,
     relative_install_path: "hw",
-    srcs: ["Gralloc.cpp"],
+    srcs: ["Gralloc.cpp", "Gralloc0Allocator.cpp", "Gralloc1Allocator.cpp"],
     cppflags: ["-Wall", "-Wextra"],
     shared_libs: [
         "android.hardware.graphics.allocator@2.0",
@@ -15,6 +15,7 @@
         "liblog",
         "libutils",
     ],
+    static_libs: ["libgrallocmapperincludes"],
 }
 
 cc_binary {
diff --git a/graphics/allocator/2.0/default/Gralloc.cpp b/graphics/allocator/2.0/default/Gralloc.cpp
index 0b9e863..273d3f5 100644
--- a/graphics/allocator/2.0/default/Gralloc.cpp
+++ b/graphics/allocator/2.0/default/Gralloc.cpp
@@ -16,17 +16,11 @@
 
 #define LOG_TAG "GrallocPassthrough"
 
-#include <mutex>
-#include <type_traits>
-#include <unordered_set>
-#include <vector>
-
-#include <string.h>
-
-#include <hardware/gralloc1.h>
-#include <log/log.h>
-
 #include "Gralloc.h"
+#include "Gralloc0Allocator.h"
+#include "Gralloc1Allocator.h"
+
+#include <log/log.h>
 
 namespace android {
 namespace hardware {
@@ -35,417 +29,6 @@
 namespace V2_0 {
 namespace implementation {
 
-class GrallocHal : public IAllocator {
-public:
-    GrallocHal(const hw_module_t* module);
-    virtual ~GrallocHal();
-
-    // IAllocator interface
-    Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
-    Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
-    Return<void> createClient(createClient_cb hidl_cb) override;
-
-    Error createDescriptor(
-            const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
-            BufferDescriptor* outDescriptor);
-    Error destroyDescriptor(BufferDescriptor descriptor);
-
-    Error testAllocate(const hidl_vec<BufferDescriptor>& descriptors);
-    Error allocate(const hidl_vec<BufferDescriptor>& descriptors,
-            hidl_vec<Buffer>* outBuffers);
-    Error free(Buffer buffer);
-
-    Error exportHandle(Buffer buffer, const native_handle_t** outHandle);
-
-private:
-    void initCapabilities();
-
-    template<typename T>
-    void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
-    void initDispatch();
-
-    bool hasCapability(Capability capability) const;
-
-    gralloc1_device_t* mDevice;
-
-    std::unordered_set<Capability> mCapabilities;
-
-    struct {
-        GRALLOC1_PFN_DUMP dump;
-        GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
-        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;
-        GRALLOC1_PFN_RELEASE release;
-    } mDispatch;
-};
-
-class GrallocClient : public IAllocatorClient {
-public:
-    GrallocClient(GrallocHal& hal);
-    virtual ~GrallocClient();
-
-    // IAllocatorClient interface
-    Return<void> createDescriptor(const BufferDescriptorInfo& descriptorInfo,
-            createDescriptor_cb hidl_cb) override;
-    Return<Error> destroyDescriptor(BufferDescriptor descriptor) override;
-
-    Return<Error> testAllocate(
-            const hidl_vec<BufferDescriptor>& descriptors) override;
-    Return<void> allocate(const hidl_vec<BufferDescriptor>& descriptors,
-            allocate_cb hidl_cb) override;
-    Return<Error> free(Buffer buffer) override;
-
-    Return<void> exportHandle(BufferDescriptor descriptor,
-            Buffer buffer, exportHandle_cb hidl_cb) override;
-
-private:
-    GrallocHal& mHal;
-
-    std::mutex mMutex;
-    std::unordered_set<BufferDescriptor> mDescriptors;
-    std::unordered_set<Buffer> mBuffers;
-};
-
-GrallocHal::GrallocHal(const hw_module_t* module)
-    : mDevice(nullptr), mDispatch()
-{
-    int status = gralloc1_open(module, &mDevice);
-    if (status) {
-        LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
-                strerror(-status));
-    }
-
-    initCapabilities();
-    initDispatch();
-}
-
-GrallocHal::~GrallocHal()
-{
-    gralloc1_close(mDevice);
-}
-
-void GrallocHal::initCapabilities()
-{
-    uint32_t count = 0;
-    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());
-}
-
-template<typename T>
-void GrallocHal::initDispatch(gralloc1_function_descriptor_t desc, T* outPfn)
-{
-    auto pfn = mDevice->getFunction(mDevice, desc);
-    if (!pfn) {
-        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
-    }
-
-    *outPfn = reinterpret_cast<T>(pfn);
-}
-
-void GrallocHal::initDispatch()
-{
-    initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump);
-    initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR,
-            &mDispatch.createDescriptor);
-    initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR,
-            &mDispatch.destroyDescriptor);
-    initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions);
-    initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat);
-    if (hasCapability(Capability::LAYERED_BUFFERS)) {
-        initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
-                &mDispatch.setLayerCount);
-    }
-    initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
-            &mDispatch.setConsumerUsage);
-    initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
-            &mDispatch.setProducerUsage);
-    initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
-    initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
-}
-
-bool GrallocHal::hasCapability(Capability capability) const
-{
-    return (mCapabilities.count(capability) > 0);
-}
-
-Return<void> GrallocHal::getCapabilities(getCapabilities_cb hidl_cb)
-{
-    std::vector<Capability> caps(
-            mCapabilities.cbegin(), mCapabilities.cend());
-
-    hidl_vec<Capability> reply;
-    reply.setToExternal(caps.data(), caps.size());
-    hidl_cb(reply);
-
-    return Void();
-}
-
-Return<void> GrallocHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
-{
-    uint32_t len = 0;
-    mDispatch.dump(mDevice, &len, nullptr);
-
-    std::vector<char> buf(len + 1);
-    mDispatch.dump(mDevice, &len, buf.data());
-    buf.resize(len + 1);
-    buf[len] = '\0';
-
-    hidl_string reply;
-    reply.setToExternal(buf.data(), len);
-    hidl_cb(reply);
-
-    return Void();
-}
-
-Return<void> GrallocHal::createClient(createClient_cb hidl_cb)
-{
-    sp<IAllocatorClient> client = new GrallocClient(*this);
-    hidl_cb(Error::NONE, client);
-
-    return Void();
-}
-
-Error GrallocHal::createDescriptor(
-        const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
-        BufferDescriptor* outDescriptor)
-{
-    gralloc1_buffer_descriptor_t descriptor;
-    int32_t err = mDispatch.createDescriptor(mDevice, &descriptor);
-    if (err != GRALLOC1_ERROR_NONE) {
-        return static_cast<Error>(err);
-    }
-
-    err = mDispatch.setDimensions(mDevice, descriptor,
-            descriptorInfo.width, descriptorInfo.height);
-    if (err == GRALLOC1_ERROR_NONE) {
-        err = mDispatch.setFormat(mDevice, descriptor,
-                static_cast<int32_t>(descriptorInfo.format));
-    }
-    if (err == GRALLOC1_ERROR_NONE) {
-        if (hasCapability(Capability::LAYERED_BUFFERS)) {
-            err = mDispatch.setLayerCount(mDevice, descriptor,
-                    descriptorInfo.layerCount);
-        } else if (descriptorInfo.layerCount != 1) {
-            err = GRALLOC1_ERROR_BAD_VALUE;
-        }
-    }
-    if (err == GRALLOC1_ERROR_NONE) {
-        uint64_t producerUsageMask = descriptorInfo.producerUsageMask;
-        if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) {
-            producerUsageMask |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
-        }
-        if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
-            producerUsageMask |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
-        }
-        err = mDispatch.setProducerUsage(mDevice, descriptor,
-                descriptorInfo.producerUsageMask);
-    }
-    if (err == GRALLOC1_ERROR_NONE) {
-        uint64_t consumerUsageMask = descriptorInfo.consumerUsageMask;
-        if (consumerUsageMask & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
-            consumerUsageMask |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
-        }
-        err = mDispatch.setConsumerUsage(mDevice, descriptor,
-                consumerUsageMask);
-    }
-
-    if (err == GRALLOC1_ERROR_NONE) {
-        *outDescriptor = descriptor;
-    } else {
-        mDispatch.destroyDescriptor(mDevice, descriptor);
-    }
-
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::destroyDescriptor(BufferDescriptor descriptor)
-{
-    int32_t err = mDispatch.destroyDescriptor(mDevice, descriptor);
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::testAllocate(const hidl_vec<BufferDescriptor>& descriptors)
-{
-    if (!hasCapability(Capability::TEST_ALLOCATE)) {
-        return Error::UNDEFINED;
-    }
-
-    int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
-            descriptors.data(), nullptr);
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::allocate(const hidl_vec<BufferDescriptor>& descriptors,
-        hidl_vec<Buffer>* outBuffers)
-{
-    std::vector<buffer_handle_t> buffers(descriptors.size());
-    int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
-            descriptors.data(), buffers.data());
-    if (err == GRALLOC1_ERROR_NONE || err == GRALLOC1_ERROR_NOT_SHARED) {
-        outBuffers->resize(buffers.size());
-        for (size_t i = 0; i < outBuffers->size(); i++) {
-            (*outBuffers)[i] = static_cast<Buffer>(
-                    reinterpret_cast<uintptr_t>(buffers[i]));
-        }
-    }
-
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::free(Buffer buffer)
-{
-    buffer_handle_t handle = reinterpret_cast<buffer_handle_t>(
-            static_cast<uintptr_t>(buffer));
-
-    int32_t err = mDispatch.release(mDevice, handle);
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::exportHandle(Buffer buffer,
-        const native_handle_t** outHandle)
-{
-    // we rely on the caller to validate buffer here
-    *outHandle = reinterpret_cast<buffer_handle_t>(
-            static_cast<uintptr_t>(buffer));
-    return Error::NONE;
-}
-
-GrallocClient::GrallocClient(GrallocHal& hal)
-    : mHal(hal)
-{
-}
-
-GrallocClient::~GrallocClient()
-{
-    if (!mBuffers.empty()) {
-        ALOGW("client destroyed with valid buffers");
-        for (auto buf : mBuffers) {
-            mHal.free(buf);
-        }
-    }
-
-    if (!mDescriptors.empty()) {
-        ALOGW("client destroyed with valid buffer descriptors");
-        for (auto desc : mDescriptors) {
-            mHal.destroyDescriptor(desc);
-        }
-    }
-}
-
-Return<void> GrallocClient::createDescriptor(
-        const BufferDescriptorInfo& descriptorInfo,
-        createDescriptor_cb hidl_cb)
-{
-    BufferDescriptor descriptor = 0;
-    Error err = mHal.createDescriptor(descriptorInfo, &descriptor);
-
-    if (err == Error::NONE) {
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        auto result = mDescriptors.insert(descriptor);
-        if (!result.second) {
-            ALOGW("duplicated buffer descriptor id returned");
-            mHal.destroyDescriptor(descriptor);
-            err = Error::NO_RESOURCES;
-        }
-    }
-
-    hidl_cb(err, descriptor);
-    return Void();
-}
-
-Return<Error> GrallocClient::destroyDescriptor(BufferDescriptor descriptor)
-{
-    {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (!mDescriptors.erase(descriptor)) {
-            return Error::BAD_DESCRIPTOR;
-        }
-    }
-
-    return mHal.destroyDescriptor(descriptor);
-}
-
-Return<Error> GrallocClient::testAllocate(
-        const hidl_vec<BufferDescriptor>& descriptors)
-{
-    return mHal.testAllocate(descriptors);
-}
-
-Return<void> GrallocClient::allocate(
-        const hidl_vec<BufferDescriptor>& descriptors,
-        allocate_cb hidl_cb) {
-    hidl_vec<Buffer> buffers;
-    Error err = mHal.allocate(descriptors, &buffers);
-
-    if (err == Error::NONE || err == Error::NOT_SHARED) {
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        for (size_t i = 0; i < buffers.size(); i++) {
-            auto result = mBuffers.insert(buffers[i]);
-            if (!result.second) {
-                ALOGW("duplicated buffer id returned");
-
-                for (size_t j = 0; j < buffers.size(); j++) {
-                    if (j < i) {
-                        mBuffers.erase(buffers[i]);
-                    }
-                    mHal.free(buffers[i]);
-                }
-
-                buffers = hidl_vec<Buffer>();
-                err = Error::NO_RESOURCES;
-                break;
-            }
-        }
-    }
-
-    hidl_cb(err, buffers);
-    return Void();
-}
-
-Return<Error> GrallocClient::free(Buffer buffer)
-{
-    {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (!mBuffers.erase(buffer)) {
-            return Error::BAD_BUFFER;
-        }
-    }
-
-    return mHal.free(buffer);
-}
-
-Return<void> GrallocClient::exportHandle(BufferDescriptor /*descriptor*/,
-        Buffer buffer, exportHandle_cb hidl_cb)
-{
-    const native_handle_t* handle = nullptr;
-
-    {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (mBuffers.count(buffer) == 0) {
-            hidl_cb(Error::BAD_BUFFER, handle);
-            return Void();
-        }
-    }
-
-    Error err = mHal.exportHandle(buffer, &handle);
-
-    hidl_cb(err, handle);
-    return Void();
-}
-
 IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
     const hw_module_t* module = nullptr;
     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
@@ -455,12 +38,15 @@
     }
 
     uint8_t major = (module->module_api_version >> 8) & 0xff;
-    if (major != 1) {
-        ALOGE("unknown gralloc module major version %d", major);
-        return nullptr;
+    switch (major) {
+        case 1:
+            return new Gralloc1Allocator(module);
+        case 0:
+            return new Gralloc0Allocator(module);
+        default:
+            ALOGE("unknown gralloc module major version %d", major);
+            return nullptr;
     }
-
-    return new GrallocHal(module);
 }
 
 } // namespace implementation
diff --git a/graphics/allocator/2.0/default/Gralloc0Allocator.cpp b/graphics/allocator/2.0/default/Gralloc0Allocator.cpp
new file mode 100644
index 0000000..3b62bb3
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc0Allocator.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc0Allocator"
+
+#include "Gralloc0Allocator.h"
+#include "GrallocBufferDescriptor.h"
+
+#include <vector>
+
+#include <string.h>
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::implementation::
+    grallocDecodeBufferDescriptor;
+
+Gralloc0Allocator::Gralloc0Allocator(const hw_module_t* module) {
+    int result = gralloc_open(module, &mDevice);
+    if (result) {
+        LOG_ALWAYS_FATAL("failed to open gralloc0 device: %s",
+                         strerror(-result));
+    }
+}
+
+Gralloc0Allocator::~Gralloc0Allocator() {
+    gralloc_close(mDevice);
+}
+
+Return<void> Gralloc0Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+    char buf[4096] = {};
+    if (mDevice->dump) {
+        mDevice->dump(mDevice, buf, sizeof(buf));
+        buf[sizeof(buf) - 1] = '\0';
+    }
+
+    hidl_cb(hidl_string(buf));
+
+    return Void();
+}
+
+Return<void> Gralloc0Allocator::allocate(const BufferDescriptor& descriptor,
+                                         uint32_t count, allocate_cb hidl_cb) {
+    IMapper::BufferDescriptorInfo descriptorInfo;
+    if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
+        hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
+        return Void();
+    }
+
+    Error error = Error::NONE;
+    uint32_t stride = 0;
+    std::vector<hidl_handle> buffers;
+    buffers.reserve(count);
+
+    // allocate the buffers
+    for (uint32_t i = 0; i < count; i++) {
+        buffer_handle_t tmpBuffer;
+        uint32_t tmpStride;
+        error = allocateOne(descriptorInfo, &tmpBuffer, &tmpStride);
+        if (error != Error::NONE) {
+            break;
+        }
+
+        if (stride == 0) {
+            stride = tmpStride;
+        } else if (stride != tmpStride) {
+            // non-uniform strides
+            mDevice->free(mDevice, tmpBuffer);
+            stride = 0;
+            error = Error::UNSUPPORTED;
+            break;
+        }
+
+        buffers.emplace_back(hidl_handle(tmpBuffer));
+    }
+
+    // return the buffers
+    hidl_vec<hidl_handle> hidl_buffers;
+    if (error == Error::NONE) {
+        hidl_buffers.setToExternal(buffers.data(), buffers.size());
+    }
+    hidl_cb(error, stride, hidl_buffers);
+
+    // free the buffers
+    for (const auto& buffer : buffers) {
+        mDevice->free(mDevice, buffer.getNativeHandle());
+    }
+
+    return Void();
+}
+
+Error Gralloc0Allocator::allocateOne(const IMapper::BufferDescriptorInfo& info,
+                                     buffer_handle_t* outBuffer,
+                                     uint32_t* outStride) {
+    if (info.layerCount > 1 || (info.usage >> 32) != 0) {
+        return Error::BAD_VALUE;
+    }
+
+    buffer_handle_t buffer = nullptr;
+    int stride = 0;
+    int result = mDevice->alloc(mDevice, info.width, info.height,
+                                static_cast<int>(info.format), info.usage,
+                                &buffer, &stride);
+    if (result) {
+        switch (result) {
+            case -EINVAL:
+                return Error::BAD_VALUE;
+            default:
+                return Error::NO_RESOURCES;
+        }
+    }
+
+    *outBuffer = buffer;
+    *outStride = stride;
+
+    return Error::NONE;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace allocator
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc0Allocator.h b/graphics/allocator/2.0/default/Gralloc0Allocator.h
new file mode 100644
index 0000000..0e90527
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc0Allocator.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
+#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <hardware/gralloc.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+using android::hardware::graphics::mapper::V2_0::Error;
+
+class Gralloc0Allocator : public IAllocator {
+   public:
+    Gralloc0Allocator(const hw_module_t* module);
+    virtual ~Gralloc0Allocator();
+
+    // IAllocator interface
+    Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+    Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
+                          allocate_cb hidl_cb) override;
+
+   private:
+    Error allocateOne(const IMapper::BufferDescriptorInfo& info,
+                      buffer_handle_t* outBuffer, uint32_t* outStride);
+
+    alloc_device_t* mDevice;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace allocator
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
diff --git a/graphics/allocator/2.0/default/Gralloc1Allocator.cpp b/graphics/allocator/2.0/default/Gralloc1Allocator.cpp
new file mode 100644
index 0000000..c0a5e1e
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc1Allocator.cpp
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc1Allocator"
+
+#include "Gralloc1Allocator.h"
+#include "GrallocBufferDescriptor.h"
+
+#include <vector>
+
+#include <string.h>
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::common::V1_0::BufferUsage;
+using android::hardware::graphics::mapper::V2_0::implementation::
+    grallocDecodeBufferDescriptor;
+
+Gralloc1Allocator::Gralloc1Allocator(const hw_module_t* module)
+    : mDevice(nullptr), mCapabilities(), mDispatch() {
+    int result = gralloc1_open(module, &mDevice);
+    if (result) {
+        LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
+                         strerror(-result));
+    }
+
+    initCapabilities();
+    initDispatch();
+}
+
+Gralloc1Allocator::~Gralloc1Allocator() {
+    gralloc1_close(mDevice);
+}
+
+void Gralloc1Allocator::initCapabilities() {
+    uint32_t count = 0;
+    mDevice->getCapabilities(mDevice, &count, nullptr);
+
+    std::vector<int32_t> capabilities(count);
+    mDevice->getCapabilities(mDevice, &count, capabilities.data());
+    capabilities.resize(count);
+
+    for (auto capability : capabilities) {
+        if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) {
+            mCapabilities.layeredBuffers = true;
+            break;
+        }
+    }
+}
+
+template <typename T>
+void Gralloc1Allocator::initDispatch(gralloc1_function_descriptor_t desc,
+                                     T* outPfn) {
+    auto pfn = mDevice->getFunction(mDevice, desc);
+    if (!pfn) {
+        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
+    }
+
+    *outPfn = reinterpret_cast<T>(pfn);
+}
+
+void Gralloc1Allocator::initDispatch() {
+    initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump);
+    initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR,
+                 &mDispatch.createDescriptor);
+    initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR,
+                 &mDispatch.destroyDescriptor);
+    initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions);
+    initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat);
+    if (mCapabilities.layeredBuffers) {
+        initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
+                     &mDispatch.setLayerCount);
+    }
+    initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
+                 &mDispatch.setConsumerUsage);
+    initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
+                 &mDispatch.setProducerUsage);
+    initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
+    initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
+    initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
+}
+
+Return<void> Gralloc1Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+    uint32_t len = 0;
+    mDispatch.dump(mDevice, &len, nullptr);
+
+    std::vector<char> buf(len + 1);
+    mDispatch.dump(mDevice, &len, buf.data());
+    buf.resize(len + 1);
+    buf[len] = '\0';
+
+    hidl_string reply;
+    reply.setToExternal(buf.data(), len);
+    hidl_cb(reply);
+
+    return Void();
+}
+
+Return<void> Gralloc1Allocator::allocate(const BufferDescriptor& descriptor,
+                                         uint32_t count, allocate_cb hidl_cb) {
+    IMapper::BufferDescriptorInfo descriptorInfo;
+    if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
+        hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
+        return Void();
+    }
+
+    gralloc1_buffer_descriptor_t desc;
+    Error error = createDescriptor(descriptorInfo, &desc);
+    if (error != Error::NONE) {
+        hidl_cb(error, 0, hidl_vec<hidl_handle>());
+        return Void();
+    }
+
+    uint32_t stride = 0;
+    std::vector<hidl_handle> buffers;
+    buffers.reserve(count);
+
+    // allocate the buffers
+    for (uint32_t i = 0; i < count; i++) {
+        buffer_handle_t tmpBuffer;
+        uint32_t tmpStride;
+        error = allocateOne(desc, &tmpBuffer, &tmpStride);
+        if (error != Error::NONE) {
+            break;
+        }
+
+        if (stride == 0) {
+            stride = tmpStride;
+        } else if (stride != tmpStride) {
+            // non-uniform strides
+            mDispatch.release(mDevice, tmpBuffer);
+            stride = 0;
+            error = Error::UNSUPPORTED;
+            break;
+        }
+
+        buffers.emplace_back(hidl_handle(tmpBuffer));
+    }
+
+    mDispatch.destroyDescriptor(mDevice, desc);
+
+    // return the buffers
+    hidl_vec<hidl_handle> hidl_buffers;
+    if (error == Error::NONE) {
+        hidl_buffers.setToExternal(buffers.data(), buffers.size());
+    }
+    hidl_cb(error, stride, hidl_buffers);
+
+    // free the buffers
+    for (const auto& buffer : buffers) {
+        mDispatch.release(mDevice, buffer.getNativeHandle());
+    }
+
+    return Void();
+}
+
+Error Gralloc1Allocator::toError(int32_t error) {
+    switch (error) {
+        case GRALLOC1_ERROR_NONE:
+            return Error::NONE;
+        case GRALLOC1_ERROR_BAD_DESCRIPTOR:
+            return Error::BAD_DESCRIPTOR;
+        case GRALLOC1_ERROR_BAD_HANDLE:
+            return Error::BAD_BUFFER;
+        case GRALLOC1_ERROR_BAD_VALUE:
+            return Error::BAD_VALUE;
+        case GRALLOC1_ERROR_NOT_SHARED:
+            return Error::NONE;  // this is fine
+        case GRALLOC1_ERROR_NO_RESOURCES:
+            return Error::NO_RESOURCES;
+        case GRALLOC1_ERROR_UNDEFINED:
+        case GRALLOC1_ERROR_UNSUPPORTED:
+        default:
+            return Error::UNSUPPORTED;
+    }
+}
+
+uint64_t Gralloc1Allocator::toProducerUsage(uint64_t usage) {
+    // this is potentially broken as we have no idea which private flags
+    // should be filtered out
+    uint64_t producerUsage =
+        usage &
+        ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
+                               BufferUsage::CPU_WRITE_MASK);
+
+    switch (usage & BufferUsage::CPU_WRITE_MASK) {
+        case static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY):
+            producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
+            break;
+        case static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN):
+            producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
+            break;
+        default:
+            break;
+    }
+
+    switch (usage & BufferUsage::CPU_READ_MASK) {
+        case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
+            producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
+            break;
+        case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
+            producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
+            break;
+        default:
+            break;
+    }
+
+    return producerUsage;
+}
+
+uint64_t Gralloc1Allocator::toConsumerUsage(uint64_t usage) {
+    // this is potentially broken as we have no idea which private flags
+    // should be filtered out
+    uint64_t consumerUsage =
+        usage &
+        ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
+                               BufferUsage::CPU_WRITE_MASK);
+
+    switch (usage & BufferUsage::CPU_READ_MASK) {
+        case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
+            consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
+            break;
+        case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
+            consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
+            break;
+        default:
+            break;
+    }
+
+    return consumerUsage;
+}
+
+Error Gralloc1Allocator::createDescriptor(
+    const IMapper::BufferDescriptorInfo& info,
+    gralloc1_buffer_descriptor_t* outDescriptor) {
+    gralloc1_buffer_descriptor_t descriptor;
+
+    int32_t error = mDispatch.createDescriptor(mDevice, &descriptor);
+
+    if (error == GRALLOC1_ERROR_NONE) {
+        error = mDispatch.setDimensions(mDevice, descriptor, info.width,
+                                        info.height);
+    }
+    if (error == GRALLOC1_ERROR_NONE) {
+        error = mDispatch.setFormat(mDevice, descriptor,
+                                    static_cast<int32_t>(info.format));
+    }
+    if (error == GRALLOC1_ERROR_NONE) {
+        if (mCapabilities.layeredBuffers) {
+            error =
+                mDispatch.setLayerCount(mDevice, descriptor, info.layerCount);
+        } else if (info.layerCount > 1) {
+            error = GRALLOC1_ERROR_UNSUPPORTED;
+        }
+    }
+    if (error == GRALLOC1_ERROR_NONE) {
+        error = mDispatch.setProducerUsage(mDevice, descriptor,
+                                           toProducerUsage(info.usage));
+    }
+    if (error == GRALLOC1_ERROR_NONE) {
+        error = mDispatch.setConsumerUsage(mDevice, descriptor,
+                                           toConsumerUsage(info.usage));
+    }
+
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outDescriptor = descriptor;
+    } else {
+        mDispatch.destroyDescriptor(mDevice, descriptor);
+    }
+
+    return toError(error);
+}
+
+Error Gralloc1Allocator::allocateOne(gralloc1_buffer_descriptor_t descriptor,
+                                     buffer_handle_t* outBuffer,
+                                     uint32_t* outStride) {
+    buffer_handle_t buffer = nullptr;
+    int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer);
+    if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) {
+        return toError(error);
+    }
+
+    uint32_t stride = 0;
+    error = mDispatch.getStride(mDevice, buffer, &stride);
+    if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) {
+        mDispatch.release(mDevice, buffer);
+        return toError(error);
+    }
+
+    *outBuffer = buffer;
+    *outStride = stride;
+
+    return Error::NONE;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace allocator
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc1Allocator.h b/graphics/allocator/2.0/default/Gralloc1Allocator.h
new file mode 100644
index 0000000..7b5a966
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc1Allocator.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
+#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <hardware/gralloc1.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+using android::hardware::graphics::mapper::V2_0::Error;
+
+class Gralloc1Allocator : public IAllocator {
+   public:
+    Gralloc1Allocator(const hw_module_t* module);
+    virtual ~Gralloc1Allocator();
+
+    // IAllocator interface
+    Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+    Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
+                          allocate_cb hidl_cb) override;
+
+   private:
+    void initCapabilities();
+
+    template <typename T>
+    void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
+    void initDispatch();
+
+    static Error toError(int32_t error);
+    static uint64_t toProducerUsage(uint64_t usage);
+    static uint64_t toConsumerUsage(uint64_t usage);
+
+    Error createDescriptor(const IMapper::BufferDescriptorInfo& info,
+                           gralloc1_buffer_descriptor_t* outDescriptor);
+    Error allocateOne(gralloc1_buffer_descriptor_t descriptor,
+                      buffer_handle_t* outBuffer, uint32_t* outStride);
+
+    gralloc1_device_t* mDevice;
+
+    struct {
+        bool layeredBuffers;
+    } mCapabilities;
+
+    struct {
+        GRALLOC1_PFN_DUMP dump;
+        GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
+        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_GET_STRIDE getStride;
+        GRALLOC1_PFN_ALLOCATE allocate;
+        GRALLOC1_PFN_RELEASE release;
+    } mDispatch;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace allocator
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H