Snap for 7550740 from 46e34f0a08f0eb934319de4ae8aa573c8ab8cb13 to sdk-release

Change-Id: I592bbbd78b1101aec2fed495f74edca6f964dc79
diff --git a/Android.bp b/Android.bp
index dff0ee8..ad09b32 100644
--- a/Android.bp
+++ b/Android.bp
@@ -71,8 +71,6 @@
 cc_defaults {
     name: "minigbm_defaults",
 
-    srcs: [":minigbm_core_files"],
-
     cflags: [
         "-D_GNU_SOURCE=1",
         "-D_FILE_OFFSET_BITS=64",
@@ -97,12 +95,9 @@
 
     defaults: ["minigbm_defaults"],
 
-    srcs: [":minigbm_gralloc_common_files"],
-
     header_libs: [
         "libhardware_headers",
         "libnativebase_headers",
-        "libnativewindow_headers",
         "libsystem_headers",
         "minigbm_headers",
     ],
@@ -118,8 +113,25 @@
         "libsync",
         "liblog",
     ],
+}
 
+cc_defaults {
+    name: "minigbm_cros_gralloc_library_defaults",
+
+    defaults: ["minigbm_cros_gralloc_defaults"],
+    srcs: [
+        ":minigbm_core_files",
+        ":minigbm_gralloc_common_files",
+    ],
+}
+
+cc_defaults {
+    name: "minigbm_cros_gralloc0_defaults",
+
+    defaults: ["minigbm_cros_gralloc_defaults"],
     relative_install_path: "hw",
+
+    srcs: [":minigbm_gralloc0_files"],
 }
 
 cc_library {
@@ -128,6 +140,7 @@
     host_supported: true,
 
     srcs: [
+        ":minigbm_core_files",
         "gbm.c",
         "gbm_helpers.c",
     ],
@@ -155,15 +168,23 @@
     export_include_dirs: ["."],
 }
 
+// Generic
 cc_library_shared {
-    name: "gralloc.minigbm",
-    defaults: ["minigbm_cros_gralloc_defaults"],
-    srcs: [":minigbm_gralloc0_files"],
+    name: "libminigbm_gralloc",
+    defaults: ["minigbm_cros_gralloc_library_defaults"],
 }
 
 cc_library_shared {
-    name: "gralloc.minigbm_intel",
-    defaults: ["minigbm_cros_gralloc_defaults"],
+    name: "gralloc.minigbm",
+    defaults: ["minigbm_cros_gralloc0_defaults"],
+    shared_libs: ["libminigbm_gralloc"],
+}
+
+// Intel
+cc_library_shared {
+    name: "libminigbm_gralloc_intel",
+    defaults: ["minigbm_cros_gralloc_library_defaults"],
+    cflags: ["-DDRV_I915"],
     enabled: false,
     arch: {
         x86: {
@@ -173,20 +194,45 @@
             enabled: true,
         },
     },
-    cflags: ["-DDRV_I915"],
-    srcs: [":minigbm_gralloc0_files"],
+}
+
+cc_library_shared {
+    name: "gralloc.minigbm_intel",
+    defaults: ["minigbm_cros_gralloc0_defaults"],
+    shared_libs: ["libminigbm_gralloc_intel"],
+    enabled: false,
+    arch: {
+        x86: {
+            enabled: true,
+        },
+        x86_64: {
+            enabled: true,
+        },
+    },
+}
+
+// Meson
+cc_library_shared {
+    name: "libminigbm_gralloc_meson",
+    defaults: ["minigbm_cros_gralloc_library_defaults"],
+    cflags: ["-DDRV_MESON"],
 }
 
 cc_library_shared {
     name: "gralloc.minigbm_meson",
-    defaults: ["minigbm_cros_gralloc_defaults"],
-    cflags: ["-DDRV_MESON"],
-    srcs: [":minigbm_gralloc0_files"],
+    defaults: ["minigbm_cros_gralloc0_defaults"],
+    shared_libs: ["libminigbm_gralloc_meson"],
+}
+
+// MSM
+cc_library_shared {
+    name: "libminigbm_gralloc_msm",
+    defaults: ["minigbm_cros_gralloc_library_defaults"],
+    cflags: ["-DDRV_MSM"],
 }
 
 cc_library_shared {
     name: "gralloc.minigbm_msm",
-    defaults: ["minigbm_cros_gralloc_defaults"],
-    cflags: ["-DDRV_MSM"],
-    srcs: [":minigbm_gralloc0_files"],
+    defaults: ["minigbm_cros_gralloc0_defaults"],
+    shared_libs: ["libminigbm_gralloc_msm"],
 }
diff --git a/amdgpu.c b/amdgpu.c
index f987f6f..66dbc2a 100644
--- a/amdgpu.c
+++ b/amdgpu.c
@@ -394,6 +394,10 @@
 	use_flags &= ~BO_USE_RENDERSCRIPT;
 	use_flags &= ~BO_USE_SW_WRITE_OFTEN;
 	use_flags &= ~BO_USE_SW_READ_OFTEN;
