diff --git a/compositor/main.c b/compositor/main.c
index cbf06690..99912f91 100644
--- a/compositor/main.c
+++ b/compositor/main.c
@@ -77,6 +77,12 @@ struct wet_output_config {
 	uint32_t transform;
 };
 
+enum wet_output_type {
+	WET_OUTPUT_NORMAL,
+	WET_OUTPUT_SHARE_CRTC,
+	WET_OUTPUT_CLONE
+};
+
 struct wet_compositor;
 struct wet_layoutput;
 
@@ -96,6 +102,7 @@ struct wet_output {
 
 struct wet_head_array {
 	struct weston_head *heads[MAX_CLONE_HEADS];	/**< heads to add */
+	enum wet_output_type types[MAX_CLONE_HEADS];
 	unsigned n;				/**< the number of heads */
 };
 
@@ -1790,17 +1797,12 @@ drm_backend_output_configure(struct weston_output *output,
 	return 0;
 }
 
-/* Find the output section to use for configuring the output with the
- * named head. If an output section with the given name contains
- * a "same-as" key, ignore all other settings in the output section and
- * instead find an output section named by the "same-as". Do this
- * recursively.
- */
 static struct weston_config_section *
-drm_config_find_controlling_output_section(struct weston_config *config,
-					   const char *head_name)
+drm_config_output_recursive_find_key(struct weston_config *config,
+                                     const char *head_name,
+                                     const char *key)
 {
-	struct weston_config_section *section;
+	struct weston_config_section *section = NULL;
 	char *same_as;
 	int depth = 0;
 
@@ -1811,7 +1813,7 @@ drm_config_find_controlling_output_section(struct weston_config *config,
 		if (!section && depth > 0)
 			weston_log("Configuration error: "
 				   "output section referred to with "
-				   "'same-as=%s' not found.\n", same_as);
+				   "'%s=%s' not found.\n", key, same_as);
 
 		free(same_as);
 
@@ -1825,13 +1827,58 @@ drm_config_find_controlling_output_section(struct weston_config *config,
 			return NULL;
 		}
 
-		weston_config_section_get_string(section, "same-as",
+		weston_config_section_get_string(section, key,
 						 &same_as, NULL);
 	} while (same_as);
 
 	return section;
 }
 
+/* Find the output section to use for configuring the output with the
+ * named head. If an output section with the given name contains
+ * a "same-as" or a "clone-from" key, ignore all other settings in
+ * the output section and instead find an output section named by the
+ * key. Do this recursively and prioritize same-as.
+ */
+static struct weston_config_section *
+drm_config_find_controlling_output_section(struct weston_config *config,
+                                           const char *head_name,
+                                           enum wet_output_type *type)
+{
+	struct weston_config_section *section;
+	char *same_as;
+	char *cloned_from;
+
+	section = weston_config_get_section(config, "output",
+	                                    "name", head_name);
+	if (!section)
+		return NULL;
+	if (type)
+		*type = WET_OUTPUT_NORMAL;
+
+	weston_config_section_get_string(section, "same-as",
+	                                 &same_as, NULL);
+	weston_config_section_get_string(section, "clone-from",
+	                                 &cloned_from, NULL);
+	if (same_as) {
+		free(same_as);
+		if (type)
+			*type = WET_OUTPUT_SHARE_CRTC;
+		return drm_config_output_recursive_find_key(config,
+		                                            head_name,
+		                                            "same-as");
+	} else if (cloned_from) {
+		free(cloned_from);
+		if (type)
+			*type = WET_OUTPUT_CLONE;
+		return drm_config_output_recursive_find_key(config,
+		                                            head_name,
+		                                            "clone-from");
+	} else
+		return section;
+
+}
+
 static struct wet_layoutput *
 wet_compositor_create_layoutput(struct wet_compositor *compositor,
 				const char *name,
@@ -1946,7 +1993,8 @@ static void
 wet_compositor_layoutput_add_head(struct wet_compositor *wet,
 				  const char *output_name,
 				  struct weston_config_section *section,
-				  struct weston_head *head)
+				  struct weston_head *head,
+                                  enum wet_output_type type)
 {
 	struct wet_layoutput *lo;
 
@@ -1960,7 +2008,8 @@ wet_compositor_layoutput_add_head(struct wet_compositor *wet,
 	if (lo->add.n + 1 >= ARRAY_LENGTH(lo->add.heads))
 		return;
 
-	lo->add.heads[lo->add.n++] = head;
+	lo->add.heads[lo->add.n] = head;
+	lo->add.types[lo->add.n++] = type;
 }
 
 static void
@@ -1986,9 +2035,11 @@ drm_head_prepare_enable(struct wet_compositor *wet,
 	const char *name = weston_head_get_name(head);
 	struct weston_config_section *section;
 	char *output_name = NULL;
-	char *mode = NULL;
+	char *mode;
+	enum wet_output_type config_type;
 
-	section = drm_config_find_controlling_output_section(wet->config, name);
+	section = drm_config_find_controlling_output_section(wet->config, name,
+	                                                     &config_type);
 	if (section) {
 		/* skip outputs that are explicitly off, or non-desktop and not
 		 * explicitly enabled. The backend turns them off automatically.
@@ -2007,10 +2058,11 @@ drm_head_prepare_enable(struct wet_compositor *wet,
 		assert(output_name);
 
 		wet_compositor_layoutput_add_head(wet, output_name,
-						  section, head);
+						  section, head, config_type);
 		free(output_name);
 	} else {
-		wet_compositor_layoutput_add_head(wet, name, NULL, head);
+		wet_compositor_layoutput_add_head(wet, name, NULL, head,
+		                                  WET_OUTPUT_NORMAL);
 	}
 }
 
@@ -2020,9 +2072,11 @@ drm_head_should_force_enable(struct wet_compositor *wet,
 {
 	const char *name = weston_head_get_name(head);
 	struct weston_config_section *section;
+	enum wet_output_type type;
 	bool force;
 
-	section = drm_config_find_controlling_output_section(wet->config, name);
+	section = drm_config_find_controlling_output_section(wet->config, name,
+	                                                     &type);
 	if (!section)
 		return false;
 
@@ -2041,79 +2095,83 @@ drm_try_attach(struct weston_output *output,
 	for (i = 0; i < add->n; i++) {
 		if (!add->heads[i])
 			continue;
+		if (add->types[i] == WET_OUTPUT_CLONE) {
+			failed->heads[failed->n] = add->heads[i];
+			failed->types[failed->n++] = WET_OUTPUT_CLONE;
+			continue;
+		}
 
 		if (weston_output_attach_head(output, add->heads[i]) < 0) {
 			assert(failed->n < ARRAY_LENGTH(failed->heads));
 
-			failed->heads[failed->n++] = add->heads[i];
+			failed->heads[failed->n] = add->heads[i];
+			failed->types[failed->n++] = WET_OUTPUT_CLONE;
 			add->heads[i] = NULL;
 		}
 	}
 }
 
 static int
-drm_try_enable(struct weston_output *output,
-	       struct wet_head_array *undo,
-	       struct wet_head_array *failed)
+drm_try_attach_enable(struct weston_output *output, struct weston_head *head,
+                      struct wet_layoutput *lo)
 {
-	/* Try to enable, and detach heads one by one until it succeeds. */
-	while (!output->enabled) {
-		if (weston_output_enable(output) == 0)
-			return 0;
-
-		/* the next head to drop */
-		while (undo->n > 0 && undo->heads[--undo->n] == NULL)
-			;
-
-		/* No heads left to undo and failed to enable. */
-		if (undo->heads[undo->n] == NULL)
-			return -1;
-
-		assert(failed->n < ARRAY_LENGTH(failed->heads));
-
-		/* undo one head */
-		weston_head_detach(undo->heads[undo->n]);
-		failed->heads[failed->n++] = undo->heads[undo->n];
-		undo->heads[undo->n] = NULL;
-	}
-
-	return 0;
-}
-
-static int
-drm_try_attach_enable(struct weston_output *output, struct wet_layoutput *lo)
-{
-	struct wet_head_array failed = {};
-	unsigned i;
-
 	assert(!output->enabled);
-
-	drm_try_attach(output, &lo->add, &failed);
+	if (weston_output_attach_head(output, head) < 0)
+		return -1;
 	if (drm_backend_output_configure(output, lo->section) < 0)
 		return -1;
-
-	if (drm_try_enable(output, &lo->add, &failed) < 0)
+	if (weston_output_enable(output) != 0)
 		return -1;
+	wet_head_tracker_create(lo->compositor, head);
 
-	/* For all successfully attached/enabled heads */
-	for (i = 0; i < lo->add.n; i++)
-		if (lo->add.heads[i])
-			wet_head_tracker_create(lo->compositor,
-						lo->add.heads[i]);
+	return 0;
+}
 
-	/* Push failed heads to the next round. */
-	lo->add = failed;
+static struct wet_output *
+drm_layoutput_create_master(struct wet_layoutput *lo)
+{
+	struct wet_output *master = NULL;
+	struct wet_head_array copies = {};
+	unsigned int i;
 
-	return 0;
+	if (wl_list_length(&lo->output_list))
+		return container_of(lo->output_list.next, struct wet_output,
+		                    link);
+
+	for (i = 0; i < lo->add.n; i++) {
+		assert(wl_list_length(&lo->output_list) <= 1);
+ 
+		if (lo->add.types[i] == WET_OUTPUT_NORMAL) {
+			master = wet_layoutput_create_output(
+				lo, weston_head_get_name(lo->add.heads[i]));
+			if (drm_try_attach_enable(master->output,
+			                          lo->add.heads[i], lo)) {
+				wet_output_destroy(master);
+				return NULL;
+			}
+		}
+		else {
+			copies.heads[copies.n] = lo->add.heads[i];
+			copies.types[copies.n++] = lo->add.types[i];
+		}
+	}
+	lo->add = copies;
+	return master;
 }
 
 static int
 drm_process_layoutput(struct wet_compositor *wet, struct wet_layoutput *lo)
 {
-	struct wet_output *output, *tmp;
+	struct wet_output *output, *tmp, *master;
 	char *name = NULL;
+	unsigned int i;
 	int ret;
 
+	master = drm_layoutput_create_master(lo);
+
+        if (!master)
+	        return -1;
+
 	/*
 	 *   For each existing wet_output:
 	 *     try attach
@@ -2133,27 +2191,22 @@ drm_process_layoutput(struct wet_compositor *wet, struct wet_layoutput *lo)
 
 		assert(output->output->enabled);
 
+		/* try to attach share_crtc clones */
 		drm_try_attach(output->output, &lo->add, &failed);
 		lo->add = failed;
 		if (lo->add.n == 0)
 			return 0;
 	}
 
-	if (!weston_compositor_find_output_by_name(wet->compositor, lo->name))
-		name = strdup(lo->name);
-
-	while (lo->add.n > 0) {
-		if (!wl_list_empty(&lo->output_list)) {
-			weston_log("Error: independent-CRTC clone mode is not implemented.\n");
-			return -1;
-		}
-
+	for (i = 0; i < lo->add.n; i++) {
 		if (!name) {
 			ret = asprintf(&name, "%s:%s", lo->name,
-				       weston_head_get_name(lo->add.heads[0]));
+				       weston_head_get_name(lo->add.heads[i]));
 			if (ret < 0)
 				return -1;
 		}
+		
+		/* creates new output for every clone */
 		output = wet_layoutput_create_output(lo, name);
 		free(name);
 		name = NULL;
@@ -2161,7 +2214,8 @@ drm_process_layoutput(struct wet_compositor *wet, struct wet_layoutput *lo)
 		if (!output)
 			return -1;
 
-		if (drm_try_attach_enable(output->output, lo) < 0) {
+		weston_output_make_slave(output->output, master->output);
+		if (drm_try_attach_enable(output->output, lo->add.heads[i], lo)) {
 			wet_output_destroy(output);
 			return -1;
 		}
@@ -3332,6 +3386,8 @@ wet_main(int argc, char *argv[])
 	weston_log_subscribe_to_scopes(log_ctx, logger, flight_rec,
 				       log_scopes, flight_rec_scopes);
 
+	weston_log("This version is patched by Metran Co \n");
+
 	weston_log("%s\n"
 		   STAMP_SPACE "%s\n"
 		   STAMP_SPACE "Bug reports to: %s\n"
diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h
index 089f2d9a..feb09b73 100644
--- a/include/libweston/libweston.h
+++ b/include/libweston/libweston.h
@@ -255,6 +255,9 @@ struct weston_output {
 
 	/** Output area in global coordinates, simple rect */
 	pixman_region32_t region;
+	
+	/** Output damage in global coordinates */
+	pixman_region32_t damage;
 
 	/** True if damage has occurred since the last repaint for this output;
 	 *  if set, a repaint will eventually occur. */
@@ -288,6 +291,7 @@ struct weston_output {
 	int disable_planes;
 	int destroying;
 	struct wl_list feedback_list;
+	struct wl_list view_list; /**< list of touched views */
 
 	uint32_t transform;
 	int32_t native_scale;
@@ -300,6 +304,7 @@ struct weston_output {
 	struct wl_list mode_list;
 
 	struct wl_list head_list; /**< List of driven weston_heads */
+	struct weston_output *clone_output;
 
 	enum weston_hdcp_protection desired_protection;
 	enum weston_hdcp_protection current_protection;
@@ -876,7 +881,6 @@ struct weston_layer {
 
 struct weston_plane {
 	struct weston_compositor *compositor;
-	pixman_region32_t damage; /**< in global coords */
 	pixman_region32_t clip;
 	int32_t x, y;
 	struct wl_list link;
@@ -1290,6 +1294,13 @@ struct weston_view {
 		struct weston_transform position; /* matrix from x, y */
 	} transform;
 
+	/* View damage output stage, write only.
+         * This is used by weston_surface_flush_damage()
+         */
+	struct {
+		struct wl_list link;
+		pixman_region32_t damage;
+	} output_damages[32];
 	/*
 	 * The primary output for this view.
 	 * Used for picking the output for driving internal animations on the
@@ -2010,7 +2021,9 @@ weston_output_destroy(struct weston_output *output);
 int
 weston_output_attach_head(struct weston_output *output,
 			  struct weston_head *head);
-
+int
+weston_output_make_slave(struct weston_output *output,
+                         struct weston_output *master);
 struct weston_head *
 weston_output_iterate_heads(struct weston_output *output,
 			    struct weston_head *iter);
diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c
index 05384d04..15d6aedd 100644
--- a/libweston/backend-drm/drm.c
+++ b/libweston/backend-drm/drm.c
@@ -54,6 +54,7 @@
 #include <libweston/config-parser.h>
 #include "compositor/weston.h"
 #include "drm-internal.h"
+#include "libweston-internal.h"
 #include "shared/helpers.h"
 #include "shared/timespec-util.h"
 #include "shared/string-helpers.h"
@@ -464,8 +465,7 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage)
 		}
 	}
 
-	pixman_region32_subtract(&c->primary_plane.damage,
-				 &c->primary_plane.damage, damage);
+	weston_output_finish_damage(&output->base, damage);
 
 	/* Don't bother calculating plane damage if the plane doesn't support it */
 	if (damage_info->prop_id == 0)
diff --git a/libweston/backend-drm/kms.c b/libweston/backend-drm/kms.c
index 5bcd868e..50788211 100644
--- a/libweston/backend-drm/kms.c
+++ b/libweston/backend-drm/kms.c
@@ -622,8 +622,6 @@ drm_output_set_cursor(struct drm_output_state *output_state)
 		return;
 
 	if (!state->fb) {
-		pixman_region32_fini(&plane->base.damage);
-		pixman_region32_init(&plane->base.damage);
 		drmModeSetCursor(b->drm.fd, output->crtc_id, 0, 0, 0);
 		return;
 	}
@@ -641,8 +639,6 @@ drm_output_set_cursor(struct drm_output_state *output_state)
 		}
 	}
 
-	pixman_region32_fini(&plane->base.damage);
-	pixman_region32_init(&plane->base.damage);
 
 	if (drmModeMoveCursor(b->drm.fd, output->crtc_id,
 	                      state->dest_x, state->dest_y)) {
diff --git a/libweston/backend-drm/state-propose.c b/libweston/backend-drm/state-propose.c
index dc227a95..d180704f 100644
--- a/libweston/backend-drm/state-propose.c
+++ b/libweston/backend-drm/state-propose.c
@@ -849,7 +849,13 @@ drm_output_propose_state(struct weston_output *output_base,
 	pixman_region32_init(&planes_region);
 	pixman_region32_init(&occluded_region);
 
-	wl_list_for_each(ev, &output_base->compositor->view_list, link) {
+	/* using output->view_list we could avoid testing if the view touches
+         * the output. Also, since we enable independent overlapping damage
+         * tracking, for cloning outputs, we would need to allow view assign on
+         * different planes in different outputs.
+         */
+	wl_list_for_each(ev, &output_base->view_list,
+	                 output_damages[output_base->id].link) {
 		struct drm_plane_state *ps = NULL;
 		bool force_renderer = false;
 		pixman_region32_t clipped_view;
@@ -860,13 +866,6 @@ drm_output_propose_state(struct weston_output *output_base,
 		          ev, output->base.name,
 			  (unsigned long) output->base.id);
 
-		/* If this view doesn't touch our output at all, there's no
-		 * reason to do anything with it. */
-		if (!(ev->output_mask & (1u << output->base.id))) {
-			drm_debug(b, "\t\t\t\t[view] ignoring view %p "
-			             "(not on our output)\n", ev);
-			continue;
-		}
 
 		/* Ignore views we know to be totally occluded. */
 		pixman_region32_init(&clipped_view);
@@ -889,13 +888,6 @@ drm_output_propose_state(struct weston_output *output_base,
 			continue;
 		}
 
-		/* We only assign planes to views which are exclusively present
-		 * on our output. */
-		if (ev->output_mask != (1u << output->base.id)) {
-			drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
-			             "(on multiple outputs)\n", ev);
-			force_renderer = true;
-		}
 
 		if (!weston_view_has_valid_buffer(ev)) {
 			drm_debug(b, "\t\t\t\t[view] not assigning view %p to plane "
@@ -1090,13 +1082,12 @@ drm_assign_planes(struct weston_output *output_base, void *repaint_data)
 	drm_debug(b, "\t[repaint] Using %s composition\n",
 		  drm_propose_state_mode_to_string(mode));
 
-	wl_list_for_each(ev, &output_base->compositor->view_list, link) {
+	/* using output->view_list we could avoid testing if the view touches
+	 * the output */
+        wl_list_for_each(ev, &output_base->view_list,
+	                 output_damages[output_base->id].link) {
 		struct drm_plane *target_plane = NULL;
 
-		/* If this view doesn't touch our output at all, there's no
-		 * reason to do anything with it. */
-		if (!(ev->output_mask & (1u << output->base.id)))
-			continue;
 
 		/* Test whether this buffer can ever go into a plane:
 		 * non-shm, or small enough to be a cursor.
diff --git a/libweston/backend-fbdev/fbdev.c b/libweston/backend-fbdev/fbdev.c
index 624e548f..544d6a66 100644
--- a/libweston/backend-fbdev/fbdev.c
+++ b/libweston/backend-fbdev/fbdev.c
@@ -192,8 +192,7 @@ fbdev_output_repaint_pixman(struct weston_output *base, pixman_region32_t *damag
 	ec->renderer->repaint_output(base, damage);
 
 	/* Update the damage region. */
-	pixman_region32_subtract(&ec->primary_plane.damage,
-	                         &ec->primary_plane.damage, damage);
+	weston_output_finish_damage(base, damage);
 
 	/* Schedule the end of the frame. We do not sync this to the frame
 	 * buffer clock because users who want that should be using the DRM
@@ -220,8 +219,9 @@ fbdev_output_repaint(struct weston_output *base, pixman_region32_t *damage,
 	} else {
 		ec->renderer->repaint_output(base, damage);
 		/* Update the damage region. */
-		pixman_region32_subtract(&ec->primary_plane.damage,
-	                         &ec->primary_plane.damage, damage);
+
+		weston_output_finish_damage(base, damage);
+		
 		wl_event_source_timer_update(output->finish_frame_timer,
                                      1000000 / output->mode.refresh);
 	}
diff --git a/libweston/backend-headless/headless.c b/libweston/backend-headless/headless.c
index c312a0f2..60849fcf 100644
--- a/libweston/backend-headless/headless.c
+++ b/libweston/backend-headless/headless.c
@@ -36,6 +36,7 @@
 
 #include <libweston/libweston.h>
 #include <libweston/backend-headless.h>
+#include "libweston-internal.h"
 #include "shared/helpers.h"
 #include "linux-explicit-synchronization.h"
 #include "pixman-renderer.h"
@@ -130,8 +131,7 @@ headless_output_repaint(struct weston_output *output_base,
 
 	ec->renderer->repaint_output(&output->base, damage);
 
-	pixman_region32_subtract(&ec->primary_plane.damage,
-				 &ec->primary_plane.damage, damage);
+	weston_output_finish_damage(output_base, damage);
 
 	wl_event_source_timer_update(output->finish_frame_timer, 16);
 
diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c
index 9e414aa2..d531fe58 100644
--- a/libweston/backend-rdp/rdp.c
+++ b/libweston/backend-rdp/rdp.c
@@ -101,6 +101,7 @@
 #include <libweston/libweston.h>
 #include <libweston/backend-rdp.h>
 #include "pixman-renderer.h"
+#include "libweston-internal.h"
 
 #define MAX_FREERDP_FDS 32
 #define DEFAULT_AXIS_STEP_DISTANCE 10
@@ -422,8 +423,7 @@ rdp_output_repaint(struct weston_output *output_base, pixman_region32_t *damage,
 		}
 	}
 
-	pixman_region32_subtract(&ec->primary_plane.damage,
-				 &ec->primary_plane.damage, damage);
+	weston_output_finish_damage(output_base, damage);
 
 	wl_event_source_timer_update(output->finish_frame_timer, 16);
 	return 0;
diff --git a/libweston/backend-wayland/wayland.c b/libweston/backend-wayland/wayland.c
index 60d42bf3..72bea78d 100644
--- a/libweston/backend-wayland/wayland.c
+++ b/libweston/backend-wayland/wayland.c
@@ -48,6 +48,7 @@
 
 #include <libweston/libweston.h>
 #include <libweston/backend-wayland.h>
+#include "libweston-internal.h"
 #include "renderer-gl/gl-renderer.h"
 #include "shared/weston-egl-ext.h"
 #include "pixman-renderer.h"
@@ -531,8 +532,8 @@ wayland_output_repaint_gl(struct weston_output *output_base,
 
 	ec->renderer->repaint_output(&output->base, damage);
 
-	pixman_region32_subtract(&ec->primary_plane.damage,
-				 &ec->primary_plane.damage, damage);
+	weston_output_finish_damage(output_base, damage);
+	
 	return 0;
 }
 #endif
@@ -664,8 +665,8 @@ wayland_output_repaint_pixman(struct weston_output *output_base,
 	pixman_region32_init(&sb->damage);
 	sb->frame_damaged = 0;
 
-	pixman_region32_subtract(&b->compositor->primary_plane.damage,
-				 &b->compositor->primary_plane.damage, damage);
+	weston_output_finish_damage(output_base, damage);
+	
 	return 0;
 }
 
diff --git a/libweston/backend-x11/x11.c b/libweston/backend-x11/x11.c
index 387e97a4..bc9bac70 100644
--- a/libweston/backend-x11/x11.c
+++ b/libweston/backend-x11/x11.c
@@ -53,6 +53,7 @@
 
 #include <libweston/libweston.h>
 #include <libweston/backend-x11.h>
+#include "libweston-internal.h"
 #include "shared/helpers.h"
 #include "shared/image-loader.h"
 #include "shared/timespec-util.h"
@@ -425,8 +426,7 @@ x11_output_repaint_gl(struct weston_output *output_base,
 
 	ec->renderer->repaint_output(output_base, damage);
 
-	pixman_region32_subtract(&ec->primary_plane.damage,
-				 &ec->primary_plane.damage, damage);
+	weston_output_finish_damage(output_base, damage);
 
 	wl_event_source_timer_update(output->finish_frame_timer, 10);
 	return 0;
@@ -498,8 +498,7 @@ x11_output_repaint_shm(struct weston_output *output_base,
 	pixman_renderer_output_set_buffer(output_base, output->hw_surface);
 	ec->renderer->repaint_output(output_base, damage);
 
-	pixman_region32_subtract(&ec->primary_plane.damage,
-				 &ec->primary_plane.damage, damage);
+	weston_output_finish_damage(output_base, damage);
 	set_clip_for_output(output_base, damage);
 	cookie = xcb_shm_put_image_checked(b->conn, output->window, output->gc,
 					pixman_image_get_width(output->hw_surface),
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 370b5d23..b150374a 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -72,6 +72,7 @@
 #include "git-version.h"
 #include <libweston/version.h>
 #include <libweston/plugin-registry.h>
+#include <wayland-util.h>
 #include "pixel-formats.h"
 #include "backend.h"
 #include "libweston-internal.h"
@@ -339,6 +340,10 @@ weston_view_create(struct weston_surface *surface)
 	wl_list_init(&view->layer_link.link);
 
 	pixman_region32_init(&view->clip);
+	
+	for (int i = 0; i < 32; i++)
+		pixman_region32_init(&view->output_damages[i].damage);
+
 
 	view->alpha = 1.0;
 	view->blending_alpha = 1.0;
@@ -1034,10 +1039,10 @@ weston_view_move_to_plane(struct weston_view *view,
  *
  * \param view The view that causes the damage.
  *
- * If the view is currently on a plane (including the primary plane),
- * take the view's boundingbox, subtract all the opaque views that cover it,
- * and add the remaining region as damage to the plane. This corresponds
- * to the damage inflicted to the plane if this view disappeared.
+ * If the view is currently on primary plane, take the view's boundingbox,
+ * subtract all the opaque views that cover it, and add the remaining region as
+ * damage to the plane. This corresponds to the damage inflicted to the plane if
+ * this view disappeared.
  *
  * A repaint is scheduled for this view.
  *
@@ -1049,14 +1054,22 @@ weston_view_move_to_plane(struct weston_view *view,
 WL_EXPORT void
 weston_view_damage_below(struct weston_view *view)
 {
+	struct weston_compositor *ec;
+	struct weston_output *output;
 	pixman_region32_t damage;
 
+	ec = view->surface->compositor;
 	pixman_region32_init(&damage);
 	pixman_region32_subtract(&damage, &view->transform.boundingbox,
 				 &view->clip);
-	if (view->plane)
-		pixman_region32_union(&view->plane->damage,
-				      &view->plane->damage, &damage);
+
+	if (view->plane == &ec->primary_plane) {
+		wl_list_for_each(output, &ec->output_list, link)
+			if (view->output_mask & 1u << output->id)
+				pixman_region32_union(&output->damage,
+				                      &output->damage,
+				                      &damage);
+	}
 	pixman_region32_fini(&damage);
 	weston_view_schedule_repaint(view);
 }
@@ -2200,6 +2213,9 @@ weston_view_destroy(struct weston_view *view)
 	pixman_region32_fini(&view->geometry.scissor);
 	pixman_region32_fini(&view->transform.boundingbox);
 	pixman_region32_fini(&view->transform.opaque);
+	
+	for (int i = 0; i< 32; i++)
+		pixman_region32_fini(&view->output_damages[i].damage);
 
 	weston_view_set_transform_parent(view, NULL);
 	weston_view_set_output(view, NULL);
@@ -2447,14 +2463,20 @@ weston_compositor_damage_all(struct weston_compositor *compositor)
 WL_EXPORT void
 weston_output_damage(struct weston_output *output)
 {
-	struct weston_compositor *compositor = output->compositor;
-
-	pixman_region32_union(&compositor->primary_plane.damage,
-			      &compositor->primary_plane.damage,
-			      &output->region);
+	pixman_region32_copy(&output->damage, &output->region);
 	weston_output_schedule_repaint(output);
 }
 
+/**
+ * \ingroup output
+ */
+WL_EXPORT void
+weston_output_finish_damage(struct weston_output *output,
+                            pixman_region32_t *damage)
+{
+	pixman_region32_subtract(&output->damage, &output->damage, damage);
+}
+
 static void
 surface_flush_damage(struct weston_surface *surface)
 {
@@ -2474,7 +2496,10 @@ view_accumulate_damage(struct weston_view *view,
 		       pixman_region32_t *opaque)
 {
 	pixman_region32_t damage;
-
+	struct weston_output *output;
+	struct weston_compositor *ec;
+ 
+	ec = view->surface->compositor;
 	pixman_region32_init(&damage);
 	if (view->transform.enabled) {
 		pixman_box32_t *extents;
@@ -2490,11 +2515,44 @@ view_accumulate_damage(struct weston_view *view,
 	pixman_region32_intersect(&damage, &damage,
 				  &view->transform.boundingbox);
 	pixman_region32_subtract(&damage, &damage, opaque);
-	pixman_region32_union(&view->plane->damage,
-			      &view->plane->damage, &damage);
-	pixman_region32_fini(&damage);
+
 	pixman_region32_copy(&view->clip, opaque);
 	pixman_region32_union(opaque, opaque, &view->transform.opaque);
+	
+	wl_list_for_each(output, &ec->output_list, link) {
+		pixman_region32_t *output_damage =
+			&view->output_damages[output->id].damage;
+
+                if (view->output_mask & (1u << output->id)) {
+			pixman_region32_union(output_damage,
+			                      output_damage, &damage);
+		}
+
+	}
+	pixman_region32_fini(&damage);
+}
+
+static void
+output_update_damage(struct weston_output *output)
+{
+	struct weston_compositor *ec = output->compositor;
+	pixman_region32_t *output_damage;
+	struct weston_view *view;
+
+	wl_list_for_each(view, &output->view_list,
+	                 output_damages[output->id].link) {
+
+		output_damage = &view->output_damages[output->id].damage;
+
+		if (view->plane == &ec->primary_plane)
+			pixman_region32_union(&output->damage,
+			                      &output->damage,
+			                      output_damage);
+		pixman_region32_clear(output_damage);
+	}
+
+	pixman_region32_intersect(&output->damage,
+	                          &output->damage, &output->region);
 }
 
 static void
@@ -2589,6 +2647,24 @@ surface_free_unused_subsurface_views(struct weston_surface *surface)
 	}
 }
 
+static void
+view_add_to_outputs(struct weston_view *view, struct weston_compositor *ec)
+{
+	struct weston_output *output;
+
+	if (!weston_view_is_mapped(view))
+		return;
+
+	wl_list_for_each(output, &ec->output_list, link) {
+		if (view->output_mask & (1u << output->id)) {
+			wl_list_init(&view->output_damages[output->id].link);
+			wl_list_insert(output->view_list.prev,
+			               &view->output_damages[output->id].link);
+		}
+	}
+
+}
+
 static void
 view_list_add_subsurface_view(struct weston_compositor *compositor,
 			      struct weston_subsurface *sub,
@@ -2624,14 +2700,16 @@ view_list_add_subsurface_view(struct weston_compositor *compositor,
 	view->is_mapped = true;
 
 	if (wl_list_empty(&sub->surface->subsurface_list)) {
+		view_add_to_outputs(view, compositor);
 		wl_list_insert(compositor->view_list.prev, &view->link);
 		return;
 	}
 
 	wl_list_for_each(child, &sub->surface->subsurface_list, parent_link) {
-		if (child->surface == sub->surface)
+		if (child->surface == sub->surface) {
+			view_add_to_outputs(view, compositor);
 			wl_list_insert(compositor->view_list.prev, &view->link);
-		else
+		} else
 			view_list_add_subsurface_view(compositor, child, view);
 	}
 }
@@ -2651,14 +2729,16 @@ view_list_add(struct weston_compositor *compositor,
 	weston_view_update_transform(view);
 
 	if (wl_list_empty(&view->surface->subsurface_list)) {
+		view_add_to_outputs(view, compositor);
 		wl_list_insert(compositor->view_list.prev, &view->link);
 		return;
 	}
 
 	wl_list_for_each(sub, &view->surface->subsurface_list, parent_link) {
-		if (sub->surface == view->surface)
+		if (sub->surface == view->surface) {
+			view_add_to_outputs(view, compositor);
 			wl_list_insert(compositor->view_list.prev, &view->link);
-		else
+		} else
 			view_list_add_subsurface_view(compositor, sub, view);
 	}
 }
@@ -2668,6 +2748,7 @@ weston_compositor_build_view_list(struct weston_compositor *compositor)
 {
 	struct weston_view *view, *tmp;
 	struct weston_layer *layer;
+	struct weston_output *output;
 
 	wl_list_for_each(layer, &compositor->layer_list, link)
 		wl_list_for_each(view, &layer->view_list.link, layer_link.link)
@@ -2676,6 +2757,9 @@ weston_compositor_build_view_list(struct weston_compositor *compositor)
 	wl_list_for_each_safe(view, tmp, &compositor->view_list, link)
 		wl_list_init(&view->link);
 	wl_list_init(&compositor->view_list);
+	
+	wl_list_for_each(output, &compositor->output_list, link)
+		wl_list_init(&output->view_list);
 
 	wl_list_for_each(layer, &compositor->layer_list, link) {
 		wl_list_for_each(view, &layer->view_list.link, layer_link.link) {
@@ -2735,18 +2819,17 @@ weston_output_repaint(struct weston_output *output, void *repaint_data)
 	weston_compositor_build_view_list(ec);
 
 	/* Find the highest protection desired for an output */
-	wl_list_for_each(ev, &ec->view_list, link) {
-		if (ev->surface->output_mask & (1u << output->id)) {
-			/*
-			 * The desired_protection of the output should be the
-			 * maximum of the desired_protection of the surfaces,
-			 * that are displayed on that output, to avoid
-			 * reducing the protection for existing surfaces.
-			 */
-			if (ev->surface->desired_protection > highest_requested)
-				highest_requested =
-						ev->surface->desired_protection;
-		}
+	wl_list_for_each(ev, &output->view_list, output_damages[output->id].link) {
+		/*
+		 * The desired_protection of the output should be the
+		 * maximum of the desired_protection of the surfaces,
+		 * that are displayed on that output, to avoid
+		 * reducing the protection for existing surfaces.
+		 */
+		if (ev->surface->desired_protection > highest_requested)
+			highest_requested =
+				ev->surface->desired_protection;
+
 	}
 
 	output->desired_protection = highest_requested;
@@ -2775,12 +2858,12 @@ weston_output_repaint(struct weston_output *output, void *repaint_data)
 	}
 
 	output_accumulate_damage(output);
+	output_update_damage(output);
 
 	pixman_region32_init(&output_damage);
-	pixman_region32_intersect(&output_damage,
-				  &ec->primary_plane.damage, &output->region);
-	pixman_region32_subtract(&output_damage,
-				 &output_damage, &ec->primary_plane.clip);
+	pixman_region32_intersect(&output_damage, &output->damage, &output->region);
+	pixman_region32_subtract(&output_damage, &output->damage,
+	                         &ec->primary_plane.clip);
 
 	if (output->dirty)
 		weston_output_update_matrix(output);
@@ -4890,7 +4973,6 @@ weston_plane_init(struct weston_plane *plane,
 			struct weston_compositor *ec,
 			int32_t x, int32_t y)
 {
-	pixman_region32_init(&plane->damage);
 	pixman_region32_init(&plane->clip);
 	plane->x = x;
 	plane->y = y;
@@ -4906,7 +4988,6 @@ weston_plane_release(struct weston_plane *plane)
 {
 	struct weston_view *view;
 
-	pixman_region32_fini(&plane->damage);
 	pixman_region32_fini(&plane->clip);
 
 	wl_list_for_each(view, &plane->compositor->view_list, link) {
@@ -5273,6 +5354,27 @@ weston_output_iterate_heads(struct weston_output *output,
 	return container_of(node, struct weston_head, output_link);
 }
 
+/** Attach a clone output to weston_output
+ *
+ * \param output The cloned output
+ * \param master The master output
+ *
+ * Attach a clone output to its master. The clone_output is a short lived
+ * field. Not used after enabling.
+ */
+WL_EXPORT int
+weston_output_make_slave(struct weston_output *output,
+                         struct weston_output *master)
+{
+	if (output->enabled) {
+		weston_log("enabled output %s cannot be a clone\n",
+		           output->name);
+		return -1;
+	}
+	output->clone_output = master;
+	return 0;
+}
+
 /** Attach a head to an output
  *
  * \param output The output to attach to.
@@ -6387,7 +6489,11 @@ weston_output_enable(struct weston_output *output)
 	iterator = container_of(c->output_list.prev,
 				struct weston_output, link);
 
-	if (!wl_list_empty(&c->output_list))
+	if (output->clone_output) {
+		x = output->clone_output->x;
+		y = output->clone_output->y;
+		output->clone_output = NULL;
+	} else if (!wl_list_empty(&c->output_list))
 		x = iterator->x + iterator->width;
 
 	/* Make sure the scale is set up */
@@ -6408,6 +6514,7 @@ weston_output_enable(struct weston_output *output)
 	weston_output_init_zoom(output);
 
 	weston_output_init_geometry(output, x, y);
+	pixman_region32_init(&output->damage);
 	weston_output_damage(output);
 
 	wl_list_init(&output->animation_list);
diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h
index 66c38e86..ae015492 100644
--- a/libweston/libweston-internal.h
+++ b/libweston/libweston-internal.h
@@ -159,6 +159,9 @@ weston_output_disable_planes_incr(struct weston_output *output);
 void
 weston_output_disable_planes_decr(struct weston_output *output);
 
+void
+weston_output_finish_damage(struct weston_output *output,
+                            pixman_region32_t *damage);
 /* weston_plane */
 
 void
diff --git a/man/weston-drm.man b/man/weston-drm.man
index 01a336e1..ff38f06e 100644
--- a/man/weston-drm.man
+++ b/man/weston-drm.man
@@ -139,6 +139,13 @@ chooses an arbitrary monitor to load the color profile for, but the
 profile is applied equally to all cloned monitors regardless of their
 properties.
 .TP
+\fBclone-from\fR=\fIname\fR
+Make this output (crtc) a clone of another. The argument
+.IR name " is the "
+.BR name " value of another output section. The
+referred to output section must exist. When this key is present in an
+output section, all other keys have no effect on the configuration.
+.TP
 \fBforce-on\fR=\fItrue\fR
 Force the output to be enabled even if the connector is disconnected.
 Defaults to false. Note that
