Support Gralloc4 in SwiftShader

Bug: b/146515640
Bug: b/161909468
Test: run Cuttlefish w/ SwiftShader w/ Gralloc4
Change-Id: I60c806f460ef4fd0b4de5e3993731c1054030159
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/48448
Presubmit-Ready: Jason Macnak <natsu@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Jason Macnak <natsu@google.com>
diff --git a/src/Android.bp b/src/Android.bp
index 621b4d0..2c124a8 100644
--- a/src/Android.bp
+++ b/src/Android.bp
@@ -46,6 +46,7 @@
             cflags: [
                 "-DHAVE_GRALLOC1",
                 "-DHAVE_GRALLOC3",
+                "-DHAVE_GRALLOC4",
             ],
             relative_install_path: "egl",
             header_libs: [
@@ -54,6 +55,7 @@
             ],
             shared_libs: [
                 "android.hardware.graphics.mapper@3.0",
+                "android.hardware.graphics.mapper@4.0",
                 "libnativewindow",
                 "libhardware",
                 "libhidlbase",
@@ -546,6 +548,7 @@
         "-D__STDC_FORMAT_MACROS",
         "-DHAVE_GRALLOC1",
         "-DHAVE_GRALLOC3",
+        "-DHAVE_GRALLOC4",
         "-DNO_SANITIZE_FUNCTION=",
         // FIXME: Use <android/api-level.h> instead?
         "-DANDROID_PLATFORM_SDK_VERSION=10000",
@@ -584,6 +587,7 @@
             ],
             shared_libs: [
                 "android.hardware.graphics.mapper@3.0",
+                "android.hardware.graphics.mapper@4.0",
                 "libnativewindow",
                 "libhardware",
                 "libhidlbase",
diff --git a/src/Common/GrallocAndroid.cpp b/src/Common/GrallocAndroid.cpp
index 6a12b2b..ffdf52e 100644
--- a/src/Common/GrallocAndroid.cpp
+++ b/src/Common/GrallocAndroid.cpp
@@ -23,6 +23,11 @@
 using V3Mapper = android::hardware::graphics::mapper::V3_0::IMapper;
 using android::hardware::hidl_handle;
 #endif
+#ifdef HAVE_GRALLOC4
+using V4Error = android::hardware::graphics::mapper::V4_0::Error;
+using V4Mapper = android::hardware::graphics::mapper::V4_0::IMapper;
+using android::hardware::hidl_handle;
+#endif
 
 GrallocModule *GrallocModule::getInstance()
 {
@@ -32,6 +37,14 @@
 
 GrallocModule::GrallocModule()
 {
+#ifdef HAVE_GRALLOC4
+	m_gralloc4_mapper = V4Mapper::getService();
+	if(m_gralloc4_mapper != nullptr)
+	{
+		return;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	m_gralloc3_mapper = V3Mapper::getService();
 	if(m_gralloc3_mapper != nullptr)
@@ -64,6 +77,22 @@
 
 int GrallocModule::import(buffer_handle_t handle, buffer_handle_t *imported_handle)
 {
+#ifdef HAVE_GRALLOC4
+	if(m_gralloc4_mapper != nullptr)
+	{
+		V4Error error;
+		auto ret = m_gralloc4_mapper->importBuffer(handle,
+		                                           [&](const auto &tmp_err, const auto &tmp_buf) {
+			                                           error = tmp_err;
+			                                           if(error == V4Error::NONE)
+			                                           {
+				                                           *imported_handle = static_cast<buffer_handle_t>(tmp_buf);
+			                                           }
+		                                           });
+		return ret.isOk() && error == V4Error::NONE ? 0 : -1;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	if(m_gralloc3_mapper != nullptr)
 	{
@@ -86,6 +115,14 @@
 
 int GrallocModule::release(buffer_handle_t handle)
 {
+#ifdef HAVE_GRALLOC4
+	if(m_gralloc4_mapper != nullptr)
+	{
+		native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
+		return m_gralloc4_mapper->freeBuffer(native_handle).isOk() ? 0 : 1;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	if(m_gralloc3_mapper != nullptr)
 	{
@@ -99,6 +136,32 @@
 
 int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr)
 {
+#ifdef HAVE_GRALLOC4
+	if(m_gralloc4_mapper != nullptr)
+	{
+		native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
+
+		V4Mapper::Rect rect;
+		rect.left = left;
+		rect.top = top;
+		rect.width = width;
+		rect.height = height;
+
+		hidl_handle empty_fence_handle;
+
+		V4Error error;
+		auto ret = m_gralloc4_mapper->lock(native_handle, usage, rect, empty_fence_handle,
+		                                   [&](const auto &tmp_err, const auto &tmp_vaddr) {
+			                                   error = tmp_err;
+			                                   if(tmp_err == V4Error::NONE)
+			                                   {
+				                                   *vaddr = tmp_vaddr;
+			                                   }
+		                                   });
+		return ret.isOk() && error == V4Error::NONE ? 0 : -1;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	if(m_gralloc3_mapper != nullptr)
 	{
@@ -155,6 +218,20 @@
 
 int GrallocModule::unlock(buffer_handle_t handle)
 {
+#ifdef HAVE_GRALLOC4
+	if(m_gralloc4_mapper != nullptr)
+	{
+		native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
+
+		V4Error error;
+		auto ret = m_gralloc4_mapper->unlock(native_handle,
+		                                     [&](const auto &tmp_err, const auto &) {
+			                                     error = tmp_err;
+		                                     });
+		return ret.isOk() && error == V4Error::NONE ? 0 : -1;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	if(m_gralloc3_mapper != nullptr)
 	{
diff --git a/src/Common/GrallocAndroid.hpp b/src/Common/GrallocAndroid.hpp
index 265608c..058eaf1 100644
--- a/src/Common/GrallocAndroid.hpp
+++ b/src/Common/GrallocAndroid.hpp
@@ -17,10 +17,15 @@
 
 #include <hardware/gralloc.h>
 #include <hardware/gralloc1.h>
+
 #ifdef HAVE_GRALLOC3
 #	include <android/hardware/graphics/mapper/3.0/IMapper.h>
 #	include <utils/StrongPointer.h>
 #endif
+#ifdef HAVE_GRALLOC4
+#	include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#	include <utils/StrongPointer.h>
+#endif
 
 #include <unistd.h>  // for close()
 
@@ -47,6 +52,9 @@
 #ifdef HAVE_GRALLOC3
 	android::sp<android::hardware::graphics::mapper::V3_0::IMapper> m_gralloc3_mapper;
 #endif
+#ifdef HAVE_GRALLOC4
+	android::sp<android::hardware::graphics::mapper::V4_0::IMapper> m_gralloc4_mapper;
+#endif
 };
 
 #endif  // GRALLOC_ANDROID
diff --git a/src/System/GrallocAndroid.cpp b/src/System/GrallocAndroid.cpp
index 6a12b2b..ffdf52e 100644
--- a/src/System/GrallocAndroid.cpp
+++ b/src/System/GrallocAndroid.cpp
@@ -23,6 +23,11 @@
 using V3Mapper = android::hardware::graphics::mapper::V3_0::IMapper;
 using android::hardware::hidl_handle;
 #endif
+#ifdef HAVE_GRALLOC4
+using V4Error = android::hardware::graphics::mapper::V4_0::Error;
+using V4Mapper = android::hardware::graphics::mapper::V4_0::IMapper;
+using android::hardware::hidl_handle;
+#endif
 
 GrallocModule *GrallocModule::getInstance()
 {
@@ -32,6 +37,14 @@
 
 GrallocModule::GrallocModule()
 {
+#ifdef HAVE_GRALLOC4
+	m_gralloc4_mapper = V4Mapper::getService();
+	if(m_gralloc4_mapper != nullptr)
+	{
+		return;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	m_gralloc3_mapper = V3Mapper::getService();
 	if(m_gralloc3_mapper != nullptr)
@@ -64,6 +77,22 @@
 
 int GrallocModule::import(buffer_handle_t handle, buffer_handle_t *imported_handle)
 {
+#ifdef HAVE_GRALLOC4
+	if(m_gralloc4_mapper != nullptr)
+	{
+		V4Error error;
+		auto ret = m_gralloc4_mapper->importBuffer(handle,
+		                                           [&](const auto &tmp_err, const auto &tmp_buf) {
+			                                           error = tmp_err;
+			                                           if(error == V4Error::NONE)
+			                                           {
+				                                           *imported_handle = static_cast<buffer_handle_t>(tmp_buf);
+			                                           }
+		                                           });
+		return ret.isOk() && error == V4Error::NONE ? 0 : -1;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	if(m_gralloc3_mapper != nullptr)
 	{
@@ -86,6 +115,14 @@
 
 int GrallocModule::release(buffer_handle_t handle)
 {
+#ifdef HAVE_GRALLOC4
+	if(m_gralloc4_mapper != nullptr)
+	{
+		native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
+		return m_gralloc4_mapper->freeBuffer(native_handle).isOk() ? 0 : 1;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	if(m_gralloc3_mapper != nullptr)
 	{
@@ -99,6 +136,32 @@
 
 int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr)
 {
+#ifdef HAVE_GRALLOC4
+	if(m_gralloc4_mapper != nullptr)
+	{
+		native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
+
+		V4Mapper::Rect rect;
+		rect.left = left;
+		rect.top = top;
+		rect.width = width;
+		rect.height = height;
+
+		hidl_handle empty_fence_handle;
+
+		V4Error error;
+		auto ret = m_gralloc4_mapper->lock(native_handle, usage, rect, empty_fence_handle,
+		                                   [&](const auto &tmp_err, const auto &tmp_vaddr) {
+			                                   error = tmp_err;
+			                                   if(tmp_err == V4Error::NONE)
+			                                   {
+				                                   *vaddr = tmp_vaddr;
+			                                   }
+		                                   });
+		return ret.isOk() && error == V4Error::NONE ? 0 : -1;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	if(m_gralloc3_mapper != nullptr)
 	{
@@ -155,6 +218,20 @@
 
 int GrallocModule::unlock(buffer_handle_t handle)
 {
+#ifdef HAVE_GRALLOC4
+	if(m_gralloc4_mapper != nullptr)
+	{
+		native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
+
+		V4Error error;
+		auto ret = m_gralloc4_mapper->unlock(native_handle,
+		                                     [&](const auto &tmp_err, const auto &) {
+			                                     error = tmp_err;
+		                                     });
+		return ret.isOk() && error == V4Error::NONE ? 0 : -1;
+	}
+#endif
+
 #ifdef HAVE_GRALLOC3
 	if(m_gralloc3_mapper != nullptr)
 	{
diff --git a/src/System/GrallocAndroid.hpp b/src/System/GrallocAndroid.hpp
index 265608c..058eaf1 100644
--- a/src/System/GrallocAndroid.hpp
+++ b/src/System/GrallocAndroid.hpp
@@ -17,10 +17,15 @@
 
 #include <hardware/gralloc.h>
 #include <hardware/gralloc1.h>
+
 #ifdef HAVE_GRALLOC3
 #	include <android/hardware/graphics/mapper/3.0/IMapper.h>
 #	include <utils/StrongPointer.h>
 #endif
+#ifdef HAVE_GRALLOC4
+#	include <android/hardware/graphics/mapper/4.0/IMapper.h>
+#	include <utils/StrongPointer.h>
+#endif
 
 #include <unistd.h>  // for close()
 
@@ -47,6 +52,9 @@
 #ifdef HAVE_GRALLOC3
 	android::sp<android::hardware::graphics::mapper::V3_0::IMapper> m_gralloc3_mapper;
 #endif
+#ifdef HAVE_GRALLOC4
+	android::sp<android::hardware::graphics::mapper::V4_0::IMapper> m_gralloc4_mapper;
+#endif
 };
 
 #endif  // GRALLOC_ANDROID