compositor: Move tracking of scanout buffers to compositor-drm

dev
Kristian Høgsberg 13 years ago
parent 5f5e42ef50
commit 9f404b7ac8
  1. 58
      src/compositor-drm.c
  2. 51
      src/compositor.c
  3. 7
      src/compositor.h

@ -76,6 +76,10 @@ struct drm_output {
uint32_t fs_surf_fb_id; uint32_t fs_surf_fb_id;
uint32_t pending_fs_surf_fb_id; uint32_t pending_fs_surf_fb_id;
struct wl_buffer *scanout_buffer;
struct wl_listener scanout_buffer_destroy_listener;
struct wl_buffer *pending_scanout_buffer;
struct wl_listener pending_scanout_buffer_destroy_listener;
}; };
static int static int
@ -124,11 +128,11 @@ drm_output_prepare_scanout_surface(struct drm_output *output)
output->pending_fs_surf_fb_id = fb_id; output->pending_fs_surf_fb_id = fb_id;
/* assert output->pending_scanout_buffer == NULL */ /* assert output->pending_scanout_buffer == NULL */
output->base.pending_scanout_buffer = es->buffer; output->pending_scanout_buffer = es->buffer;
output->base.pending_scanout_buffer->busy_count++; output->pending_scanout_buffer->busy_count++;
wl_list_insert(output->base.pending_scanout_buffer->resource.destroy_listener_list.prev, wl_list_insert(output->pending_scanout_buffer->resource.destroy_listener_list.prev,
&output->base.pending_scanout_buffer_destroy_listener.link); &output->pending_scanout_buffer_destroy_listener.link);
pixman_region32_fini(&es->damage); pixman_region32_fini(&es->damage);
pixman_region32_init(&es->damage); pixman_region32_init(&es->damage);
@ -187,12 +191,20 @@ page_flip_handler(int fd, unsigned int frame,
(struct drm_compositor *) output->base.compositor; (struct drm_compositor *) output->base.compositor;
uint32_t msecs; uint32_t msecs;
if (output->fs_surf_fb_id) { if (output->scanout_buffer) {
weston_buffer_post_release(output->scanout_buffer);
wl_list_remove(&output->scanout_buffer_destroy_listener.link);
output->scanout_buffer = NULL;
drmModeRmFB(c->drm.fd, output->fs_surf_fb_id); drmModeRmFB(c->drm.fd, output->fs_surf_fb_id);
output->fs_surf_fb_id = 0; output->fs_surf_fb_id = 0;
} }
if (output->pending_fs_surf_fb_id) { if (output->pending_scanout_buffer) {
output->scanout_buffer = output->pending_scanout_buffer;
wl_list_remove(&output->pending_scanout_buffer_destroy_listener.link);
wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev,
&output->scanout_buffer_destroy_listener.link);
output->pending_scanout_buffer = NULL;
output->fs_surf_fb_id = output->pending_fs_surf_fb_id; output->fs_surf_fb_id = output->pending_fs_surf_fb_id;
output->pending_fs_surf_fb_id = 0; output->pending_fs_surf_fb_id = 0;
} }
@ -439,6 +451,35 @@ drm_subpixel_to_wayland(int drm_value)
} }
} }
static void
output_handle_scanout_buffer_destroy(struct wl_listener *listener,
struct wl_resource *resource,
uint32_t time)
{
struct drm_output *output =
container_of(listener, struct drm_output,
scanout_buffer_destroy_listener);
output->scanout_buffer = NULL;
if (!output->pending_scanout_buffer)
weston_compositor_schedule_repaint(output->base.compositor);
}
static void
output_handle_pending_scanout_buffer_destroy(struct wl_listener *listener,
struct wl_resource *resource,
uint32_t time)
{
struct drm_output *output =
container_of(listener, struct drm_output,
pending_scanout_buffer_destroy_listener);
output->pending_scanout_buffer = NULL;
weston_compositor_schedule_repaint(output->base.compositor);
}
static int static int
create_output_for_connector(struct drm_compositor *ec, create_output_for_connector(struct drm_compositor *ec,
drmModeRes *resources, drmModeRes *resources,
@ -563,6 +604,11 @@ create_output_for_connector(struct drm_compositor *ec,
wl_list_insert(ec->base.output_list.prev, &output->base.link); wl_list_insert(ec->base.output_list.prev, &output->base.link);
output->scanout_buffer_destroy_listener.func =
output_handle_scanout_buffer_destroy;
output->pending_scanout_buffer_destroy_listener.func =
output_handle_pending_scanout_buffer_destroy;
output->pending_fs_surf_fb_id = 0; output->pending_fs_surf_fb_id = 0;
output->base.repaint = drm_output_repaint; output->base.repaint = drm_output_repaint;
output->base.set_hardware_cursor = drm_output_set_cursor; output->base.set_hardware_cursor = drm_output_set_cursor;

@ -171,36 +171,6 @@ surface_handle_buffer_destroy(struct wl_listener *listener,
es->buffer = NULL; es->buffer = NULL;
} }
static void
output_handle_scanout_buffer_destroy(struct wl_listener *listener,
struct wl_resource *resource,
uint32_t time)
{
struct weston_output *output =
container_of(listener, struct weston_output,
scanout_buffer_destroy_listener);
output->scanout_buffer = NULL;
if (!output->pending_scanout_buffer)
weston_compositor_schedule_repaint(output->compositor);
}
static void
output_handle_pending_scanout_buffer_destroy(struct wl_listener *listener,
struct wl_resource *resource,
uint32_t time)
{
struct weston_output *output =
container_of(listener, struct weston_output,
pending_scanout_buffer_destroy_listener);
output->pending_scanout_buffer = NULL;
weston_compositor_schedule_repaint(output->compositor);
}
WL_EXPORT struct weston_surface * WL_EXPORT struct weston_surface *
weston_surface_create(struct weston_compositor *compositor, weston_surface_create(struct weston_compositor *compositor,
int32_t x, int32_t y, int32_t width, int32_t height) int32_t x, int32_t y, int32_t width, int32_t height)
@ -645,7 +615,7 @@ weston_compositor_damage_all(struct weston_compositor *compositor)
weston_output_damage(output); weston_output_damage(output);
} }
static inline void WL_EXPORT void
weston_buffer_post_release(struct wl_buffer *buffer) weston_buffer_post_release(struct wl_buffer *buffer)
{ {
if (--buffer->busy_count > 0) if (--buffer->busy_count > 0)
@ -883,20 +853,6 @@ idle_repaint(void *data)
WL_EXPORT void WL_EXPORT void
weston_output_finish_frame(struct weston_output *output, int msecs) weston_output_finish_frame(struct weston_output *output, int msecs)
{ {
if (output->scanout_buffer) {
weston_buffer_post_release(output->scanout_buffer);
wl_list_remove(&output->scanout_buffer_destroy_listener.link);
output->scanout_buffer = NULL;
}
if (output->pending_scanout_buffer) {
output->scanout_buffer = output->pending_scanout_buffer;
wl_list_remove(&output->pending_scanout_buffer_destroy_listener.link);
wl_list_insert(output->scanout_buffer->resource.destroy_listener_list.prev,
&output->scanout_buffer_destroy_listener.link);
output->pending_scanout_buffer = NULL;
}
if (output->repaint_needed) if (output->repaint_needed)
repaint(output, msecs); repaint(output, msecs);
else else
@ -1822,11 +1778,6 @@ weston_output_init(struct weston_output *output, struct weston_compositor *c,
output->flags = flags; output->flags = flags;
weston_output_move(output, x, y); weston_output_move(output, x, y);
output->scanout_buffer_destroy_listener.func =
output_handle_scanout_buffer_destroy;
output->pending_scanout_buffer_destroy_listener.func =
output_handle_pending_scanout_buffer_destroy;
wl_list_init(&output->frame_callback_list); wl_list_init(&output->frame_callback_list);
wl_display_add_global(c->wl_display, wl_display_add_global(c->wl_display,

@ -82,10 +82,6 @@ struct weston_output {
struct weston_mode *current; struct weston_mode *current;
struct wl_list mode_list; struct wl_list mode_list;
struct wl_buffer *scanout_buffer;
struct wl_listener scanout_buffer_destroy_listener;
struct wl_buffer *pending_scanout_buffer;
struct wl_listener pending_scanout_buffer_destroy_listener;
void (*repaint)(struct weston_output *output); void (*repaint)(struct weston_output *output);
int (*set_hardware_cursor)(struct weston_output *output, int (*set_hardware_cursor)(struct weston_output *output,
@ -366,6 +362,9 @@ weston_surface_damage_rectangle(struct weston_surface *surface,
int32_t x, int32_t y, int32_t x, int32_t y,
int32_t width, int32_t height); int32_t width, int32_t height);
void
weston_buffer_post_release(struct wl_buffer *buffer);
uint32_t uint32_t
weston_compositor_get_time(void); weston_compositor_get_time(void);

Loading…
Cancel
Save