pixman-renderer: add weston_renderbuffer and create/destroy interface

Add a create_image_from_ptr vfunc to struct pixman_renderer_interface,
which wraps weston_renderbuffer creation for the pixman renderer via
pixman_image_create_bits(), as well as a renderbuffer_destroy vfunc
to dispose of the pixman image renderbuffer.
Also add create_image_no_clear using pixman_image_create_bits_no_clear()
instead.

Make the backends create and destroy their pixman image renderbuffers
through this interface.

Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
This commit is contained in:
Philipp Zabel 2023-01-11 21:53:43 +01:00 committed by Daniel Stone
parent 32c7629516
commit 89e1831cd7
11 changed files with 183 additions and 69 deletions

View file

@ -593,7 +593,7 @@ struct drm_output {
struct drm_output_state *state_last; struct drm_output_state *state_last;
struct drm_fb *dumb[2]; struct drm_fb *dumb[2];
pixman_image_t *image[2]; struct weston_renderbuffer *renderbuffer[2];
int current_image; int current_image;
pixman_region32_t previous_damage; pixman_region32_t previous_damage;

View file

@ -344,7 +344,7 @@ drm_output_render_pixman(struct drm_output_state *state,
output->current_image ^= 1; output->current_image ^= 1;
pixman_renderer_output_set_buffer(&output->base, pixman_renderer_output_set_buffer(&output->base,
output->image[output->current_image]); output->renderbuffer[output->current_image]->image);
pixman_renderer_output_set_hw_extra_damage(&output->base, pixman_renderer_output_set_hw_extra_damage(&output->base,
&output->previous_damage); &output->previous_damage);
@ -1180,6 +1180,7 @@ static int
drm_output_init_pixman(struct drm_output *output, struct drm_backend *b) drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
{ {
struct weston_renderer *renderer = output->base.compositor->renderer; struct weston_renderer *renderer = output->base.compositor->renderer;
const struct pixman_renderer_interface *pixman = renderer->pixman;
struct drm_device *device = output->device; struct drm_device *device = output->device;
int w = output->base.current_mode->width; int w = output->base.current_mode->width;
int h = output->base.current_mode->height; int h = output->base.current_mode->height;
@ -1209,15 +1210,16 @@ drm_output_init_pixman(struct drm_output *output, struct drm_backend *b)
if (!output->dumb[i]) if (!output->dumb[i])
goto err; goto err;
output->image[i] = output->renderbuffer[i] =
pixman_image_create_bits(pixman_format, w, h, pixman->create_image_from_ptr(&output->base,
output->dumb[i]->map, pixman_format, w, h,
output->dumb[i]->strides[0]); output->dumb[i]->map,
if (!output->image[i]) output->dumb[i]->strides[0]);
if (!output->renderbuffer[i])
goto err; goto err;
} }
if (renderer->pixman->output_create(&output->base, &options) < 0) if (pixman->output_create(&output->base, &options) < 0)
goto err; goto err;
weston_log("DRM: output %s %s shadow framebuffer.\n", output->base.name, weston_log("DRM: output %s %s shadow framebuffer.\n", output->base.name,
@ -1232,11 +1234,11 @@ err:
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) { for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
if (output->dumb[i]) if (output->dumb[i])
drm_fb_unref(output->dumb[i]); drm_fb_unref(output->dumb[i]);
if (output->image[i]) if (output->renderbuffer[i])
pixman_image_unref(output->image[i]); pixman->renderbuffer_destroy(output->renderbuffer[i]);
output->dumb[i] = NULL; output->dumb[i] = NULL;
output->image[i] = NULL; output->renderbuffer[i] = NULL;
} }
return -1; return -1;
@ -1261,10 +1263,10 @@ drm_output_fini_pixman(struct drm_output *output)
pixman_region32_fini(&output->previous_damage); pixman_region32_fini(&output->previous_damage);
for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) { for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) {
pixman_image_unref(output->image[i]); renderer->pixman->renderbuffer_destroy(output->renderbuffer[i]);
drm_fb_unref(output->dumb[i]); drm_fb_unref(output->dumb[i]);
output->dumb[i] = NULL; output->dumb[i] = NULL;
output->image[i] = NULL; output->renderbuffer[i] = NULL;
} }
} }

