pixman-renderer: add pixman_renderbuffer specialization

Add a private struct pixman_renderbuffer that derives from struct
weston_renderbuffer and move the pixman renderer specific image and link
fields into it.

Add a pixman_renderbuffer_get_image() helper for the backends that need
to access the contained pixman image, RDP and X11.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
This commit is contained in:
Philipp Zabel 2023-01-13 16:14:18 +01:00 committed by Daniel Stone
parent 4d96635a3f
commit 116c234703
5 changed files with 61 additions and 25 deletions

View File

@ -247,13 +247,18 @@ rdp_peer_refresh_region(pixman_region32_t *region, freerdp_peer *peer)
RdpPeerContext *context = (RdpPeerContext *)peer->context;
struct rdp_output *output = rdp_get_first_output(context->rdpBackend);
rdpSettings *settings = peer->context->settings;
const struct weston_renderer *renderer;
pixman_image_t *image;
renderer = output->base.compositor->renderer;
image = renderer->pixman->renderbuffer_get_image(output->renderbuffer);
if (settings->RemoteFxCodec)
rdp_peer_refresh_rfx(region, output->renderbuffer->image, peer);
rdp_peer_refresh_rfx(region, image, peer);
else if (settings->NSCodec)
rdp_peer_refresh_nsc(region, output->renderbuffer->image, peer);
rdp_peer_refresh_nsc(region, image, peer);
else
rdp_peer_refresh_raw(region, output->renderbuffer->image, peer);
rdp_peer_refresh_raw(region, image, peer);
}
static int
@ -400,21 +405,24 @@ rdp_output_set_mode(struct weston_output *base, struct weston_mode *mode)
base->native_mode = cur;
if (base->enabled) {
const struct pixman_renderer_interface *pixman;
pixman_image_t *old_image, *new_image;
weston_renderer_resize_output(output, &(struct weston_size){
.width = output->current_mode->width,
.height = output->current_mode->height }, NULL);
pixman = b->compositor->renderer->pixman;
old_image =
pixman->renderbuffer_get_image(rdpOutput->renderbuffer);
new_renderbuffer =
pixman->create_image_from_ptr(output, PIXMAN_x8r8g8b8,
mode->width, mode->height,
0, mode->width * 4);
pixman_image_composite32(PIXMAN_OP_SRC,
rdpOutput->renderbuffer->image, 0,
new_renderbuffer->image,
0, 0, 0, 0, 0, 0,
mode->width, mode->height);
new_image = pixman->renderbuffer_get_image(new_renderbuffer);
pixman_image_composite32(PIXMAN_OP_SRC, old_image, 0, new_image,
0, 0, 0, 0, 0, 0, mode->width,
mode->height);
pixman->renderbuffer_destroy(rdpOutput->renderbuffer);
rdpOutput->renderbuffer = new_renderbuffer;
}

View File

