[PATCH 4/9] output gl repaint in clone mode

Zhang, Xiong Y xiong.y.zhang at intel.com
Sat Sep 21 18:46:55 PDT 2013


The primary output will wait clone output. Until all the finish of clone output's page flip, primary output can send frame callback to clients and begin the next page flip.

thanks 
-----Original Message-----
From: wayland-devel-bounces+xiong.y.zhang=intel.com at lists.freedesktop.org [mailto:wayland-devel-bounces+xiong.y.zhang=intel.com at lists.freedesktop.org] On Behalf Of Axel Davy
Sent: Thursday, September 19, 2013 4:21 PM
To: wayland mailing list
Subject: Re: [PATCH 4/9] output gl repaint in clone mode



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(&region);
>
> @@ -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);
>



_______________________________________________
wayland-devel mailing list
wayland-devel at lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list