+#if __ANDROID__
+	use_flags &= ~BO_USE_SW_WRITE_RARELY;
+	use_flags &= ~BO_USE_SW_READ_RARELY;
+#endif
 	use_flags &= ~BO_USE_LINEAR;
 
 	metadata.tiling = TILE_TYPE_DRI;
@@ -503,23 +507,8 @@
 		return -EINVAL;
 
 	if (combo->metadata.tiling == TILE_TYPE_DRI) {
-		bool needs_alignment = false;
-#ifdef __ANDROID__
-		/*
-		 * Currently, the gralloc API doesn't differentiate between allocation time and map
-		 * time strides. A workaround for amdgpu DRI buffers is to always to align to 256 at
-		 * allocation time.
-		 *
-		 * See b/115946221,b/117942643
-		 */
-		if (use_flags & (BO_USE_SW_MASK))
-			needs_alignment = true;
-#endif
 		// See b/122049612
-		if (use_flags & (BO_USE_SCANOUT) && priv->dev_info.family == AMDGPU_FAMILY_CZ)
-			needs_alignment = true;
-
-		if (needs_alignment) {
+		if (use_flags & (BO_USE_SCANOUT) && priv->dev_info.family == AMDGPU_FAMILY_CZ) {
 			uint32_t bytes_per_pixel = drv_bytes_per_pixel_from_format(format, 0);
 			width = ALIGN(width, 256 / bytes_per_pixel);
 		}
diff --git a/cros_gralloc/cros_gralloc_driver.cc b/cros_gralloc/cros_gralloc_driver.cc
index f0c0392..aa53537 100644
--- a/cros_gralloc/cros_gralloc_driver.cc
+++ b/cros_gralloc/cros_gralloc_driver.cc
@@ -45,21 +45,16 @@
 	return fd;
 }
 
-cros_gralloc_driver::cros_gralloc_driver() : drv_(nullptr)
+cros_gralloc_driver *cros_gralloc_driver::get_instance()
 {
-}
+	static cros_gralloc_driver s_instance;
 
-cros_gralloc_driver::~cros_gralloc_driver()
-{
-	buffers_.clear();
-	handles_.clear();
-
-	if (drv_) {
-		int fd = drv_get_fd(drv_);
-		drv_destroy(drv_);
-		drv_ = nullptr;
-		close(fd);
+	if (!s_instance.is_initialized()) {
+		drv_log("Failed to initialize driver.\n");
+		return nullptr;
 	}
+
+	return &s_instance;
 }
 
 static struct driver *init_try_node(int idx, char const *str)
@@ -84,7 +79,7 @@
 	return drv;
 }
 
-int32_t cros_gralloc_driver::init()
+cros_gralloc_driver::cros_gralloc_driver()
 {
 	/*
 	 * Create a driver from render nodes first, then try card
@@ -105,17 +100,33 @@
 	for (uint32_t i = min_render_node; i < max_render_node; i++) {
 		drv_ = init_try_node(i, render_nodes_fmt);
 		if (drv_)
-			return 0;
+			return;
 	}
 
 	// Try card nodes... for vkms mostly.
 	for (uint32_t i = min_card_node; i < max_card_node; i++) {
 		drv_ = init_try_node(i, card_nodes_fmt);
 		if (drv_)
-			return 0;
+			return;
 	}
+}
 
-	return -ENODEV;
+cros_gralloc_driver::~cros_gralloc_driver()
+{
+	buffers_.clear();
+	handles_.clear();
+
+	if (drv_) {
+		int fd = drv_get_fd(drv_);
+		drv_destroy(drv_);
+		drv_ = nullptr;
+		close(fd);
+	}
+}
+
+bool cros_gralloc_driver::is_initialized()
+{
+	return drv_ != nullptr;
 }
 
 bool cros_gralloc_driver::is_supported(const struct cros_gralloc_buffer_descriptor *descriptor)
diff --git a/cros_gralloc/cros_gralloc_driver.h b/cros_gralloc/cros_gralloc_driver.h
index ef9e21f..580605c 100644
--- a/cros_gralloc/cros_gralloc_driver.h
+++ b/cros_gralloc/cros_gralloc_driver.h
@@ -16,10 +16,7 @@
 class cros_gralloc_driver
 {
       public:
-	cros_gralloc_driver();
-	~cros_gralloc_driver();
-
-	int32_t init();
+	static cros_gralloc_driver *get_instance();
 	bool is_supported(const struct cros_gralloc_buffer_descriptor *descriptor);
 	int32_t allocate(const struct cros_gralloc_buffer_descriptor *descriptor,
 			 buffer_handle_t *out_handle);
@@ -47,12 +44,13 @@
 	void for_each_handle(const std::function<void(cros_gralloc_handle_t)> &function);
 
       private:
-	cros_gralloc_driver(cros_gralloc_driver const &);
-	cros_gralloc_driver operator=(cros_gralloc_driver const &);
+	cros_gralloc_driver();
+	~cros_gralloc_driver();
+	bool is_initialized();
 	cros_gralloc_buffer *get_buffer(cros_gralloc_handle_t hnd);
 	void emplace_buffer(struct bo *bo, struct cros_gralloc_handle *hnd);
 
-	struct driver *drv_;
+	struct driver *drv_ = nullptr;
 	std::mutex mutex_;
 	std::unordered_map<uint32_t, cros_gralloc_buffer *> buffers_;
 	std::unordered_map<cros_gralloc_handle_t, std::pair<cros_gralloc_buffer *, int32_t>>
diff --git a/cros_gralloc/cros_gralloc_types.h b/cros_gralloc/cros_gralloc_types.h
index 22f58e2..7c51778 100644
--- a/cros_gralloc/cros_gralloc_types.h
+++ b/cros_gralloc/cros_gralloc_types.h
@@ -9,6 +9,11 @@
 
 #include <string>
 
+// Reserve the GRALLOC_USAGE_PRIVATE_0 bit from hardware/gralloc.h for buffers
+// used for front rendering. minigbm backend later decides to use
+// BO_USE_FRONT_RENDERING or BO_USE_LINEAR upon buffer allocaton.
+#define BUFFER_USAGE_FRONT_RENDERING (1U << 28)
+
 struct cros_gralloc_buffer_descriptor {
 	uint32_t width;
 	uint32_t height;
diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc
index 5899d5a..afd40d4 100644
--- a/cros_gralloc/gralloc0/gralloc0.cc
+++ b/cros_gralloc/gralloc0/gralloc0.cc
@@ -15,7 +15,7 @@
 struct gralloc0_module {
 	gralloc_module_t base;
 	std::unique_ptr<alloc_device_t> alloc;
-	std::unique_ptr<cros_gralloc_driver> driver;
+	cros_gralloc_driver *driver;
 	bool initialized;
 	std::mutex initialization_mutex;
 };
@@ -66,10 +66,10 @@
 // entirety, so we can detect the video decoder flag passed by IAllocator clients.
 #define BUFFER_USAGE_VIDEO_DECODER (1 << 22)
 
-// Reserve the GRALLOC_USAGE_PRIVATE_0 bit for buffers used for front rendering.
-// minigbm backend later decides to use BO_USE_FRONT_RENDERING or BO_USE_LINEAR
-// upon buffer allocaton.
-#define BUFFER_USAGE_FRONT_RENDERING GRALLOC_USAGE_PRIVATE_0
+// Gralloc0 doesn't define the BufferUsage::GPU_DATA_BUFFER flag. Define here to
+// align accordingly since AHardwareBuffer and Vulkan interop requires gralloc
+// to support allocating with AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER.
+#define BUFFER_USAGE_GPU_DATA_BUFFER (1 << 24)
 
 static uint64_t gralloc0_convert_usage(int usage)
 {
@@ -120,6 +120,8 @@
 		use_flags |= BO_USE_HW_VIDEO_DECODER;
 	if (usage & BUFFER_USAGE_FRONT_RENDERING)
 		use_flags |= BO_USE_FRONT_RENDERING;
+	if (usage & BUFFER_USAGE_GPU_DATA_BUFFER)
+		use_flags |= BO_USE_GPU_DATA_BUFFER;
 
 	return use_flags;
 }
@@ -217,11 +219,9 @@
 	if (mod->initialized)
 		return 0;
 
-	mod->driver = std::make_unique<cros_gralloc_driver>();
-	if (mod->driver->init()) {
-		drv_log("Failed to initialize driver.\n");
+	mod->driver = cros_gralloc_driver::get_instance();
+	if (!mod->driver)
 		return -ENODEV;
-	}
 
 	if (initialize_alloc) {
 		mod->alloc = std::make_unique<alloc_device_t>();
diff --git a/cros_gralloc/gralloc3/Android.bp b/cros_gralloc/gralloc3/Android.bp
index 5e66bec..ac6931f 100644
--- a/cros_gralloc/gralloc3/Android.bp
+++ b/cros_gralloc/gralloc3/Android.bp
@@ -52,6 +52,7 @@
     ],
 
     cflags: ["-Wno-sign-compare"],
+    relative_install_path: "hw",
 }
 
 cc_defaults {
@@ -65,12 +66,14 @@
 cc_binary {
     name: "android.hardware.graphics.allocator@3.0-service.minigbm",
     defaults: ["minigbm_gralloc3_allocator_defaults"],
+    shared_libs: ["libminigbm_gralloc"],
     init_rc: ["android.hardware.graphics.allocator@3.0-service.minigbm.rc"],
 }
 
 cc_library_shared {
     name: "android.hardware.graphics.mapper@3.0-impl.minigbm",
     defaults: ["minigbm_gralloc3_common_defaults"],
+    shared_libs: ["libminigbm_gralloc"],
 
     srcs: [":minigbm_gralloc3_mapper_files"],
 }
diff --git a/cros_gralloc/gralloc3/CrosGralloc3Allocator.cc b/cros_gralloc/gralloc3/CrosGralloc3Allocator.cc
index 57c49e9..65637bc 100644
--- a/cros_gralloc/gralloc3/CrosGralloc3Allocator.cc
+++ b/cros_gralloc/gralloc3/CrosGralloc3Allocator.cc
@@ -24,11 +24,9 @@
 using BufferDescriptorInfo =
         android::hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo;
 
-CrosGralloc3Allocator::CrosGralloc3Allocator() : mDriver(std::make_unique<cros_gralloc_driver>()) {
-    if (mDriver->init()) {
-        drv_log("Failed to initialize driver.\n");
-        mDriver = nullptr;
-    }
+Error CrosGralloc3Allocator::init() {
+    mDriver = cros_gralloc_driver::get_instance();
+    return mDriver ? Error::NONE : Error::NO_RESOURCES;
 }
 
 Error CrosGralloc3Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride,
diff --git a/cros_gralloc/gralloc3/CrosGralloc3Allocator.h b/cros_gralloc/gralloc3/CrosGralloc3Allocator.h
index 655143c..be5b5b9 100644
--- a/cros_gralloc/gralloc3/CrosGralloc3Allocator.h
+++ b/cros_gralloc/gralloc3/CrosGralloc3Allocator.h
@@ -11,12 +11,14 @@
 
 class CrosGralloc3Allocator : public android::hardware::graphics::allocator::V3_0::IAllocator {
   public:
-    CrosGralloc3Allocator();
+    CrosGralloc3Allocator() = default;
 
     android::hardware::Return<void> allocate(
             const android::hardware::hidl_vec<uint32_t>& descriptor, uint32_t count,
             allocate_cb hidl_cb) override;
 
+    android::hardware::graphics::mapper::V3_0::Error init();
+
     android::hardware::Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
 
   private:
@@ -25,5 +27,5 @@
                     description,
             uint32_t* outStride, android::hardware::hidl_handle* outHandle);
 
-    std::unique_ptr<cros_gralloc_driver> mDriver;
+    cros_gralloc_driver* mDriver = nullptr;
 };
diff --git a/cros_gralloc/gralloc3/CrosGralloc3AllocatorService.cc b/cros_gralloc/gralloc3/CrosGralloc3AllocatorService.cc
index daab508..6bde1d6 100644
--- a/cros_gralloc/gralloc3/CrosGralloc3AllocatorService.cc
+++ b/cros_gralloc/gralloc3/CrosGralloc3AllocatorService.cc
@@ -13,18 +13,22 @@
 using android::sp;
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
-using android::hardware::graphics::allocator::V3_0::IAllocator;
+using android::hardware::graphics::mapper::V3_0::Error;
 
 int main(int, char**) {
-    sp<IAllocator> allocator = new CrosGralloc3Allocator();
+    sp<CrosGralloc3Allocator> allocator = new CrosGralloc3Allocator();
+    if (allocator->init() != Error::NONE) {
+        ALOGE("Failed to initialize IAllocator 3.0 service.");
+        return -EINVAL;
+    }
     configureRpcThreadpool(4, true /* callerWillJoin */);
     if (allocator->registerAsService() != android::NO_ERROR) {
-        ALOGE("failed to register graphics IAllocator 3.0 service");
+        ALOGE("Failed to register graphics IAllocator 3.0 service.");
         return -EINVAL;
     }
 
-    ALOGI("graphics IAllocator 3.0 service is initialized");
+    ALOGI("IAllocator 3.0 service is initialized.");
     android::hardware::joinRpcThreadpool();
-    ALOGI("graphics IAllocator 3.0 service is terminating");
+    ALOGI("IAllocator 3.0 service is terminating.");
     return 0;
 }
diff --git a/cros_gralloc/gralloc3/CrosGralloc3Mapper.cc b/cros_gralloc/gralloc3/CrosGralloc3Mapper.cc
index 08da016..a0b19f0 100644
--- a/cros_gralloc/gralloc3/CrosGralloc3Mapper.cc
+++ b/cros_gralloc/gralloc3/CrosGralloc3Mapper.cc
@@ -23,13 +23,6 @@
 using android::hardware::graphics::mapper::V3_0::IMapper;
 using android::hardware::graphics::mapper::V3_0::YCbCrLayout;
 
-CrosGralloc3Mapper::CrosGralloc3Mapper() : mDriver(std::make_unique<cros_gralloc_driver>()) {
-    if (mDriver->init()) {
-        drv_log("Failed to initialize driver.\n");
-        mDriver = nullptr;
-    }
-}
-
 Return<void> CrosGralloc3Mapper::createDescriptor(const BufferDescriptorInfo& description,
                                                   createDescriptor_cb hidlCb) {
     hidl_vec<uint32_t> descriptor;
diff --git a/cros_gralloc/gralloc3/CrosGralloc3Mapper.h b/cros_gralloc/gralloc3/CrosGralloc3Mapper.h
index 7ec92d5..54db61e 100644
--- a/cros_gralloc/gralloc3/CrosGralloc3Mapper.h
+++ b/cros_gralloc/gralloc3/CrosGralloc3Mapper.h
@@ -13,7 +13,7 @@
 
 class CrosGralloc3Mapper : public android::hardware::graphics::mapper::V3_0::IMapper {
   public:
-    CrosGralloc3Mapper();
+    CrosGralloc3Mapper() = default;
 
     android::hardware::Return<void> createDescriptor(const BufferDescriptorInfo& description,
                                                      createDescriptor_cb hidlCb) override;
@@ -58,7 +58,7 @@
                             const Rect& accessRegion,
                             const android::hardware::hidl_handle& acquireFence);
 
-    std::unique_ptr<cros_gralloc_driver> mDriver;
+    cros_gralloc_driver* mDriver = cros_gralloc_driver::get_instance();
 };
 
 extern "C" android::hardware::graphics::mapper::V3_0::IMapper* HIDL_FETCH_IMapper(const char* name);