View file

@ -70,7 +70,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;
pixman_image_t *image; struct weston_renderbuffer *renderbuffer;
struct frame *frame; struct frame *frame;
struct { struct {
@ -191,7 +191,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;
renderer->pixman->output_destroy(&output->base); renderer->pixman->output_destroy(&output->base);
pixman_image_unref(output->image); renderer->pixman->renderbuffer_destroy(output->renderbuffer);
} }
static int static int
@ -304,23 +304,24 @@ headless_output_enable_pixman(struct headless_output *output)
pixman = output->base.compositor->renderer->pixman; pixman = output->base.compositor->renderer->pixman;
pfmt = pixel_format_get_info(headless_formats[0]); pfmt = pixel_format_get_info(headless_formats[0]);
output->image = output->renderbuffer =
pixman_image_create_bits_no_clear(pfmt->pixman_format, pixman->create_image_no_clear(&output->base,
output->base.current_mode->width, pfmt->pixman_format,
output->base.current_mode->height, output->base.current_mode->width,
NULL, 0); output->base.current_mode->height);
if (!output->image) if (!output->renderbuffer)
return -1; return -1;
if (pixman->output_create(&output->base, &options) < 0) if (pixman->output_create(&output->base, &options) < 0)
goto err_renderer; goto err_renderer;
pixman_renderer_output_set_buffer(&output->base, output->image); pixman_renderer_output_set_buffer(&output->base,
output->renderbuffer->image);
return 0; return 0;
err_renderer: err_renderer:
pixman_image_unref(output->image); pixman->renderbuffer_destroy(output->renderbuffer);
return -1; return -1;
} }

View file

