gl-renderer: query EGL to determine if GL_TEXTURE_EXTERNAL_OES should be used
Using the number of planes to determine if GL_TEXTURE_EXTERNAL_OES should be used is incorrect with some modifiers: For example RGBA with a I915_FORMAT_MOD_Y_TILED_CCS modifier has two planes. Use eglQueryDmaBufModifiersEXT() to query if the current format/modifier only supports GL_TEXTURE_EXTERNAL_OES. Use the current code as fallback of modifiers are not supported. Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
This commit is contained in:
committed by
Daniel Stone
parent
f6bd212924
commit
40c519a3e6
@@ -89,6 +89,7 @@ struct gl_renderer {
|
|||||||
|
|
||||||
bool has_dmabuf_import;
|
bool has_dmabuf_import;
|
||||||
struct wl_list dmabuf_images;
|
struct wl_list dmabuf_images;
|
||||||
|
struct wl_list dmabuf_formats;
|
||||||
|
|
||||||
bool has_gl_texture_rg;
|
bool has_gl_texture_rg;
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,15 @@ struct dmabuf_image {
|
|||||||
struct gl_shader *shader;
|
struct gl_shader *shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dmabuf_format {
|
||||||
|
uint32_t format;
|
||||||
|
struct wl_list link;
|
||||||
|
|
||||||
|
uint64_t *modifiers;
|
||||||
|
unsigned *external_only;
|
||||||
|
int num_modifiers;
|
||||||
|
};
|
||||||
|
|
||||||
struct yuv_plane_descriptor {
|
struct yuv_plane_descriptor {
|
||||||
int width_divisor;
|
int width_divisor;
|
||||||
int height_divisor;
|
int height_divisor;
|
||||||
@@ -2219,9 +2228,75 @@ import_yuv_dmabuf(struct gl_renderer *gr,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLenum
|
static void
|
||||||
choose_texture_target(struct dmabuf_attributes *attributes)
|
gl_renderer_query_dmabuf_modifiers_full(struct gl_renderer *gr, int format,
|
||||||
|
uint64_t **modifiers,
|
||||||
|
unsigned **external_only,
|
||||||
|
int *num_modifiers);
|
||||||
|
|
||||||
|
static struct dmabuf_format*
|
||||||
|
dmabuf_format_create(struct gl_renderer *gr, uint32_t format)
|
||||||
{
|
{
|
||||||
|
struct dmabuf_format *dmabuf_format;
|
||||||
|
|
||||||
|
dmabuf_format = calloc(1, sizeof(struct dmabuf_format));
|
||||||
|
if (!dmabuf_format)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dmabuf_format->format = format;
|
||||||
|
|
||||||
|
gl_renderer_query_dmabuf_modifiers_full(gr, format,
|
||||||
|
&dmabuf_format->modifiers,
|
||||||
|
&dmabuf_format->external_only,
|
||||||
|
&dmabuf_format->num_modifiers);
|
||||||
|
|
||||||
|
if (dmabuf_format->num_modifiers == 0) {
|
||||||
|
free(dmabuf_format);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_list_insert(&gr->dmabuf_formats, &dmabuf_format->link);
|
||||||
|
return dmabuf_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dmabuf_format_destroy(struct dmabuf_format *format)
|
||||||
|
{
|
||||||
|
free(format->modifiers);
|
||||||
|
free(format->external_only);
|
||||||
|
wl_list_remove(&format->link);
|
||||||
|
free(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLenum
|
||||||
|
choose_texture_target(struct gl_renderer *gr,
|
||||||
|
struct dmabuf_attributes *attributes)
|
||||||
|
{
|
||||||
|
struct dmabuf_format *tmp, *format = NULL;
|
||||||
|
|
||||||
|
wl_list_for_each(tmp, &gr->dmabuf_formats, link) {
|
||||||
|
if (tmp->format == attributes->format) {
|
||||||
|
format = tmp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!format)
|
||||||
|
format = dmabuf_format_create(gr, attributes->format);
|
||||||
|
|
||||||
|
if (format) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < format->num_modifiers; ++i) {
|
||||||
|
if (format->modifiers[i] == attributes->modifier[0]) {
|
||||||
|
if(format->external_only[i])
|
||||||
|
return GL_TEXTURE_EXTERNAL_OES;
|
||||||
|
else
|
||||||
|
return GL_TEXTURE_2D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (attributes->n_planes > 1)
|
if (attributes->n_planes > 1)
|
||||||
return GL_TEXTURE_EXTERNAL_OES;
|
return GL_TEXTURE_EXTERNAL_OES;
|
||||||
|
|
||||||
@@ -2253,7 +2328,7 @@ import_dmabuf(struct gl_renderer *gr,
|
|||||||
image->num_images = 1;
|
image->num_images = 1;
|
||||||
image->images[0] = egl_image;
|
image->images[0] = egl_image;
|
||||||
image->import_type = IMPORT_TYPE_DIRECT;
|
image->import_type = IMPORT_TYPE_DIRECT;
|
||||||
image->target = choose_texture_target(&dmabuf->attributes);
|
image->target = choose_texture_target(gr, &dmabuf->attributes);
|
||||||
|
|
||||||
switch (image->target) {
|
switch (image->target) {
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
@@ -2321,11 +2396,11 @@ gl_renderer_query_dmabuf_formats(struct weston_compositor *wc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gl_renderer_query_dmabuf_modifiers(struct weston_compositor *wc, int format,
|
gl_renderer_query_dmabuf_modifiers_full(struct gl_renderer *gr, int format,
|
||||||
uint64_t **modifiers,
|
uint64_t **modifiers,
|
||||||
|
unsigned **external_only,
|
||||||
int *num_modifiers)
|
int *num_modifiers)
|
||||||
{
|
{
|
||||||
struct gl_renderer *gr = get_renderer(wc);
|
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
assert(gr->has_dmabuf_import);
|
assert(gr->has_dmabuf_import);
|
||||||
@@ -2343,16 +2418,38 @@ gl_renderer_query_dmabuf_modifiers(struct weston_compositor *wc, int format,
|
|||||||
*num_modifiers = 0;
|
*num_modifiers = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (external_only) {
|
||||||
|
*external_only = calloc(num, sizeof(unsigned));
|
||||||
|
if (*external_only == NULL) {
|
||||||
|
*num_modifiers = 0;
|
||||||
|
free(*modifiers);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!gr->query_dmabuf_modifiers(gr->egl_display, format,
|
if (!gr->query_dmabuf_modifiers(gr->egl_display, format,
|
||||||
num, *modifiers, NULL, &num)) {
|
num, *modifiers, external_only ?
|
||||||
|
*external_only : NULL, &num)) {
|
||||||
*num_modifiers = 0;
|
*num_modifiers = 0;
|
||||||
free(*modifiers);
|
free(*modifiers);
|
||||||
|
if (external_only)
|
||||||
|
free(*external_only);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*num_modifiers = num;
|
*num_modifiers = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gl_renderer_query_dmabuf_modifiers(struct weston_compositor *wc, int format,
|
||||||
|
uint64_t **modifiers,
|
||||||
|
int *num_modifiers)
|
||||||
|
{
|
||||||
|
struct gl_renderer *gr = get_renderer(wc);
|
||||||
|
|
||||||
|
gl_renderer_query_dmabuf_modifiers_full(gr, format, modifiers, NULL,
|
||||||
|
num_modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
gl_renderer_import_dmabuf(struct weston_compositor *ec,
|
gl_renderer_import_dmabuf(struct weston_compositor *ec,
|
||||||
struct linux_dmabuf_buffer *dmabuf)
|
struct linux_dmabuf_buffer *dmabuf)
|
||||||
@@ -3289,6 +3386,7 @@ gl_renderer_destroy(struct weston_compositor *ec)
|
|||||||
{
|
{
|
||||||
struct gl_renderer *gr = get_renderer(ec);
|
struct gl_renderer *gr = get_renderer(ec);
|
||||||
struct dmabuf_image *image, *next;
|
struct dmabuf_image *image, *next;
|
||||||
|
struct dmabuf_format *format, *next_format;
|
||||||
|
|
||||||
wl_signal_emit(&gr->destroy_signal, gr);
|
wl_signal_emit(&gr->destroy_signal, gr);
|
||||||
|
|
||||||
@@ -3304,6 +3402,9 @@ gl_renderer_destroy(struct weston_compositor *ec)
|
|||||||
wl_list_for_each_safe(image, next, &gr->dmabuf_images, link)
|
wl_list_for_each_safe(image, next, &gr->dmabuf_images, link)
|
||||||
dmabuf_image_destroy(image);
|
dmabuf_image_destroy(image);
|
||||||
|
|
||||||
|
wl_list_for_each_safe(format, next_format, &gr->dmabuf_formats, link)
|
||||||
|
dmabuf_format_destroy(format);
|
||||||
|
|
||||||
if (gr->dummy_surface != EGL_NO_SURFACE)
|
if (gr->dummy_surface != EGL_NO_SURFACE)
|
||||||
weston_platform_destroy_egl_surface(gr->egl_display,
|
weston_platform_destroy_egl_surface(gr->egl_display,
|
||||||
gr->dummy_surface);
|
gr->dummy_surface);
|
||||||
@@ -3432,6 +3533,7 @@ gl_renderer_display_create(struct weston_compositor *ec,
|
|||||||
gr->base.query_dmabuf_modifiers =
|
gr->base.query_dmabuf_modifiers =
|
||||||
gl_renderer_query_dmabuf_modifiers;
|
gl_renderer_query_dmabuf_modifiers;
|
||||||
}
|
}
|
||||||
|
wl_list_init(&gr->dmabuf_formats);
|
||||||
|
|
||||||
if (gr->has_surfaceless_context) {
|
if (gr->has_surfaceless_context) {
|
||||||
weston_log("EGL_KHR_surfaceless_context available\n");
|
weston_log("EGL_KHR_surfaceless_context available\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user