diff --git a/cros_gralloc/gralloc3/CrosGralloc3Utils.cc b/cros_gralloc/gralloc3/CrosGralloc3Utils.cc
index 3f39305..d15c431 100644
--- a/cros_gralloc/gralloc3/CrosGralloc3Utils.cc
+++ b/cros_gralloc/gralloc3/CrosGralloc3Utils.cc
@@ -157,6 +157,14 @@
         usage &= ~static_cast<Underlying>(BufferUsage::VIDEO_ENCODER);
         usages.push_back("BufferUsage::VIDEO_ENCODER");
     }
+    if (usage & BufferUsage::GPU_DATA_BUFFER) {
+        usage &= ~static_cast<Underlying>(BufferUsage::GPU_DATA_BUFFER);
+        usages.push_back("BufferUsage::GPU_DATA_BUFFER");
+    }
+    if (usage & BUFFER_USAGE_FRONT_RENDERING) {
+        usage &= ~static_cast<Underlying>(BUFFER_USAGE_FRONT_RENDERING);
+        usages.push_back("BUFFER_USAGE_FRONT_RENDERING");
+    }
 
     if (usage) {
         usages.push_back(android::base::StringPrintf("UnknownUsageBits-%" PRIu64, usage));
@@ -301,6 +309,12 @@
     if (grallocUsage & BufferUsage::VIDEO_DECODER) {
         bufferUsage |= BO_USE_HW_VIDEO_DECODER;
     }
+    if (grallocUsage & BufferUsage::GPU_DATA_BUFFER) {
+        bufferUsage |= BO_USE_GPU_DATA_BUFFER;
+    }
+    if (grallocUsage & BUFFER_USAGE_FRONT_RENDERING) {
+        bufferUsage |= BO_USE_FRONT_RENDERING;
+    }
 
     *outBufferUsage = bufferUsage;
     return 0;
diff --git a/cros_gralloc/gralloc4/Android.bp b/cros_gralloc/gralloc4/Android.bp
index 2ff1199..b9d94a9 100644
--- a/cros_gralloc/gralloc4/Android.bp
+++ b/cros_gralloc/gralloc4/Android.bp
@@ -53,6 +53,7 @@
     ],
 
     cflags: ["-Wno-sign-compare"],
