}
static void
-drm_output_flush_surface_damage(void *o, pepper_surface_t *surface)
+drm_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
{
- pepper_renderer_flush_surface_damage(((drm_output_t *)o)->renderer, surface);
+ drm_output_t *output = o;
+ pepper_buffer_t *buffer = pepper_surface_get_buffer(surface);
+
+ pepper_renderer_flush_surface_damage(output->renderer, surface);
+
+ if (output->render_type == DRM_RENDER_TYPE_PIXMAN ||
+ (buffer && !wl_shm_buffer_get(pepper_buffer_get_resource(buffer))))
+ {
+ *keep_buffer = PEPPER_TRUE;
+ }
+ else
+ {
+ *keep_buffer = PEPPER_FALSE;
+ }
}
struct pepper_output_backend drm_output_backend =
}
static void
-fbdev_output_flush_surface_damage(void *o, pepper_surface_t *surface)
+fbdev_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
{
pepper_renderer_flush_surface_damage(((fbdev_output_t *)o)->renderer, surface);
+ *keep_buffer = PEPPER_TRUE;
}
struct pepper_output_backend fbdev_output_backend =
struct {
pepper_buffer_t *buffer;
- pepper_event_listener_t *release_listener;
+ pepper_bool_t has_ref;
pepper_event_listener_t *destroy_listener;
int32_t x, y;
int32_t transform;
int32_t scale;
- pepper_bool_t flushed;
} buffer;
/* Surface size in surface local coordinate space.
void (*start_repaint_loop)(void *output);
void (*repaint)(void *output, const pepper_list_t *plane_list);
void (*attach_surface)(void *output, pepper_surface_t *surface, int *w, int *h);
- void (*flush_surface_damage)(void *output, pepper_surface_t *surface);
+ void (*flush_surface_damage)(void *output, pepper_surface_t *surface,
+ pepper_bool_t *keep_buffer);
};
PEPPER_API pepper_output_t *
}
static void
-surface_handle_buffer_release(pepper_event_listener_t *listener,
- pepper_object_t *object, uint32_t id, void *info, void *data)
-{
- pepper_surface_t *surface = data;
- surface->buffer.buffer = NULL;
- pepper_event_listener_remove(listener);
- pepper_event_listener_remove(surface->buffer.destroy_listener);
-}
-
-static void
surface_handle_buffer_destroy(pepper_event_listener_t *listener,
pepper_object_t *object, uint32_t id, void *info, void *data)
{
if (surface->buffer.buffer)
{
pepper_event_listener_remove(surface->buffer.destroy_listener);
- pepper_event_listener_remove(surface->buffer.release_listener);
pepper_buffer_unreference(surface->buffer.buffer);
}
if (surface->buffer.buffer)
{
pepper_event_listener_remove(surface->buffer.destroy_listener);
- pepper_event_listener_remove(surface->buffer.release_listener);
- if (!surface->buffer.flushed)
+ if (surface->buffer.has_ref)
pepper_buffer_unreference(surface->buffer.buffer);
}
{
pepper_event_listener_remove(surface->pending.buffer_destroy_listener);
pepper_buffer_reference(surface->pending.buffer);
-
- surface->buffer.release_listener =
- pepper_object_add_event_listener(&surface->pending.buffer->base,
- PEPPER_EVENT_BUFFER_RELEASE, 0,
- surface_handle_buffer_release, surface);
+ surface->buffer.has_ref = PEPPER_TRUE;
surface->buffer.destroy_listener =
pepper_object_add_event_listener(&surface->pending.buffer->base,
surface->buffer.buffer = surface->pending.buffer;
surface->buffer.x += surface->pending.x;
surface->buffer.y += surface->pending.y;
- surface->buffer.flushed = PEPPER_FALSE;
surface->pending.newly_attached = PEPPER_FALSE;
surface->pending.buffer = NULL;
{
pepper_view_t *view;
pepper_output_t *output;
+ pepper_bool_t release_buffer = PEPPER_TRUE;
if (!pixman_region32_not_empty(&surface->damage_region))
return;
pepper_view_surface_damage(view);
pepper_list_for_each(output, &surface->compositor->output_list, link)
- output->backend->flush_surface_damage(output->data, surface);
+ {
+ pepper_bool_t keep_buffer;
+
+ output->backend->flush_surface_damage(output->data, surface, &keep_buffer);
+
+ if (keep_buffer)
+ release_buffer = PEPPER_FALSE;
+ }
pixman_region32_clear(&surface->damage_region);
- if (surface->buffer.buffer)
+ if (surface->buffer.buffer && release_buffer)
{
pepper_buffer_unreference(surface->buffer.buffer);
- surface->buffer.flushed = PEPPER_TRUE;
+ surface->buffer.has_ref = PEPPER_FALSE;
}
}
if (state->buffer)
{
- pepper_buffer_unreference(state->buffer);
pepper_event_listener_remove(state->buffer_destroy_listener);
state->buffer = NULL;
}
if (state->buffer)
{
- pepper_buffer_reference(state->buffer);
state->buffer_destroy_listener =
pepper_object_add_event_listener((pepper_object_t *)buffer,
PEPPER_EVENT_OBJECT_DESTROY, 0,
wl_shm_buffer_end_access(state->shm.buffer);
}
- pepper_buffer_unreference(state->buffer);
state->buffer = NULL;
-
return PEPPER_TRUE;
}
if (state->buffer)
{
- pepper_buffer_unreference(state->buffer);
pepper_event_listener_remove(state->buffer_destroy_listener);
state->buffer = NULL;
}
if (state->buffer)
{
- pepper_buffer_reference(state->buffer);
state->buffer_destroy_listener =
pepper_object_add_event_listener((pepper_object_t *)buffer,
PEPPER_EVENT_OBJECT_DESTROY, 0,
}
static void
-wayland_output_flush_surface_damage(void *o, pepper_surface_t *surface)
+wayland_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
{
- pepper_renderer_flush_surface_damage(((wayland_output_t *)o)->renderer, surface);
+ wayland_output_t *output = o;
+ pepper_buffer_t *buffer = pepper_surface_get_buffer(surface);
+
+ pepper_renderer_flush_surface_damage(output->renderer, surface);
+
+ if (output->renderer == output->conn->pixman_renderer ||
+ (buffer && !wl_shm_buffer_get(pepper_buffer_get_resource(buffer))))
+ {
+ *keep_buffer = PEPPER_TRUE;
+ }
+ else
+ {
+ *keep_buffer = PEPPER_FALSE;
+ }
}
static const pepper_output_backend_t wayland_output_backend =
}
static void
-x11_output_flush_surface_damage(void *o, pepper_surface_t *surface)
+x11_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
{
- pepper_renderer_flush_surface_damage(((x11_output_t *)o)->renderer, surface);
+ x11_output_t *output = o;
+ pepper_buffer_t *buffer = pepper_surface_get_buffer(surface);
+
+ pepper_renderer_flush_surface_damage(output->renderer, surface);
+
+ if (output->renderer == output->connection->pixman_renderer ||
+ (buffer && !wl_shm_buffer_get(pepper_buffer_get_resource(buffer))))
+ {
+ *keep_buffer = PEPPER_TRUE;
+ }
+ else
+ {
+ *keep_buffer = PEPPER_FALSE;
+ }
}
/* X11 output backend to export for PePPer core */