[PATCH 4/9] output gl repaint in clone mode
Axel Davy
davy at clipper.ens.fr
Thu Sep 19 01:21:20 PDT 2013
How does this work if the primary output frequency is more than the
clone output?
I'm afraid the weston log might become very big after a while when
running a such a configuration
Axel Davy
Le 18/09/2013 05:50, Xiong Zhang a écrit :
> Only repsone to primary output repaint request; Primary output and
> clone output share the same frame buffer, once primary output do page
> flip, clone output will do page flip also. When both primary output
> and clone output finish the page flip, the fb obj can be released.
>
> Signed-off-by: Xiong Zhang <xiong.y.zhang at intel.com>
> ---
> src/compositor-drm.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
> src/compositor.c | 9 +++++
> 2 files changed, 110 insertions(+)
>
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index 8d16d29..0b9ab45 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -103,6 +103,8 @@ struct drm_compositor {
>
> clockid_t clock;
> struct udev_input input;
> +
> + uint32_t flip_counter;
> };
>
> struct drm_mode {
> @@ -581,6 +583,12 @@ drm_output_repaint(struct weston_output *output_base,
> struct drm_sprite *s;
> struct drm_mode *mode;
> int ret = 0;
> + struct drm_output *clone_output;
> +
> + /*ignore clone output repaint request*/
> + if ((compositor->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) &&
> + output_base != compositor->base.primary_output)
> + return;
>
> if (!output->next)
> drm_output_render(output, damage);
> @@ -598,6 +606,22 @@ drm_output_repaint(struct weston_output *output_base,
> return;
> }
> output_base->set_dpms(output_base, WESTON_DPMS_ON);
> + if (compositor->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) {
> + wl_list_for_each(clone_output, &compositor->base.output_list, base.link) {
> + if (&clone_output->base != output_base) {
> + mode = container_of(clone_output->base.current, struct drm_mode, base);
> + ret = drmModeSetCrtc(compositor->drm.fd, clone_output->crtc_id,
> + output->next->fb_id, 0, 0,
> + &clone_output->connector_id, 1,
> + &mode->mode_info);
> + if (ret) {
> + weston_log("set mode failed: %m\n");
> + return;
> + }
> + clone_output->base.set_dpms(&clone_output->base, WESTON_DPMS_ON);
> + }
> + }
> + }
> }
>
> if (drmModePageFlip(compositor->drm.fd, output->crtc_id,
> @@ -608,6 +632,21 @@ drm_output_repaint(struct weston_output *output_base,
> }
>
> output->page_flip_pending = 1;
> + compositor->flip_counter++;
> +
> + if (compositor->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) {
> + wl_list_for_each(clone_output, &compositor->base.output_list, base.link) {
> + if (&clone_output->base != output_base) {
> + if (drmModePageFlip(compositor->drm.fd, clone_output->crtc_id,
> + output->next->fb_id,
> + DRM_MODE_PAGE_FLIP_EVENT, clone_output) < 0) {
> + weston_log("queueing pageflip failed: %m\n");
> + return;
> + }
> + compositor->flip_counter++;
> + }
> + }
> + }
>
> drm_output_set_cursor(output);
>
> @@ -666,9 +705,19 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
> struct drm_compositor *compositor = (struct drm_compositor *)
> output_base->compositor;
> uint32_t fb_id;
> + struct drm_output *clone_output;
>
> struct timespec ts;
>
> + /* ignore clone output repaint request */
> + /* clear clone_output->repaint_scheduled, so when clone_output became primary */
> + /* output, it can repaint */
> + if ((compositor->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) &&
> + output_base != compositor->base.primary_output) {
> + output_base->repaint_scheduled = 0;
> + return;
> + }
> +
> if (!output->current) {
> /* We can't page flip if there's no mode set */
> uint32_t msec;
> @@ -686,6 +735,21 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
> weston_log("queueing pageflip failed: %m\n");
> return;
> }
> + compositor->flip_counter++;
> +
> + /*clone output repiant*/
> + if (compositor->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) {
> + wl_list_for_each(clone_output, &compositor->base.output_list, base.link) {
> + if (compositor->base.primary_output != &clone_output->base) {
> + if (drmModePageFlip(compositor->drm.fd, clone_output->crtc_id, fb_id,
> + DRM_MODE_PAGE_FLIP_EVENT, clone_output) < 0) {
> + weston_log("queueing pageflip failed: %m\n");
> + return;
> + }
> + compositor->flip_counter++;
> + }
> + }
> + }
> }
>
> static void
> @@ -714,6 +778,15 @@ page_flip_handler(int fd, unsigned int frame,
> {
> struct drm_output *output = (struct drm_output *) data;
> uint32_t msecs;
> + struct drm_compositor *c = (struct drm_compositor *)output->base.compositor;
> +
> + if ((--c->flip_counter != 0) &&
> + (c->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE))
> + return;
> +
> + if ((c->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) &&
> + (&output->base != c->base.primary_output))
> + output = (struct drm_output *)c->base.primary_output;
>
> /* We don't set page_flip_pending on start_repaint_loop, in that case
> * we just want to page flip to the current buffer to get an accurate
> @@ -947,10 +1020,17 @@ drm_output_set_cursor(struct drm_output *output)
> uint32_t buf[64 * 64];
> unsigned char *s;
> int i, x, y;
> + struct drm_output *clone_output;
>
> output->cursor_surface = NULL;
> if (es == NULL) {
> drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
> + if (c->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) {
> + wl_list_for_each(clone_output, &c->base.output_list, base.link) {
> + if (&clone_output->base != c->base.primary_output)
> + drmModeSetCursor(c->drm.fd, clone_output->crtc_id, 0, 0, 0);
> + }
> + }
> return;
> }
>
> @@ -976,6 +1056,16 @@ drm_output_set_cursor(struct drm_output *output)
> weston_log("failed to set cursor: %m\n");
> c->cursors_are_broken = 1;
> }
> + if (c->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) {
> + wl_list_for_each(clone_output, &c->base.output_list, base.link) {
> + if ((&clone_output->base != c->base.primary_output) &&
> + (drmModeSetCursor(c->drm.fd,
> + clone_output->crtc_id, handle, 64, 64) < 0)) {
> + weston_log("failed to set cursor:%m\n");
> + c->cursors_are_broken = 1;
> + }
> + }
> + }
> }
>
> x = (es->geometry.x - output->base.x) * output->base.scale;
> @@ -989,6 +1079,17 @@ drm_output_set_cursor(struct drm_output *output)
> output->cursor_plane.x = x;
> output->cursor_plane.y = y;
> }
> + if (c->base.multiscreen_mode == WESTON_MULTISCREEN_CLONE) {
> + wl_list_for_each(clone_output, &c->base.output_list, base.link) {
> + if ((&clone_output->base != c->base.primary_output) &&
> + drmModeMoveCursor(c->drm.fd, clone_output->crtc_id, x, y) < 0) {
> + weston_log("failed to move cursor: %m\n");
> + c->cursors_are_broken = 1;
> + }
> + clone_output->cursor_plane.x = x;
> + clone_output->cursor_plane.y = y;
> + }
> + }
> }
>
> static void
> diff --git a/src/compositor.c b/src/compositor.c
> index f9e9ba1..5d927fd 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -564,6 +564,9 @@ weston_surface_assign_output(struct weston_surface *es)
> new_output = output;
> max = area;
> }
> + /*surface can only be assigned to primary output in clone mode */
> + if (ec->multiscreen_mode == WESTON_MULTISCREEN_CLONE)
> + break;
> }
> pixman_region32_fini(®ion);
>
> @@ -1294,6 +1297,12 @@ weston_output_repaint(struct weston_output *output, uint32_t msecs)
> struct wl_list frame_callback_list;
> pixman_region32_t output_damage;
>
> + /* ignore clone output repaint request */
> + if ((ec->multiscreen_mode == WESTON_MULTISCREEN_CLONE) &&
> + (output != ec->primary_output)) {
> + return;
> + }
> +
> /* Rebuild the surface list and update surface transforms up front. */
> weston_compositor_build_surface_list(ec);
>
More information about the wayland-devel
mailing list