@ -501,7 +501,8 @@ x11_output_repaint_shm(struct weston_output *output_base,
pixman_region32_t *damage)
{
struct x11_output *output = to_x11_output(output_base);
pixman_image_t *image = output->renderbuffer->image;
const struct weston_renderer *renderer;
pixman_image_t *image;
struct weston_compositor *ec;
struct x11_backend *b;
xcb_void_cookie_t cookie;
@ -510,8 +511,11 @@ x11_output_repaint_shm(struct weston_output *output_base,
assert(output);
ec = output->base.compositor;
renderer = ec->renderer;
b = output->backend;
image = renderer->pixman->renderbuffer_get_image(output->renderbuffer);
ec->renderer->repaint_output(output_base, damage, output->renderbuffer);
pixman_region32_subtract(&ec->primary_plane.damage,

View File

@ -47,9 +47,7 @@
/* compositor <-> renderer interface */
struct weston_renderbuffer {
pixman_image_t *image;
pixman_region32_t damage;
struct wl_list link;
};
struct weston_renderer_options {

View File

@ -64,6 +64,13 @@ struct pixman_surface_state {
struct wl_listener renderer_destroy_listener;
};
struct pixman_renderbuffer {
struct weston_renderbuffer base;
pixman_image_t *image;
struct wl_list link;
};
struct pixman_renderer {
struct weston_renderer base;
@ -74,6 +81,15 @@ struct pixman_renderer {
struct wl_signal destroy_signal;
};
static pixman_image_t *
pixman_renderer_renderbuffer_get_image(struct weston_renderbuffer *renderbuffer)
{
struct pixman_renderbuffer *rb;
rb = container_of(renderbuffer, struct pixman_renderbuffer, base);
return rb->image;
}
static inline struct pixman_output_state *
get_output_state(struct weston_output *output)
{
@ -627,11 +643,13 @@ pixman_renderer_repaint_output(struct weston_output *output,
struct weston_renderbuffer *renderbuffer)
{
struct pixman_output_state *po = get_output_state(output);
struct weston_renderbuffer *rb;
struct pixman_renderbuffer *rb;
assert(renderbuffer);
pixman_renderer_output_set_buffer(output, renderbuffer->image);
rb = container_of(renderbuffer, struct pixman_renderbuffer, base);
pixman_renderer_output_set_buffer(output, rb->image);
assert(output->from_blend_to_output_by_backend ||
output->color_outcome->from_blend_to_output == NULL);
@ -640,8 +658,11 @@ pixman_renderer_repaint_output(struct weston_output *output,
return;
/* Accumulate damage in all renderbuffers */
wl_list_for_each(rb, &po->renderbuffer_list, link)
pixman_region32_union(&rb->damage, &rb->damage, output_damage);
wl_list_for_each(rb, &po->renderbuffer_list, link) {
pixman_region32_union(&rb->base.damage,
&rb->base.damage,
output_damage);
}
if (po->shadow_image) {
repaint_surfaces(output, output_damage);
@ -1113,7 +1134,7 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output,
int height, uint32_t *ptr, int rowstride)
{
struct pixman_output_state *po = get_output_state(output);
struct weston_renderbuffer *renderbuffer;
struct pixman_renderbuffer *renderbuffer;
assert(po);
@ -1126,10 +1147,10 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output,
return NULL;
}
pixman_region32_init(&renderbuffer->damage);
pixman_region32_init(&renderbuffer->base.damage);
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
return renderbuffer;
return &renderbuffer->base;
}
static struct weston_renderbuffer *
@ -1138,7 +1159,7 @@ pixman_renderer_create_image_no_clear(struct weston_output *output,
int height)
{
struct pixman_output_state *po = get_output_state(output);
struct weston_renderbuffer *renderbuffer;
struct pixman_renderbuffer *renderbuffer;
assert(po);
@ -1152,19 +1173,22 @@ pixman_renderer_create_image_no_clear(struct weston_output *output,
return NULL;
}
pixman_region32_init(&renderbuffer->damage);
pixman_region32_init(&renderbuffer->base.damage);
wl_list_insert(&po->renderbuffer_list, &renderbuffer->link);
return renderbuffer;
return &renderbuffer->base;
}
static void
pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
{
wl_list_remove(&renderbuffer->link);
pixman_image_unref(renderbuffer->image);
pixman_region32_fini(&renderbuffer->damage);
free(renderbuffer);
struct pixman_renderbuffer *rb;
rb = container_of(renderbuffer, struct pixman_renderbuffer, base);
wl_list_remove(&rb->link);
pixman_image_unref(rb->image);
pixman_region32_fini(&rb->base.damage);
free(rb);
}
static struct pixman_renderer_interface pixman_renderer_interface = {
@ -1173,4 +1197,5 @@ static struct pixman_renderer_interface pixman_renderer_interface = {
.create_image_from_ptr = pixman_renderer_create_image_from_ptr,
.create_image_no_clear = pixman_renderer_create_image_no_clear,
.renderbuffer_destroy = pixman_renderer_renderbuffer_destroy,
.renderbuffer_get_image = pixman_renderer_renderbuffer_get_image,
};

View File

@ -56,4 +56,5 @@ struct pixman_renderer_interface {
int width,
int height);
void (*renderbuffer_destroy)(struct weston_renderbuffer *renderbuffer);
pixman_image_t *(*renderbuffer_get_image)(struct weston_renderbuffer *renderbuffer);
};