[PATCH 7/7] damageext: Xineramify

Adam Jackson ajax at redhat.com
Mon Sep 2 07:19:02 PDT 2013


Probable issues:

Pixmaps will get N times as many reports as they should; they're
replicated to all screens, so.

Windows will have funny-looking seams in the damage report.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 Xext/panoramiX.c      |   3 +
 damageext/damageext.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++-
 damageext/damageext.h |   6 +-
 3 files changed, 175 insertions(+), 3 deletions(-)

diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index 2b3a570..7734309 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -54,6 +54,7 @@ Equipment Corporation.
 #include "resource.h"
 #include "picturestr.h"
 #include "xfixesint.h"
+#include "damageext.h"
 #ifdef COMPOSITE
 #include "compint.h"
 #endif
@@ -582,6 +583,7 @@ PanoramiXExtensionInit(void)
 
     PanoramiXRenderInit();
     PanoramiXFixesInit();
+    PanoramiXDamageInit();
 #ifdef COMPOSITE
     PanoramiXCompositeInit();
 #endif
@@ -887,6 +889,7 @@ PanoramiXResetProc(ExtensionEntry * extEntry)
 
     PanoramiXRenderReset();
     PanoramiXFixesReset();
+    PanoramiXDamageReset();
 #ifdef COMPOSITE
     PanoramiXCompositeReset ();
 #endif
diff --git a/damageext/damageext.c b/damageext/damageext.c
index 01b88ef..62a6c43 100644
--- a/damageext/damageext.c
+++ b/damageext/damageext.c
@@ -24,10 +24,21 @@
 #include <dix-config.h>
 #endif
 
+#include "damageext.h"
 #include "damageextint.h"
 #include "protocol-versions.h"
 #include "extinit.h"
 
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+
+static RESTYPE XRT_DAMAGE;
+static XID PanoramiXReportDrawable;
+static int (*PanoramiXSaveDamageVector[XDamageNumberRequests]) (ClientPtr);
+
+#endif
+
 static unsigned char DamageReqCode;
 static int DamageEventBase;
 static RESTYPE DamageExtType;
@@ -170,6 +181,7 @@ ProcDamageCreate(ClientPtr client)
     DamageReportLevel level;
     RegionPtr pRegion;
     int rc;
+    XID report;
 
     REQUEST(xDamageCreateReq);
 
@@ -198,11 +210,18 @@ ProcDamageCreate(ClientPtr client)
         return BadValue;
     }
 
+#ifdef PANORAMIX
+    if (!noPanoramiXExtension)
+        report = PanoramiXReportDrawable;
+    else
+#endif
+        report = stuff->drawable;
+
     pDamageExt = malloc(sizeof(DamageExtRec));
     if (!pDamageExt)
         return BadAlloc;
     pDamageExt->id = stuff->damage;
-    pDamageExt->drawable = stuff->drawable;
+    pDamageExt->drawable = report;
     pDamageExt->pDrawable = pDrawable;
     pDamageExt->level = level;
     pDamageExt->pClient = client;
@@ -458,6 +477,149 @@ SDamageNotifyEvent(xDamageNotifyEvent * from, xDamageNotifyEvent * to)
     cpswaps(from->geometry.height, to->geometry.height);
 }
 
