compositor: Let renderers create and destroy surface state on their own
Remove create_surface() and destroy_surface() from the renderer interface and change the renderers to create surface state on demand and destroy it using the weston_surface's destroy signal. Also make sure the surfaces' renderer state is reset to NULL on destruction. This is a step towards runtime switchable renderers. (rpi-renderer changes are only compile-tested)
This commit is contained in:
committed by
Kristian Høgsberg
parent
6b16214fb9
commit
aa398ae1f3
@@ -407,11 +407,6 @@ weston_surface_create(struct weston_compositor *compositor)
|
|||||||
surface->compositor = compositor;
|
surface->compositor = compositor;
|
||||||
surface->ref_count = 1;
|
surface->ref_count = 1;
|
||||||
|
|
||||||
if (compositor->renderer->create_surface(surface) < 0) {
|
|
||||||
free(surface);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
surface->buffer_transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
surface->buffer_transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||||
surface->buffer_scale = 1;
|
surface->buffer_scale = 1;
|
||||||
surface->pending.buffer_transform = surface->buffer_transform;
|
surface->pending.buffer_transform = surface->buffer_transform;
|
||||||
@@ -1220,7 +1215,6 @@ weston_view_destroy(struct weston_view *view)
|
|||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
weston_surface_destroy(struct weston_surface *surface)
|
weston_surface_destroy(struct weston_surface *surface)
|
||||||
{
|
{
|
||||||
struct weston_compositor *compositor = surface->compositor;
|
|
||||||
struct weston_frame_callback *cb, *next;
|
struct weston_frame_callback *cb, *next;
|
||||||
struct weston_view *ev, *nv;
|
struct weston_view *ev, *nv;
|
||||||
|
|
||||||
@@ -1248,8 +1242,6 @@ weston_surface_destroy(struct weston_surface *surface)
|
|||||||
|
|
||||||
weston_buffer_reference(&surface->buffer_ref, NULL);
|
weston_buffer_reference(&surface->buffer_ref, NULL);
|
||||||
|
|
||||||
compositor->renderer->destroy_surface(surface);
|
|
||||||
|
|
||||||
pixman_region32_fini(&surface->damage);
|
pixman_region32_fini(&surface->damage);
|
||||||
pixman_region32_fini(&surface->opaque);
|
pixman_region32_fini(&surface->opaque);
|
||||||
pixman_region32_fini(&surface->input);
|
pixman_region32_fini(&surface->input);
|
||||||
|
|||||||
@@ -521,12 +521,10 @@ struct weston_renderer {
|
|||||||
pixman_region32_t *output_damage);
|
pixman_region32_t *output_damage);
|
||||||
void (*flush_damage)(struct weston_surface *surface);
|
void (*flush_damage)(struct weston_surface *surface);
|
||||||
void (*attach)(struct weston_surface *es, struct weston_buffer *buffer);
|
void (*attach)(struct weston_surface *es, struct weston_buffer *buffer);
|
||||||
int (*create_surface)(struct weston_surface *surface);
|
|
||||||
int (*create_view)(struct weston_view *view);
|
int (*create_view)(struct weston_view *view);
|
||||||
void (*surface_set_color)(struct weston_surface *surface,
|
void (*surface_set_color)(struct weston_surface *surface,
|
||||||
float red, float green,
|
float red, float green,
|
||||||
float blue, float alpha);
|
float blue, float alpha);
|
||||||
void (*destroy_surface)(struct weston_surface *surface);
|
|
||||||
void (*destroy_view)(struct weston_view *view);
|
void (*destroy_view)(struct weston_view *view);
|
||||||
void (*destroy)(struct weston_compositor *ec);
|
void (*destroy)(struct weston_compositor *ec);
|
||||||
};
|
};
|
||||||
|
|||||||
+42
-19
@@ -79,6 +79,10 @@ struct gl_surface_state {
|
|||||||
int pitch; /* in pixels */
|
int pitch; /* in pixels */
|
||||||
int height; /* in pixels */
|
int height; /* in pixels */
|
||||||
int y_inverted;
|
int y_inverted;
|
||||||
|
|
||||||
|
struct weston_surface *surface;
|
||||||
|
|
||||||
|
struct wl_listener surface_destroy_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gl_renderer {
|
struct gl_renderer {
|
||||||
@@ -134,9 +138,15 @@ get_output_state(struct weston_output *output)
|
|||||||
return (struct gl_output_state *)output->renderer_state;
|
return (struct gl_output_state *)output->renderer_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gl_renderer_create_surface(struct weston_surface *surface);
|
||||||
|
|
||||||
static inline struct gl_surface_state *
|
static inline struct gl_surface_state *
|
||||||
get_surface_state(struct weston_surface *surface)
|
get_surface_state(struct weston_surface *surface)
|
||||||
{
|
{
|
||||||
|
if (!surface->renderer_state)
|
||||||
|
gl_renderer_create_surface(surface);
|
||||||
|
|
||||||
return (struct gl_surface_state *)surface->renderer_state;
|
return (struct gl_surface_state *)surface->renderer_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,6 +1007,8 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
|
|||||||
gs->needs_full_upload = 1;
|
gs->needs_full_upload = 1;
|
||||||
gs->y_inverted = 1;
|
gs->y_inverted = 1;
|
||||||
|
|
||||||
|
gs->surface = es;
|
||||||
|
|
||||||
ensure_textures(gs, 1);
|
ensure_textures(gs, 1);
|
||||||
glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
|
glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
|
||||||
@@ -1136,6 +1148,31 @@ gl_renderer_surface_set_color(struct weston_surface *surface,
|
|||||||
gs->shader = &gr->solid_shader;
|
gs->shader = &gr->solid_shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct gl_surface_state *gs;
|
||||||
|
struct gl_renderer *gr;
|
||||||
|
struct weston_surface *surface = data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
gr = get_renderer(surface->compositor);
|
||||||
|
|
||||||
|
gs = container_of(listener, struct gl_surface_state,
|
||||||
|
surface_destroy_listener);
|
||||||
|
|
||||||
|
gs->surface->renderer_state = NULL;
|
||||||
|
|
||||||
|
glDeleteTextures(gs->num_textures, gs->textures);
|
||||||
|
|
||||||
|
for (i = 0; i < gs->num_images; i++)
|
||||||
|
gr->destroy_image(gr->egl_display, gs->images[i]);
|
||||||
|
|
||||||
|
weston_buffer_reference(&gs->buffer_ref, NULL);
|
||||||
|
pixman_region32_fini(&gs->texture_damage);
|
||||||
|
free(gs);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gl_renderer_create_surface(struct weston_surface *surface)
|
gl_renderer_create_surface(struct weston_surface *surface)
|
||||||
{
|
{
|
||||||
@@ -1155,26 +1192,14 @@ gl_renderer_create_surface(struct weston_surface *surface)
|
|||||||
pixman_region32_init(&gs->texture_damage);
|
pixman_region32_init(&gs->texture_damage);
|
||||||
surface->renderer_state = gs;
|
surface->renderer_state = gs;
|
||||||
|
|
||||||
|
gs->surface_destroy_listener.notify =
|
||||||
|
surface_state_handle_surface_destroy;
|
||||||
|
wl_signal_add(&surface->destroy_signal,
|
||||||
|
&gs->surface_destroy_listener);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gl_renderer_destroy_surface(struct weston_surface *surface)
|
|
||||||
{
|
|
||||||
struct gl_surface_state *gs = get_surface_state(surface);
|
|
||||||
struct gl_renderer *gr = get_renderer(surface->compositor);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
glDeleteTextures(gs->num_textures, gs->textures);
|
|
||||||
|
|
||||||
for (i = 0; i < gs->num_images; i++)
|
|
||||||
gr->destroy_image(gr->egl_display, gs->images[i]);
|
|
||||||
|
|
||||||
weston_buffer_reference(&gs->buffer_ref, NULL);
|
|
||||||
pixman_region32_fini(&gs->texture_damage);
|
|
||||||
free(gs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char vertex_shader[] =
|
static const char vertex_shader[] =
|
||||||
"uniform mat4 proj;\n"
|
"uniform mat4 proj;\n"
|
||||||
"attribute vec2 position;\n"
|
"attribute vec2 position;\n"
|
||||||
@@ -1655,9 +1680,7 @@ gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
|
|||||||
gr->base.repaint_output = gl_renderer_repaint_output;
|
gr->base.repaint_output = gl_renderer_repaint_output;
|
||||||
gr->base.flush_damage = gl_renderer_flush_damage;
|
gr->base.flush_damage = gl_renderer_flush_damage;
|
||||||
gr->base.attach = gl_renderer_attach;
|
gr->base.attach = gl_renderer_attach;
|
||||||
gr->base.create_surface = gl_renderer_create_surface;
|
|
||||||
gr->base.surface_set_color = gl_renderer_surface_set_color;
|
gr->base.surface_set_color = gl_renderer_surface_set_color;
|
||||||
gr->base.destroy_surface = gl_renderer_destroy_surface;
|
|
||||||
gr->base.destroy = gl_renderer_destroy;
|
gr->base.destroy = gl_renderer_destroy;
|
||||||
|
|
||||||
gr->egl_display = eglGetDisplay(display);
|
gr->egl_display = eglGetDisplay(display);
|
||||||
|
|||||||
@@ -51,23 +51,12 @@ noop_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
noop_renderer_create_surface(struct weston_surface *surface)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
noop_renderer_surface_set_color(struct weston_surface *surface,
|
noop_renderer_surface_set_color(struct weston_surface *surface,
|
||||||
float red, float green, float blue, float alpha)
|
float red, float green, float blue, float alpha)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
noop_renderer_destroy_surface(struct weston_surface *surface)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
noop_renderer_destroy(struct weston_compositor *ec)
|
noop_renderer_destroy(struct weston_compositor *ec)
|
||||||
{
|
{
|
||||||
@@ -88,9 +77,7 @@ noop_renderer_init(struct weston_compositor *ec)
|
|||||||
renderer->repaint_output = noop_renderer_repaint_output;
|
renderer->repaint_output = noop_renderer_repaint_output;
|
||||||
renderer->flush_damage = noop_renderer_flush_damage;
|
renderer->flush_damage = noop_renderer_flush_damage;
|
||||||
renderer->attach = noop_renderer_attach;
|
renderer->attach = noop_renderer_attach;
|
||||||
renderer->create_surface = noop_renderer_create_surface;
|
|
||||||
renderer->surface_set_color = noop_renderer_surface_set_color;
|
renderer->surface_set_color = noop_renderer_surface_set_color;
|
||||||
renderer->destroy_surface = noop_renderer_destroy_surface;
|
|
||||||
renderer->destroy = noop_renderer_destroy;
|
renderer->destroy = noop_renderer_destroy;
|
||||||
ec->renderer = renderer;
|
ec->renderer = renderer;
|
||||||
|
|
||||||
|
|||||||
+35
-15
@@ -37,8 +37,12 @@ struct pixman_output_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct pixman_surface_state {
|
struct pixman_surface_state {
|
||||||
|
struct weston_surface *surface;
|
||||||
|
|
||||||
pixman_image_t *image;
|
pixman_image_t *image;
|
||||||
struct weston_buffer_reference buffer_ref;
|
struct weston_buffer_reference buffer_ref;
|
||||||
|
|
||||||
|
struct wl_listener surface_destroy_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pixman_renderer {
|
struct pixman_renderer {
|
||||||
@@ -55,9 +59,15 @@ get_output_state(struct weston_output *output)
|
|||||||
return (struct pixman_output_state *)output->renderer_state;
|
return (struct pixman_output_state *)output->renderer_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pixman_renderer_create_surface(struct weston_surface *surface);
|
||||||
|
|
||||||
static inline struct pixman_surface_state *
|
static inline struct pixman_surface_state *
|
||||||
get_surface_state(struct weston_surface *surface)
|
get_surface_state(struct weston_surface *surface)
|
||||||
{
|
{
|
||||||
|
if (!surface->renderer_state)
|
||||||
|
pixman_renderer_create_surface(surface);
|
||||||
|
|
||||||
return (struct pixman_surface_state *)surface->renderer_state;
|
return (struct pixman_surface_state *)surface->renderer_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,6 +592,24 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
|
|||||||
wl_shm_buffer_get_stride(shm_buffer));
|
wl_shm_buffer_get_stride(shm_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct pixman_surface_state *ps;
|
||||||
|
|
||||||
|
ps = container_of(listener, struct pixman_surface_state,
|
||||||
|
surface_destroy_listener);
|
||||||
|
|
||||||
|
ps->surface->renderer_state = NULL;
|
||||||
|
|
||||||
|
if (ps->image) {
|
||||||
|
pixman_image_unref(ps->image);
|
||||||
|
ps->image = NULL;
|
||||||
|
}
|
||||||
|
weston_buffer_reference(&ps->buffer_ref, NULL);
|
||||||
|
free(ps);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pixman_renderer_create_surface(struct weston_surface *surface)
|
pixman_renderer_create_surface(struct weston_surface *surface)
|
||||||
{
|
{
|
||||||
@@ -593,6 +621,13 @@ pixman_renderer_create_surface(struct weston_surface *surface)
|
|||||||
|
|
||||||
surface->renderer_state = ps;
|
surface->renderer_state = ps;
|
||||||
|
|
||||||
|
ps->surface = surface;
|
||||||
|
|
||||||
|
ps->surface_destroy_listener.notify =
|
||||||
|
surface_state_handle_surface_destroy;
|
||||||
|
wl_signal_add(&surface->destroy_signal,
|
||||||
|
&ps->surface_destroy_listener);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,19 +651,6 @@ pixman_renderer_surface_set_color(struct weston_surface *es,
|
|||||||
ps->image = pixman_image_create_solid_fill(&color);
|
ps->image = pixman_image_create_solid_fill(&color);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
pixman_renderer_destroy_surface(struct weston_surface *surface)
|
|
||||||
{
|
|
||||||
struct pixman_surface_state *ps = get_surface_state(surface);
|
|
||||||
|
|
||||||
if (ps->image) {
|
|
||||||
pixman_image_unref(ps->image);
|
|
||||||
ps->image = NULL;
|
|
||||||
}
|
|
||||||
weston_buffer_reference(&ps->buffer_ref, NULL);
|
|
||||||
free(ps);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pixman_renderer_destroy(struct weston_compositor *ec)
|
pixman_renderer_destroy(struct weston_compositor *ec)
|
||||||
{
|
{
|
||||||
@@ -676,9 +698,7 @@ pixman_renderer_init(struct weston_compositor *ec)
|
|||||||
renderer->base.repaint_output = pixman_renderer_repaint_output;
|
renderer->base.repaint_output = pixman_renderer_repaint_output;
|
||||||
renderer->base.flush_damage = pixman_renderer_flush_damage;
|
renderer->base.flush_damage = pixman_renderer_flush_damage;
|
||||||
renderer->base.attach = pixman_renderer_attach;
|
renderer->base.attach = pixman_renderer_attach;
|
||||||
renderer->base.create_surface = pixman_renderer_create_surface;
|
|
||||||
renderer->base.surface_set_color = pixman_renderer_surface_set_color;
|
renderer->base.surface_set_color = pixman_renderer_surface_set_color;
|
||||||
renderer->base.destroy_surface = pixman_renderer_destroy_surface;
|
|
||||||
renderer->base.destroy = pixman_renderer_destroy;
|
renderer->base.destroy = pixman_renderer_destroy;
|
||||||
ec->renderer = &renderer->base;
|
ec->renderer = &renderer->base;
|
||||||
ec->capabilities |= WESTON_CAP_ROTATION_ANY;
|
ec->capabilities |= WESTON_CAP_ROTATION_ANY;
|
||||||
|
|||||||
+35
-19
@@ -120,6 +120,8 @@ struct rpir_surface {
|
|||||||
|
|
||||||
struct weston_buffer_reference buffer_ref;
|
struct weston_buffer_reference buffer_ref;
|
||||||
enum buffer_type buffer_type;
|
enum buffer_type buffer_type;
|
||||||
|
|
||||||
|
struct wl_listener surface_destroy_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rpir_view {
|
struct rpir_view {
|
||||||
@@ -167,9 +169,15 @@ struct rpi_renderer {
|
|||||||
int has_bind_display;
|
int has_bind_display;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
rpi_renderer_create_surface(struct weston_surface *base);
|
||||||
|
|
||||||
static inline struct rpir_surface *
|
static inline struct rpir_surface *
|
||||||
to_rpir_surface(struct weston_surface *surface)
|
to_rpir_surface(struct weston_surface *surface)
|
||||||
{
|
{
|
||||||
|
if (!surface->renderer_state)
|
||||||
|
rpi_renderer_create_surface(surface);
|
||||||
|
|
||||||
return surface->renderer_state;
|
return surface->renderer_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1411,6 +1419,27 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpir_surface_handle_surface_destroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct rpir_surface *surface;
|
||||||
|
struct weston_surface *base = data;
|
||||||
|
|
||||||
|
surface = container_of(listener, struct rpir_surface,
|
||||||
|
surface_destroy_listener);
|
||||||
|
|
||||||
|
assert(surface);
|
||||||
|
assert(surface->surface == base);
|
||||||
|
if (!surface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
surface->surface = NULL;
|
||||||
|
base->renderer_state = NULL;
|
||||||
|
|
||||||
|
if (wl_list_empty(&surface->views))
|
||||||
|
rpir_surface_destroy(surface);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rpi_renderer_create_surface(struct weston_surface *base)
|
rpi_renderer_create_surface(struct weston_surface *base)
|
||||||
{
|
{
|
||||||
@@ -1425,6 +1454,12 @@ rpi_renderer_create_surface(struct weston_surface *base)
|
|||||||
|
|
||||||
surface->surface = base;
|
surface->surface = base;
|
||||||
base->renderer_state = surface;
|
base->renderer_state = surface;
|
||||||
|
|
||||||
|
surface->surface_destroy_listener.notify =
|
||||||
|
rpir_surface_handle_surface_destroy;
|
||||||
|
wl_signal_add(&base->destroy_signal,
|
||||||
|
&surface->surface_destroy_listener);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1486,23 +1521,6 @@ rpi_renderer_surface_set_color(struct weston_surface *base,
|
|||||||
surface->need_swap = 1;
|
surface->need_swap = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
rpi_renderer_destroy_surface(struct weston_surface *base)
|
|
||||||
{
|
|
||||||
struct rpir_surface *surface = to_rpir_surface(base);
|
|
||||||
|
|
||||||
assert(surface);
|
|
||||||
assert(surface->surface == base);
|
|
||||||
if (!surface)
|
|
||||||
return;
|
|
||||||
|
|
||||||
surface->surface = NULL;
|
|
||||||
base->renderer_state = NULL;
|
|
||||||
|
|
||||||
if (wl_list_empty(&surface->views))
|
|
||||||
rpir_surface_destroy(surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rpi_renderer_destroy_view(struct weston_view *base)
|
rpi_renderer_destroy_view(struct weston_view *base)
|
||||||
{
|
{
|
||||||
@@ -1564,10 +1582,8 @@ rpi_renderer_create(struct weston_compositor *compositor,
|
|||||||
renderer->base.repaint_output = rpi_renderer_repaint_output;
|
renderer->base.repaint_output = rpi_renderer_repaint_output;
|
||||||
renderer->base.flush_damage = rpi_renderer_flush_damage;
|
renderer->base.flush_damage = rpi_renderer_flush_damage;
|
||||||
renderer->base.attach = rpi_renderer_attach;
|
renderer->base.attach = rpi_renderer_attach;
|
||||||
renderer->base.create_surface = rpi_renderer_create_surface;
|
|
||||||
renderer->base.create_view = rpi_renderer_create_view;
|
renderer->base.create_view = rpi_renderer_create_view;
|
||||||
renderer->base.surface_set_color = rpi_renderer_surface_set_color;
|
renderer->base.surface_set_color = rpi_renderer_surface_set_color;
|
||||||
renderer->base.destroy_surface = rpi_renderer_destroy_surface;
|
|
||||||
renderer->base.destroy_view = rpi_renderer_destroy_view;
|
renderer->base.destroy_view = rpi_renderer_destroy_view;
|
||||||
renderer->base.destroy = rpi_renderer_destroy;
|
renderer->base.destroy = rpi_renderer_destroy;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user