[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-intel: Changes to 'upstream-experimental'



 configure.ac                       |   87 ++
 man/intel.man                      |    5 
 src/Makefile.am                    |    4 
 src/intel_device.c                 |  101 ++-
 src/intel_driver.h                 |    1 
 src/intel_options.c                |    1 
 src/intel_options.h                |    1 
 src/legacy/i810/Makefile.am        |    3 
 src/sna/Makefile.am                |   14 
 src/sna/gen8_render.c              |   20 
 src/sna/kgem.c                     |  273 ++++++---
 src/sna/kgem.h                     |   23 
 src/sna/sna.h                      |   91 ++-
 src/sna/sna_accel.c                |  582 ++++++++++---------
 src/sna/sna_composite.c            |   17 
 src/sna/sna_damage.h               |   20 
 src/sna/sna_display.c              |  841 +++++++++++++++++++---------
 src/sna/sna_dri2.c                 |  735 +++++++++++++-----------
 src/sna/sna_dri3.c                 |  379 ++++++++++++
 src/sna/sna_driver.c               |  145 +++-
 src/sna/sna_io.c                   |   39 -
 src/sna/sna_present.c              |  465 +++++++++++++++
 src/sna/sna_render.c               |    3 
 src/sna/sna_trapezoids.c           |    4 
 src/sna/sna_trapezoids_imprecise.c |    4 
 src/uxa/Makefile.am                |   13 
 src/uxa/intel.h                    |   78 ++
 src/uxa/intel_display.c            |  419 ++++++++++++--
 src/uxa/intel_dri.c                |  212 ++++---
 src/uxa/intel_dri3.c               |  140 ++++
 src/uxa/intel_driver.c             |   89 ++
 src/uxa/intel_present.c            |  401 +++++++++++++
 src/uxa/intel_sync.c               |  111 +++
 src/uxa/intel_uxa.c                |   67 +-
 test/.gitignore                    |    2 
 test/Makefile.am                   |   15 
 test/dri3-test.c                   | 1100 +++++++++++++++++++++++++++++++++++++
 test/dri3.c                        |  133 ++++
 test/dri3.h                        |   50 +
 test/present-test.c                |  726 ++++++++++++++++++++++++
 test/test.h                        |   14 
 tools/virtual.c                    |  343 +++++++++--
 42 files changed, 6442 insertions(+), 1329 deletions(-)

New commits:
commit c6cd10f536e099277cdc46643725a5a50ea8b525
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Jun 5 22:43:37 2014 +0100

    sna: Hook up a backlight udev monitor for external changes
    
    Changes to the backlights are notified through uevents. Hooking up a
    udev monitor to listen out for external changes to the backlight (e.g.
    through ACPI function keys, or by the user writing to
    /sys/class/backlight directly) is easier than enabling polling on the
    backlight sysfs file using X's select() mechanism.
    
    Since we listen to backlight changes, we have to be careful not to
    confuse the side-effects of disabling connectors (which may cause either
    ourselves or the kernel to turn off the backlight) with the user value.
    
    Many thanks to Alexander Mezin for the suggestion to use udev for
    tracking the notifications for external changes to the backlight.
    
    Reported-by: Alexander Mezin <mezin.alexander@gmail.com>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=79699
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 7845cd1..0739f7b 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -298,6 +298,11 @@ struct sna {
 		unsigned serial;
 
 		uint32_t *encoders;
+
+#if HAVE_UDEV
+		struct udev_monitor *backlight_monitor;
+		pointer backlight_handler;
+#endif
 	} mode;
 
 	struct {
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 2dbe3f3..c6bb9cd 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -399,6 +399,129 @@ static void gem_close(int fd, uint32_t handle)
 #define BACKLIGHT_DEPRECATED_NAME  "BACKLIGHT"
 static Atom backlight_atom, backlight_deprecated_atom;
 
+#if HAVE_UDEV
+static void
+sna_backlight_uevent(int fd, void *closure)
+{
+	struct sna *sna = closure;
+	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
+	int i;
+
+	DBG(("%s()\n", __FUNCTION__));
+
+	/* Drain the event queue */
+	do {
+		struct udev_device *dev;
+
+		dev = udev_monitor_receive_device(sna->mode.backlight_monitor);
+		if (dev == NULL)
+			break;
+
+		udev_device_unref(dev);
+	} while (1);
+
+	/* Query all backlights for any changes */
+	for (i = 0; i < sna->mode.num_real_output; i++) {
+		xf86OutputPtr output = config->output[i];
+		struct sna_output *sna_output = to_sna_output(output);
+		int val;
+
+		if (sna_output->dpms_mode != DPMSModeOn)
+			continue;
+
+		assert(output->randr_output);
+
+		val = backlight_get(&sna_output->backlight);
+		if (val < 0)
+			continue;
+		DBG(("%s(%s): backlight '%s' was %d, now %d\n",
+		     __FUNCTION__, output->name, sna_output->backlight.iface,
+		     sna_output->backlight_active_level, val));
+
+		if (val == sna_output->backlight_active_level)
+			continue;
+
+		sna_output->backlight_active_level = val;
+
+		DBG(("%s(%s): sending change notification\n", __FUNCTION__, output->name));
+		RRChangeOutputProperty(output->randr_output,
+				       backlight_atom, XA_INTEGER,
+				       32, PropModeReplace, 1, &val,
+				       TRUE, FALSE);
+		RRChangeOutputProperty(output->randr_output,
+				       backlight_deprecated_atom, XA_INTEGER,
+				       32, PropModeReplace, 1, &val,
+				       TRUE, FALSE);
+	}
+}
+
+static void sna_backlight_pre_init(struct sna *sna)
+{
+	struct udev *u;
+	struct udev_monitor *mon;
+
+	u = udev_new();
+	if (!u)
+		return;
+
+	mon = udev_monitor_new_from_netlink(u, "udev");
+	if (!mon)
+		goto free_udev;
+
+	if (udev_monitor_filter_add_match_subsystem_devtype(mon, "backlight", NULL))
+		goto free_monitor;
+
+	if (udev_monitor_enable_receiving(mon))
+		goto free_monitor;
+
+	sna->mode.backlight_handler =
+		xf86AddGeneralHandler(udev_monitor_get_fd(mon),
+				      sna_backlight_uevent, sna);
+	if (!sna->mode.backlight_handler)
+		goto free_monitor;
+
+	DBG(("%s: installed backlight monitor\n", __FUNCTION__));
+	sna->mode.backlight_monitor = mon;
+
+	return;
+
+free_monitor:
+	udev_monitor_unref(mon);
+free_udev:
+	udev_unref(u);
+}
+
+static void sna_backlight_drain_uevents(struct sna *sna)
+{
+	if (sna->mode.backlight_monitor == NULL)
+		return;
+
+	sna_backlight_uevent(udev_monitor_get_fd(sna->mode.backlight_monitor),
+			     sna);
+}
+
+static void sna_backlight_close(struct sna *sna)
+{
+	struct udev *u;
+
+	if (sna->mode.backlight_handler == NULL)
+		return;
+
+	xf86RemoveGeneralHandler(sna->mode.backlight_handler);
+
+	u = udev_monitor_get_udev(sna->mode.backlight_monitor);
+	udev_monitor_unref(sna->mode.backlight_monitor);
+	udev_unref(u);
+
+	sna->mode.backlight_handler = NULL;
+	sna->mode.backlight_monitor = NULL;
+}
+#else
+static void sna_backlight_pre_init(struct sna *sna) { }
+static void sna_backlight_drain_uevents(struct sna *sna) { }
+static void sna_backlight_close(struct sna *sna) { }
+#endif
+
 static void
 sna_output_backlight_set(xf86OutputPtr output, int level)
 {
@@ -417,6 +540,12 @@ sna_output_backlight_set(xf86OutputPtr output, int level)
 			RRDeleteOutputProperty(output->randr_output, backlight_deprecated_atom);
 		}
 	}
+
+	/* Consume the uevent notification now so that we don't misconstrue
+	 * the change latter when we wake up and the output is in a different
+	 * state.
+	 */
+	sna_backlight_drain_uevents(to_sna(output->scrn));
 }
 
 static int
@@ -820,6 +949,14 @@ sna_crtc_apply(xf86CrtcPtr crtc)
 	for (i = 0; i < config->num_output; i++) {
 		xf86OutputPtr output = config->output[i];
 
+		/* Make sure we mark the output as off (and save the backlight)
+		 * before the kernel turns it off due to changing the pipe.
+		 * This is necessary as the kernel may turn off the backlight
+		 * and we lose track of the user settings.
+		 */
+		if (output->crtc == NULL)
+			output->funcs->dpms(output, DPMSModeOff);
+
 		if (output->crtc != crtc)
 			continue;
 
@@ -2374,6 +2511,7 @@ sna_output_dpms(xf86OutputPtr output, int dpms)
 {
 	struct sna *sna = to_sna(output->scrn);
 	struct sna_output *sna_output = output->driver_private;
+	int old_dpms = sna_output->dpms_mode;
 
 	DBG(("%s(%s:%d): dpms=%d (current: %d), active? %d\n",
 	     __FUNCTION__, output->name, sna_output->id,
@@ -2383,7 +2521,7 @@ sna_output_dpms(xf86OutputPtr output, int dpms)
 	if (!sna_output->id)
 		return;
 
-	if (sna_output->dpms_mode == dpms)
+	if (old_dpms == dpms)
 		return;
 
 	/* Record the value of the backlight before turning
@@ -2394,11 +2532,12 @@ sna_output_dpms(xf86OutputPtr output, int dpms)
 	 * and reapply it afterwards.
 	 */
 	if (sna_output->backlight.iface && dpms != DPMSModeOn) {
-		if (sna_output->dpms_mode == DPMSModeOn) {
+		if (old_dpms == DPMSModeOn) {
 			sna_output->backlight_active_level = sna_output_backlight_get(output);
 			DBG(("%s: saving current backlight %d\n",
 			     __FUNCTION__, sna_output->backlight_active_level));
 		}
+		sna_output->dpms_mode = dpms;
 		sna_output_backlight_set(output, 0);
 	}
 
@@ -2407,7 +2546,7 @@ sna_output_dpms(xf86OutputPtr output, int dpms)
 					sna_output->id,
 					sna_output->dpms_id,
 					dpms))
-		dpms = sna_output->dpms_mode;
+		dpms = old_dpms;
 
 	if (sna_output->backlight.iface && dpms == DPMSModeOn) {
 		DBG(("%s: restoring previous backlight %d\n",
@@ -2577,9 +2716,9 @@ sna_output_set_property(xf86OutputPtr output, Atom property,
 		if (val < 0 || val > sna_output->backlight.max)
 			return FALSE;
 
+		sna_output->backlight_active_level = val;
 		if (sna_output->dpms_mode == DPMSModeOn)
 			sna_output_backlight_set(output, val);
-		sna_output->backlight_active_level = val;
 		return TRUE;
 	}
 
@@ -4736,6 +4875,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
 		drmModeFreeResources(res);
 
 		sna_cursor_pre_init(sna);
+		sna_backlight_pre_init(sna);
 	} else {
 		if (num_fake == 0)
 			num_fake = 1;
@@ -4772,6 +4912,7 @@ sna_mode_close(struct sna *sna)
 	if (sna->flags & SNA_IS_HOSTED)
 		return;
 
+	sna_backlight_close(sna);
 	sna_cursor_close(sna);
 
 	for (i = 0; i < sna->mode.num_real_crtc; i++)

commit b545e10c50cbb2dd6f9fd53369667bed0d8f1b51
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Jun 5 15:54:32 2014 +0100

    sna: When the output is off, report the cached backlight value
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 8757847..2dbe3f3 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2646,9 +2646,17 @@ sna_output_get_property(xf86OutputPtr output, Atom property)
 		if (!sna_output->backlight.iface)
 			return FALSE;
 
-		val = sna_output_backlight_get(output);
-		if (val < 0)
-			return FALSE;
+		if (sna_output->dpms_mode == DPMSModeOn) {
+			val = sna_output_backlight_get(output);
+			if (val < 0)
+				return FALSE;
+			DBG(("%s(%s): output on, reporting actual backlight value [%d]\n",
+			     __FUNCTION__, output->name, val));
+		} else {
+			val = sna_output->backlight_active_level;
+			DBG(("%s(%s): output off, reporting cached backlight value [%d]\n",
+			     __FUNCTION__, output->name, val));
+		}
 
 		err = RRChangeOutputProperty(output->randr_output, property,
 					     XA_INTEGER, 32, PropModeReplace, 1, &val,

commit f0b8720807d9c1994e6db91a607efe4711b0d1ca
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Jun 5 15:31:54 2014 +0100

    sna: Inline calls to save/restore backlight around output DPMS
    
    The intertwined logic was a little confusing to read mixed between the
    functions, so inline it.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index bfc95f6..8757847 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -475,6 +475,8 @@ done:
 	     output->name, best_iface ?: "none"));
 	sna_output->backlight_active_level =
 		backlight_open(&sna_output->backlight, best_iface);
+	DBG(("%s(%s): initial backlight value %d\n",
+	     __FUNCTION__, output->name, sna_output->backlight_active_level));
 	if (sna_output->backlight_active_level < 0)
 		return;
 
@@ -2368,29 +2370,6 @@ sna_output_destroy(xf86OutputPtr output)
 }
 
 static void
-sna_output_dpms_backlight(xf86OutputPtr output, int oldmode, int mode)
-{
-	struct sna_output *sna_output = output->driver_private;
-
-	if (!sna_output->backlight.iface)
-		return;
-
-	DBG(("%s(%s:%d) -- %d -> %d\n", __FUNCTION__, output->name, sna_output->id, oldmode, mode));
-
-	if (mode == DPMSModeOn) {
-		/* If we're going from off->on we may need to turn on the backlight. */
-		if (oldmode != DPMSModeOn)
-			sna_output_backlight_set(output,
-						   sna_output->backlight_active_level);
-	} else {
-		/* Only save the current backlight value if we're going from on to off. */
-		if (oldmode == DPMSModeOn)
-			sna_output->backlight_active_level = sna_output_backlight_get(output);
-		sna_output_backlight_set(output, 0);
-	}
-}
-
-static void
 sna_output_dpms(xf86OutputPtr output, int dpms)
 {
 	struct sna *sna = to_sna(output->scrn);
@@ -2414,10 +2393,14 @@ sna_output_dpms(xf86OutputPtr output, int dpms)
 	 * record the value before the kernel modifies it
 	 * and reapply it afterwards.
 	 */
-	if (dpms != DPMSModeOn)
-		sna_output_dpms_backlight(output,
-					  sna_output->dpms_mode,
-					  dpms);
+	if (sna_output->backlight.iface && dpms != DPMSModeOn) {
+		if (sna_output->dpms_mode == DPMSModeOn) {
+			sna_output->backlight_active_level = sna_output_backlight_get(output);
+			DBG(("%s: saving current backlight %d\n",
+			     __FUNCTION__, sna_output->backlight_active_level));
+		}
+		sna_output_backlight_set(output, 0);
+	}
 
 	if (output->crtc &&
 	    drmModeConnectorSetProperty(sna->kgem.fd,
@@ -2426,10 +2409,12 @@ sna_output_dpms(xf86OutputPtr output, int dpms)
 					dpms))
 		dpms = sna_output->dpms_mode;
 
-	if (dpms == DPMSModeOn)
-		sna_output_dpms_backlight(output,
-					  sna_output->dpms_mode,
-					  dpms);
+	if (sna_output->backlight.iface && dpms == DPMSModeOn) {
+		DBG(("%s: restoring previous backlight %d\n",
+		     __FUNCTION__, sna_output->backlight_active_level));
+		sna_output_backlight_set(output,
+					 sna_output->backlight_active_level);
+	}
 
 	sna_output->dpms_mode = dpms;
 }

commit 9f7775158341c8384da870e06cab200deddf48c1
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Jun 5 15:31:27 2014 +0100

    sna: Set initial output DPMS state from kernel
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index b0edd06..bfc95f6 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2023,13 +2023,6 @@ find_property(struct sna *sna, struct sna_output *output, const char *name)
 	return -1;
 }
 
-static int
-find_property_id(struct sna *sna, struct sna_output *output, const char *name)
-{
-	int idx = find_property(sna, output, name);
-	return idx != -1 ? output->prop_ids[idx] : 0;
-}
-
 static xf86OutputStatus
 sna_output_detect(xf86OutputPtr output)
 {
@@ -2913,7 +2906,7 @@ sna_output_add(struct sna *sna, int id, int serial)
 	char name[32];
 	int len, i;
 
-	DBG(("%s(%d)\n", __FUNCTION__, id));
+	DBG(("%s(%d): serial=%d\n", __FUNCTION__, id, serial));
 
 	COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad));
 
@@ -3007,7 +3000,6 @@ sna_output_add(struct sna *sna, int id, int serial)
 	sna_output->num_props = compat_conn.conn.count_props;
 	sna_output->prop_ids = malloc(sizeof(uint32_t)*compat_conn.conn.count_props);
 	sna_output->prop_values = malloc(sizeof(uint64_t)*compat_conn.conn.count_props);
-	sna_output->dpms_mode = DPMSModeOff;
 
 	compat_conn.conn.count_encoders = 0;
 
@@ -3059,7 +3051,16 @@ sna_output_add(struct sna *sna, int id, int serial)
 	sna_output->id = compat_conn.conn.connector_id;
 	sna_output->is_panel = is_panel(compat_conn.conn.connector_type);
 	sna_output->edid_idx = find_property(sna, sna_output, "EDID");
-	sna_output->dpms_id = find_property_id(sna, sna_output, "DPMS");
+	i = find_property(sna, sna_output, "DPMS");
+	if (i != -1) {
+		sna_output->dpms_id = sna_output->prop_ids[i];
+		sna_output->dpms_mode = sna_output->prop_values[i];
+		DBG(("%s: found 'DPMS' (idx=%d, id=%d), initial value=%d\n",
+		     __FUNCTION__, i, sna_output->dpms_id, sna_output->dpms_mode));
+	} else {
+		sna_output->dpms_id = -1;
+		sna_output->dpms_mode = DPMSModeOff;
+	}
 
 	sna_output->possible_encoders = possible_encoders;
 	sna_output->attached_encoders = attached_encoders;

commit 9e02fe269dc79ff867d1d2cb3a8673ee2861bd56
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Jun 5 15:49:03 2014 +0100

    sna: Make sure we recompute the vblank interval after reconfiguring the CRTC
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 4006efe..b0edd06 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1785,10 +1785,8 @@ sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
 	} else
 		sna_crtc_disable(crtc);
 
-	if (priv->bo != NULL) {
+	if (priv->bo != NULL)
 		priv->dpms_mode = mode;
-		update_flush_interval(to_sna(crtc->scrn));
-	}
 }
 
 void sna_mode_adjust_frame(struct sna *sna, int x, int y)
