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





More information about the wayland-devel mailing list