mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-01-01 03:40:14 +01:00
libweston: Use explicit renderbuffer destruction
Renderbuffers currently have a libweston-internal base data structure with a ref-counting system to handle their lifetime. The problem is that renderers keep a ref to all renderbuffers in a list per output (to deal with damages) and that it prevents backends from releasing renderbuffer resources when not needed anymore. Renderbuffers are then only released (last ref removed) when the output is destroyed or resized. dma-buf renderbuffers even expose a dedicated function remove_renderbuffer_dmabuf() to explictly request the release of their resources. This commit proposes to get rid of the ref-counting system by exposing a single entry point to explicitly destroy all types of renderbuffers from the renderer. Instead of removing a renderbuffer from its output list and dropping its ref when the output is resized, this commit also introduces the concept of stale renderbuffers which consists in releasing the resources of a renderbuffer when it's discarded by the renderer while keeping it in the output list, with a stale state, until it's explicitly destroyed. Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
parent
1619a4a1e5
commit
b9e199b47d
16 changed files with 196 additions and 222 deletions
|
|
@ -580,7 +580,7 @@ struct drm_output {
|
||||||
struct drm_writeback_state *wb_state;
|
struct drm_writeback_state *wb_state;
|
||||||
|
|
||||||
struct drm_fb *dumb[2];
|
struct drm_fb *dumb[2];
|
||||||
struct weston_renderbuffer *renderbuffer[2];
|
weston_renderbuffer_t renderbuffer[2];
|
||||||
int current_image;
|
int current_image;
|
||||||
|
|
||||||
struct vaapi_recorder *recorder;
|
struct vaapi_recorder *recorder;
|
||||||
|
|
|
||||||
|
|
@ -1642,7 +1642,7 @@ err:
|
||||||
if (output->dumb[i])
|
if (output->dumb[i])
|
||||||
drm_fb_unref(output->dumb[i]);
|
drm_fb_unref(output->dumb[i]);
|
||||||
if (output->renderbuffer[i])
|
if (output->renderbuffer[i])
|
||||||
weston_renderbuffer_unref(output->renderbuffer[i]);
|
renderer->destroy_renderbuffer(output->renderbuffer[i]);
|
||||||
|
|
||||||
output->dumb[i] = NULL;
|
output->dumb[i] = NULL;
|
||||||
output->renderbuffer[i] = NULL;
|
output->renderbuffer[i] = NULL;
|
||||||
|
|
@ -1668,7 +1668,7 @@ drm_output_fini_pixman(struct drm_output *output)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
|
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
|
||||||
weston_renderbuffer_unref(output->renderbuffer[i]);
|
renderer->destroy_renderbuffer(output->renderbuffer[i]);
|
||||||
drm_fb_unref(output->dumb[i]);
|
drm_fb_unref(output->dumb[i]);
|
||||||
output->dumb[i] = NULL;
|
output->dumb[i] = NULL;
|
||||||
output->renderbuffer[i] = NULL;
|
output->renderbuffer[i] = NULL;
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ struct headless_output {
|
||||||
|
|
||||||
struct weston_mode mode;
|
struct weston_mode mode;
|
||||||
struct wl_event_source *finish_frame_timer;
|
struct wl_event_source *finish_frame_timer;
|
||||||
struct weston_renderbuffer *renderbuffer;
|
weston_renderbuffer_t renderbuffer;
|
||||||
|
|
||||||
struct frame *frame;
|
struct frame *frame;
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -192,7 +192,7 @@ headless_output_disable_gl(struct headless_output *output)
|
||||||
|
|
||||||
weston_gl_borders_fini(&output->gl.borders, &output->base);
|
weston_gl_borders_fini(&output->gl.borders, &output->base);
|
||||||
|
|
||||||
weston_renderbuffer_unref(output->renderbuffer);
|
renderer->destroy_renderbuffer(output->renderbuffer);
|
||||||
output->renderbuffer = NULL;
|
output->renderbuffer = NULL;
|
||||||
renderer->gl->output_destroy(&output->base);
|
renderer->gl->output_destroy(&output->base);
|
||||||
|
|
||||||
|
|
@ -207,7 +207,7 @@ headless_output_disable_pixman(struct headless_output *output)
|
||||||
{
|
{
|
||||||
struct weston_renderer *renderer = output->base.compositor->renderer;
|
struct weston_renderer *renderer = output->base.compositor->renderer;
|
||||||
|
|
||||||
weston_renderbuffer_unref(output->renderbuffer);
|
renderer->destroy_renderbuffer(output->renderbuffer);
|
||||||
output->renderbuffer = NULL;
|
output->renderbuffer = NULL;
|
||||||
renderer->pixman->output_destroy(&output->base);
|
renderer->pixman->output_destroy(&output->base);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ struct pipewire_head {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pipewire_frame_data {
|
struct pipewire_frame_data {
|
||||||
struct weston_renderbuffer *renderbuffer;
|
weston_renderbuffer_t renderbuffer;
|
||||||
struct pipewire_memfd *memfd;
|
struct pipewire_memfd *memfd;
|
||||||
struct pipewire_dmabuf *dmabuf;
|
struct pipewire_dmabuf *dmabuf;
|
||||||
};
|
};
|
||||||
|
|
@ -593,7 +593,7 @@ pipewire_output_stream_param_changed(void *data, uint32_t id,
|
||||||
pw_stream_update_params(output->stream, params, 2);
|
pw_stream_update_params(output->stream, params, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct weston_renderbuffer *
|
static weston_renderbuffer_t
|
||||||
pipewire_output_stream_add_buffer_pixman(struct pipewire_output *output,
|
pipewire_output_stream_add_buffer_pixman(struct pipewire_output *output,
|
||||||
struct pw_buffer *buffer)
|
struct pw_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
|
@ -618,7 +618,7 @@ pipewire_output_stream_add_buffer_pixman(struct pipewire_output *output,
|
||||||
ptr, stride);
|
ptr, stride);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct weston_renderbuffer *
|
static weston_renderbuffer_t
|
||||||
pipewire_output_stream_add_buffer_gl(struct pipewire_output *output,
|
pipewire_output_stream_add_buffer_gl(struct pipewire_output *output,
|
||||||
struct pw_buffer *buffer)
|
struct pw_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
|
@ -800,21 +800,20 @@ pipewire_output_stream_remove_buffer(void *data, struct pw_buffer *buffer)
|
||||||
|
|
||||||
pipewire_output_debug(output, "remove buffer: %p", buffer);
|
pipewire_output_debug(output, "remove buffer: %p", buffer);
|
||||||
|
|
||||||
if (frame_data->dmabuf) {
|
if (frame_data->dmabuf)
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
|
||||||
const struct weston_renderer *renderer = ec->renderer;
|
|
||||||
|
|
||||||
renderer->remove_renderbuffer_dmabuf(&output->base,
|
|
||||||
frame_data->renderbuffer);
|
|
||||||
pipewire_destroy_dmabuf(output, frame_data->dmabuf);
|
pipewire_destroy_dmabuf(output, frame_data->dmabuf);
|
||||||
}
|
|
||||||
if (frame_data->memfd) {
|
if (frame_data->memfd) {
|
||||||
munmap(d[0].data, d[0].maxsize);
|
munmap(d[0].data, d[0].maxsize);
|
||||||
pipewire_destroy_memfd(output, frame_data->memfd);
|
pipewire_destroy_memfd(output, frame_data->memfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame_data->renderbuffer)
|
if (frame_data->renderbuffer) {
|
||||||
weston_renderbuffer_unref(frame_data->renderbuffer);
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
|
const struct weston_renderer *renderer = ec->renderer;
|
||||||
|
|
||||||
|
renderer->destroy_renderbuffer(frame_data->renderbuffer);
|
||||||
|
}
|
||||||
wl_list_for_each(fence_data, &output->fence_list, link) {
|
wl_list_for_each(fence_data, &output->fence_list, link) {
|
||||||
if (fence_data->buffer == buffer)
|
if (fence_data->buffer == buffer)
|
||||||
fence_data->buffer = NULL;
|
fence_data->buffer = NULL;
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ rdp_output_set_mode(struct weston_output *base, struct weston_mode *mode)
|
||||||
struct weston_output *output = base;
|
struct weston_output *output = base;
|
||||||
struct rdp_peers_item *rdpPeer;
|
struct rdp_peers_item *rdpPeer;
|
||||||
rdpSettings *settings;
|
rdpSettings *settings;
|
||||||
struct weston_renderbuffer *new_renderbuffer;
|
weston_renderbuffer_t new_renderbuffer;
|
||||||
|
|
||||||
mode->refresh = b->rdp_monitor_refresh_rate;
|
mode->refresh = b->rdp_monitor_refresh_rate;
|
||||||
weston_output_set_single_mode(base, mode);
|
weston_output_set_single_mode(base, mode);
|
||||||
|
|
@ -384,7 +384,7 @@ rdp_output_set_mode(struct weston_output *base, struct weston_mode *mode)
|
||||||
default:
|
default:
|
||||||
unreachable("cannot have auto renderer at runtime");
|
unreachable("cannot have auto renderer at runtime");
|
||||||
}
|
}
|
||||||
weston_renderbuffer_unref(rdpOutput->renderbuffer);
|
renderer->destroy_renderbuffer(rdpOutput->renderbuffer);
|
||||||
rdpOutput->renderbuffer = new_renderbuffer;
|
rdpOutput->renderbuffer = new_renderbuffer;
|
||||||
pixman_image_unref(rdpOutput->shadow_surface);
|
pixman_image_unref(rdpOutput->shadow_surface);
|
||||||
rdpOutput->shadow_surface = new_image;
|
rdpOutput->shadow_surface = new_image;
|
||||||
|
|
@ -531,7 +531,7 @@ rdp_output_disable(struct weston_output *base)
|
||||||
if (!output->base.enabled)
|
if (!output->base.enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
weston_renderbuffer_unref(output->renderbuffer);
|
renderer->destroy_renderbuffer(output->renderbuffer);
|
||||||
output->renderbuffer = NULL;
|
output->renderbuffer = NULL;
|
||||||
switch (renderer->type) {
|
switch (renderer->type) {
|
||||||
case WESTON_RENDERER_PIXMAN:
|
case WESTON_RENDERER_PIXMAN:
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@
|
||||||
#include <winpr/string.h>
|
#include <winpr/string.h>
|
||||||
|
|
||||||
#include "backend.h"
|
#include "backend.h"
|
||||||
|
#include "libweston-internal.h"
|
||||||
|
|
||||||
#include "shared/helpers.h"
|
#include "shared/helpers.h"
|
||||||
#include "shared/string-helpers.h"
|
#include "shared/string-helpers.h"
|
||||||
|
|
@ -149,7 +150,7 @@ struct rdp_output {
|
||||||
struct weston_output base;
|
struct weston_output base;
|
||||||
struct rdp_backend *backend;
|
struct rdp_backend *backend;
|
||||||
struct wl_event_source *finish_frame_timer;
|
struct wl_event_source *finish_frame_timer;
|
||||||
struct weston_renderbuffer *renderbuffer;
|
weston_renderbuffer_t renderbuffer;
|
||||||
pixman_image_t *shadow_surface;
|
pixman_image_t *shadow_surface;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -674,7 +674,7 @@ vnc_update_buffer(struct nvnc_display *display, struct pixman_region32 *damage)
|
||||||
struct vnc_backend *backend = nvnc_get_userdata(server);
|
struct vnc_backend *backend = nvnc_get_userdata(server);
|
||||||
struct vnc_output *output = backend->output;
|
struct vnc_output *output = backend->output;
|
||||||
struct weston_compositor *ec = output->base.compositor;
|
struct weston_compositor *ec = output->base.compositor;
|
||||||
struct weston_renderbuffer *renderbuffer;
|
weston_renderbuffer_t renderbuffer;
|
||||||
pixman_region32_t local_damage;
|
pixman_region32_t local_damage;
|
||||||
pixman_region16_t nvnc_damage;
|
pixman_region16_t nvnc_damage;
|
||||||
struct nvnc_fb *fb;
|
struct nvnc_fb *fb;
|
||||||
|
|
@ -715,7 +715,7 @@ vnc_update_buffer(struct nvnc_display *display, struct pixman_region32 *damage)
|
||||||
}
|
}
|
||||||
|
|
||||||
nvnc_set_userdata(fb, renderbuffer,
|
nvnc_set_userdata(fb, renderbuffer,
|
||||||
(nvnc_cleanup_fn)weston_renderbuffer_unref);
|
(nvnc_cleanup_fn)ec->renderer->destroy_renderbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
vnc_log_damage(backend, damage);
|
vnc_log_damage(backend, damage);
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ struct wayland_shm_buffer {
|
||||||
int height;
|
int height;
|
||||||
int frame_damaged;
|
int frame_damaged;
|
||||||
|
|
||||||
struct weston_renderbuffer *renderbuffer;
|
weston_renderbuffer_t renderbuffer;
|
||||||
cairo_surface_t *c_surface;
|
cairo_surface_t *c_surface;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -266,9 +266,14 @@ to_wayland_backend(struct weston_backend *base)
|
||||||
static void
|
static void
|
||||||
wayland_shm_buffer_destroy(struct wayland_shm_buffer *buffer)
|
wayland_shm_buffer_destroy(struct wayland_shm_buffer *buffer)
|
||||||
{
|
{
|
||||||
|
struct wayland_output *output = buffer->output;
|
||||||
|
const struct weston_renderer *renderer;
|
||||||
|
|
||||||
cairo_surface_destroy(buffer->c_surface);
|
cairo_surface_destroy(buffer->c_surface);
|
||||||
if (buffer->output)
|
if (output) {
|
||||||
weston_renderbuffer_unref(buffer->renderbuffer);
|
renderer = output->base.compositor->renderer;
|
||||||
|
renderer->destroy_renderbuffer(buffer->renderbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
wl_buffer_destroy(buffer->buffer);
|
wl_buffer_destroy(buffer->buffer);
|
||||||
munmap(buffer->data, buffer->size);
|
munmap(buffer->data, buffer->size);
|
||||||
|
|
@ -657,15 +662,16 @@ wayland_backend_destroy_output_surface(struct wayland_output *output)
|
||||||
static void
|
static void
|
||||||
wayland_output_destroy_shm_buffers(struct wayland_output *output)
|
wayland_output_destroy_shm_buffers(struct wayland_output *output)
|
||||||
{
|
{
|
||||||
|
const struct weston_renderer *renderer =
|
||||||
|
output->base.compositor->renderer;
|
||||||
struct wayland_shm_buffer *buffer, *next;
|
struct wayland_shm_buffer *buffer, *next;
|
||||||
|
|
||||||
/* Throw away any remaining SHM buffers */
|
/* Throw away any remaining SHM buffers */
|
||||||
wl_list_for_each_safe(buffer, next, &output->shm.free_buffers, free_link)
|
wl_list_for_each_safe(buffer, next, &output->shm.free_buffers, free_link)
|
||||||
wayland_shm_buffer_destroy(buffer);
|
wayland_shm_buffer_destroy(buffer);
|
||||||
/* These will get thrown away when they get released */
|
|
||||||
wl_list_for_each(buffer, &output->shm.buffers, link) {
|
wl_list_for_each(buffer, &output->shm.buffers, link) {
|
||||||
if (buffer->renderbuffer) {
|
if (buffer->renderbuffer) {
|
||||||
weston_renderbuffer_unref(buffer->renderbuffer);
|
renderer->destroy_renderbuffer(buffer->renderbuffer);
|
||||||
buffer->renderbuffer = NULL;
|
buffer->renderbuffer = NULL;
|
||||||
}
|
}
|
||||||
buffer->output = NULL;
|
buffer->output = NULL;
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ struct x11_output {
|
||||||
|
|
||||||
xcb_gc_t gc;
|
xcb_gc_t gc;
|
||||||
xcb_shm_seg_t segment;
|
xcb_shm_seg_t segment;
|
||||||
struct weston_renderbuffer *renderbuffer;
|
weston_renderbuffer_t renderbuffer;
|
||||||
int shm_id;
|
int shm_id;
|
||||||
void *buf;
|
void *buf;
|
||||||
uint8_t depth;
|
uint8_t depth;
|
||||||
|
|
@ -568,7 +568,7 @@ x11_output_deinit_shm(struct x11_backend *b, struct x11_output *output)
|
||||||
xcb_generic_error_t *err;
|
xcb_generic_error_t *err;
|
||||||
xcb_free_gc(b->conn, output->gc);
|
xcb_free_gc(b->conn, output->gc);
|
||||||
|
|
||||||
weston_renderbuffer_unref(output->renderbuffer);
|
b->compositor->renderer->destroy_renderbuffer(output->renderbuffer);
|
||||||
output->renderbuffer = NULL;
|
output->renderbuffer = NULL;
|
||||||
cookie = xcb_shm_detach_checked(b->conn, output->segment);
|
cookie = xcb_shm_detach_checked(b->conn, output->segment);
|
||||||
err = xcb_request_check(b->conn, cookie);
|
err = xcb_request_check(b->conn, cookie);
|
||||||
|
|
|
||||||
|
|
@ -10414,25 +10414,6 @@ weston_output_disable_planes_decr(struct weston_output *output)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT struct weston_renderbuffer *
|
|
||||||
weston_renderbuffer_ref(struct weston_renderbuffer *renderbuffer)
|
|
||||||
{
|
|
||||||
renderbuffer->refcount++;
|
|
||||||
|
|
||||||
return renderbuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
WL_EXPORT void
|
|
||||||
weston_renderbuffer_unref(struct weston_renderbuffer *renderbuffer)
|
|
||||||
{
|
|
||||||
assert(renderbuffer->refcount > 0);
|
|
||||||
|
|
||||||
if (--renderbuffer->refcount > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
renderbuffer->destroy(renderbuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Tell the renderer that the target framebuffer size has changed
|
/** Tell the renderer that the target framebuffer size has changed
|
||||||
*
|
*
|
||||||
* \param output The output that was resized.
|
* \param output The output that was resized.
|
||||||
|
|
|
||||||
|
|
@ -46,17 +46,9 @@
|
||||||
|
|
||||||
/* compositor <-> renderer interface */
|
/* compositor <-> renderer interface */
|
||||||
|
|
||||||
struct weston_renderbuffer {
|
/** Opaque pointer to renderbuffer data.
|
||||||
int refcount;
|
*/
|
||||||
|
typedef void *weston_renderbuffer_t;
|
||||||
void (*destroy)(struct weston_renderbuffer *renderbuffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct weston_renderbuffer *
|
|
||||||
weston_renderbuffer_ref(struct weston_renderbuffer *renderbuffer);
|
|
||||||
|
|
||||||
void
|
|
||||||
weston_renderbuffer_unref(struct weston_renderbuffer *renderbuffer);
|
|
||||||
|
|
||||||
struct weston_renderer_options {
|
struct weston_renderer_options {
|
||||||
};
|
};
|
||||||
|
|
@ -74,7 +66,7 @@ struct weston_renderer {
|
||||||
uint32_t width, uint32_t height);
|
uint32_t width, uint32_t height);
|
||||||
void (*repaint_output)(struct weston_output *output,
|
void (*repaint_output)(struct weston_output *output,
|
||||||
pixman_region32_t *output_damage,
|
pixman_region32_t *output_damage,
|
||||||
struct weston_renderbuffer *renderbuffer);
|
weston_renderbuffer_t renderbuffer);
|
||||||
|
|
||||||
/** See weston_renderer_resize_output()
|
/** See weston_renderer_resize_output()
|
||||||
*
|
*
|
||||||
|
|
@ -112,34 +104,27 @@ struct weston_renderer {
|
||||||
*
|
*
|
||||||
* \param output The output to add the DMABUF renderbuffer for.
|
* \param output The output to add the DMABUF renderbuffer for.
|
||||||
* \param dmabuf The description object of the DMABUF to import.
|
* \param dmabuf The description object of the DMABUF to import.
|
||||||
* \return A weston_renderbuffer on success, NULL on failure.
|
* \return A renderbuffer on success, NULL on failure.
|
||||||
*
|
*
|
||||||
* This function imports the DMABUF memory as renderbuffer and adds
|
* This function imports the DMABUF memory as renderbuffer and adds it
|
||||||
* it to the output. The returned weston_renderbuffer can be passed to
|
* to the output. The returned renderbuffer can be passed to
|
||||||
* repaint_output() to render into the DMABUF.
|
* repaint_output() to render into the DMABUF.
|
||||||
*
|
*
|
||||||
* The ownership of the linux_dmabuf_memory is transferred to the
|
* The ownership of the linux_dmabuf_memory is transferred to the
|
||||||
* returned weston_renderbuffer. The linux_dmabuf_memory will be
|
* returned renderbuffer. The linux_dmabuf_memory will be destroyed
|
||||||
* destroyed automatically when the weston_renderbuffer is destroyed.
|
* automatically when the renderbuffer is destroyed.
|
||||||
*/
|
*/
|
||||||
struct weston_renderbuffer *
|
weston_renderbuffer_t
|
||||||
(*create_renderbuffer_dmabuf)(struct weston_output *output,
|
(*create_renderbuffer_dmabuf)(struct weston_output *output,
|
||||||
struct linux_dmabuf_memory *dmabuf);
|
struct linux_dmabuf_memory *dmabuf);
|
||||||
|
|
||||||
/**
|
/** Destroy a renderbuffer
|
||||||
* Remove the DAMBUF renderbuffer from the output
|
|
||||||
*
|
*
|
||||||
* \param output The output to remove a DMABUF renderbuffer from.
|
* \param renderbuffer The renderbuffer to destroy.
|
||||||
* \param renderbuffer The weston_renderbuffer that shall be removed
|
|
||||||
*
|
*
|
||||||
* This function removes the DMABUF renderbuffer from the output.
|
* This function destroys a \c renderbuffer.
|
||||||
*
|
|
||||||
* This allows the backend to signal the renderer that it will no longer
|
|
||||||
* use the renderbuffer for rendering and the renderer may free the
|
|
||||||
* resources of the renderbuffer.
|
|
||||||
*/
|
*/
|
||||||
void (*remove_renderbuffer_dmabuf)(struct weston_output *output,
|
void (*destroy_renderbuffer)(weston_renderbuffer_t renderbuffer);
|
||||||
struct weston_renderbuffer *renderbuffer);
|
|
||||||
|
|
||||||
/* Allocate a DMABUF that can be imported as renderbuffer
|
/* Allocate a DMABUF that can be imported as renderbuffer
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ noop_renderer_read_pixels(struct weston_output *output,
|
||||||
static void
|
static void
|
||||||
noop_renderer_repaint_output(struct weston_output *output,
|
noop_renderer_repaint_output(struct weston_output *output,
|
||||||
pixman_region32_t *output_damage,
|
pixman_region32_t *output_damage,
|
||||||
struct weston_renderbuffer *renderbuffer)
|
weston_renderbuffer_t renderbuffer)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,9 @@ struct pixman_surface_state {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pixman_renderbuffer {
|
struct pixman_renderbuffer {
|
||||||
struct weston_renderbuffer base;
|
|
||||||
|
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
pixman_image_t *image;
|
pixman_image_t *image;
|
||||||
|
bool stale;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -81,16 +80,11 @@ struct pixman_renderer {
|
||||||
struct wl_signal destroy_signal;
|
struct wl_signal destroy_signal;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct pixman_renderbuffer *
|
|
||||||
to_pixman_renderbuffer(struct weston_renderbuffer *renderbuffer)
|
|
||||||
{
|
|
||||||
return container_of(renderbuffer, struct pixman_renderbuffer, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static pixman_image_t *
|
static pixman_image_t *
|
||||||
pixman_renderer_renderbuffer_get_image(struct weston_renderbuffer *renderbuffer)
|
pixman_renderer_renderbuffer_get_image(weston_renderbuffer_t renderbuffer)
|
||||||
{
|
{
|
||||||
struct pixman_renderbuffer *rb = to_pixman_renderbuffer(renderbuffer);
|
struct pixman_renderbuffer *rb =
|
||||||
|
(struct pixman_renderbuffer *) renderbuffer;
|
||||||
|
|
||||||
return rb->image;
|
return rb->image;
|
||||||
}
|
}
|
||||||
|
|
@ -645,7 +639,7 @@ pixman_renderer_output_set_buffer(struct weston_output *output,
|
||||||
static void
|
static void
|
||||||
pixman_renderer_repaint_output(struct weston_output *output,
|
pixman_renderer_repaint_output(struct weston_output *output,
|
||||||
pixman_region32_t *output_damage,
|
pixman_region32_t *output_damage,
|
||||||
struct weston_renderbuffer *renderbuffer)
|
weston_renderbuffer_t renderbuffer)
|
||||||
{
|
{
|
||||||
struct pixman_output_state *po = get_output_state(output);
|
struct pixman_output_state *po = get_output_state(output);
|
||||||
struct pixman_renderbuffer *rb;
|
struct pixman_renderbuffer *rb;
|
||||||
|
|
@ -657,7 +651,7 @@ pixman_renderer_repaint_output(struct weston_output *output,
|
||||||
pixman_region32_union(&rb->damage, &rb->damage, output_damage);
|
pixman_region32_union(&rb->damage, &rb->damage, output_damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb = to_pixman_renderbuffer(renderbuffer);
|
rb = (struct pixman_renderbuffer *) renderbuffer;
|
||||||
|
|
||||||
pixman_renderer_output_set_buffer(output, rb->image);
|
pixman_renderer_output_set_buffer(output, rb->image);
|
||||||
|
|
||||||
|
|
@ -921,13 +915,54 @@ pixman_renderer_surface_copy_content(struct weston_surface *surface,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pixman_renderbuffer_fini(struct pixman_renderbuffer *renderbuffer)
|
||||||
|
{
|
||||||
|
assert(!renderbuffer->stale);
|
||||||
|
|
||||||
|
pixman_region32_fini(&renderbuffer->damage);
|
||||||
|
pixman_image_unref(renderbuffer->image);
|
||||||
|
|
||||||
|
renderbuffer->stale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pixman_renderer_destroy_renderbuffer(weston_renderbuffer_t renderbuffer)
|
||||||
|
{
|
||||||
|
struct pixman_renderbuffer *rb =
|
||||||
|
(struct pixman_renderbuffer *) renderbuffer;
|
||||||
|
|
||||||
|
wl_list_remove(&rb->link);
|
||||||
|
|
||||||
|
if (!rb->stale)
|
||||||
|
pixman_renderbuffer_fini(rb);
|
||||||
|
|
||||||
|
free(rb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pixman_renderer_discard_renderbuffers(struct pixman_output_state *po,
|
||||||
|
bool destroy)
|
||||||
|
{
|
||||||
|
struct pixman_renderbuffer *rb, *tmp;
|
||||||
|
|
||||||
|
/* A renderbuffer goes stale after being discarded. Most resources are
|
||||||
|
* released. It's kept in the output state's renderbuffer list while
|
||||||
|
* waiting for the backend to destroy it. */
|
||||||
|
wl_list_for_each_safe(rb, tmp, &po->renderbuffer_list, link) {
|
||||||
|
if (destroy)
|
||||||
|
pixman_renderer_destroy_renderbuffer((weston_renderbuffer_t) rb);
|
||||||
|
else if (!rb->stale)
|
||||||
|
pixman_renderbuffer_fini(rb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
pixman_renderer_resize_output(struct weston_output *output,
|
pixman_renderer_resize_output(struct weston_output *output,
|
||||||
const struct weston_size *fb_size,
|
const struct weston_size *fb_size,
|
||||||
const struct weston_geometry *area)
|
const struct weston_geometry *area)
|
||||||
{
|
{
|
||||||
struct pixman_output_state *po = get_output_state(output);
|
struct pixman_output_state *po = get_output_state(output);
|
||||||
struct pixman_renderbuffer *renderbuffer, *tmp;
|
|
||||||
|
|
||||||
check_compositing_area(fb_size, area);
|
check_compositing_area(fb_size, area);
|
||||||
|
|
||||||
|
|
@ -942,10 +977,7 @@ pixman_renderer_resize_output(struct weston_output *output,
|
||||||
|
|
||||||
pixman_renderer_output_set_buffer(output, NULL);
|
pixman_renderer_output_set_buffer(output, NULL);
|
||||||
|
|
||||||
wl_list_for_each_safe(renderbuffer, tmp, &po->renderbuffer_list, link) {
|
pixman_renderer_discard_renderbuffers(po, false);
|
||||||
wl_list_remove(&renderbuffer->link);
|
|
||||||
weston_renderbuffer_unref(&renderbuffer->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
po->fb_size = *fb_size;
|
po->fb_size = *fb_size;
|
||||||
|
|
||||||
|
|
@ -1025,6 +1057,8 @@ pixman_renderer_init(struct weston_compositor *ec)
|
||||||
renderer->base.destroy = pixman_renderer_destroy;
|
renderer->base.destroy = pixman_renderer_destroy;
|
||||||
renderer->base.surface_copy_content =
|
renderer->base.surface_copy_content =
|
||||||
pixman_renderer_surface_copy_content;
|
pixman_renderer_surface_copy_content;
|
||||||
|
renderer->base.destroy_renderbuffer =
|
||||||
|
pixman_renderer_destroy_renderbuffer;
|
||||||
renderer->base.type = WESTON_RENDERER_PIXMAN;
|
renderer->base.type = WESTON_RENDERER_PIXMAN;
|
||||||
renderer->base.pixman = &pixman_renderer_interface;
|
renderer->base.pixman = &pixman_renderer_interface;
|
||||||
ec->renderer = &renderer->base;
|
ec->renderer = &renderer->base;
|
||||||
|
|
@ -1133,7 +1167,6 @@ static void
|
||||||
pixman_renderer_output_destroy(struct weston_output *output)
|
pixman_renderer_output_destroy(struct weston_output *output)
|
||||||
{
|
{
|
||||||
struct pixman_output_state *po = get_output_state(output);
|
struct pixman_output_state *po = get_output_state(output);
|
||||||
struct pixman_renderbuffer *renderbuffer, *tmp;
|
|
||||||
|
|
||||||
if (po->shadow_image)
|
if (po->shadow_image)
|
||||||
pixman_image_unref(po->shadow_image);
|
pixman_image_unref(po->shadow_image);
|
||||||
|
|
@ -1144,18 +1177,12 @@ pixman_renderer_output_destroy(struct weston_output *output)
|
||||||
po->shadow_image = NULL;
|
po->shadow_image = NULL;
|
||||||
po->hw_buffer = NULL;
|
po->hw_buffer = NULL;
|
||||||
|
|
||||||
wl_list_for_each_safe(renderbuffer, tmp, &po->renderbuffer_list, link) {
|
pixman_renderer_discard_renderbuffers(po, true);
|
||||||
wl_list_remove(&renderbuffer->link);
|
|
||||||
weston_renderbuffer_unref(&renderbuffer->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(po);
|
free(po);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static weston_renderbuffer_t
|
||||||
pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer);
|
|
||||||
|
|
||||||
static struct weston_renderbuffer *
|
|
||||||
pixman_renderer_create_image_from_ptr(struct weston_output *output,
|
pixman_renderer_create_image_from_ptr(struct weston_output *output,
|
||||||
const struct pixel_format_info *format,
|
const struct pixel_format_info *format,
|
||||||
int width, int height, uint32_t *ptr,
|
int width, int height, uint32_t *ptr,
|
||||||
|
|
@ -1178,14 +1205,12 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output,
|
||||||
|
|
||||||
pixman_region32_init(&renderbuffer->damage);
|
pixman_region32_init(&renderbuffer->damage);
|
||||||
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
||||||
renderbuffer->base.refcount = 2;
|
|
||||||
renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy;
|
|
||||||
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
||||||
|
|
||||||
return &renderbuffer->base;
|
return (weston_renderbuffer_t) renderbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct weston_renderbuffer *
|
static weston_renderbuffer_t
|
||||||
pixman_renderer_create_image(struct weston_output *output,
|
pixman_renderer_create_image(struct weston_output *output,
|
||||||
const struct pixel_format_info *format, int width,
|
const struct pixel_format_info *format, int width,
|
||||||
int height)
|
int height)
|
||||||
|
|
@ -1207,21 +1232,9 @@ pixman_renderer_create_image(struct weston_output *output,
|
||||||
|
|
||||||
pixman_region32_init(&renderbuffer->damage);
|
pixman_region32_init(&renderbuffer->damage);
|
||||||
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
||||||
renderbuffer->base.refcount = 2;
|
|
||||||
renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy;
|
|
||||||
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
|
||||||
|
|
||||||
return &renderbuffer->base;
|
return (weston_renderbuffer_t) renderbuffer;
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
|
|
||||||
{
|
|
||||||
struct pixman_renderbuffer *rb = to_pixman_renderbuffer(renderbuffer);
|
|
||||||
|
|
||||||
pixman_image_unref(rb->image);
|
|
||||||
pixman_region32_fini(&rb->damage);
|
|
||||||
free(rb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pixman_renderer_interface pixman_renderer_interface = {
|
static struct pixman_renderer_interface pixman_renderer_interface = {
|
||||||
|
|
|
||||||
|
|
@ -47,14 +47,14 @@ struct pixman_renderer_interface {
|
||||||
const struct pixman_renderer_output_options *options);
|
const struct pixman_renderer_output_options *options);
|
||||||
void (*output_destroy)(struct weston_output *output);
|
void (*output_destroy)(struct weston_output *output);
|
||||||
|
|
||||||
struct weston_renderbuffer *(*create_image_from_ptr)(struct weston_output *output,
|
weston_renderbuffer_t (*create_image_from_ptr)(struct weston_output *output,
|
||||||
const struct pixel_format_info *format,
|
const struct pixel_format_info *format,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
uint32_t *ptr,
|
uint32_t *ptr,
|
||||||
int stride);
|
int stride);
|
||||||
struct weston_renderbuffer *(*create_image)(struct weston_output *output,
|
weston_renderbuffer_t (*create_image)(struct weston_output *output,
|
||||||
const struct pixel_format_info *format,
|
const struct pixel_format_info *format,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
pixman_image_t *(*renderbuffer_get_image)(struct weston_renderbuffer *renderbuffer);
|
pixman_image_t *(*renderbuffer_get_image)(weston_renderbuffer_t renderbuffer);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,12 @@ enum gl_border_status {
|
||||||
BORDER_SIZE_CHANGED = 0x10
|
BORDER_SIZE_CHANGED = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum gl_renderbuffer_type {
|
||||||
|
RENDERBUFFER_DUMMY = 0,
|
||||||
|
RENDERBUFFER_FBO,
|
||||||
|
RENDERBUFFER_DMABUF,
|
||||||
|
};
|
||||||
|
|
||||||
struct gl_border_image {
|
struct gl_border_image {
|
||||||
GLuint tex;
|
GLuint tex;
|
||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
|
|
@ -103,9 +109,10 @@ struct gl_fbo_texture {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gl_renderbuffer {
|
struct gl_renderbuffer {
|
||||||
struct weston_renderbuffer base;
|
enum gl_renderbuffer_type type;
|
||||||
pixman_region32_t damage;
|
pixman_region32_t damage;
|
||||||
enum gl_border_status border_damage;
|
enum gl_border_status border_damage;
|
||||||
|
bool stale;
|
||||||
/* The fbo value zero represents the default surface framebuffer. */
|
/* The fbo value zero represents the default surface framebuffer. */
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
GLuint rb;
|
GLuint rb;
|
||||||
|
|
@ -677,12 +684,6 @@ gl_fbo_texture_fini(struct gl_fbo_texture *fbotex)
|
||||||
fbotex->tex = 0;
|
fbotex->tex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct gl_renderbuffer *
|
|
||||||
to_gl_renderbuffer(struct weston_renderbuffer *renderbuffer)
|
|
||||||
{
|
|
||||||
return container_of(renderbuffer, struct gl_renderbuffer, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct dmabuf_renderbuffer *
|
static inline struct dmabuf_renderbuffer *
|
||||||
to_dmabuf_renderbuffer(struct gl_renderbuffer *renderbuffer)
|
to_dmabuf_renderbuffer(struct gl_renderbuffer *renderbuffer)
|
||||||
{
|
{
|
||||||
|
|
@ -690,14 +691,61 @@ to_dmabuf_renderbuffer(struct gl_renderbuffer *renderbuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gl_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
|
gl_renderbuffer_fini(struct gl_renderbuffer *renderbuffer)
|
||||||
{
|
{
|
||||||
struct gl_renderbuffer *rb = to_gl_renderbuffer(renderbuffer);
|
struct dmabuf_renderbuffer *dmabuf_rb;
|
||||||
|
|
||||||
glDeleteFramebuffers(1, &rb->fbo);
|
assert(!renderbuffer->stale);
|
||||||
glDeleteRenderbuffers(1, &rb->rb);
|
|
||||||
pixman_region32_fini(&rb->damage);
|
pixman_region32_fini(&renderbuffer->damage);
|
||||||
free(rb);
|
glDeleteFramebuffers(1, &renderbuffer->fbo);
|
||||||
|
glDeleteRenderbuffers(1, &renderbuffer->rb);
|
||||||
|
|
||||||
|
if (renderbuffer->type == RENDERBUFFER_DMABUF) {
|
||||||
|
dmabuf_rb = to_dmabuf_renderbuffer(renderbuffer);
|
||||||
|
dmabuf_rb->gr->destroy_image(dmabuf_rb->gr->egl_display,
|
||||||
|
dmabuf_rb->image);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderbuffer->stale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gl_renderer_destroy_renderbuffer(weston_renderbuffer_t weston_renderbuffer)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *rb =
|
||||||
|
(struct gl_renderbuffer *) weston_renderbuffer;
|
||||||
|
struct dmabuf_renderbuffer *dmabuf_rb;
|
||||||
|
|
||||||
|
wl_list_remove(&rb->link);
|
||||||
|
|
||||||
|
if (!rb->stale)
|
||||||
|
gl_renderbuffer_fini(rb);
|
||||||
|
|
||||||
|
if (rb->type == RENDERBUFFER_DMABUF) {
|
||||||
|
dmabuf_rb = to_dmabuf_renderbuffer(rb);
|
||||||
|
dmabuf_rb->dmabuf->destroy(dmabuf_rb->dmabuf);
|
||||||
|
free(dmabuf_rb);
|
||||||
|
} else {
|
||||||
|
free(rb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gl_renderer_discard_renderbuffers(struct gl_output_state *go,
|
||||||
|
bool destroy)
|
||||||
|
{
|
||||||
|
struct gl_renderbuffer *rb, *tmp;
|
||||||
|
|
||||||
|
/* A renderbuffer goes stale after being discarded. Most resources are
|
||||||
|
* released. It's kept in the output states' renderbuffer list waiting
|
||||||
|
* for the backend to destroy it. */
|
||||||
|
wl_list_for_each_safe(rb, tmp, &go->renderbuffer_list, link) {
|
||||||
|
if ((rb->type == RENDERBUFFER_DUMMY) || destroy)
|
||||||
|
gl_renderer_destroy_renderbuffer((weston_renderbuffer_t) rb);
|
||||||
|
else if (!rb->stale)
|
||||||
|
gl_renderbuffer_fini(rb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct gl_renderbuffer *
|
static struct gl_renderbuffer *
|
||||||
|
|
@ -708,23 +756,18 @@ gl_renderer_create_dummy_renderbuffer(struct weston_output *output)
|
||||||
|
|
||||||
renderbuffer = xzalloc(sizeof(*renderbuffer));
|
renderbuffer = xzalloc(sizeof(*renderbuffer));
|
||||||
|
|
||||||
|
renderbuffer->type = RENDERBUFFER_DUMMY;
|
||||||
renderbuffer->fbo = 0;
|
renderbuffer->fbo = 0;
|
||||||
|
|
||||||
pixman_region32_init(&renderbuffer->damage);
|
pixman_region32_init(&renderbuffer->damage);
|
||||||
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
||||||
renderbuffer->border_damage = BORDER_ALL_DIRTY;
|
renderbuffer->border_damage = BORDER_ALL_DIRTY;
|
||||||
/*
|
|
||||||
* A single reference is kept on the renderbuffer_list,
|
|
||||||
* the caller just borrows it.
|
|
||||||
*/
|
|
||||||
renderbuffer->base.refcount = 1;
|
|
||||||
renderbuffer->base.destroy = gl_renderer_renderbuffer_destroy;
|
|
||||||
wl_list_insert(&go->renderbuffer_list, &renderbuffer->link);
|
wl_list_insert(&go->renderbuffer_list, &renderbuffer->link);
|
||||||
|
|
||||||
return renderbuffer;
|
return renderbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct weston_renderbuffer *
|
static weston_renderbuffer_t
|
||||||
gl_renderer_create_fbo(struct weston_output *output,
|
gl_renderer_create_fbo(struct weston_output *output,
|
||||||
const struct pixel_format_info *format,
|
const struct pixel_format_info *format,
|
||||||
int width, int height, uint32_t *pixels)
|
int width, int height, uint32_t *pixels)
|
||||||
|
|
@ -775,18 +818,13 @@ gl_renderer_create_fbo(struct weston_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
renderbuffer->pixels = pixels;
|
renderbuffer->pixels = pixels;
|
||||||
|
renderbuffer->type = RENDERBUFFER_FBO;
|
||||||
|
|
||||||
pixman_region32_init(&renderbuffer->damage);
|
pixman_region32_init(&renderbuffer->damage);
|
||||||
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
||||||
/*
|
|
||||||
* One reference is kept on the renderbuffer_list,
|
|
||||||
* the other is returned to the calling backend.
|
|
||||||
*/
|
|
||||||
renderbuffer->base.refcount = 2;
|
|
||||||
renderbuffer->base.destroy = gl_renderer_renderbuffer_destroy;
|
|
||||||
wl_list_insert(&go->renderbuffer_list, &renderbuffer->link);
|
wl_list_insert(&go->renderbuffer_list, &renderbuffer->link);
|
||||||
|
|
||||||
return &renderbuffer->base;
|
return (weston_renderbuffer_t) renderbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -2337,7 +2375,7 @@ blit_shadow_to_output(struct weston_output *output,
|
||||||
static void
|
static void
|
||||||
gl_renderer_repaint_output(struct weston_output *output,
|
gl_renderer_repaint_output(struct weston_output *output,
|
||||||
pixman_region32_t *output_damage,
|
pixman_region32_t *output_damage,
|
||||||
struct weston_renderbuffer *renderbuffer)
|
weston_renderbuffer_t renderbuffer)
|
||||||
{
|
{
|
||||||
struct gl_output_state *go = get_output_state(output);
|
struct gl_output_state *go = get_output_state(output);
|
||||||
struct weston_compositor *compositor = output->compositor;
|
struct weston_compositor *compositor = output->compositor;
|
||||||
|
|
@ -2362,7 +2400,7 @@ gl_renderer_repaint_output(struct weston_output *output,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderbuffer)
|
if (renderbuffer)
|
||||||
rb = to_gl_renderbuffer(renderbuffer);
|
rb = (struct gl_renderbuffer *) renderbuffer;
|
||||||
else
|
else
|
||||||
rb = output_get_dummy_renderbuffer(output);
|
rb = output_get_dummy_renderbuffer(output);
|
||||||
|
|
||||||
|
|
@ -4020,22 +4058,6 @@ gl_renderer_output_set_border(struct weston_output *output,
|
||||||
go->border_status |= 1 << side;
|
go->border_status |= 1 << side;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gl_renderer_remove_renderbuffer(struct gl_renderbuffer *renderbuffer)
|
|
||||||
{
|
|
||||||
wl_list_remove(&renderbuffer->link);
|
|
||||||
weston_renderbuffer_unref(&renderbuffer->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gl_renderer_remove_renderbuffers(struct gl_output_state *go)
|
|
||||||
{
|
|
||||||
struct gl_renderbuffer *renderbuffer, *tmp;
|
|
||||||
|
|
||||||
wl_list_for_each_safe(renderbuffer, tmp, &go->renderbuffer_list, link)
|
|
||||||
gl_renderer_remove_renderbuffer(renderbuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
gl_renderer_resize_output(struct weston_output *output,
|
gl_renderer_resize_output(struct weston_output *output,
|
||||||
const struct weston_size *fb_size,
|
const struct weston_size *fb_size,
|
||||||
|
|
@ -4048,7 +4070,7 @@ gl_renderer_resize_output(struct weston_output *output,
|
||||||
|
|
||||||
check_compositing_area(fb_size, area);
|
check_compositing_area(fb_size, area);
|
||||||
|
|
||||||
gl_renderer_remove_renderbuffers(go);
|
gl_renderer_discard_renderbuffers(go, false);
|
||||||
|
|
||||||
go->fb_size = *fb_size;
|
go->fb_size = *fb_size;
|
||||||
go->area = *area;
|
go->area = *area;
|
||||||
|
|
@ -4199,26 +4221,7 @@ gl_renderer_output_fbo_create(struct weston_output *output,
|
||||||
&options->fb_size, &options->area);
|
&options->fb_size, &options->area);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static weston_renderbuffer_t
|
||||||
gl_renderer_dmabuf_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
|
|
||||||
{
|
|
||||||
struct gl_renderbuffer *gl_renderbuffer = to_gl_renderbuffer(renderbuffer);
|
|
||||||
struct dmabuf_renderbuffer *dmabuf_renderbuffer = to_dmabuf_renderbuffer(gl_renderbuffer);
|
|
||||||
struct gl_renderer *gr = dmabuf_renderbuffer->gr;
|
|
||||||
|
|
||||||
glDeleteFramebuffers(1, &gl_renderbuffer->fbo);
|
|
||||||
glDeleteRenderbuffers(1, &gl_renderbuffer->rb);
|
|
||||||
pixman_region32_fini(&gl_renderbuffer->damage);
|
|
||||||
|
|
||||||
gr->destroy_image(gr->egl_display, dmabuf_renderbuffer->image);
|
|
||||||
|
|
||||||
/* Destroy the owned dmabuf */
|
|
||||||
dmabuf_renderbuffer->dmabuf->destroy(dmabuf_renderbuffer->dmabuf);
|
|
||||||
|
|
||||||
free(dmabuf_renderbuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct weston_renderbuffer *
|
|
||||||
gl_renderer_create_renderbuffer_dmabuf(struct weston_output *output,
|
gl_renderer_create_renderbuffer_dmabuf(struct weston_output *output,
|
||||||
struct linux_dmabuf_memory *dmabuf)
|
struct linux_dmabuf_memory *dmabuf)
|
||||||
{
|
{
|
||||||
|
|
@ -4272,26 +4275,12 @@ gl_renderer_create_renderbuffer_dmabuf(struct weston_output *output,
|
||||||
rb->gr = gr;
|
rb->gr = gr;
|
||||||
rb->dmabuf = dmabuf;
|
rb->dmabuf = dmabuf;
|
||||||
|
|
||||||
|
renderbuffer->type = RENDERBUFFER_DMABUF;
|
||||||
pixman_region32_init(&renderbuffer->damage);
|
pixman_region32_init(&renderbuffer->damage);
|
||||||
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
pixman_region32_copy(&renderbuffer->damage, &output->region);
|
||||||
/*
|
wl_list_insert(&go->renderbuffer_list, &renderbuffer->link);
|
||||||
* One reference is kept on the renderbuffer_list,
|
|
||||||
* the other is returned to the calling backend.
|
|
||||||
*/
|
|
||||||
rb->base.base.refcount = 2;
|
|
||||||
rb->base.base.destroy = gl_renderer_dmabuf_renderbuffer_destroy;
|
|
||||||
wl_list_insert(&go->renderbuffer_list, &rb->base.link);
|
|
||||||
|
|
||||||
return &rb->base.base;
|
return (weston_renderbuffer_t) rb;
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gl_renderer_remove_renderbuffer_dmabuf(struct weston_output *output,
|
|
||||||
struct weston_renderbuffer *renderbuffer)
|
|
||||||
{
|
|
||||||
struct gl_renderbuffer *gl_renderbuffer = to_gl_renderbuffer(renderbuffer);
|
|
||||||
|
|
||||||
gl_renderer_remove_renderbuffer(gl_renderbuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_GBM
|
#ifdef HAVE_GBM
|
||||||
|
|
@ -4403,7 +4392,7 @@ gl_renderer_output_destroy(struct weston_output *output)
|
||||||
if (go->render_sync != EGL_NO_SYNC_KHR)
|
if (go->render_sync != EGL_NO_SYNC_KHR)
|
||||||
gr->destroy_sync(gr->egl_display, go->render_sync);
|
gr->destroy_sync(gr->egl_display, go->render_sync);
|
||||||
|
|
||||||
gl_renderer_remove_renderbuffers(go);
|
gl_renderer_discard_renderbuffers(go, true);
|
||||||
|
|
||||||
free(go);
|
free(go);
|
||||||
}
|
}
|
||||||
|
|
@ -4581,6 +4570,7 @@ gl_renderer_display_create(struct weston_compositor *ec,
|
||||||
gr->base.read_pixels = gl_renderer_read_pixels;
|
gr->base.read_pixels = gl_renderer_read_pixels;
|
||||||
gr->base.repaint_output = gl_renderer_repaint_output;
|
gr->base.repaint_output = gl_renderer_repaint_output;
|
||||||
gr->base.resize_output = gl_renderer_resize_output;
|
gr->base.resize_output = gl_renderer_resize_output;
|
||||||
|
gr->base.destroy_renderbuffer = gl_renderer_destroy_renderbuffer;
|
||||||
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.destroy = gl_renderer_destroy;
|
gr->base.destroy = gl_renderer_destroy;
|
||||||
|
|
@ -4649,7 +4639,6 @@ gl_renderer_display_create(struct weston_compositor *ec,
|
||||||
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;
|
||||||
gr->base.create_renderbuffer_dmabuf = gl_renderer_create_renderbuffer_dmabuf;
|
gr->base.create_renderbuffer_dmabuf = gl_renderer_create_renderbuffer_dmabuf;
|
||||||
gr->base.remove_renderbuffer_dmabuf = gl_renderer_remove_renderbuffer_dmabuf;
|
|
||||||
ret = populate_supported_formats(ec, &gr->supported_formats);
|
ret = populate_supported_formats(ec, &gr->supported_formats);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail_terminate;
|
goto fail_terminate;
|
||||||
|
|
|
||||||
|
|
@ -230,8 +230,8 @@ struct gl_renderer_interface {
|
||||||
* glReadPixels to download pixel data into the provided buffer after
|
* glReadPixels to download pixel data into the provided buffer after
|
||||||
* repaint.
|
* repaint.
|
||||||
*/
|
*/
|
||||||
struct weston_renderbuffer *(*create_fbo)(struct weston_output *output,
|
weston_renderbuffer_t (*create_fbo)(struct weston_output *output,
|
||||||
const struct pixel_format_info *format,
|
const struct pixel_format_info *format,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
uint32_t *pixels);
|
uint32_t *pixels);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue