<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 7, 2013 at 4:24 PM, Pekka Paalanen <span dir="ltr"><<a href="mailto:ppaalanen@gmail.com" target="_blank">ppaalanen@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Fri,  5 Apr 2013 23:07:11 +0200<br>
Jonas Ådahl <<a href="mailto:jadahl@gmail.com">jadahl@gmail.com</a>> wrote:<br>
<br>
> Most backends relies on gettimeofday(2) for output repaint timestamps<br>
> but this is not a requirement. Before this patch repaints coming from<br>
> idle_repaint() always used gettimeofday(2) for timestamps. For backends<br>
> not using that time source this could cause large jumps between<br>
> timestamps.<br>
><br>
> To fix this, timestamps needs to always come from the backend. This<br>
> means that the backend needs to always be responsible of starting the<br>
> repaint loop in case that the repaint cannot start immediately.<br>
<br>
</div>Good idea.<br>
<div><div class="h5"><br>
> The drm backend implementation is from the patch by Ander Conselvan de<br>
> Oliveira found here:<br>
> <a href="http://lists.freedesktop.org/archives/wayland-devel/2013-February/007393.html" target="_blank">http://lists.freedesktop.org/archives/wayland-devel/2013-February/007393.html</a><br>
><br>
> Signed-off-by: Jonas Ådahl <<a href="mailto:jadahl@gmail.com">jadahl@gmail.com</a>><br>
> ---<br>
><br>
> Hi,<br>
><br>
> This is a follow up from reviews of Ander's patch[0] from February.<br>
><br>
> What is done since that patch is to implement the "start_repaint_loop"<br>
> for the current backends found in weston. All but the wayland backend<br>
> implementation are pretty straight forward.<br>
><br>
> [0] <a href="http://lists.freedesktop.org/archives/wayland-devel/2013-February/007393.html" target="_blank">http://lists.freedesktop.org/archives/wayland-devel/2013-February/007393.html</a><br>
><br>
> Jonas<br>
><br>
>  src/compositor-drm.c      |   34 ++++++++++++++--<br>
>  src/compositor-fbdev.c    |   18 ++++++---<br>
>  src/compositor-headless.c |   12 ++++--<br>
>  src/compositor-rdp.c      |   19 +++++----<br>
>  src/compositor-rpi.c      |   27 ++++++++++---<br>
>  src/compositor-wayland.c  |   97 +++++++++++++++++++++++++++++++++++++++++++++<br>
>  src/compositor-x11.c      |   20 +++++++---<br>
>  src/compositor.c          |    2 +-<br>
>  src/compositor.h          |    1 +<br>
>  9 files changed, 199 insertions(+), 31 deletions(-)<br>
><br>
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c<br>
> index 6e0a126..49f197e 100644<br>
> --- a/src/compositor-drm.c<br>
> +++ b/src/compositor-drm.c<br>
> @@ -623,6 +623,26 @@ drm_output_repaint(struct weston_output *output_base,<br>
>  }<br>
><br>
>  static void<br>
> +drm_output_start_repaint_loop(struct weston_output *output_base)<br>
> +{<br>
> +     struct drm_output *output = (struct drm_output *) output_base;<br>
> +     struct drm_compositor *compositor = (struct drm_compositor *)<br>
> +             output_base->compositor;<br>
> +     uint32_t fb_id;<br>
> +<br>
> +     if (output->current)<br>
> +             fb_id = output->current->fb_id;<br>
> +     else<br>
> +             fb_id = output->original_crtc->buffer_id;<br>
> +<br>
> +     if (drmModePageFlip(compositor->drm.fd, output->crtc_id, fb_id,<br>
> +                         DRM_MODE_PAGE_FLIP_EVENT, output) < 0) {<br>
> +             weston_log("queueing pageflip failed: %m\n");<br>
<br>
</div></div>Btw, does this cause one refresh cycle (scanout frame) delay in<br>
starting the repaint loop?<br></blockquote><div><br></div><div>As far as I understand it, yes.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
> +             return;<br>
> +     }<br>
> +}<br>
> +<br>
> +static void<br>
>  vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec,<br>
>              void *data)<br>
>  {<br>
> @@ -649,11 +669,16 @@ page_flip_handler(int fd, unsigned int frame,<br>
>       struct drm_output *output = (struct drm_output *) data;<br>
>       uint32_t msecs;<br>
><br>
> -     output->page_flip_pending = 0;<br>
> +     /* We don't set page_flip_pending on start_repaint_loop, in that case<br>
> +      * we just want to page flip to the current buffer to get an accurate<br>
> +      * timestamp */<br>
> +     if (output->page_flip_pending) {<br>
> +             drm_output_release_fb(output, output->current);<br>
> +             output->current = output->next;<br>
> +             output->next = NULL;<br>
> +     }<br>
><br>
> -     drm_output_release_fb(output, output->current);<br>
> -     output->current = output->next;<br>
> -     output->next = NULL;<br>
> +     output->page_flip_pending = 0;<br>
><br>
>       if (!output->vblank_pending) {<br>
>               msecs = sec * 1000 + usec / 1000;<br>
> @@ -1618,6 +1643,7 @@ create_output_for_connector(struct drm_compositor *ec,<br>
>       wl_list_insert(ec->base.output_list.prev, &output->base.link);<br>
><br>
>       output->base.origin = output->base.current;<br>
> +     output->base.start_repaint_loop = drm_output_start_repaint_loop;<br>
>       output->base.repaint = drm_output_repaint;<br>
>       output->base.destroy = drm_output_destroy;<br>
>       output->base.assign_planes = drm_assign_planes;<br>
<br>
<br>
<br>
</div></div><div class="im">> diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c<br>
> index cae6f7b..43fc14a 100644<br>
> --- a/src/compositor-rpi.c<br>
> +++ b/src/compositor-rpi.c<br>
> @@ -612,19 +612,26 @@ rpi_element_update(struct rpi_element *element,<br>
>       return 0;<br>
>  }<br>
><br>
> +static uint64_t<br>
> +rpi_get_current_time(void)<br>
> +{<br>
> +     struct timeval tv;<br>
> +<br>
> +     /* manufacture flip completion timestamp */<br>
<br>
</div>See below.<br>
<div class="im"><br>
> +     /* XXX: use CLOCK_MONOTONIC instead? */<br>
> +     gettimeofday(&tv, NULL);<br>
> +     return (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;<br>
> +}<br>
> +<br>
>  static void<br>
>  rpi_flippipe_update_complete(DISPMANX_UPDATE_HANDLE_T update, void *data)<br>
>  {<br>
>       /* This function runs in a different thread. */<br>
>       struct rpi_flippipe *flippipe = data;<br>
> -     struct timeval tv;<br>
>       uint64_t time;<br>
>       ssize_t ret;<br>
><br>
> -     /* manufacture flip completion timestamp */<br>
<br>
</div>This "manufacture" comment should stay here, not be moved.<br>
Otherwise ok.<br>
<div><div class="h5"><br>
> -     /* XXX: use CLOCK_MONOTONIC instead? */<br>
> -     gettimeofday(&tv, NULL);<br>
> -     time = (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;<br>
> +     time = rpi_get_current_time();<br>
><br>
>       ret = write(flippipe->writefd, &time, sizeof time);<br>
>       if (ret != sizeof time)<br>
> @@ -885,6 +892,15 @@ rpi_output_destroy_old_elements(struct rpi_output *output)<br>
>  }<br>
><br>
>  static void<br>
> +rpi_output_start_repaint_loop(struct weston_output *output)<br>
> +{<br>
> +     uint64_t time;<br>
> +<br>
> +     time = rpi_get_current_time();<br>
> +     weston_output_finish_frame(output, time);<br>
> +}<br>
> +<br>
> +static void<br>
>  rpi_output_repaint(struct weston_output *base, pixman_region32_t *damage)<br>
>  {<br>
>       struct rpi_output *output = to_rpi_output(base);<br>
> @@ -1029,6 +1045,7 @@ rpi_output_create(struct rpi_compositor *compositor)<br>
>       output->egl_window.width = modeinfo.width;<br>
>       output->egl_window.height = modeinfo.height;<br>
><br>
> +     output->base.start_repaint_loop = rpi_output_start_repaint_loop;<br>
>       output->base.repaint = rpi_output_repaint;<br>
>       output->base.destroy = rpi_output_destroy;<br>
>       if (compositor->max_planes > 0)<br>
<br>
</div></div>The rpi bits look good, apart from that one comment.<br>
<div class="im"><br>
<br>
> diff --git a/src/compositor.c b/src/compositor.c<br>
> index e7c22db..693df2c 100644<br>
> --- a/src/compositor.c<br>
> +++ b/src/compositor.c<br>
> @@ -1308,7 +1308,7 @@ idle_repaint(void *data)<br>
>  {<br>
>       struct weston_output *output = data;<br>
><br>
> -     weston_output_finish_frame(output, weston_compositor_get_time());<br>
> +     output->start_repaint_loop(output);<br>
<br>
</div>Very nice to see this get_time() removed.<br>
<div class="im"><br>
>  }<br>
><br>
>  WL_EXPORT void<br>
> diff --git a/src/compositor.h b/src/compositor.h<br>
> index 7d1d68e..1e999a6 100644<br>
> --- a/src/compositor.h<br>
> +++ b/src/compositor.h<br>
> @@ -186,6 +186,7 @@ struct weston_output {<br>
>       struct weston_mode *origin;<br>
>       struct wl_list mode_list;<br>
><br>
> +     void (*start_repaint_loop)(struct weston_output *output);<br>
>       void (*repaint)(struct weston_output *output,<br>
>                       pixman_region32_t *damage);<br>
>       void (*destroy)(struct weston_output *output);<br>
> --<br>
> 1.7.10.4<br>
<br>
</div>I checked only the rpi specific bits, looking good.<br></blockquote><div><br></div><div>Thanks for the review.<br><br></div><div>Jonas<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br>
<br>
Thanks,<br>
pq<br>
</blockquote></div><br></div></div>