@ -249,11 +249,11 @@ rdp_peer_refresh_region(pixman_region32_t *region, freerdp_peer *peer)
rdpSettings *settings = peer->context->settings; rdpSettings *settings = peer->context->settings;
if (settings->RemoteFxCodec) if (settings->RemoteFxCodec)
rdp_peer_refresh_rfx(region, output->shadow_surface, peer); rdp_peer_refresh_rfx(region, output->renderbuffer->image, peer);
else if (settings->NSCodec) else if (settings->NSCodec)
rdp_peer_refresh_nsc(region, output->shadow_surface, peer); rdp_peer_refresh_nsc(region, output->renderbuffer->image, peer);
else else
rdp_peer_refresh_raw(region, output->shadow_surface, peer); rdp_peer_refresh_raw(region, output->renderbuffer->image, peer);
} }
static int static int
@ -295,7 +295,8 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage)
assert(output); assert(output);
pixman_renderer_output_set_buffer(output_base, output->shadow_surface); pixman_renderer_output_set_buffer(output_base,
output->renderbuffer->image);
ec->renderer->repaint_output(&output->base, damage); ec->renderer->repaint_output(&output->base, damage);
if (pixman_region32_not_empty(damage)) { if (pixman_region32_not_empty(damage)) {
@ -391,7 +392,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;
pixman_image_t *new_shadow_buffer; struct weston_renderbuffer *new_renderbuffer;
mode->refresh = b->rdp_monitor_refresh_rate; mode->refresh = b->rdp_monitor_refresh_rate;
cur = ensure_single_mode(base, mode); cur = ensure_single_mode(base, mode);
@ -399,16 +400,24 @@ rdp_output_set_mode(struct weston_output *base, struct weston_mode *mode)
base->current_mode = cur; base->current_mode = cur;
base->native_mode = cur; base->native_mode = cur;
if (base->enabled) { if (base->enabled) {
const struct pixman_renderer_interface *pixman;
weston_renderer_resize_output(output, &(struct weston_size){ weston_renderer_resize_output(output, &(struct weston_size){
.width = output->current_mode->width, .width = output->current_mode->width,
.height = output->current_mode->height }, NULL); .height = output->current_mode->height }, NULL);
new_shadow_buffer = pixman_image_create_bits(PIXMAN_x8r8g8b8, mode->width, pixman = b->compositor->renderer->pixman;
mode->height, 0, mode->width * 4);
pixman_image_composite32(PIXMAN_OP_SRC, rdpOutput->shadow_surface, 0, new_shadow_buffer, new_renderbuffer =
0, 0, 0, 0, 0, 0, mode->width, mode->height); pixman->create_image_from_ptr(output, PIXMAN_x8r8g8b8,
pixman_image_unref(rdpOutput->shadow_surface); mode->width, mode->height,
rdpOutput->shadow_surface = new_shadow_buffer; 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);
pixman->renderbuffer_destroy(rdpOutput->renderbuffer);
rdpOutput->renderbuffer = new_renderbuffer;
} }
/* Apparently settings->DesktopWidth is supposed to be primary only. /* Apparently settings->DesktopWidth is supposed to be primary only.
@ -457,7 +466,8 @@ rdp_head_get_monitor(struct weston_head *base,
static int static int
rdp_output_enable(struct weston_output *base) rdp_output_enable(struct weston_output *base)
{ {
struct weston_renderer *renderer = base->compositor->renderer; const struct weston_renderer *renderer = base->compositor->renderer;
const struct pixman_renderer_interface *pixman = renderer->pixman;
struct rdp_output *output = to_rdp_output(base); struct rdp_output *output = to_rdp_output(base);
struct rdp_backend *b; struct rdp_backend *b;
struct wl_event_loop *loop; struct wl_event_loop *loop;
@ -472,18 +482,19 @@ rdp_output_enable(struct weston_output *base)
b = output->backend; b = output->backend;
output->shadow_surface = pixman_image_create_bits(PIXMAN_x8r8g8b8, output->renderbuffer =
output->base.current_mode->width, pixman->create_image_from_ptr(&output->base, PIXMAN_x8r8g8b8,
output->base.current_mode->height, output->base.current_mode->width,
NULL, output->base.current_mode->height,
output->base.current_mode->width * 4); NULL,
if (output->shadow_surface == NULL) { output->base.current_mode->width * 4);
if (output->renderbuffer == NULL) {
weston_log("Failed to create surface for frame buffer.\n"); weston_log("Failed to create surface for frame buffer.\n");
return -1; return -1;
} }
if (renderer->pixman->output_create(&output->base, &options) < 0) { if (renderer->pixman->output_create(&output->base, &options) < 0) {
pixman_image_unref(output->shadow_surface); renderer->pixman->renderbuffer_destroy(output->renderbuffer);
return -1; return -1;
} }
@ -504,7 +515,7 @@ rdp_output_disable(struct weston_output *base)
if (!output->base.enabled) if (!output->base.enabled)
return 0; return 0;
pixman_image_unref(output->shadow_surface); renderer->pixman->renderbuffer_destroy(output->renderbuffer);
renderer->pixman->output_destroy(&output->base); renderer->pixman->output_destroy(&output->base);
wl_event_source_remove(output->finish_frame_timer); wl_event_source_remove(output->finish_frame_timer);

View file

@ -125,7 +125,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;
pixman_image_t *shadow_surface; struct weston_renderbuffer *renderbuffer;
}; };
struct rdp_peer_context { struct rdp_peer_context {

View file

@ -99,7 +99,8 @@ struct vnc_head {
}; };
struct fb_side_data { struct fb_side_data {
pixman_image_t *pixman_image; struct weston_renderer *renderer;
struct weston_renderbuffer *renderbuffer;
pixman_region32_t damage; pixman_region32_t damage;
struct wl_list link; struct wl_list link;
}; };
@ -447,10 +448,11 @@ static void
fb_side_data_destroy(void *userdata) fb_side_data_destroy(void *userdata)
{ {
struct fb_side_data *fb_side_data = userdata; struct fb_side_data *fb_side_data = userdata;
struct weston_renderer *renderer = fb_side_data->renderer;
wl_list_remove(&fb_side_data->link); wl_list_remove(&fb_side_data->link);
pixman_region32_fini(&fb_side_data->damage); pixman_region32_fini(&fb_side_data->damage);
pixman_image_unref(fb_side_data->pixman_image); renderer->pixman->renderbuffer_destroy(fb_side_data->renderbuffer);
free(fb_side_data); free(fb_side_data);
} }
@ -501,17 +503,21 @@ vnc_update_buffer(struct nvnc_display *display, struct pixman_region32 *damage)
fb_side_data = nvnc_get_userdata(fb); fb_side_data = nvnc_get_userdata(fb);
if (!fb_side_data) { if (!fb_side_data) {
const struct pixman_renderer_interface *pixman;
const struct pixel_format_info *pfmt; const struct pixel_format_info *pfmt;
fb_side_data = xzalloc(sizeof(*fb_side_data)); fb_side_data = xzalloc(sizeof(*fb_side_data));
pixman = ec->renderer->pixman;
pfmt = pixel_format_get_info(DRM_FORMAT_XRGB8888); pfmt = pixel_format_get_info(DRM_FORMAT_XRGB8888);
fb_side_data->pixman_image = fb_side_data->renderer = ec->renderer;
pixman_image_create_bits(pfmt->pixman_format, fb_side_data->renderbuffer =
output->base.width, pixman->create_image_from_ptr(&output->base,
output->base.height, pfmt->pixman_format,
nvnc_fb_get_addr(fb), output->base.width,
output->base.width * 4); output->base.height,
nvnc_fb_get_addr(fb),
output->base.width * 4);
/* This is a new buffer, so the whole surface is damaged. */ /* This is a new buffer, so the whole surface is damaged. */
pixman_region32_copy(&fb_side_data->damage, pixman_region32_copy(&fb_side_data->damage,
@ -522,7 +528,7 @@ vnc_update_buffer(struct nvnc_display *display, struct pixman_region32 *damage)
} }
pixman_renderer_output_set_buffer(&output->base, pixman_renderer_output_set_buffer(&output->base,
fb_side_data->pixman_image); fb_side_data->renderbuffer->image);
ec->renderer->repaint_output(&output->base, &fb_side_data->damage); ec->renderer->repaint_output(&output->base, &fb_side_data->damage);

View file

@ -182,6 +182,7 @@ struct wayland_shm_buffer {
pixman_region32_t damage; /**< in global coords */ pixman_region32_t damage; /**< in global coords */
int frame_damaged; int frame_damaged;
struct weston_renderbuffer *renderbuffer;
pixman_image_t *pm_image; pixman_image_t *pm_image;
cairo_surface_t *c_surface; cairo_surface_t *c_surface;
}; };
@ -257,7 +258,14 @@ static void
wayland_shm_buffer_destroy(struct wayland_shm_buffer *buffer) wayland_shm_buffer_destroy(struct wayland_shm_buffer *buffer)
{ {
cairo_surface_destroy(buffer->c_surface); cairo_surface_destroy(buffer->c_surface);
pixman_image_unref(buffer->pm_image); if (buffer->pm_image)
pixman_image_unref(buffer->pm_image);
if (buffer->output) {
const struct pixman_renderer_interface *pixman;
pixman = buffer->output->base.compositor->renderer->pixman;
pixman->renderbuffer_destroy(buffer->renderbuffer);
}
wl_buffer_destroy(buffer->buffer); wl_buffer_destroy(buffer->buffer);
munmap(buffer->data, buffer->size); munmap(buffer->data, buffer->size);
@ -288,6 +296,8 @@ static const struct wl_buffer_listener buffer_listener = {
static struct wayland_shm_buffer * static struct wayland_shm_buffer *
wayland_output_get_shm_buffer(struct wayland_output *output) wayland_output_get_shm_buffer(struct wayland_output *output)
{ {
const struct weston_renderer *renderer;
const struct pixman_renderer_interface *pixman;
struct wayland_backend *b = output->backend; struct wayland_backend *b = output->backend;
struct wl_shm *shm = b->parent.shm; struct wl_shm *shm = b->parent.shm;
struct wayland_shm_buffer *sb; struct wayland_shm_buffer *sb;
@ -380,11 +390,23 @@ wayland_output_get_shm_buffer(struct wayland_output *output)
area.height = output->base.current_mode->height; area.height = output->base.current_mode->height;
} }
renderer = b->compositor->renderer;
pixman = renderer->pixman;
/* Address only the interior, excluding output decorations */ /* Address only the interior, excluding output decorations */
sb->pm_image = if (renderer->type == WESTON_RENDERER_PIXMAN) {
pixman_image_create_bits(PIXMAN_a8r8g8b8, area.width, area.height, sb->renderbuffer =
(uint32_t *)(data + area.y * stride) + area.x, pixman->create_image_from_ptr(&output->base, PIXMAN_a8r8g8b8,
stride); area.width, area.height,
(uint32_t *)(data + area.y * stride) + area.x,
stride);
} else {
sb->pm_image =
pixman_image_create_bits(PIXMAN_a8r8g8b8,
area.width, area.height,
(uint32_t *)(data + area.y * stride) + area.x,
stride);
}
return sb; return sb;
} }
@ -608,7 +630,7 @@ wayland_output_repaint_pixman(struct weston_output *output_base,
sb = wayland_output_get_shm_buffer(output); sb = wayland_output_get_shm_buffer(output);
wayland_output_update_shm_border(sb); wayland_output_update_shm_border(sb);
pixman_renderer_output_set_buffer(output_base, sb->pm_image); pixman_renderer_output_set_buffer(output_base, sb->renderbuffer->image);
b->compositor->renderer->repaint_output(output_base, &sb->damage); b->compositor->renderer->repaint_output(output_base, &sb->damage);
wayland_shm_buffer_attach(sb); wayland_shm_buffer_attach(sb);

View file

@ -136,7 +136,7 @@ struct x11_output {
xcb_gc_t gc; xcb_gc_t gc;
xcb_shm_seg_t segment; xcb_shm_seg_t segment;
pixman_image_t *hw_surface; struct weston_renderbuffer *renderbuffer;
int shm_id; int shm_id;
void *buf; void *buf;
uint8_t depth; uint8_t depth;
@ -501,6 +501,7 @@ x11_output_repaint_shm(struct weston_output *output_base,
pixman_region32_t *damage) pixman_region32_t *damage)
{ {
struct x11_output *output = to_x11_output(output_base); struct x11_output *output = to_x11_output(output_base);
pixman_image_t *image = output->renderbuffer->image;
struct weston_compositor *ec; struct weston_compositor *ec;
struct x11_backend *b; struct x11_backend *b;
xcb_void_cookie_t cookie; xcb_void_cookie_t cookie;
@ -511,18 +512,18 @@ x11_output_repaint_shm(struct weston_output *output_base,
ec = output->base.compositor; ec = output->base.compositor;
b = output->backend; b = output->backend;
pixman_renderer_output_set_buffer(output_base, output->hw_surface); pixman_renderer_output_set_buffer(output_base, image);
ec->renderer->repaint_output(output_base, damage); ec->renderer->repaint_output(output_base, damage);
pixman_region32_subtract(&ec->primary_plane.damage, pixman_region32_subtract(&ec->primary_plane.damage,
&ec->primary_plane.damage, damage); &ec->primary_plane.damage, damage);
set_clip_for_output(output_base, damage); set_clip_for_output(output_base, damage);
cookie = xcb_shm_put_image_checked(b->conn, output->window, output->gc, cookie = xcb_shm_put_image_checked(b->conn, output->window, output->gc,
pixman_image_get_width(output->hw_surface), pixman_image_get_width(image),
pixman_image_get_height(output->hw_surface), pixman_image_get_height(image),
0, 0, 0, 0,
pixman_image_get_width(output->hw_surface), pixman_image_get_width(image),
pixman_image_get_height(output->hw_surface), pixman_image_get_height(image),
0, 0, output->depth, XCB_IMAGE_FORMAT_Z_PIXMAP, 0, 0, output->depth, XCB_IMAGE_FORMAT_Z_PIXMAP,
0, output->segment, 0); 0, output->segment, 0);
err = xcb_request_check(b->conn, cookie); err = xcb_request_check(b->conn, cookie);
@ -550,12 +551,13 @@ finish_frame_handler(void *data)
static void static void
x11_output_deinit_shm(struct x11_backend *b, struct x11_output *output) x11_output_deinit_shm(struct x11_backend *b, struct x11_output *output)
{ {
const struct weston_renderer *renderer = b->compositor->renderer;
xcb_void_cookie_t cookie; xcb_void_cookie_t cookie;
xcb_generic_error_t *err; xcb_generic_error_t *err;
xcb_free_gc(b->conn, output->gc); xcb_free_gc(b->conn, output->gc);
pixman_image_unref(output->hw_surface); renderer->pixman->renderbuffer_destroy(output->renderbuffer);
output->hw_surface = 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);
if (err) { if (err) {
@ -719,6 +721,7 @@ static int
x11_output_init_shm(struct x11_backend *b, struct x11_output *output, x11_output_init_shm(struct x11_backend *b, struct x11_output *output,
int width, int height) int width, int height)
{ {
struct weston_renderer *renderer = output->base.compositor->renderer;
xcb_visualtype_t *visual_type; xcb_visualtype_t *visual_type;
xcb_screen_t *screen; xcb_screen_t *screen;
xcb_format_iterator_t fmt; xcb_format_iterator_t fmt;
@ -806,8 +809,11 @@ x11_output_init_shm(struct x11_backend *b, struct x11_output *output,
shmctl(output->shm_id, IPC_RMID, NULL); shmctl(output->shm_id, IPC_RMID, NULL);
/* Now create pixman image */ /* Now create pixman image */
output->hw_surface = pixman_image_create_bits(pixman_format, width, height, output->buf, output->renderbuffer =
width * (bitsperpixel / 8)); renderer->pixman->create_image_from_ptr(&output->base,
pixman_format, width,
height, output->buf,
width * (bitsperpixel / 8));
output->gc = xcb_generate_id(b->conn); output->gc = xcb_generate_id(b->conn);
xcb_create_gc(b->conn, output->gc, output->window, 0, NULL); xcb_create_gc(b->conn, output->gc, output->window, 0, NULL);

View file

@ -46,6 +46,10 @@
/* compositor <-> renderer interface */ /* compositor <-> renderer interface */
struct weston_renderbuffer {
pixman_image_t *image;
};
struct weston_renderer_options { struct weston_renderer_options {
}; };

View file

@ -1110,7 +1110,56 @@ pixman_renderer_output_destroy(struct weston_output *output)
free(po); free(po);
} }
static struct weston_renderbuffer *
pixman_renderer_create_image_from_ptr(struct weston_output *output,
pixman_format_code_t format, int width,
int height, uint32_t *ptr, int rowstride)
{
struct weston_renderbuffer *renderbuffer;
renderbuffer = xzalloc(sizeof(*renderbuffer));
renderbuffer->image = pixman_image_create_bits(format, width, height,
ptr, rowstride);
if (!renderbuffer->image) {
free(renderbuffer);
return NULL;
}
return renderbuffer;
}
static struct weston_renderbuffer *
pixman_renderer_create_image_no_clear(struct weston_output *output,
pixman_format_code_t format, int width,
int height)
{
struct weston_renderbuffer *renderbuffer;
renderbuffer = xzalloc(sizeof(*renderbuffer));
renderbuffer->image =
pixman_image_create_bits_no_clear(format, width, height,
NULL, 0);
if (!renderbuffer->image) {
free(renderbuffer);
return NULL;
}
return renderbuffer;
}
static void
pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer)
{
pixman_image_unref(renderbuffer->image);
free(renderbuffer);
}
static struct pixman_renderer_interface pixman_renderer_interface = { static struct pixman_renderer_interface pixman_renderer_interface = {
.output_create = pixman_renderer_output_create, .output_create = pixman_renderer_output_create,
.output_destroy = pixman_renderer_output_destroy, .output_destroy = pixman_renderer_output_destroy,
.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,
}; };

View file

@ -28,6 +28,7 @@
#include <libweston/libweston.h> #include <libweston/libweston.h>
#include "backend.h" #include "backend.h"
#include "libweston-internal.h" #include "libweston-internal.h"
#include "pixman.h"
int int
pixman_renderer_init(struct weston_compositor *ec); pixman_renderer_init(struct weston_compositor *ec);
@ -51,4 +52,16 @@ struct pixman_renderer_interface {
int (*output_create)(struct weston_output *output, int (*output_create)(struct weston_output *output,
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,
pixman_format_code_t format,
int width,
int height,
uint32_t *ptr,
int stride);
struct weston_renderbuffer *(*create_image_no_clear)(struct weston_output *output,
pixman_format_code_t format,
int width,
int height);
void (*renderbuffer_destroy)(struct weston_renderbuffer *renderbuffer);
}; };