gl-renderer: Store dmabuf buffer state in weston_buffer
Similarly to EGL buffers, store the gl_buffer_state for a dmabuf buffer inside weston_buffer, rather than on the linux_dmabuf_buffer. This slightly simplifies our gl_buffer_state handling, and will be used later to eliminate the egl_image refcounting. Signed-off-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
@@ -114,16 +114,6 @@ struct egl_image {
|
|||||||
int refcount;
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct dmabuf_image {
|
|
||||||
struct linux_dmabuf_buffer *dmabuf;
|
|
||||||
int num_images;
|
|
||||||
struct egl_image *images[3];
|
|
||||||
struct wl_list link;
|
|
||||||
|
|
||||||
enum gl_shader_texture_variant shader_variant;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dmabuf_format {
|
struct dmabuf_format {
|
||||||
uint32_t format;
|
uint32_t format;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
@@ -403,32 +393,6 @@ egl_image_unref(struct egl_image *image)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dmabuf_image*
|
|
||||||
dmabuf_image_create(void)
|
|
||||||
{
|
|
||||||
struct dmabuf_image *img;
|
|
||||||
|
|
||||||
img = zalloc(sizeof *img);
|
|
||||||
wl_list_init(&img->link);
|
|
||||||
|
|
||||||
return img;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
dmabuf_image_destroy(struct dmabuf_image *image)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < image->num_images; ++i)
|
|
||||||
egl_image_unref(image->images[i]);
|
|
||||||
|
|
||||||
if (image->dmabuf)
|
|
||||||
linux_dmabuf_buffer_set_user_data(image->dmabuf, NULL, NULL);
|
|
||||||
|
|
||||||
wl_list_remove(&image->link);
|
|
||||||
free(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
#define max(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
#define min(a, b) (((a) > (b)) ? (b) : (a))
|
#define min(a, b) (((a) > (b)) ? (b) : (a))
|
||||||
|
|
||||||
@@ -2347,9 +2311,11 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer)
|
|||||||
static void
|
static void
|
||||||
gl_renderer_destroy_dmabuf(struct linux_dmabuf_buffer *dmabuf)
|
gl_renderer_destroy_dmabuf(struct linux_dmabuf_buffer *dmabuf)
|
||||||
{
|
{
|
||||||
struct dmabuf_image *image = linux_dmabuf_buffer_get_user_data(dmabuf);
|
struct gl_buffer_state *gb =
|
||||||
|
linux_dmabuf_buffer_get_user_data(dmabuf);
|
||||||
|
|
||||||
dmabuf_image_destroy(image);
|
linux_dmabuf_buffer_set_user_data(dmabuf, NULL, NULL);
|
||||||
|
destroy_buffer_state(gb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct egl_image *
|
static struct egl_image *
|
||||||
@@ -2573,14 +2539,13 @@ import_dmabuf_single_plane(struct gl_renderer *gr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
import_yuv_dmabuf(struct gl_renderer *gr,
|
import_yuv_dmabuf(struct gl_renderer *gr, struct gl_buffer_state *gb,
|
||||||
struct dmabuf_image *image)
|
struct dmabuf_attributes *attributes)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int j;
|
int j;
|
||||||
int ret;
|
int ret;
|
||||||
struct yuv_format_descriptor *format = NULL;
|
struct yuv_format_descriptor *format = NULL;
|
||||||
struct dmabuf_attributes *attributes = &image->dmabuf->attributes;
|
|
||||||
char fmt[4];
|
char fmt[4];
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(yuv_formats); ++i) {
|
for (i = 0; i < ARRAY_LENGTH(yuv_formats); ++i) {
|
||||||
@@ -2607,31 +2572,32 @@ import_yuv_dmabuf(struct gl_renderer *gr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < format->output_planes; ++j) {
|
for (j = 0; j < format->output_planes; ++j) {
|
||||||
image->images[j] = import_dmabuf_single_plane(gr, attributes,
|
gb->images[j] = import_dmabuf_single_plane(gr, attributes,
|
||||||
&format->plane[j]);
|
&format->plane[j]);
|
||||||
if (!image->images[j]) {
|
if (!gb->images[j]) {
|
||||||
while (j) {
|
while (--j >= 0) {
|
||||||
ret = egl_image_unref(image->images[--j]);
|
ret = egl_image_unref(gb->images[j]);
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
|
gb->images[j] = NULL;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
image->num_images = format->output_planes;
|
gb->num_images = format->output_planes;
|
||||||
|
|
||||||
switch (format->texture_type) {
|
switch (format->texture_type) {
|
||||||
case TEXTURE_Y_XUXV_WL:
|
case TEXTURE_Y_XUXV_WL:
|
||||||
image->shader_variant = SHADER_VARIANT_Y_XUXV;
|
gb->shader_variant = SHADER_VARIANT_Y_XUXV;
|
||||||
break;
|
break;
|
||||||
case TEXTURE_Y_UV_WL:
|
case TEXTURE_Y_UV_WL:
|
||||||
image->shader_variant = SHADER_VARIANT_Y_UV;
|
gb->shader_variant = SHADER_VARIANT_Y_UV;
|
||||||
break;
|
break;
|
||||||
case TEXTURE_Y_U_V_WL:
|
case TEXTURE_Y_U_V_WL:
|
||||||
image->shader_variant = SHADER_VARIANT_Y_U_V;
|
gb->shader_variant = SHADER_VARIANT_Y_U_V;
|
||||||
break;
|
break;
|
||||||
case TEXTURE_XYUV_WL:
|
case TEXTURE_XYUV_WL:
|
||||||
image->shader_variant = SHADER_VARIANT_XYUV;
|
gb->shader_variant = SHADER_VARIANT_XYUV;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
@@ -2725,41 +2691,46 @@ choose_texture_target(struct gl_renderer *gr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dmabuf_image *
|
static struct gl_buffer_state *
|
||||||
import_dmabuf(struct gl_renderer *gr,
|
import_dmabuf(struct gl_renderer *gr,
|
||||||
struct linux_dmabuf_buffer *dmabuf)
|
struct linux_dmabuf_buffer *dmabuf)
|
||||||
{
|
{
|
||||||
struct egl_image *egl_image;
|
struct egl_image *egl_image;
|
||||||
struct dmabuf_image *image;
|
struct gl_buffer_state *gb = zalloc(sizeof(*gb));
|
||||||
GLenum target;
|
|
||||||
|
|
||||||
if (!pixel_format_get_info(dmabuf->attributes.format))
|
if (!pixel_format_get_info(dmabuf->attributes.format))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
image = dmabuf_image_create();
|
gb = zalloc(sizeof(*gb));
|
||||||
image->dmabuf = dmabuf;
|
if (!gb)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
wl_list_init(&gb->destroy_listener.link);
|
||||||
|
|
||||||
egl_image = import_simple_dmabuf(gr, &dmabuf->attributes);
|
egl_image = import_simple_dmabuf(gr, &dmabuf->attributes);
|
||||||
if (egl_image) {
|
if (egl_image) {
|
||||||
image->num_images = 1;
|
GLenum target = choose_texture_target(gr, &dmabuf->attributes);
|
||||||
image->images[0] = egl_image;
|
|
||||||
target = choose_texture_target(gr, &dmabuf->attributes);
|
gb->num_images = 1;
|
||||||
|
gb->images[0] = egl_image;
|
||||||
|
|
||||||
switch (target) {
|
switch (target) {
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
image->shader_variant = SHADER_VARIANT_RGBA;
|
gb->shader_variant = SHADER_VARIANT_RGBA;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
image->shader_variant = SHADER_VARIANT_EXTERNAL;
|
gb->shader_variant = SHADER_VARIANT_EXTERNAL;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!import_yuv_dmabuf(gr, image)) {
|
|
||||||
dmabuf_image_destroy(image);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return gb;
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
if (!import_yuv_dmabuf(gr, gb, &dmabuf->attributes)) {
|
||||||
|
destroy_buffer_state(gb);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2868,7 +2839,7 @@ gl_renderer_import_dmabuf(struct weston_compositor *ec,
|
|||||||
struct linux_dmabuf_buffer *dmabuf)
|
struct linux_dmabuf_buffer *dmabuf)
|
||||||
{
|
{
|
||||||
struct gl_renderer *gr = get_renderer(ec);
|
struct gl_renderer *gr = get_renderer(ec);
|
||||||
struct dmabuf_image *image;
|
struct gl_buffer_state *gb;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert(gr->has_dmabuf_import);
|
assert(gr->has_dmabuf_import);
|
||||||
@@ -2889,12 +2860,11 @@ gl_renderer_import_dmabuf(struct weston_compositor *ec,
|
|||||||
if (dmabuf->attributes.flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT)
|
if (dmabuf->attributes.flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
image = import_dmabuf(gr, dmabuf);
|
gb = import_dmabuf(gr, dmabuf);
|
||||||
if (!image)
|
if (!gb)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wl_list_insert(&gr->dmabuf_images, &image->link);
|
linux_dmabuf_buffer_set_user_data(dmabuf, gb,
|
||||||
linux_dmabuf_buffer_set_user_data(dmabuf, image,
|
|
||||||
gl_renderer_destroy_dmabuf);
|
gl_renderer_destroy_dmabuf);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -2906,37 +2876,51 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
|
|||||||
{
|
{
|
||||||
struct gl_renderer *gr = get_renderer(surface->compositor);
|
struct gl_renderer *gr = get_renderer(surface->compositor);
|
||||||
struct gl_surface_state *gs = get_surface_state(surface);
|
struct gl_surface_state *gs = get_surface_state(surface);
|
||||||
struct gl_buffer_state *gb = &gs->buffer;
|
struct gl_buffer_state *gb;
|
||||||
struct linux_dmabuf_buffer *dmabuf = buffer->dmabuf;
|
struct linux_dmabuf_buffer *dmabuf = buffer->dmabuf;
|
||||||
struct dmabuf_image *image;
|
|
||||||
GLenum target;
|
GLenum target;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < gb->num_images; i++)
|
for (i = 0; i < gs->buffer.num_images; i++)
|
||||||
egl_image_unref(gb->images[i]);
|
egl_image_unref(gs->buffer.images[i]);
|
||||||
gb->num_images = 0;
|
gs->buffer.num_images = 0;
|
||||||
|
|
||||||
if (buffer->direct_display)
|
if (buffer->direct_display)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
image = linux_dmabuf_buffer_get_user_data(dmabuf);
|
/* Thanks to linux-dmabuf being totally independent of libweston,
|
||||||
|
* the first time a dmabuf is attached, the gl_buffer_state will
|
||||||
/* The dmabuf_image should have been created during the import */
|
* only be set as userdata on the dmabuf, not on the weston_buffer.
|
||||||
assert(image != NULL);
|
* When this happens, steal it away into the weston_buffer. */
|
||||||
|
if (!buffer->renderer_private) {
|
||||||
gb->num_images = image->num_images;
|
gb = linux_dmabuf_buffer_get_user_data(dmabuf);
|
||||||
for (i = 0; i < gb->num_images; ++i)
|
assert(gb);
|
||||||
gb->images[i] = egl_image_ref(image->images[i]);
|
linux_dmabuf_buffer_set_user_data(dmabuf, NULL, NULL);
|
||||||
|
buffer->renderer_private = gb;
|
||||||
target = gl_shader_texture_variant_get_target(image->shader_variant);
|
gb->destroy_listener.notify = handle_buffer_destroy;
|
||||||
ensure_textures(gs, target, gb->num_images);
|
wl_signal_add(&buffer->destroy_signal, &gb->destroy_listener);
|
||||||
for (i = 0; i < gb->num_images; ++i) {
|
|
||||||
glActiveTexture(GL_TEXTURE0 + i);
|
|
||||||
glBindTexture(target, gs->textures[i]);
|
|
||||||
gr->image_target_texture_2d(target, gb->images[i]->image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gb->shader_variant = image->shader_variant;
|
assert(buffer->renderer_private);
|
||||||
|
assert(linux_dmabuf_buffer_get_user_data(dmabuf) == NULL);
|
||||||
|
gb = buffer->renderer_private;
|
||||||
|
|
||||||
|
/* The gl_buffer_state stored in the weston_buffer holds a reference
|
||||||
|
* on the EGLImages; we take another ref when we copy into the
|
||||||
|
* gl_surface_state so we don't lose track of anything. This is
|
||||||
|
* temporary and will be removed when gl_surface_state starts
|
||||||
|
* referencing rather than inlining the gl_buffer_state. */
|
||||||
|
memcpy(&gs->buffer, gb, sizeof(*gb));
|
||||||
|
for (i = 0; i < gb->num_images; ++i)
|
||||||
|
gs->buffer.images[i] = egl_image_ref(gs->buffer.images[i]);
|
||||||
|
|
||||||
|
target = gl_shader_texture_variant_get_target(gs->buffer.shader_variant);
|
||||||
|
ensure_textures(gs, target, gb->num_images);
|
||||||
|
for (i = 0; i < gs->buffer.num_images; ++i) {
|
||||||
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
glBindTexture(target, gs->textures[i]);
|
||||||
|
gr->image_target_texture_2d(target, gs->buffer.images[i]->image);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3610,7 +3594,6 @@ static void
|
|||||||
gl_renderer_destroy(struct weston_compositor *ec)
|
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_format *format, *next_format;
|
struct dmabuf_format *format, *next_format;
|
||||||
|
|
||||||
wl_signal_emit(&gr->destroy_signal, gr);
|
wl_signal_emit(&gr->destroy_signal, gr);
|
||||||
@@ -3627,9 +3610,6 @@ gl_renderer_destroy(struct weston_compositor *ec)
|
|||||||
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||||
EGL_NO_CONTEXT);
|
EGL_NO_CONTEXT);
|
||||||
|
|
||||||
wl_list_for_each_safe(image, next, &gr->dmabuf_images, link)
|
|
||||||
dmabuf_image_destroy(image);
|
|
||||||
|
|
||||||
wl_list_for_each_safe(format, next_format, &gr->dmabuf_formats, link)
|
wl_list_for_each_safe(format, next_format, &gr->dmabuf_formats, link)
|
||||||
dmabuf_format_destroy(format);
|
dmabuf_format_destroy(format);
|
||||||
|
|
||||||
@@ -3783,7 +3763,6 @@ gl_renderer_display_create(struct weston_compositor *ec,
|
|||||||
if (gr->has_native_fence_sync && gr->has_wait_sync)
|
if (gr->has_native_fence_sync && gr->has_wait_sync)
|
||||||
ec->capabilities |= WESTON_CAP_EXPLICIT_SYNC;
|
ec->capabilities |= WESTON_CAP_EXPLICIT_SYNC;
|
||||||
|
|
||||||
wl_list_init(&gr->dmabuf_images);
|
|
||||||
if (gr->has_dmabuf_import) {
|
if (gr->has_dmabuf_import) {
|
||||||
gr->base.import_dmabuf = gl_renderer_import_dmabuf;
|
gr->base.import_dmabuf = gl_renderer_import_dmabuf;
|
||||||
gr->base.get_supported_formats = gl_renderer_get_supported_formats;
|
gr->base.get_supported_formats = gl_renderer_get_supported_formats;
|
||||||
|
|||||||
Reference in New Issue
Block a user