+    relative_install_path: "hw",
 }
 
 cc_defaults {
@@ -66,6 +67,7 @@
 cc_binary {
     name: "android.hardware.graphics.allocator@4.0-service.minigbm",
     defaults: ["minigbm_gralloc4_allocator_defaults"],
+    shared_libs: ["libminigbm_gralloc"],
     vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"],
     init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm.rc"],
 }
@@ -73,25 +75,23 @@
 cc_binary {
     name: "android.hardware.graphics.allocator@4.0-service.minigbm_msm",
     defaults: ["minigbm_gralloc4_allocator_defaults"],
+    shared_libs: ["libminigbm_gralloc_msm"],
     vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"],
     init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm_msm.rc"],
-
-    cflags: ["-DDRV_MSM"],
 }
 
 cc_library_shared {
     name: "android.hardware.graphics.mapper@4.0-impl.minigbm",
     defaults: ["minigbm_gralloc4_common_defaults"],
+    shared_libs: ["libminigbm_gralloc"],
     vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"],
-
     srcs: [":minigbm_gralloc4_mapper_files"],
 }
 
 cc_library_shared {
     name: "android.hardware.graphics.mapper@4.0-impl.minigbm_msm",
     defaults: ["minigbm_gralloc4_common_defaults"],
+    shared_libs: ["libminigbm_gralloc_msm"],
     vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"],
-
-    cflags: ["-DDRV_MSM"],
     srcs: [":minigbm_gralloc4_mapper_files"],
 }
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc
index e7e5f3a..3f77b54 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.cc
@@ -23,11 +23,9 @@
 using BufferDescriptorInfo =
         android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
 
-CrosGralloc4Allocator::CrosGralloc4Allocator() : mDriver(std::make_unique<cros_gralloc_driver>()) {
-    if (mDriver->init()) {
-        drv_log("Failed to initialize driver.\n");
-        mDriver = nullptr;
-    }
+Error CrosGralloc4Allocator::init() {
+    mDriver = cros_gralloc_driver::get_instance();
+    return mDriver ? Error::NONE : Error::NO_RESOURCES;
 }
 
 Error CrosGralloc4Allocator::allocate(const BufferDescriptorInfo& descriptor, uint32_t* outStride,
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h
index 21ad7ad..1555a61 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Allocator.h
+++ b/cros_gralloc/gralloc4/CrosGralloc4Allocator.h
@@ -11,16 +11,18 @@
 
 class CrosGralloc4Allocator : public android::hardware::graphics::allocator::V4_0::IAllocator {
   public:
-    CrosGralloc4Allocator();
+    CrosGralloc4Allocator() = default;
 
     android::hardware::Return<void> allocate(const android::hardware::hidl_vec<uint8_t>& descriptor,
                                              uint32_t count, allocate_cb hidl_cb) override;
 
+    android::hardware::graphics::mapper::V4_0::Error init();
+
   private:
     android::hardware::graphics::mapper::V4_0::Error allocate(
             const android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo&
                     description,
             uint32_t* outStride, android::hardware::hidl_handle* outHandle);
 
-    std::unique_ptr<cros_gralloc_driver> mDriver;
+    cros_gralloc_driver* mDriver = nullptr;
 };
diff --git a/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc b/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc
index 5b79860..99bc92e 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4AllocatorService.cc
@@ -13,18 +13,23 @@
 using android::sp;
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
-using android::hardware::graphics::allocator::V4_0::IAllocator;
+using android::hardware::graphics::mapper::V4_0::Error;
 
 int main(int, char**) {
-    sp<IAllocator> allocator = new CrosGralloc4Allocator();
-    configureRpcThreadpool(4, true /* callerWillJoin */);
-    if (allocator->registerAsService() != android::NO_ERROR) {
-        ALOGE("failed to register graphics IAllocator 4.0 service");
+    sp<CrosGralloc4Allocator> allocator = new CrosGralloc4Allocator();
+    if (allocator->init() != Error::NONE) {
+        ALOGE("Failed to initialize IAllocator 4.0 service.");
         return -EINVAL;
     }
 
-    ALOGI("graphics IAllocator 4.0 service is initialized");
+    configureRpcThreadpool(4, true /* callerWillJoin */);
+    if (allocator->registerAsService() != android::NO_ERROR) {
+        ALOGE("Failed to register graphics IAllocator 4.0 service.");
+        return -EINVAL;
+    }
+
+    ALOGI("IAllocator 4.0 service is initialized.");
     android::hardware::joinRpcThreadpool();
-    ALOGI("graphics IAllocator 4.0 service is terminating");
+    ALOGI("IAllocator 4.0 service is terminating.");
     return 0;
 }
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc
index 1bfd442..807eba1 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.cc
@@ -31,62 +31,6 @@
 using android::hardware::graphics::mapper::V4_0::Error;
 using android::hardware::graphics::mapper::V4_0::IMapper;
 
-namespace {
-
-// Provides a single instance of cros_gralloc_driver to all active instances of
-// CrosGralloc4Mapper in a single process while destroying the cros_gralloc_driver
-// when there are no active instances of CrosGralloc4Mapper.
-class DriverProvider {
-  public:
-    static DriverProvider* Get() {
-        static DriverProvider* instance = new DriverProvider();
-        return instance;
-    }
-
-    cros_gralloc_driver* GetAndReferenceDriver() {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (!mDriver) {
-            mDriver = std::make_unique<cros_gralloc_driver>();
-            if (mDriver->init()) {
-                drv_log("Failed to initialize driver.\n");
-                mDriver.reset();
-                return nullptr;
-            }
-        }
-
-        ++mReferenceCount;
-        return mDriver.get();
-    }
-
-    void UnreferenceDriver() {
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        --mReferenceCount;
-
-        if (mReferenceCount == 0) {
-            mDriver.reset();
-        }
-    }
-
-  private:
-    DriverProvider() = default;
-
-    std::mutex mMutex;
-    std::unique_ptr<cros_gralloc_driver> mDriver;
-    std::size_t mReferenceCount = 0;
-};
-
-}  // namespace
-
-CrosGralloc4Mapper::CrosGralloc4Mapper() {
-    mDriver = DriverProvider::Get()->GetAndReferenceDriver();
-}
-
-CrosGralloc4Mapper::~CrosGralloc4Mapper() {
-    mDriver = nullptr;
-    DriverProvider::Get()->UnreferenceDriver();
-}
-
 Return<void> CrosGralloc4Mapper::createDescriptor(const BufferDescriptorInfo& description,
                                                   createDescriptor_cb hidlCb) {
     hidl_vec<uint8_t> descriptor;
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h
index 3c159a2..0641b29 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Mapper.h
+++ b/cros_gralloc/gralloc4/CrosGralloc4Mapper.h
@@ -11,8 +11,7 @@
 
 class CrosGralloc4Mapper : public android::hardware::graphics::mapper::V4_0::IMapper {
   public:
-    CrosGralloc4Mapper();
-    ~CrosGralloc4Mapper();
+    CrosGralloc4Mapper() = default;
 
     android::hardware::Return<void> createDescriptor(const BufferDescriptorInfo& description,
                                                      createDescriptor_cb hidlCb) override;
@@ -75,7 +74,7 @@
     int getResolvedDrmFormat(android::hardware::graphics::common::V1_2::PixelFormat pixelFormat,
                              uint64_t bufferUsage, uint32_t* outDrmFormat);
 
-    cros_gralloc_driver* mDriver = nullptr;
+    cros_gralloc_driver* mDriver = cros_gralloc_driver::get_instance();
 };
 
 extern "C" android::hardware::graphics::mapper::V4_0::IMapper* HIDL_FETCH_IMapper(const char* name);
diff --git a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
index 9bc27cb..e2940cc 100644
--- a/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
+++ b/cros_gralloc/gralloc4/CrosGralloc4Utils.cc
@@ -161,6 +161,14 @@
         usage &= ~static_cast<Underlying>(BufferUsage::VIDEO_ENCODER);
         usages.push_back("BufferUsage::VIDEO_ENCODER");
     }
+    if (usage & BufferUsage::GPU_DATA_BUFFER) {
+        usage &= ~static_cast<Underlying>(BufferUsage::GPU_DATA_BUFFER);
+        usages.push_back("BufferUsage::GPU_DATA_BUFFER");
+    }
+    if (usage & BUFFER_USAGE_FRONT_RENDERING) {
+        usage &= ~static_cast<Underlying>(BUFFER_USAGE_FRONT_RENDERING);
+        usages.push_back("BUFFER_USAGE_FRONT_RENDERING");
+    }
 
     if (usage) {
         usages.push_back(android::base::StringPrintf("UnknownUsageBits-%" PRIu64, usage));
@@ -305,6 +313,12 @@
     if (grallocUsage & BufferUsage::VIDEO_DECODER) {
         bufferUsage |= BO_USE_HW_VIDEO_DECODER;
     }
+    if (grallocUsage & BufferUsage::GPU_DATA_BUFFER) {
+        bufferUsage |= BO_USE_GPU_DATA_BUFFER;
+    }
+    if (grallocUsage & BUFFER_USAGE_FRONT_RENDERING) {
+        bufferUsage |= BO_USE_FRONT_RENDERING;
+    }
 
     *outBufferUsage = bufferUsage;
     return 0;
diff --git a/dri.c b/dri.c
index 13d4833..12e6a30 100644
--- a/dri.c
+++ b/dri.c
@@ -196,8 +196,12 @@
 	const __DRIextension *loader_extensions[] = { NULL };
 
 	struct dri_driver *dri = drv->priv;
+	char *node_name = drmGetRenderDeviceNameFromFd(drv_get_fd(drv));
+	if (!node_name)
+		return -ENODEV;
 
-	dri->fd = open(drmGetRenderDeviceNameFromFd(drv_get_fd(drv)), O_RDWR);
+	dri->fd = open(node_name, O_RDWR);
+	free(node_name);
 	if (dri->fd < 0)
 		return -ENODEV;
 
diff --git a/drv.h b/drv.h
index 4689558..29c1334 100644
--- a/drv.h
+++ b/drv.h
@@ -39,6 +39,7 @@
 #define BO_USE_TEST_ALLOC		(1ull << 15)
 #define BO_USE_FRONT_RENDERING		(1ull << 16)
 #define BO_USE_RENDERSCRIPT		(1ull << 17)
+#define BO_USE_GPU_DATA_BUFFER		(1ull << 18)
 
 /* Quirks for allocating a buffer. */
 #define BO_QUIRK_NONE			0
diff --git a/i915.c b/i915.c
index 9de38b2..fe2b20c 100644
--- a/i915.c
+++ b/i915.c
@@ -37,9 +37,6 @@
 static const uint64_t gen_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED,
 					       I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR };
 
-static const uint64_t gen11_modifier_order[] = { I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
-						 DRM_FORMAT_MOD_LINEAR };
-
 struct modifier_support_t {
 	const uint64_t *order;
 	uint32_t count;
@@ -61,10 +58,9 @@
 	const uint16_t gen11_ids[] = { 0x4E71, 0x4E61, 0x4E51, 0x4E55, 0x4E57 };
 	const uint16_t gen12_ids[] = { 0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68, 0x9A70,
 				       0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8 };
-	const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6,
-				      0x46A8, 0x46AA, 0x462A, 0x4626, 0x4628,
-				      0x46B0, 0x46B1, 0x46B2, 0x46B3, 0x46C0,
-				      0x46C1, 0x46C2, 0x46C3 };
+	const uint16_t adlp_ids[] = { 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8,
+				      0x46AA, 0x462A, 0x4626, 0x4628, 0x46B0, 0x46B1,
+				      0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3 };
 	unsigned i;
 	i915->gen = 4;
 	i915->is_adlp = false;
@@ -92,13 +88,8 @@
 
 static void i915_get_modifier_order(struct i915_device *i915)
 {
-	if (i915->gen == 11) {
-		i915->modifier.order = gen11_modifier_order;
-		i915->modifier.count = ARRAY_SIZE(gen11_modifier_order);
-	} else {
-		i915->modifier.order = gen_modifier_order;
-		i915->modifier.count = ARRAY_SIZE(gen_modifier_order);
-	}
+	i915->modifier.order = gen_modifier_order;
+	i915->modifier.count = ARRAY_SIZE(gen_modifier_order);
 }
 
 static uint64_t unset_flags(uint64_t current_flags, uint64_t mask)
@@ -251,7 +242,7 @@
 
 	/* stride must be power-of-two aligned for ADL-P tiled buffers*/
 	if (i915->is_adlp && (*stride > 1) && (tiling != I915_TILING_NONE))
-		*stride = 1 << (32 - __builtin_clz(*stride -1));
+		*stride = 1 << (32 - __builtin_clz(*stride - 1));
 
 	if (i915->gen <= 3 && *stride > 8192)
 		return -EINVAL;
@@ -316,7 +307,8 @@
  * to the largest coded unit (LCU) assuming that it will be used for video. This
  * is based on gmmlib's GmmIsYUVFormatLCUAligned().
  */
-static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane, const struct i915_device* i915)
+static bool i915_format_needs_LCU_alignment(uint32_t format, size_t plane,
+					    const struct i915_device *i915)
 {
 	switch (format) {
 	case DRM_FORMAT_NV12:
diff --git a/virtgpu_virgl.c b/virtgpu_virgl.c
index 32ca6a1..5b74744 100644
--- a/virtgpu_virgl.c
+++ b/virtgpu_virgl.c
@@ -63,6 +63,8 @@
 		return VIRGL_FORMAT_R8G8B8A8_UNORM;
 	case DRM_FORMAT_ABGR16161616F:
 		return VIRGL_FORMAT_R16G16B16A16_FLOAT;
+	case DRM_FORMAT_ABGR2101010:
+		return VIRGL_FORMAT_R10G10B10A2_UNORM;
 	case DRM_FORMAT_RGB565:
 		return VIRGL_FORMAT_B5G6R5_UNORM;
 	case DRM_FORMAT_R8:
@@ -391,6 +393,8 @@
 	handle_flag(&use_flags, BO_USE_SCANOUT, &bind, VIRGL_BIND_SCANOUT);
 	handle_flag(&use_flags, BO_USE_CURSOR, &bind, VIRGL_BIND_CURSOR);
 	handle_flag(&use_flags, BO_USE_LINEAR, &bind, VIRGL_BIND_LINEAR);
+	handle_flag(&use_flags, BO_USE_GPU_DATA_BUFFER, &bind, VIRGL_BIND_LINEAR);
+	handle_flag(&use_flags, BO_USE_FRONT_RENDERING, &bind, VIRGL_BIND_LINEAR);
 
 	if (use_flags & BO_USE_PROTECTED) {
 		handle_flag(&use_flags, BO_USE_PROTECTED, &bind, VIRGL_BIND_MINIGBM_PROTECTED);
@@ -612,14 +616,13 @@
 	virgl_add_combination(drv, DRM_FORMAT_ABGR2101010, &LINEAR_METADATA,
 			      BO_USE_SW_MASK | BO_USE_TEXTURE_MASK);
 	virgl_add_combination(drv, DRM_FORMAT_P010, &LINEAR_METADATA,
-				   BO_USE_SW_MASK | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
-
+			      BO_USE_SW_MASK | BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
 	drv_modify_combination(drv, DRM_FORMAT_NV12, &LINEAR_METADATA,
 			       BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
 				   BO_USE_HW_VIDEO_ENCODER);
 	drv_modify_combination(drv, DRM_FORMAT_R8, &LINEAR_METADATA,
 			       BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE | BO_USE_HW_VIDEO_DECODER |
-				   BO_USE_HW_VIDEO_ENCODER);
+				   BO_USE_HW_VIDEO_ENCODER | BO_USE_GPU_DATA_BUFFER);
 
 	if (!priv->host_gbm_enabled) {
 		drv_modify_combination(drv, DRM_FORMAT_ABGR8888, &LINEAR_METADATA,
@@ -714,9 +717,10 @@
 	if (!priv->host_gbm_enabled)
 		return false;
 
-	// Use regular resources if only the GPU needs efficient access
-	if (!(use_flags &
-	      (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | BO_USE_LINEAR | BO_USE_NON_GPU_HW)))
+	// Use regular resources if only the GPU needs efficient access. Blob resource is a better
+	// fit for BO_USE_GPU_DATA_BUFFER which is mapped to VIRGL_BIND_LINEAR.
+	if (!(use_flags & (BO_USE_SW_READ_OFTEN | BO_USE_SW_WRITE_OFTEN | BO_USE_LINEAR |
+			   BO_USE_NON_GPU_HW | BO_USE_GPU_DATA_BUFFER)))
 		return false;
 
 	switch (format) {