@@ -4670,6 +4668,7 @@ sna_crtc_config_notify(ScreenPtr screen)
 		return;
 
 	probe_capabilities(sna);
+	update_flush_interval(sna);
 
 	sna_cursors_reload(sna);
 

commit 51909f37ed6405c38f1c46a4012952be79031994
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Jun 5 14:54:55 2014 +0100

    sna: Skip marking the CRTC as damaged for TearFree
    
    As we have reorder the application of damage on a TearFree frontbuffer
    to before we attach the CRTC, we do not need to then schedule the update
    afterwards (until it gets drawn by the client).
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 46fc22c..4006efe 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1756,7 +1756,7 @@ retry: /* Attach per-crtc pixmap or direct */
 	}
 
 	sna_crtc_randr(crtc);
-	if (sna_crtc->shadow)
+	if (sna_crtc->transform)
 		sna_crtc_damage(crtc);
 	sna->mode.front_active += saved_bo == NULL;
 	sna->mode.dirty = true;

commit c7efe88a895a692e5f840562a09dac385508db57
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Jun 5 14:50:04 2014 +0100

    sna: Fix DBG compilation
    
    Update the DBG to reflect the new arguments to sna_damage_reduce_all()
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_damage.h b/src/sna/sna_damage.h
index 42edb10..9b6f213 100644
--- a/src/sna/sna_damage.h
+++ b/src/sna/sna_damage.h
@@ -268,11 +268,11 @@ static inline void sna_damage_reduce_all(struct sna_damage **_damage,
 {
 	struct sna_damage *damage = *_damage;
 
-	DBG(("%s(width=%d, height=%d)\n", __FUNCTION__, width, height));
-
 	if (damage == NULL || DAMAGE_IS_ALL(damage))
 		return;
 
+	DBG(("%s(width=%d, height=%d)\n", __FUNCTION__, pixmap->drawable.width, pixmap->drawable.height));
+
 	if (damage->mode == DAMAGE_ADD) {
 		if (damage->extents.x1 <= 0 &&
 		    damage->extents.y1 <= 0 &&

commit 9566fc0ccc71bc4fcd6bf83b567a41cc5366f5ee
Author: Chris Wilson <chris@chris-wilson.co.uk>
Date:   Thu Jun 5 12:26:23 2014 +0100

    sna: Curry parameters to sna_damage_all()
    
    It is far easily to pass the PixmapPtr into the function and have it
    pluck out the width and height than do so in all callers.
    
    Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 70211eb..a307d9e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -768,14 +768,10 @@ struct sna_pixmap *sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo)
 
 	if (bo->snoop) {
 		priv->cpu_bo = bo;
-		sna_damage_all(&priv->cpu_damage,
-				pixmap->drawable.width,
-				pixmap->drawable.height);
+		sna_damage_all(&priv->cpu_damage, pixmap);
 	} else {
 		priv->gpu_bo = bo;
-		sna_damage_all(&priv->gpu_damage,
-				pixmap->drawable.width,
-				pixmap->drawable.height);
+		sna_damage_all(&priv->gpu_damage, pixmap);
 	}
 
 	return priv;
@@ -996,7 +992,7 @@ fallback:
 	priv->shm = true;
 	priv->stride = pitch;
 	priv->ptr = MAKE_STATIC_PTR(addr);
-	sna_damage_all(&priv->cpu_damage, width, height);
+	sna_damage_all(&priv->cpu_damage, pixmap);
 
 	pixmap->devKind = pitch;
 	pixmap->devPrivate.ptr = addr;
@@ -1061,7 +1057,7 @@ sna_pixmap_create_scratch(ScreenPtr screen,
 		return NullPixmap;
 	}
 
-	sna_damage_all(&priv->gpu_damage, width, height);
+	sna_damage_all(&priv->gpu_damage, pixmap);
 
 	assert(to_sna_from_pixmap(pixmap) == sna);
 	assert(pixmap->drawable.pScreen == screen);
@@ -1198,9 +1194,7 @@ sna_set_shared_pixmap_backing(PixmapPtr pixmap, void *fd_handle)
 	if (bo == NULL)
 		return FALSE;
 
-	sna_damage_all(&priv->gpu_damage,
-		       pixmap->drawable.width,
-		       pixmap->drawable.height);
+	sna_damage_all(&priv->gpu_damage, pixmap);
 
 	bo->pitch = pixmap->devKind;
 	priv->stride = pixmap->devKind;
@@ -1274,7 +1268,7 @@ sna_create_pixmap_shared(struct sna *sna, ScreenPtr screen,
 		priv->mapped = MAPPED_GTT;
 		assert_pixmap_map(pixmap, priv);
 
-		sna_damage_all(&priv->gpu_damage, width, height);
+		sna_damage_all(&priv->gpu_damage, pixmap);
 	}
 
 	return pixmap;
@@ -2131,9 +2125,7 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 			assert(has_coherent_ptr(sna, priv, flags));
 
 			assert(priv->gpu_bo->proxy == NULL);
-			sna_damage_all(&priv->gpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
+			sna_damage_all(&priv->gpu_damage, pixmap);
 			sna_damage_destroy(&priv->cpu_damage);
 			priv->clear = false;
 			list_del(&priv->flush_list);
@@ -2194,9 +2186,7 @@ skip_inplace_map:
 
 			if (flags & MOVE_WRITE) {
 				assert(priv->gpu_bo->proxy == NULL);
-				sna_damage_all(&priv->gpu_damage,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height);
+				sna_damage_all(&priv->gpu_damage, pixmap);
 				sna_damage_destroy(&priv->cpu_damage);
 				sna_pixmap_free_cpu(sna, priv, priv->cpu);
 				list_del(&priv->flush_list);
@@ -2236,9 +2226,7 @@ skip_inplace_map:
 
 			if (flags & MOVE_WRITE) {
 				assert(priv->gpu_bo->proxy == NULL);
-				sna_damage_all(&priv->gpu_damage,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height);
+				sna_damage_all(&priv->gpu_damage, pixmap);
 				sna_damage_destroy(&priv->cpu_damage);
 				sna_pixmap_free_cpu(sna, priv, priv->cpu);
 				list_del(&priv->flush_list);
@@ -2301,9 +2289,7 @@ skip_inplace_map:
 					    priv->clear_color);
 			}
 
-			sna_damage_all(&priv->cpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
+			sna_damage_all(&priv->cpu_damage, pixmap);
 			sna_pixmap_free_gpu(sna, priv);
 			assert(priv->gpu_damage == NULL);
 			assert(priv->clear == false);
@@ -2334,9 +2320,7 @@ skip_inplace_map:
 	if (flags & MOVE_WRITE || priv->create & KGEM_CAN_CREATE_LARGE) {
 mark_damage:
 		DBG(("%s: marking as damaged\n", __FUNCTION__));
-		sna_damage_all(&priv->cpu_damage,
-			       pixmap->drawable.width,
-			       pixmap->drawable.height);
+		sna_damage_all(&priv->cpu_damage, pixmap);
 		sna_pixmap_free_gpu(sna, priv);
 		assert(priv->gpu_damage == NULL);
 		assert(priv->clear == false);
@@ -2572,9 +2556,7 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 							sna_add_flush_pixmap(sna, priv, priv->gpu_bo);
 
 						assert(priv->cpu_damage == NULL);
-						sna_damage_all(&priv->gpu_damage,
-							       pixmap->drawable.width,
-							       pixmap->drawable.height);
+						sna_damage_all(&priv->gpu_damage, pixmap);
 						sna_damage_subtract(&priv->gpu_damage, region);
 						discard_gpu = false;
 					}
@@ -2773,9 +2755,7 @@ move_to_cpu:
 		sna_damage_subtract(&priv->cpu_damage, region);
 		if (sna_pixmap_move_to_gpu(pixmap, MOVE_READ | MOVE_ASYNC_HINT)) {
 			assert(priv->gpu_bo);
-			sna_damage_all(&priv->gpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
+			sna_damage_all(&priv->gpu_damage, pixmap);
 			sna_pixmap_free_cpu(sna, priv, false);
 		}
 	}
@@ -2976,9 +2956,7 @@ done:
 		assert(!DAMAGE_IS_ALL(priv->cpu_damage));
 		assert_pixmap_contains_box(pixmap, RegionExtents(region));
 		sna_damage_add(&priv->cpu_damage, region);
-		sna_damage_reduce_all(&priv->cpu_damage,
-				      pixmap->drawable.width,
-				      pixmap->drawable.height);
+		sna_damage_reduce_all(&priv->cpu_damage, pixmap);
 		if (DAMAGE_IS_ALL(priv->cpu_damage)) {
 			DBG(("%s: replaced entire pixmap\n", __FUNCTION__));
 			sna_pixmap_free_gpu(sna, priv);
@@ -3141,9 +3119,7 @@ __sna_pixmap_for_gpu(struct sna *sna, PixmapPtr pixmap, unsigned flags)
 		if (priv == NULL)
 			return NULL;
 
-		sna_damage_all(&priv->cpu_damage,
-			       pixmap->drawable.width,
-			       pixmap->drawable.height);
+		sna_damage_all(&priv->cpu_damage, pixmap);
 
 		assert(priv->gpu_bo == NULL);
 		assert(priv->gpu_damage == NULL);
@@ -3406,9 +3382,7 @@ done:
 			     __FUNCTION__));
 			assert(priv->gpu_bo);
 			assert(priv->gpu_bo->proxy == NULL);
-			sna_damage_all(&priv->gpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
+			sna_damage_all(&priv->gpu_damage, pixmap);
 		}
 		if (DAMAGE_IS_ALL(priv->gpu_damage))
 			sna_pixmap_free_cpu(sna, priv, priv->cpu);
@@ -3892,8 +3866,8 @@ sna_pixmap_create_upload(ScreenPtr screen,
 	 * but will work so long as we always check before doing the
 	 * transfer.
 	 */
-	sna_damage_all(&priv->gpu_damage, width, height);
-	sna_damage_all(&priv->cpu_damage, width, height);
+	sna_damage_all(&priv->gpu_damage, pixmap);
+	sna_damage_all(&priv->cpu_damage, pixmap);
 
 	pixmap->devKind = priv->gpu_bo->pitch;
 	pixmap->devPrivate.ptr = ptr;
@@ -4016,9 +3990,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 				priv->cpu_bo = NULL;
 				priv->ptr = NULL;
 				pixmap->devPrivate.ptr = NULL;
-				sna_damage_all(&priv->gpu_damage,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height);
+				sna_damage_all(&priv->gpu_damage, pixmap);
 				sna_damage_destroy(&priv->cpu_damage);
 				goto done;
 			}
@@ -4051,9 +4023,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 			 */
 			assert(priv->gpu_bo);
 			assert(priv->gpu_bo->proxy == NULL);
-			sna_damage_all(&priv->gpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
+			sna_damage_all(&priv->gpu_damage, pixmap);
 			DBG(("%s: marking as all-damaged for GPU\n",
 			     __FUNCTION__));
 			goto active;
@@ -4085,9 +4055,7 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 		priv->cpu_bo = NULL;
 		priv->ptr = NULL;
 		pixmap->devPrivate.ptr = NULL;
-		sna_damage_all(&priv->gpu_damage,
-			       pixmap->drawable.width,
-			       pixmap->drawable.height);
+		sna_damage_all(&priv->gpu_damage, pixmap);
 		sna_damage_destroy(&priv->cpu_damage);
 		goto done;
 	}
@@ -4147,18 +4115,14 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 		assert(!priv->shm);
 		assert(priv->gpu_bo);
 		assert(priv->gpu_bo->proxy == NULL);
-		sna_damage_all(&priv->gpu_damage,
-			       pixmap->drawable.width,
-			       pixmap->drawable.height);
+		sna_damage_all(&priv->gpu_damage, pixmap);
 		sna_pixmap_free_cpu(sna, priv,
 				    (priv->create & KGEM_CAN_CREATE_LARGE) ? false : priv->cpu);
 	}
 done:
 	list_del(&priv->flush_list);
 
-	sna_damage_reduce_all(&priv->gpu_damage,
-			      pixmap->drawable.width,
-			      pixmap->drawable.height);
+	sna_damage_reduce_all(&priv->gpu_damage, pixmap);
 	if (DAMAGE_IS_ALL(priv->gpu_damage))
 		sna_pixmap_free_cpu(sna, priv, priv->cpu);
 
@@ -4520,14 +4484,10 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
 	if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 		assert(!priv->clear);
 		if (region_subsumes_drawable(region, &pixmap->drawable)) {
-			sna_damage_all(&priv->gpu_damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
+			sna_damage_all(&priv->gpu_damage, pixmap);
 		} else {
 			sna_damage_add(&priv->gpu_damage, region);
-			sna_damage_reduce_all(&priv->gpu_damage,
-					      pixmap->drawable.width,
-					      pixmap->drawable.height);
+			sna_damage_reduce_all(&priv->gpu_damage, pixmap);
 		}
 		if (DAMAGE_IS_ALL(priv->gpu_damage))
 			sna_damage_destroy(&priv->cpu_damage);
@@ -4603,9 +4563,7 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 			sna_pixmap_free_gpu(sna, priv);
 			ignore_cpu = priv->cpu_damage == NULL;
 			if (priv->ptr)
-				sna_damage_all(&priv->cpu_damage,
-						pixmap->drawable.width,
-						pixmap->drawable.height);
+				sna_damage_all(&priv->cpu_damage, pixmap);
 		}
 	}
 
@@ -4721,14 +4679,10 @@ try_upload_tiled_x(PixmapPtr pixmap, RegionRec *region,
 	if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 		assert(!priv->clear);
 		if (replaces) {
-			sna_damage_all(&priv->gpu_damage,
-					pixmap->drawable.width,
-					pixmap->drawable.height);
+			sna_damage_all(&priv->gpu_damage, pixmap);
 		} else {
 			sna_damage_add(&priv->gpu_damage, region);
-			sna_damage_reduce_all(&priv->gpu_damage,
-					      pixmap->drawable.width,
-					      pixmap->drawable.height);
+			sna_damage_reduce_all(&priv->gpu_damage, pixmap);
 		}
 		if (DAMAGE_IS_ALL(priv->gpu_damage))
 			sna_damage_destroy(&priv->cpu_damage);
@@ -5499,9 +5453,7 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 			assert(!priv->clear);
 			if (priv->cpu_bo == NULL) {
-				sna_damage_all(&priv->gpu_damage,
-						pixmap->drawable.width,
-						pixmap->drawable.height);
+				sna_damage_all(&priv->gpu_damage, pixmap);
 			} else {
 				RegionTranslate(region, tx, ty);
 				sna_damage_add(&priv->gpu_damage, region);
@@ -6073,9 +6025,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 					     src_priv->clear_color));
 					dst_priv->clear = true;
 					dst_priv->clear_color = color;
-					sna_damage_all(&dst_priv->gpu_damage,
-						       dst_pixmap->drawable.width,
-						       dst_pixmap->drawable.height);
+					sna_damage_all(&dst_priv->gpu_damage, dst_pixmap);
 					sna_damage_destroy(&dst_priv->cpu_damage);
 					list_del(&dst_priv->flush_list);
 					return;
@@ -6116,9 +6066,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 				assert(src_pixmap->drawable.bitsPerPixel == dst_pixmap->drawable.bitsPerPixel);
 				if (sna_pixmap_make_cow(sna, src_priv, dst_priv)) {
 					assert(dst_priv->gpu_bo == src_priv->gpu_bo);
-					sna_damage_all(&dst_priv->gpu_damage,
-						       dst_pixmap->drawable.width,
-						       dst_pixmap->drawable.height);
+					sna_damage_all(&dst_priv->gpu_damage, dst_pixmap);
 					sna_damage_destroy(&dst_priv->cpu_damage);
 					list_del(&dst_priv->flush_list);
 					if (dst_priv->shm)
@@ -6386,9 +6334,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 				assert(*damage == dst_priv->gpu_damage);
 				if (replaces) {
 					sna_damage_destroy(&dst_priv->cpu_damage);
-					sna_damage_all(&dst_priv->gpu_damage,
-						       dst_pixmap->drawable.width,
-						       dst_pixmap->drawable.height);
+					sna_damage_all(&dst_priv->gpu_damage, dst_pixmap);
 					list_del(&dst_priv->flush_list);
 				} else
 					sna_damage_add(&dst_priv->gpu_damage,
@@ -11374,11 +11320,9 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 				if (damage) {
 					assert_pixmap_contains_box(pixmap, &r);
 					if (r.x2 - r.x1 == pixmap->drawable.width &&
-					    r.y2 - r.y1 == pixmap->drawable.height) {
-						sna_damage_all(damage,
-							       pixmap->drawable.width,
-							       pixmap->drawable.height);
-					} else
+					    r.y2 - r.y1 == pixmap->drawable.height)
+						sna_damage_all(damage, pixmap);
+					else
 						sna_damage_add_box(damage, &r);
 				}
 				assert_pixmap_damage(pixmap);
@@ -11389,9 +11333,7 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 					struct sna_pixmap *priv = sna_pixmap(pixmap);
 					if (bo == priv->gpu_bo) {
 						assert(priv->gpu_bo->proxy == NULL);
-						sna_damage_all(&priv->gpu_damage,
-							       pixmap->drawable.width,
-							       pixmap->drawable.height);
+						sna_damage_all(&priv->gpu_damage, pixmap);
 						sna_damage_destroy(&priv->cpu_damage);
 						list_del(&priv->flush_list);
 						priv->clear = true;
@@ -14337,9 +14279,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 				DBG(("%s: promoting to full GPU\n",
 				     __FUNCTION__));
 				assert(priv->gpu_bo->proxy == NULL);
-				sna_damage_all(&priv->gpu_damage,
-					       pixmap->drawable.width,
-					       pixmap->drawable.height);
+				sna_damage_all(&priv->gpu_damage, pixmap);
 			}
 			DBG(("%s: dropping last-cpu hint\n", __FUNCTION__));
 			priv->cpu = false;
diff --git a/src/sna/sna_composite.c b/src/sna/sna_composite.c
index 070faf4..8b4aa80 100644
--- a/src/sna/sna_composite.c
+++ b/src/sna/sna_composite.c
@@ -418,9 +418,12 @@ static void apply_damage(struct sna_composite_op *op, RegionPtr region)
 	assert_pixmap_contains_box(op->dst.pixmap, RegionExtents(region));
 	if (region->data == NULL &&
 	    region->extents.x2 - region->extents.x1 == op->dst.width &&
-	    region->extents.y2 - region->extents.y1 == op->dst.height)
-		sna_damage_all(op->damage, op->dst.width, op->dst.height);
-	else
+	    region->extents.y2 - region->extents.y1 == op->dst.height) {
+		*op->damage = _sna_damage_all(*op->damage,
+					      op->dst.width,
+					      op->dst.height);
+		op->damage = NULL;
+	} else
 		sna_damage_add(op->damage, region);
 }
 
@@ -964,9 +967,7 @@ sna_composite_rectangles(CARD8		 op,
 				if (priv->gpu_bo && priv->cpu_damage == NULL) {
 					DBG(("%s: promoting to full GPU\n", __FUNCTION__));
 					assert(priv->gpu_bo->proxy == NULL);
-					sna_damage_all(&priv->gpu_damage,
-						       pixmap->drawable.width,
-						       pixmap->drawable.height);
+					sna_damage_all(&priv->gpu_damage, pixmap);
 				}
 			}
 		}
@@ -1037,9 +1038,7 @@ sna_composite_rectangles(CARD8		 op,
 	 */
 	if (region_subsumes_drawable(&region, &pixmap->drawable)) {
 		if (damage) {
-			sna_damage_all(damage,
-				       pixmap->drawable.width,
-				       pixmap->drawable.height);
+			sna_damage_all(damage, pixmap);
 			sna_damage_destroy(damage == &priv->gpu_damage ?


Reply to: