Introduce a mode for HWC2 to talk to HIDL graphics HALs directly

gralloc is deprecated, we have to use IMapper and IAllocator instead.

Bug: 145244672
Test: boot
Change-Id: I142cb1c7bfed0c59c8396a3512b30c9bd7564547
Signed-off-by: Roman Kiryanov <rkir@google.com>
diff --git a/Android.mk b/Android.mk
index 744b2a6..467dbcd 100644
--- a/Android.mk
+++ b/Android.mk
@@ -149,6 +149,7 @@
 include $(GOLDFISH_OPENGL_PATH)/system/GLESv2/Android.mk
 
 include $(GOLDFISH_OPENGL_PATH)/system/gralloc/Android.mk
+include $(GOLDFISH_OPENGL_PATH)/system/cbmanager/Android.mk
 
 include $(GOLDFISH_OPENGL_PATH)/system/egl/Android.mk
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f460f77..b7615d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@
 # instead run make from .../device/generic/goldfish-opengl
 # which will re-generate this file.
 set(GOLDFISH_DEVICE_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/./Android.mk" "2f7f8e63d569d7c81c7e0d010cf61995ec70d4def8b1d72673270bd4a372e426")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/./Android.mk" "e4989c6c970b11f3d6baf80ac7115cc18f90031d0df26db2002c984a4b39229b")
 add_subdirectory(shared/OpenglCodecCommon)
 add_subdirectory(system/GLESv1_enc)
 add_subdirectory(system/GLESv2_enc)
@@ -14,4 +14,4 @@
 add_subdirectory(system/GLESv2)
 add_subdirectory(system/gralloc)
 add_subdirectory(system/egl)
