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>
This commit is contained in:
parent
8ed9b31127
commit
cd6e63c123
2 changed files with 71 additions and 10 deletions
|
|
@ -42,6 +42,22 @@ enum {
|
|||
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 @@ enum {
|
|||
// 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 @@ static uint64_t gralloc0_convert_usage(int usage)
|
|||
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 @@ static int gralloc0_alloc(alloc_device_t *dev, int w, int h, int format, int usa
|
|||
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 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
|
|||
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 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
|
|||
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 @@ static int gralloc0_perform(struct gralloc_module_t const *module, int op, ...)
|
|||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,12 +41,20 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define BUFFER_USAGE_FRONT_RENDERING GRALLOC_USAGE_PRIVATE_0
|
||||
|
||||
/* Private API enumeration -- see <gralloc_drm.h> */
|
||||
enum {
|
||||
GRALLOC_DRM_GET_STRIDE,
|
||||
GRALLOC_DRM_GET_FORMAT,
|
||||
GRALLOC_DRM_GET_DIMENSIONS,
|
||||
GRALLOC_DRM_GET_BACKING_STORE,
|
||||
GRALLOC_DRM_GET_BUFFER_INFO,
|
||||
GRALLOC_DRM_GET_USAGE,
|
||||
};
|
||||
|
||||
enum {
|
||||
GRALLOC_DRM_GET_USAGE_FRONT_RENDERING_BIT = 0x00000001,
|
||||
};
|
||||
|
||||
struct gralloctest_context {
|
||||
|
|
@ -467,7 +475,7 @@ static int test_perform(struct gralloctest_context *ctx)
|
|||
{
|
||||
int32_t format;
|
||||
uint64_t id1, id2;
|
||||
uint32_t stride, width, height;
|
||||
uint32_t stride, width, height, req_usage, gralloc_usage;
|
||||
struct grallocinfo info, duplicate;
|
||||
struct gralloc_module_t *mod = ctx->module;
|
||||
|
||||
|
|
@ -498,6 +506,16 @@ static int test_perform(struct gralloctest_context *ctx)
|
|||
CHECK(unregister_buffer(mod, &duplicate));
|
||||
CHECK(deallocate(ctx->device, &info));
|
||||
|
||||
req_usage = 0;
|
||||
gralloc_usage = 0;
|
||||
CHECK(mod->perform(mod, GRALLOC_DRM_GET_USAGE, req_usage, &gralloc_usage) == 0);
|
||||
CHECK(gralloc_usage == 0);
|
||||
|
||||
req_usage = GRALLOC_DRM_GET_USAGE_FRONT_RENDERING_BIT;
|
||||
gralloc_usage = 0;
|
||||
CHECK(mod->perform(mod, GRALLOC_DRM_GET_USAGE, req_usage, &gralloc_usage) == 0);
|
||||
CHECK(gralloc_usage == BUFFER_USAGE_FRONT_RENDERING);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue