[PATCH weston 3/5] compositor-drm: Wait for vblank events before starting next frame
Ander Conselvan de Oliveira
conselvan2 at gmail.com
Tue Jun 26 07:09:13 PDT 2012
Besides the fact of the frame not being done, assigning planes before
the vblank handler is called will make the state inconsistent, leading
to a crash.
---
src/compositor-drm.c | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 5543462..d969d52 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -98,6 +98,9 @@ struct drm_output {
uint32_t connector_id;
drmModeCrtcPtr original_crtc;
+ int vblank_pending;
+ int page_flip_pending;
+
struct gbm_surface *surface;
struct gbm_bo *cursor_bo[2];
int current_cursor;
@@ -118,6 +121,8 @@ struct drm_sprite {
struct weston_surface *surface;
struct weston_surface *pending_surface;
+ struct drm_output *output;
+
struct drm_compositor *compositor;
struct wl_listener destroy_listener;
@@ -358,6 +363,8 @@ drm_output_repaint(struct weston_output *output_base,
return;
}
+ output->page_flip_pending = 1;
+
/*
* Now, update all the sprite surfaces
*/
@@ -391,6 +398,9 @@ drm_output_repaint(struct weston_output *output_base,
weston_log("vblank event request failed: %d: %s\n",
ret, strerror(errno));
}
+
+ s->output = output;
+ output->vblank_pending = 1;
}
return;
@@ -402,6 +412,10 @@ vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
{
struct drm_sprite *s = (struct drm_sprite *)data;
struct drm_compositor *c = s->compositor;
+ struct drm_output *output = s->output;
+ uint32_t msecs;
+
+ output->vblank_pending = 0;
if (s->surface) {
weston_buffer_post_release(s->surface->buffer);
@@ -420,6 +434,11 @@ vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,
s->fb_id = s->pending_fb_id;
s->pending_fb_id = 0;
}
+
+ if (!output->page_flip_pending) {
+ msecs = sec * 1000 + usec / 1000;
+ weston_output_finish_frame(&output->base, msecs);
+ }
}
static void
@@ -429,6 +448,8 @@ page_flip_handler(int fd, unsigned int frame,
struct drm_output *output = (struct drm_output *) data;
uint32_t msecs;
+ output->page_flip_pending = 0;
+
if (output->current) {
if (output->current->is_client_buffer)
gbm_bo_destroy(output->current->bo);
@@ -440,8 +461,10 @@ page_flip_handler(int fd, unsigned int frame,
output->current = output->next;
output->next = NULL;
- msecs = sec * 1000 + usec / 1000;
- weston_output_finish_frame(&output->base, msecs);
+ if (!output->vblank_pending) {
+ msecs = sec * 1000 + usec / 1000;
+ weston_output_finish_frame(&output->base, msecs);
+ }
}
static int
--
1.7.9.5
More information about the wayland-devel
mailing list