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
---
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");