+#ifdef PANORAMIX
+
+#define VERIFY_XIN_DAMAGE(damage, did, client, mode) do { \
+    int rc = dixLookupResourceByType((void **)&damage, did, XRT_DAMAGE, client, mode); \
+    if (rc != Success) \
+        return rc; \
+} while (0)
+
+static int
+PanoramiXDamageCreate(ClientPtr client)
+{
+    PanoramiXRes *draw, *damage;
+    int i, rc;
+
+    REQUEST(xDamageCreateReq);
+
+    REQUEST_SIZE_MATCH(xDamageCreateReq);
+    LEGAL_NEW_RESOURCE(stuff->damage, client);
+    rc = dixLookupResourceByClass((void **)&draw, stuff->drawable, XRC_DRAWABLE,
+                                  client, DixGetAttrAccess | DixReadAccess);
+    if (rc != Success)
+        return rc;
+
+    if (!(damage = malloc(sizeof(PanoramiXRes))))
+        return BadAlloc;
+
+    damage->type = XRT_DAMAGE;
+    panoramix_setup_ids(damage, client, stuff->damage);
+
+    /*
+     * This is a break from the usual panoramix pattern.  Refer to the
+     * panoramix conditional section in ProcDamageCreate for the other
+     * half of the story, we're doing this in order to get the drawable
+     * ID right in the reported event.
+     */
+
+    PanoramiXReportDrawable = stuff->drawable;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        stuff->damage = damage->info[i].id;
+        stuff->drawable = draw->info[i].id;
+        rc = PanoramiXSaveDamageVector[X_DamageCreate](client);
+        if (rc != Success)
+            break;
+    }
+
+    if (rc == Success)
+        AddResource(damage->info[0].id, XRT_DAMAGE, damage);
+    else
+        free(damage);
+
+    return rc;
+}
+
+static int
+PanoramiXDamageDestroy(ClientPtr client)
+{
+    REQUEST(xDamageDestroyReq);
+    PanoramiXRes *damage;
+    int i, result = Success;
+
+    REQUEST_SIZE_MATCH(xDamageDestroyReq);
+    VERIFY_XIN_DAMAGE(damage, stuff->damage, client, DixWriteAccess);
+
+    FOR_NSCREENS_BACKWARD(i) {
+        stuff->damage = damage->info[i].id;
+        result = PanoramiXSaveDamageVector[X_DamageDestroy](client);
+        if (result != Success)
+            break;
+    }
+
+    return result;
+}
+
+static int
+PanoramiXDamageSubtract(ClientPtr client)
+{
+    REQUEST(xDamageSubtractReq);
+    PanoramiXRes *damage;
+    int i, result = Success;
+
+    REQUEST_SIZE_MATCH(xDamageSubtractReq);
+    VERIFY_XIN_DAMAGE(damage, stuff->damage, client, DixWriteAccess);
+
+    FOR_NSCREENS_BACKWARD(i) {
+        stuff->damage = damage->info[i].id;
+        result = PanoramiXSaveDamageVector[X_DamageSubtract](client);
+        if (result != Success)
+            break;
+    }
+
+    return result;
+}
+
+static int
+PanoramiXDamageAdd(ClientPtr client)
+{
+    REQUEST(xDamageAddReq);
+    PanoramiXRes *draw;
+    RegionPtr pRegion;
+    int i, rc;
+
+    REQUEST_SIZE_MATCH(xDamageAddReq);
+    VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
+    rc = dixLookupResourceByClass((void **)&draw, stuff->drawable, XRC_DRAWABLE,
+                                  client, DixWriteAccess);
+    if (rc != Success)
+        return rc;
+
+    FOR_NSCREENS_BACKWARD(i) {
+        stuff->drawable = draw->info[i].id;
+        rc = PanoramiXSaveDamageVector[X_DamageAdd](client);
+        if (rc != Success)
+            break;
+    }
+
+    return rc;
+}
+
+void
+PanoramiXDamageInit(void)
+{
+    XRT_DAMAGE = CreateNewResourceType(XineramaDeleteResource,
+                                       "XineramaDamage");
+
+    memcpy(PanoramiXSaveDamageVector, ProcDamageVector,
+           sizeof(ProcDamageVector));
+
+    ProcDamageVector[X_DamageCreate] = PanoramiXDamageCreate;
+    ProcDamageVector[X_DamageDestroy] = PanoramiXDamageDestroy;
+    ProcDamageVector[X_DamageSubtract] = PanoramiXDamageSubtract;
+    ProcDamageVector[X_DamageAdd] = PanoramiXDamageAdd;
+}
+
+void
+PanoramiXDamageReset(void)
+{
+    memcpy(ProcDamageVector, PanoramiXSaveDamageVector,
+           sizeof(ProcDamageVector));
+}
+
+#endif /* PANORAMIX */
+
 void
 DamageExtensionInit(void)
 {
@@ -488,5 +650,10 @@ DamageExtensionInit(void)
             (EventSwapPtr) SDamageNotifyEvent;
         SetResourceTypeErrorValue(DamageExtType,
                                   extEntry->errorBase + BadDamage);
+#ifdef PANORAMIX
+        if (XRT_DAMAGE)
+            SetResourceTypeErrorValue(XRT_DAMAGE,
+                                      extEntry->errorBase + BadDamage);
+#endif
     }
 }
diff --git a/damageext/damageext.h b/damageext/damageext.h
index bd99635..3898cc5 100644
--- a/damageext/damageext.h
+++ b/damageext/damageext.h
@@ -27,7 +27,9 @@
 #ifndef _DAMAGEEXT_H_
 #define _DAMAGEEXT_H_
 
-void
- DamageExtensionInit(void);
+#ifdef PANORAMIX
+void PanoramiXDamageInit(void);
+void PanoramiXDamageReset(void);
+#endif
 
 #endif                          /* _DAMAGEEXT_H_ */
-- 
1.8.3.1



More information about the xorg-devel mailing list