-add_subdirectory(system/vulkan)
+add_subdirectory(system/vulkan)
\ No newline at end of file
diff --git a/system/cbmanager/Android.mk b/system/cbmanager/Android.mk
new file mode 100644
index 0000000..418902f
--- /dev/null
+++ b/system/cbmanager/Android.mk
@@ -0,0 +1,57 @@
+#
+# Copyright 2015 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS += \
+    -DLOG_TAG=\"cbmanager\" \
+    -Werror \
+
+ifeq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
+LOCAL_CFLAGS += \
+    -DHOST_BUILD \
+
+LOCAL_SRC_FILES := host.cpp
+else
+LOCAL_SHARED_LIBRARIES += \
+    liblog \
+    libcutils \
+    libutils
+
+LOCAL_CFLAGS += \
+    -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) \
+
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 30; echo $$?), 0)
+LOCAL_SRC_FILES := hidl.cpp
+LOCAL_SHARED_LIBRARIES += \
+    libhidlbase \
+    android.hardware.graphics.mapper@2.0 \
+    android.hardware.graphics.allocator@2.0
+else
+LOCAL_SRC_FILES := gralloc.cpp
+LOCAL_SHARED_LIBRARIES += \
+    libhardware
+endif
+endif
+
+LOCAL_C_INCLUDES += \
+    device/generic/goldfish-opengl/system/include \
+    device/generic/goldfish-opengl/shared/OpenglCodecCommon \
+
+LOCAL_MODULE := libcbmanager
+LOCAL_VENDOR_MODULE := true
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/system/cbmanager/gralloc.cpp b/system/cbmanager/gralloc.cpp
new file mode 100644
index 0000000..dab4e39
--- /dev/null
+++ b/system/cbmanager/gralloc.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#include <hardware/gralloc.h>
+#include "cbmanager.h"
+
+namespace android {
+namespace {
+
+class CbManagerGrallocImpl : public CbManager::CbManagerImpl {
+public:
+    CbManagerGrallocImpl(const hw_module_t* hwModule, alloc_device_t* allocDev)
+      : mHwModule(hwModule), mAllocDev(allocDev) {}
+
+    ~CbManagerGrallocImpl() {
+        gralloc_close(mAllocDev);
+    }
+
+    const cb_handle_t* allocateBuffer(int width, int height, int format) {
+        int ret;
+        int stride;
+        buffer_handle_t handle;
+
+        ret = mAllocDev->alloc(mAllocDev, width, height, format,
+                               GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER,
+                               &handle, &stride);
+        return ret ? nullptr : cb_handle_t::from(handle);
+    }
+
+    void freeBuffer(const cb_handle_t* h) {
+        mAllocDev->free(mAllocDev, h);
+    }
+
+private:
+    const hw_module_t* mHwModule;
+    alloc_device_t* mAllocDev;
+};
+
+std::unique_ptr<CbManager::CbManagerImpl> buildGrallocImpl() {
+    int ret;
+    const hw_module_t* hwModule;
+
+    ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &hwModule);
+    if (ret) {
+        return nullptr;
+    }
+
+    alloc_device_t* allocDev;
+    ret = gralloc_open(hwModule, &allocDev);
+    if (ret) {
+        return nullptr;
+    }
+
+    return std::make_unique<CbManagerGrallocImpl>(hwModule, allocDev);
+}
+}  // namespace
+
+CbManager::CbManager() : mImpl(buildGrallocImpl()) {}
+
+}  // namespace android
diff --git a/system/cbmanager/hidl.cpp b/system/cbmanager/hidl.cpp
new file mode 100644
index 0000000..ff08642
--- /dev/null
+++ b/system/cbmanager/hidl.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#include <cutils/native_handle.h>
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+#include "cbmanager.h"
+
+namespace android {
+namespace {
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_vec;
+using PixelFormat10 = ::android::hardware::graphics::common::V1_0::PixelFormat;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+
+namespace IMapper2ns = ::android::hardware::graphics::mapper::V2_0;
+namespace IAllocator2ns = ::android::hardware::graphics::allocator::V2_0;
+
+class CbManagerHidlV3Impl : public CbManager::CbManagerImpl {
+public:
+    CbManagerHidlV3Impl(::android::sp<IMapper2ns::IMapper> mapper,
+                        ::android::sp<IAllocator2ns::IAllocator> allocator)
+      : mMapper(mapper), mAllocator(allocator) {}
+
+    const cb_handle_t* allocateBuffer(int width, int height, int format) {
+        using IMapper2ns::Error;
+        using IMapper2ns::BufferDescriptor;
+
+        IMapper2ns::IMapper::BufferDescriptorInfo descriptor_info;
+        descriptor_info.width = width;
+        descriptor_info.height = height;
+        descriptor_info.layerCount = 1;
+        descriptor_info.format = static_cast<PixelFormat10>(format);
+        descriptor_info.usage =
+            BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_RENDER_TARGET;
+        Error hidl_err = Error::NONE;
+
+        BufferDescriptor descriptor;
+        mMapper->createDescriptor(descriptor_info,
+                                  [&](const Error &_error,
+                                      const BufferDescriptor &_descriptor) {
+            hidl_err = _error;
+            descriptor = _descriptor;
+        });
+        if (hidl_err != Error::NONE) {
+          return nullptr;
+        }
+
+        hidl_handle raw_handle = nullptr;
+        mAllocator->allocate(descriptor, 1,
+                             [&](const Error &_error,
+                                 uint32_t /*_stride*/,
+                                 const hidl_vec<hidl_handle> &_buffers) {
+            hidl_err = _error;
+            raw_handle = _buffers[0];
+        });
+        if (hidl_err != Error::NONE) {
+            return nullptr;
+        }
+
+        const cb_handle_t *buf = nullptr;
+        mMapper->importBuffer(raw_handle, [&](const Error &_error,
+                                              void *_buf) {
+            hidl_err = _error;
+            buf = cb_handle_t::from(_buf);
+        });
+        if (hidl_err != Error::NONE) {
+          return nullptr;
+        }
+
+        return buf;
+    }
+
+    void freeBuffer(const cb_handle_t* _h) {
+        using IMapper2ns::Error;
+
+        cb_handle_t* h = const_cast<cb_handle_t*>(_h);
+
+        mMapper->freeBuffer(h);
+        native_handle_close(h);
+        native_handle_delete(h);
+    }
+
+private:
+    const ::android::sp<IMapper2ns::IMapper> mMapper;
+    const ::android::sp<IAllocator2ns::IAllocator> mAllocator;
+};
+
+std::unique_ptr<CbManager::CbManagerImpl> buildHidlImpl() {
+    {
+        ::android::sp<IMapper2ns::IMapper> mapper =
+            IMapper2ns::IMapper::getService();
+        ::android::sp<IAllocator2ns::IAllocator> allocator =
+            IAllocator2ns::IAllocator::getService();
+        if (mapper && allocator) {
+            return std::make_unique<CbManagerHidlV3Impl>(mapper, allocator);
+        }
+    }
+
+    ALOGE("%s:%d: no IMapper and IAllocator implementations found",
+          __func__, __LINE__);
+    return nullptr;
+}
+
+}  // namespace
+
+CbManager::CbManager() : mImpl(buildHidlImpl()) {}
+
+}  // namespace android
diff --git a/system/cbmanager/host.cpp b/system/cbmanager/host.cpp
new file mode 100644
index 0000000..c1a46af
--- /dev/null
+++ b/system/cbmanager/host.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 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.
+ */
+
+#include <hardware/gralloc.h>
+#include "cbmanager.h"
+
+namespace android {
+namespace {
+
+class CbManagerHostImpl : public CbManager::CbManagerImpl {
+public:
+    CbManagerHostImpl() {}
+
+    ~CbManagerHostImpl() {}
+
+    const cb_handle_t* allocateBuffer(int width, int height, int format) {
+        return nullptr;
+    }
+
+    void freeBuffer(const cb_handle_t* h) {
+    }
+
+private:
+};
+
+std::unique_ptr<CbManager::CbManagerImpl> buildHostImpl() {
+    return std::make_unique<CbManagerHostImpl>();
+}
+}  // namespace
+
+CbManager::CbManager() : mImpl(buildHostImpl()) {}
+
+}  // namespace android
diff --git a/system/hwc2/Android.mk b/system/hwc2/Android.mk
index c46ea11..489a98e 100644
--- a/system/hwc2/Android.mk
+++ b/system/hwc2/Android.mk
@@ -52,6 +52,7 @@
 LOCAL_VENDOR_MODULE := true
 LOCAL_SHARED_LIBRARIES := $(emulator_hwcomposer_shared_libraries)
 LOCAL_SHARED_LIBRARIES += libOpenglSystemCommon lib_renderControl_enc
+LOCAL_SHARED_LIBRARIES += libcbmanager
 LOCAL_SRC_FILES := $(emulator_hwcomposer2_src_files)
 LOCAL_C_INCLUDES := $(emulator_hwcomposer_c_includes)
 LOCAL_MODULE_RELATIVE_PATH := $(emulator_hwcomposer_relative_path)
diff --git a/system/hwc2/EmuHWC2.cpp b/system/hwc2/EmuHWC2.cpp
index a2f7b0c..89d95c8 100644
--- a/system/hwc2/EmuHWC2.cpp
+++ b/system/hwc2/EmuHWC2.cpp
@@ -66,7 +66,6 @@
         return Error::NoResources; \
     }
 
-
 using namespace HWC2;
 
 namespace android {
@@ -391,50 +390,12 @@
 }
 
 const cb_handle_t* EmuHWC2::allocateDisplayColorBuffer() {
-    // HAL_PIXEL_FORMAT_RGBA_8888 was hardcoded in framebuffer_device_t in
-    // gralloc
-
-    return mGrallocModule.allocateBuffer(mDisplayWidth, mDisplayHeight,
-                                         HAL_PIXEL_FORMAT_RGBA_8888);
+    return mCbManager.allocateBuffer(mDisplayWidth, mDisplayHeight,
+                                     HAL_PIXEL_FORMAT_RGBA_8888);
 }
 
 void EmuHWC2::freeDisplayColorBuffer(const cb_handle_t* h) {
-    mGrallocModule.freeBuffer(h);
-}
-
-//Gralloc Functions
-EmuHWC2::GrallocModule::GrallocModule() {
-    int ret;
-
-    ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mHw);
-    assert(ret == 0 && "Gralloc moudle not found");
-    mGralloc = reinterpret_cast<const gralloc_module_t*>(mHw);
-    ret = gralloc_open(mHw, &mAllocDev);
-    assert(ret == 0 && "Fail to open GPU device");
-}
-
-EmuHWC2::GrallocModule::~GrallocModule() {
-    gralloc_close(mAllocDev);
-}
-
-const cb_handle_t* EmuHWC2::GrallocModule::allocateBuffer(int width, int height, int format) {
-    int ret;
-    int stride;
-    buffer_handle_t handle;
-
-    ret = mAllocDev->alloc(mAllocDev, width, height, format,
-                           GRALLOC_USAGE_HW_COMPOSER|GRALLOC_USAGE_HW_RENDER,
-                           &handle, &stride);
-    assert(ret == 0 && "Fail to allocate target ColorBuffer");
-
-    return cb_handle_t::from(handle);
-}
-
-void EmuHWC2::GrallocModule::freeBuffer(const cb_handle_t* h) {
-    int ret;
-
-    ret = mAllocDev->free(mAllocDev, h);
-    assert(ret == 0 && "Fail to free target ColorBuffer");
+    mCbManager.freeBuffer(h);
 }
 
 // Display functions
