minigbm: add GRALLOC_DRM_GET_USAGE query
Low-latency stylus support requires EGL_KHR_mutable_render_buffer, and
front rendering support in mesa requires the bo to be shared between gpu
and composer simultaneously. Either BO_USE_FRONT_RENDERING or forcing
linear with BO_USE_LINEAR is needed upon bo allocation. This change adds
a way for the client to inform gralloc of such info so that the minigbm
backend can choose the proper bo use flags upon allocation.
BUG=b:183507528
TEST=dEQP-EGL.functional.mutable_render_buffer.*
TEST=tast run $DUT arc.Gralloc.vm
Change-Id: Id7da33cea7d62aa9ae035ee3a6767f87874cb6ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2895370
Tested-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Commit-Queue: Yiwei Zhang <zzyiwei@chromium.org>
diff --git a/cros_gralloc/gralloc0/gralloc0.cc b/cros_gralloc/gralloc0/gralloc0.cc
index e8b5f7c..078ec24 100644
--- a/cros_gralloc/gralloc0/gralloc0.cc
+++ b/cros_gralloc/gralloc0/gralloc0.cc
@@ -42,6 +42,22 @@
GRALLOC_DRM_GET_DIMENSIONS,
GRALLOC_DRM_GET_BACKING_STORE,
GRALLOC_DRM_GET_BUFFER_INFO,
+ GRALLOC_DRM_GET_USAGE,
+};
+
+/* This enumeration corresponds to the GRALLOC_DRM_GET_USAGE query op, which
+ * defines a set of bit flags used by the client to query vendor usage bits.
+ *
+ * Here is the common flow:
+ * 1) EGL/Vulkan calls GRALLOC_DRM_GET_USAGE to append one or multiple vendor
+ * usage bits to the existing usage and sets onto the ANativeWindow.
+ * 2) Some implicit GL draw cmd or the explicit vkCreateSwapchainKHR kicks off
+ * the next dequeueBuffer on the ANativeWindow with the combined usage.
+ * 3) dequeueBuffer then asks gralloc hal for an allocation/re-allocation, and
+ * calls into the below `gralloc0_alloc(...)` api.
+ */
+enum {
+ GRALLOC_DRM_GET_USAGE_FRONT_RENDERING_BIT = 0x00000001,
};
// clang-format on
@@ -50,6 +66,11 @@
// 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
+
static uint64_t gralloc0_convert_usage(int usage)
{
uint64_t use_flags = BO_USE_NONE;
@@ -97,6 +118,8 @@
use_flags |= BO_USE_RENDERSCRIPT;
if (usage & BUFFER_USAGE_VIDEO_DECODER)
use_flags |= BO_USE_HW_VIDEO_DECODER;
+ if (usage & BUFFER_USAGE_FRONT_RENDERING)
+ use_flags |= BO_USE_FRONT_RENDERING;
return use_flags;
}
@@ -151,6 +174,11 @@
drv_log("Retrying format %u allocation without encoder flag", format);
supported = mod->driver->is_supported(&descriptor);
}
+ if (!supported && (usage & BUFFER_USAGE_FRONT_RENDERING)) {
+ descriptor.use_flags &= ~BO_USE_FRONT_RENDERING;
+ descriptor.use_flags |= BO_USE_LINEAR;
+ supported = mod->driver->is_supported(&descriptor);
+ }
if (!supported) {
drv_log("Unsupported combination -- HAL format: %u, HAL usage: %u, "
@@ -276,12 +304,18 @@
int32_t *out_format, ret;
uint64_t *out_store;
buffer_handle_t handle;
+ cros_gralloc_handle_t hnd;
uint32_t *out_width, *out_height, *out_stride;
uint32_t strides[DRV_MAX_PLANES] = { 0, 0, 0, 0 };
uint32_t offsets[DRV_MAX_PLANES] = { 0, 0, 0, 0 };
uint64_t format_modifier = 0;
struct cros_gralloc0_buffer_info *info;
auto mod = (struct gralloc0_module const *)module;
+ uint32_t req_usage;
+ uint32_t gralloc_usage = 0;
+ uint32_t *out_gralloc_usage;
+
+ va_start(args, op);
switch (op) {
case GRALLOC_DRM_GET_STRIDE:
@@ -289,21 +323,23 @@
case GRALLOC_DRM_GET_DIMENSIONS:
case GRALLOC_DRM_GET_BACKING_STORE:
case GRALLOC_DRM_GET_BUFFER_INFO:
+ /* retrieve handles for ops with buffer_handle_t */
+ handle = va_arg(args, buffer_handle_t);
+ hnd = cros_gralloc_convert_handle(handle);
+ if (!hnd) {
+ va_end(args);
+ drv_log("Invalid handle.\n");
+ return -EINVAL;
+ }
+ break;
+ case GRALLOC_DRM_GET_USAGE:
break;
default:
+ va_end(args);
return -EINVAL;
}
- va_start(args, op);
-
ret = 0;
- handle = va_arg(args, buffer_handle_t);
- auto hnd = cros_gralloc_convert_handle(handle);
- if (!hnd) {
- drv_log("Invalid handle.\n");
- return -EINVAL;
- }
-
switch (op) {
case GRALLOC_DRM_GET_STRIDE:
out_stride = va_arg(args, uint32_t *);
@@ -353,6 +389,13 @@
}
}
break;
+ case GRALLOC_DRM_GET_USAGE:
+ req_usage = va_arg(args, uint32_t);
+ out_gralloc_usage = va_arg(args, uint32_t *);
+ if (req_usage & GRALLOC_DRM_GET_USAGE_FRONT_RENDERING_BIT)
+ gralloc_usage |= BUFFER_USAGE_FRONT_RENDERING;
+ *out_gralloc_usage = gralloc_usage;
+ break;
default:
ret = -EINVAL;
}