diff --git a/system/hwc2/EmuHWC2.h b/system/hwc2/EmuHWC2.h
index dfc51e4..3428ec0 100644
--- a/system/hwc2/EmuHWC2.h
+++ b/system/hwc2/EmuHWC2.h
@@ -33,9 +33,9 @@
 #include <unordered_set>
 #include <unordered_map>
 #include <set>
-#include <cutils/native_handle.h>
 
 #include "gralloc_cb.h"
+#include "cbmanager.h"
 #include "MiniFence.h"
 #include "HostConnection.h"
 
@@ -138,20 +138,6 @@
             sp<MiniFence> mFence;
     };
 
-    class GrallocModule {
-    public:
-        GrallocModule();
-        ~GrallocModule();
-
-        const cb_handle_t* allocateBuffer(int width, int height, int format);
-        void freeBuffer(const cb_handle_t*);
-
-    private:
-        const hw_module_t* mHw = nullptr;
-        const gralloc_module_t* mGralloc = nullptr;
-        alloc_device_t* mAllocDev = nullptr;
-    };
-
     typedef struct compose_layer {
         uint32_t cbHandle;
         hwc2_composition_t composeMode;
@@ -480,7 +466,7 @@
     const cb_handle_t* allocateDisplayColorBuffer();
     void freeDisplayColorBuffer(const cb_handle_t* h);
 
-    GrallocModule mGrallocModule;
+    CbManager mCbManager;
     std::unordered_set<HWC2::Capability> mCapabilities;
 
     // These are potentially accessed from multiple threads, and are protected
diff --git a/system/include/cbmanager.h b/system/include/cbmanager.h
new file mode 100644
index 0000000..4d98641
--- /dev/null
+++ b/system/include/cbmanager.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 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_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_CBMANAGER_H
+#define ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_CBMANAGER_H
+
+#include <memory>
+#include "gralloc_cb.h"
+
+namespace android {
+
+class CbManager {
+public:
+    CbManager();
+
+    class CbManagerImpl {
+    public:
+        virtual ~CbManagerImpl() {}
+        virtual const cb_handle_t* allocateBuffer(int width,
+                                                  int height,
+                                                  int format) = 0;
+        virtual void freeBuffer(const cb_handle_t* h) = 0;
+    };
+
+    const cb_handle_t* allocateBuffer(int width, int height, int format) {
+        return mImpl->allocateBuffer(width, height, format);
+    }
+
+    void freeBuffer(const cb_handle_t* h) {
+        mImpl->freeBuffer(h);
+    }
+
+private:
+    std::unique_ptr<CbManagerImpl> mImpl;
+};
+
+}  // namespace android
+
+#endif  // ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_CBMANAGER_H