[Xquartz-changes] xserver: Branch 'server-1.12-apple' - 8 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Wed Oct 19 00:17:19 PDT 2011


Rebased ref, commits from common ancestor:
commit e317872c6050749ff34ea054a95549565cafe669
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Feb 12 19:48:52 2010 -0800

    fb: Revert fb changes that broke XQuartz
    
    http://bugs.freedesktop.org/show_bug.cgi?id=26124
    
    Revert "Fix source pictures getting random transforms after 2d6a8f668342a5190cdf43b5."
    Revert "fb: Adjust transform or composite coordinates for pixman operations"
    
    http://bugs.freedesktop.org/26124
    
    This reverts commit a72c65e9176c51de95db2fdbf4c5d946a4911695.
    This reverts commit a6bd5d2e482a5aa84acb3d4932e2a166d8670ef1.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/fb/fb.h b/fb/fb.h
index eaa21ad..e65a1c0 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -2049,11 +2049,8 @@ fbFillRegionSolid (DrawablePtr	pDrawable,
 		   FbBits	xor);
 
 extern _X_EXPORT pixman_image_t *
-image_from_pict (PicturePtr	pict,
-		 Bool		has_clip,
-		 int		*xoff,
-		 int		*yoff);
-
+image_from_pict (PicturePtr pict,
+		 Bool       has_clip);
 extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *);
 
 #endif /* _FB_H_ */
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 57c93fd..127e5c7 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -50,24 +50,19 @@ fbComposite (CARD8      op,
 	     CARD16     height)
 {
     pixman_image_t *src, *mask, *dest;
-    int src_xoff, src_yoff;
-    int msk_xoff, msk_yoff;
-    int dst_xoff, dst_yoff;
     
     miCompositeSourceValidate (pSrc);
     if (pMask)
 	miCompositeSourceValidate (pMask);
     
-    src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
-    mask = image_from_pict (pMask, FALSE, &msk_xoff, &msk_yoff);
-    dest = image_from_pict (pDst, TRUE, &dst_xoff, &dst_yoff);
+    src = image_from_pict (pSrc, TRUE);
+    mask = image_from_pict (pMask, TRUE);
+    dest = image_from_pict (pDst, TRUE);
 
     if (src && dest && !(pMask && !mask))
     {
 	pixman_image_composite (op, src, mask, dest,
-				xSrc + src_xoff, ySrc + src_yoff,
-				xMask + msk_xoff, yMask + msk_yoff,
-				xDst + dst_xoff, yDst + dst_yoff,
+				xSrc, ySrc, xMask, yMask, xDst, yDst,
 				width, height);
     }
 
@@ -146,22 +141,22 @@ create_conical_gradient_image (PictGradient *gradient)
 
 static pixman_image_t *
 create_bits_picture (PicturePtr pict,
-		     Bool       has_clip,
-		     int	*xoff,
-		     int	*yoff)
+		     Bool       has_clip)
 {
-    PixmapPtr pixmap;
     FbBits *bits;
     FbStride stride;
-    int bpp;
+    int bpp, xoff, yoff;
     pixman_image_t *image;
     
-    fbGetDrawablePixmap (pict->pDrawable, pixmap, *xoff, *yoff);
-    fbGetPixmapBitsData(pixmap, bits, stride, bpp);
+    fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
+
+    bits = (FbBits*)((CARD8*)bits +
+		     (pict->pDrawable->y + yoff) * stride * sizeof(FbBits) +
+		     (pict->pDrawable->x + xoff) * (bpp / 8));
 
     image = pixman_image_create_bits (
 	(pixman_format_code_t)pict->format,
-	pixmap->drawable.width, pixmap->drawable.height,
+	pict->pDrawable->width, pict->pDrawable->height,
 	(uint32_t *)bits, stride * sizeof (FbStride));
 
     if (!image)
@@ -189,55 +184,33 @@ create_bits_picture (PicturePtr pict,
 	if (pict->clientClipType != CT_NONE)
 	    pixman_image_set_has_client_clip (image, TRUE);
 
-	if (*xoff || *yoff)
-	    pixman_region_translate (pict->pCompositeClip, *xoff, *yoff);
+	pixman_region_translate (pict->pCompositeClip, - pict->pDrawable->x, - pict->pDrawable->y);
 
 	pixman_image_set_clip_region (image, pict->pCompositeClip);
 
-	if (*xoff || *yoff)
-	    pixman_region_translate (pict->pCompositeClip, -*xoff, -*yoff);
+	pixman_region_translate (pict->pCompositeClip, pict->pDrawable->x, pict->pDrawable->y);
     }
     
     /* Indexed table */
     if (pict->pFormat->index.devPrivate)
 	pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
 
-    /* Add in drawable origin to position within the image */
-    *xoff += pict->pDrawable->x;
-    *yoff += pict->pDrawable->y;
-
     return image;
 }
 
 static pixman_image_t *
-image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map);
+image_from_pict_internal (PicturePtr pict, Bool has_clip, Bool is_alpha_map);
 
 static void
-set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map)
+set_image_properties (pixman_image_t *image, PicturePtr pict, Bool is_alpha_map)
 {
     pixman_repeat_t repeat;
     pixman_filter_t filter;
     
     if (pict->transform)
     {
-	/* For source images, adjust the transform to account
-	 * for the drawable offset within the pixman image,
-	 * then set the offset to 0 as it will be used
-	 * to compute positions within the transformed image.
-	 */
-	if (!has_clip) {
-	    struct pixman_transform	adjusted;
-
-	    adjusted = *pict->transform;
-	    pixman_transform_translate(&adjusted,
-				       NULL,
-				       pixman_int_to_fixed(*xoff),
-				       pixman_int_to_fixed(*yoff));
-	    pixman_image_set_transform (image, &adjusted);
-	    *xoff = 0;
-	    *yoff = 0;
-	} else
-	    pixman_image_set_transform (image, pict->transform);
+	pixman_image_set_transform (
+	    image, (pixman_transform_t *)pict->transform);
     }
     
     switch (pict->repeatType)
@@ -267,8 +240,7 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
      */
     if (pict->alphaMap && !is_alpha_map)
     {
-	int alpha_xoff, alpha_yoff;
-	pixman_image_t *alpha_map = image_from_pict_internal (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff, TRUE);
+	pixman_image_t *alpha_map = image_from_pict_internal (pict->alphaMap, TRUE, TRUE);
 	
 	pixman_image_set_alpha_map (
 	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
@@ -301,7 +273,8 @@ set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int
 }
 
 static pixman_image_t *
-image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map)
+image_from_pict_internal (PicturePtr pict,
+		 Bool has_clip, Bool is_alpha_map)
 {
     pixman_image_t *image = NULL;
 
@@ -310,7 +283,7 @@ image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff,
 
     if (pict->pDrawable)
     {
-	image = create_bits_picture (pict, has_clip, xoff, yoff);
+	image = create_bits_picture (pict, has_clip);
     }
     else if (pict->pSourcePict)
     {
@@ -331,19 +304,18 @@ image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff,
 	    else if (sp->type == SourcePictTypeConical)
 		image = create_conical_gradient_image (gradient);
 	}
-	*xoff = *yoff = 0;
     }
     
     if (image)
-	set_image_properties (image, pict, has_clip, xoff, yoff, is_alpha_map);
+	set_image_properties (image, pict, is_alpha_map);
     
     return image;
 }
 
 pixman_image_t *
-image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+image_from_pict (PicturePtr pict, Bool has_clip)
 {
-    return image_from_pict_internal (pict, has_clip, xoff, yoff, FALSE);
+    return image_from_pict_internal (pict, has_clip, FALSE);
 }
 
 void
diff --git a/fb/fbtrap.c b/fb/fbtrap.c
index 0b5a638..fbe2647 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -39,12 +39,11 @@ fbAddTraps (PicturePtr	pPicture,
 	    xTrap	*traps)
 {
     pixman_image_t *image;
-    int dst_xoff, dst_yoff;
 
-    if (!(image = image_from_pict (pPicture, FALSE, &dst_xoff, &dst_yoff)))
+    if (!(image = image_from_pict (pPicture, FALSE)))
 	return;
     
-    pixman_add_traps (image, x_off + dst_xoff, y_off + dst_yoff,
+    pixman_add_traps (image, x_off, y_off,
 		      ntrap, (pixman_trap_t *)traps);
 
     free_pixman_pict (pPicture, image);
@@ -57,14 +56,13 @@ fbRasterizeTrapezoid (PicturePtr    pPicture,
 		      int	    y_off)
 {
     pixman_image_t *image;
-    int	dst_xoff, dst_yoff;
 
-    if (!(image = image_from_pict (pPicture, FALSE, &dst_xoff, &dst_yoff)))
+    if (!(image = image_from_pict (pPicture, FALSE)))
 	return;
 
     pixman_rasterize_trapezoid (image, (pixman_trapezoid_t *)trap,
-				x_off + dst_xoff,
-				y_off + dst_yoff);
+				x_off,
+				y_off);
 
     free_pixman_pict (pPicture, image);
 }
@@ -77,13 +75,12 @@ fbAddTriangles (PicturePtr  pPicture,
 		xTriangle *tris)
 {
     pixman_image_t *image;
-    int dst_xoff, dst_yoff;
 
-    if (!(image = image_from_pict (pPicture, FALSE, &dst_xoff, &dst_yoff)))
+    if (!(image = image_from_pict (pPicture, FALSE)))
 	return;
     
     pixman_add_triangles (image,
-			  dst_xoff + x_off, dst_yoff + y_off,
+			  x_off, y_off,
 			  ntri, (pixman_triangle_t *)tris);
 
     free_pixman_pict (pPicture, image);
@@ -110,13 +107,11 @@ fbShapes (CompositeShapesFunc	composite,
 	  const uint8_t *	shapes)
 {
     pixman_image_t *src, *dst;
-    int src_xoff, src_yoff;
-    int dst_xoff, dst_yoff;
 
     miCompositeSourceValidate (pSrc);
 
-    src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
-    dst = image_from_pict (pDst, TRUE, &dst_xoff, &dst_yoff);
+    src = image_from_pict (pSrc, FALSE);
+    dst = image_from_pict (pDst, TRUE);
 
     if (src && dst)
     {
@@ -136,10 +131,10 @@ fbShapes (CompositeShapesFunc	composite,
 	    for (i = 0; i < nshapes; ++i)
 	    {
 		composite (op, src, dst, format,
-			   xSrc + src_xoff,
-			   ySrc + src_yoff,
-			   dst_xoff,
-			   dst_yoff,
+			   xSrc,
+			   ySrc,
+			   0,
+			   0,
 			   1, shapes + i * shape_size);
 	    }
 	}
@@ -162,10 +157,10 @@ fbShapes (CompositeShapesFunc	composite,
 	    }
 	    
 	    composite (op, src, dst, format,
-		       xSrc + src_xoff,
-		       ySrc + src_yoff,
-		       dst_xoff,
-		       dst_yoff,
+		       xSrc,
+		       ySrc,
+		       0,
+		       0,
 		       nshapes, shapes);
 	}
 
commit d3e20bae5295b3989fc262ecbb6904af21c58ad4
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Fri Apr 30 13:08:25 2010 -0700

    Workaround the GC clipping problem in miPaintWindow and add some debugging output.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/mi/miexpose.c b/mi/miexpose.c
index 0f1ebe5..dcbfe1c 100644
--- a/mi/miexpose.c
+++ b/mi/miexpose.c
@@ -521,6 +521,7 @@ void RootlessSetPixmapOfAncestors(WindowPtr pWin);
 void RootlessStartDrawing(WindowPtr pWin);
 void RootlessDamageRegion(WindowPtr pWin, RegionPtr prgn);
 Bool IsFramedWindow(WindowPtr pWin);
+#include "../fb/fb.h"
 #endif 
 
 void
@@ -548,24 +549,37 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     Bool	solid = TRUE;
     DrawablePtr	drawable = &pWin->drawable;
 
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("START %d BS %d (pR = %ld)\n", what, pWin->backgroundState, ParentRelative);
+    ErrorF("      Rgn: %d %d %d %d\n", prgn->extents.x1, prgn->extents.y1,
+	                               prgn->extents.x2 - prgn->extents.x1,
+	                               prgn->extents.y2 - prgn->extents.y1);
+    ErrorF("      Win: %d %d (%d %d) %d %d\n", pWin->origin.x, pWin->origin.y,
+	                                       pWin->winSize.extents.x1, pWin->winSize.extents.y1,
+	                                       pWin->winSize.extents.x2 - pWin->winSize.extents.x1,
+					       pWin->winSize.extents.y2 - pWin->winSize.extents.y1);
+    ErrorF("     Draw: %d %d %d %d\n", pWin->drawable.x, pWin->drawable.y,
+				       pWin->drawable.width, pWin->drawable.height);
+#endif
+
 #ifdef ROOTLESS
     if(!drawable || drawable->type == UNDRAWABLE_WINDOW)
 	return;
-
-    if(IsFramedWindow(pWin)) {
-        RootlessStartDrawing(pWin);
-        RootlessDamageRegion(pWin, prgn);
-    
-        if(pWin->backgroundState == ParentRelative) {
-            if((what == PW_BACKGROUND) || 
-               (what == PW_BORDER && !pWin->borderIsPixel))
-                RootlessSetPixmapOfAncestors(pWin);
-        }
-    }
 #endif
     
     if (what == PW_BACKGROUND)
     {
+#ifdef ROOTLESS
+	if(IsFramedWindow(pWin)) {
+	    RootlessStartDrawing(pWin);
+	    RootlessDamageRegion(pWin, prgn);
+
+	    if(pWin->backgroundState == ParentRelative) {
+		RootlessSetPixmapOfAncestors(pWin);
+	    }
+	}
+#endif
+
 	while (pWin->backgroundState == ParentRelative)
 	    pWin = pWin->parent;
 
@@ -591,6 +605,18 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     {
 	PixmapPtr   pixmap;
 
+#ifdef ROOTLESS
+	if(IsFramedWindow(pWin)) {
+	    RootlessStartDrawing(pWin);
+	    RootlessDamageRegion(pWin, prgn);
+	    
+	    if(!pWin->borderIsPixel &&
+		pWin->backgroundState == ParentRelative) {
+		RootlessSetPixmapOfAncestors(pWin);
+	    }
+	}
+#endif
+
 	tile_x_off = drawable->x;
 	tile_y_off = drawable->y;
 	
@@ -599,6 +625,12 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
 	    return;
 	pixmap = (*pScreen->GetWindowPixmap) ((WindowPtr) drawable);
 	drawable = &pixmap->drawable;
+
+#ifdef XQUARTZ_CLIP_DEBUG
+	ErrorF("     Draw: %d %d %d %d\n",
+	       drawable->x, drawable->y, drawable->width, drawable->height);    
+#endif
+	
 #ifdef COMPOSITE
 	draw_x_off = pixmap->screen_x;
 	draw_y_off = pixmap->screen_y;
@@ -661,6 +693,57 @@ miPaintWindow(WindowPtr pWin, RegionPtr prgn, int what)
     ChangeGC (NullClient, pGC, gcmask, gcval);
     ValidateGC (drawable, pGC);
 
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("       GC: %d %d %d %d\n",
+	   pGC->pCompositeClip->extents.x1, pGC->pCompositeClip->extents.y1,
+	   pGC->pCompositeClip->extents.x2 - pGC->pCompositeClip->extents.x1,
+	   pGC->pCompositeClip->extents.y2 - pGC->pCompositeClip->extents.y1);
+#endif
+    
+#ifdef XQUARTZ
+    /* Looks like our clipping isn't set right for some reason:
+     * http://xquartz.macosforge.org/trac/ticket/290
+     */
+    if(what == PW_BORDER) {
+
+#if 0
+	if(solid) {
+#if 1
+	    fbFillRegionSolid(&pWin->drawable,
+			      prgn,
+			      0,
+			      fbReplicatePixel(fill.pixel,
+					       pWin->drawable.bitsPerPixel));
+#else
+	    fbFillRegionSolid(drawable,
+			      prgn,
+			      0,
+			      fbReplicatePixel(fill.pixel,
+					       drawable->bitsPerPixel));
+#endif
+	    return;
+	}
+#endif
+    
+	pGC->pCompositeClip->extents.x1 += prgn->extents.x1;
+	pGC->pCompositeClip->extents.y1 += prgn->extents.y1;
+	pGC->pCompositeClip->extents.x2 += prgn->extents.x1;
+	pGC->pCompositeClip->extents.y2 += prgn->extents.y1;
+	
+	if(pGC->pCompositeClip->extents.x2 > drawable->pScreen->width)
+	    pGC->pCompositeClip->extents.x2 = drawable->pScreen->width;
+	if(pGC->pCompositeClip->extents.y2 > drawable->pScreen->height)
+	    pGC->pCompositeClip->extents.y2 = drawable->pScreen->height;
+    }
+#endif
+
+#ifdef XQUARTZ_CLIP_DEBUG
+    ErrorF("       GC: %d %d %d %d\n",
+	   pGC->pCompositeClip->extents.x1, pGC->pCompositeClip->extents.y1,
+	   pGC->pCompositeClip->extents.x2 - pGC->pCompositeClip->extents.x1,
+	   pGC->pCompositeClip->extents.y2 - pGC->pCompositeClip->extents.y1);    
+#endif
+
     numRects = RegionNumRects(prgn);
     pbox = RegionRects(prgn);
     for (i= numRects; --i >= 0; pbox++, prect++)
commit 2e386340d005e1b062a4eabe9d72e4e548cc2adb
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Mon Oct 17 01:47:18 2011 -0700

    pci: Add identifier for Cirus Logic GD-7556
    
    https://bugs.freedesktop.org/show_bug.cgi?id=1837
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xfree86/common/xf86PciInfo.h b/hw/xfree86/common/xf86PciInfo.h
index 356c7db..2825ece 100644
--- a/hw/xfree86/common/xf86PciInfo.h
+++ b/hw/xfree86/common/xf86PciInfo.h
@@ -386,6 +386,7 @@
 /* Cirrus Logic */
 #define PCI_CHIP_GD7548			0x0038
 #define PCI_CHIP_GD7555			0x0040
+#define PCI_CHIP_GD7556			0x004C
 #define PCI_CHIP_GD5430			0x00A0
 #define PCI_CHIP_GD5434_4		0x00A4
 #define PCI_CHIP_GD5434_8		0x00A8
commit ae4f7c23426c5119bec7159484b954a45a83906f
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Mon Oct 17 23:45:32 2011 -0700

    test: Add unit test for mieq
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/test/input.c b/test/input.c
index 8e9e3e7..04e0c7b 100644
--- a/test/input.c
+++ b/test/input.c
@@ -40,6 +40,7 @@
 #include "dixgrabs.h"
 #include "eventstr.h"
 #include "inpututils.h"
+#include "mi.h"
 #include "assert.h"
 
 /**
@@ -1593,6 +1594,73 @@ dix_double_fp_conversion(void)
     }
 }
 
+/* The mieq test verifies that events added to the queue come out in the same
+ * order that they went in.
+ */
+static uint32_t mieq_test_event_last_processed;
+
+static void
+mieq_test_event_handler(int screenNum, InternalEvent *ie, DeviceIntPtr dev) {
+    RawDeviceEvent *e = (RawDeviceEvent *)ie;
+
+    assert(e->type == ET_RawMotion);
+    assert(e->flags > mieq_test_event_last_processed);
+    mieq_test_event_last_processed = e->flags;
+}
+
+static void _mieq_test_generate_events(uint32_t start, uint32_t count) {
+    count += start;
+    while (start < count) {
+        RawDeviceEvent e = {0};
+        e.header = ET_Internal;
+        e.type = ET_RawMotion;
+        e.length = sizeof(e);
+        e.time = GetTimeInMillis();
+        e.flags = start;
+
+        mieqEnqueue(NULL, (InternalEvent*)&e);
+
+        start++;
+    }
+}
+
+#define mieq_test_generate_events(c) { _mieq_test_generate_events(next, c); next += c; }
+
+static void
+mieq_test(void) {
+    uint32_t next = 1;
+
+    mieq_test_event_last_processed = 0;
+    mieqInit();
+    mieqSetHandler(ET_RawMotion, mieq_test_event_handler);
+
+    /* Enough to fit the buffer but trigger a grow */
+    mieq_test_generate_events(180);
+
+    /* We should resize to 512 now */
+    mieqProcessInputEvents();
+
+    /* Some should now get dropped */
+    mieq_test_generate_events(500);
+
+    /* Tell us how many got dropped, 1024 now */
+    mieqProcessInputEvents();
+
+    /* Now make it 2048 */
+    mieq_test_generate_events(900);
+    mieqProcessInputEvents();
+
+    /* Now make it 4096 (max) */
+    mieq_test_generate_events(1950);
+    mieqProcessInputEvents();
+
+    /* Now overflow one last time with the maximal queue and reach the verbosity limit */
+    mieq_test_generate_events(10000);
+    mieqProcessInputEvents();
+
+    mieqFini();
+}
+
 int main(int argc, char** argv)
 {
     dix_double_fp_conversion();
@@ -1611,6 +1679,7 @@ int main(int argc, char** argv)
     dix_valuator_alloc();
     dix_get_master();
     input_option_test();
+    mieq_test();
 
     return 0;
 }
commit e1bf6aac8282ce4cf59f5020f763568b70262482
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Mon Oct 17 21:16:37 2011 -0700

    mieq: Reserve some space in EQ for release and other special events
    
    The last 64 events in the event queue will be reserved for release
    events in order to help return the system to a cleaner state when
    it comes back from a soft wedge.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mieq.c b/mi/mieq.c
index c9a4370..9394074 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -60,7 +60,8 @@ in this Software without prior written authorization from The Open Group.
 #endif
 
 /* Maximum size should be initial size multiplied by a power of 2 */
-#define QUEUE_INITIAL_SIZE                 128
+#define QUEUE_INITIAL_SIZE                 256
+#define QUEUE_RESERVED_SIZE                 64
 #define QUEUE_MAXIMUM_SIZE                4096
 #define QUEUE_DROP_BACKTRACE_FREQUENCY     100
 #define QUEUE_DROP_BACKTRACE_MAX            10
@@ -205,6 +206,26 @@ mieqFini(void)
     free(miEventQueue.events);
 }
 
+/* This function will determine if the given event is allowed to used the reserved
+ * queue space.
+ */
+static Bool
+mieqReservedCandidate(InternalEvent *e) {
+    switch(e->any.type) {
+        case ET_KeyRelease:
+        case ET_ButtonRelease:
+#if XFreeXDGA
+        case ET_DGAEvent:
+#endif
+        case ET_RawKeyRelease:
+        case ET_RawButtonRelease:
+        case ET_XQuartz:
+            return TRUE;
+        default:
+            return FALSE;
+    }
+}
+
 /*
  * Must be reentrant with ProcessInputEvents.  Assumption: mieqEnqueue
  * will never be interrupted.  If this is called from both signal
@@ -220,6 +241,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
     int                    isMotion = 0;
     int                    evlen;
     Time                   time;
+    size_t                 n_enqueued;
 
 #ifdef XQUARTZ
     wait_for_server_init();
@@ -228,6 +250,8 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
 
     verify_internal_event(e);
 
+    n_enqueued = mieqNumEnqueued(&miEventQueue);
+
     /* avoid merging events from different devices */
     if (e->any.type == ET_Motion)
         isMotion = pDev->id;
@@ -235,7 +259,8 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
     if (isMotion && isMotion == miEventQueue.lastMotion &&
         oldtail != miEventQueue.head) {
         oldtail = (oldtail - 1) % miEventQueue.nevents;
-    } else if (((oldtail + 1) % miEventQueue.nevents) == miEventQueue.head) {
+    } else if ((n_enqueued + 1 == miEventQueue.nevents) ||
+               ((n_enqueued + 1 >= miEventQueue.nevents - QUEUE_RESERVED_SIZE) && !mieqReservedCandidate(e))) {
         /* Toss events which come in late.  Usually this means your server's
          * stuck in an infinite loop somewhere, but SIGIO is still getting
          * handled.
@@ -517,9 +542,9 @@ mieqProcessInputEvents(void)
     pthread_mutex_lock(&miEventQueueMutex);
 #endif
 
-    /* Grow our queue if we are reaching capacity: > 50% full */
+    /* Grow our queue if we are reaching capacity: < 2 * QUEUE_RESERVED_SIZE remaining */
     n_enqueued = mieqNumEnqueued(&miEventQueue);
-    if (n_enqueued >= (miEventQueue.nevents >> 1) &&
+    if (n_enqueued >= (miEventQueue.nevents - (2 * QUEUE_RESERVED_SIZE)) &&
         miEventQueue.nevents < QUEUE_MAXIMUM_SIZE) {
         ErrorF("[mi] Increasing EQ size to %lu to prevent dropped events.\n", miEventQueue.nevents << 1);
         if (!mieqGrowQueue(&miEventQueue, miEventQueue.nevents << 1)) {
commit 441e5df2c29af76627882491db3eb8a5c4d79bd4
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sat Oct 15 22:51:30 2011 -0700

    mieq: Provide better adaptability and diagnostics during mieq overflow
    
    This patch changes from a static length event queue (512) to one that
    starts at 128 and grows to 4096 as it overflows, logging each time it
    grows.
    
    This change also allows for multiple backtraces to be printed when the
    server is wedged rather than just one.  This increased sampling should
    help identify the true hog in cases where one backtrace might be
    insufficient.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/mi/mieq.c b/mi/mieq.c
index b75bde9..c9a4370 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -59,7 +59,11 @@ in this Software without prior written authorization from The Open Group.
 # include <X11/extensions/dpmsconst.h>
 #endif
 
-#define QUEUE_SIZE  512
+/* Maximum size should be initial size multiplied by a power of 2 */
+#define QUEUE_INITIAL_SIZE                 128
+#define QUEUE_MAXIMUM_SIZE                4096
+#define QUEUE_DROP_BACKTRACE_FREQUENCY     100
+#define QUEUE_DROP_BACKTRACE_MAX            10
 
 #define EnqueueScreen(dev) dev->spriteInfo->sprite->pEnqueueScreen
 #define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen
@@ -74,7 +78,9 @@ typedef struct _EventQueue {
     HWEventQueueType head, tail;         /* long for SetInputCheck */
     CARD32           lastEventTime;      /* to avoid time running backwards */
     int              lastMotion;         /* device ID if last event motion? */
-    EventRec         events[QUEUE_SIZE]; /* static allocation for signals */
+    EventRec         *events;            /* our queue as an array */
+    size_t           nevents;            /* the number of buckets in our queue */
+    size_t           dropped;            /* counter for number of consecutive dropped events */
     mieqHandler      handlers[128];      /* custom event handler */
 } EventQueueRec, *EventQueuePtr;
 
@@ -99,25 +105,87 @@ static inline void wait_for_server_init(void) {
 }
 #endif
 
+static size_t
+mieqNumEnqueued(EventQueuePtr eventQueue) {
+    size_t n_enqueued = 0;
+    if (eventQueue->nevents) {
+        /* % is not well-defined with negative numbers... sigh */
+        n_enqueued = eventQueue->tail - eventQueue->head + eventQueue->nevents;
+        if (n_enqueued >= eventQueue->nevents)
+            n_enqueued -= eventQueue->nevents;
+    }
+    return n_enqueued;
+}
+
+/* Pre-condition: Called with miEventQueueMutex held */
+static Bool
+mieqGrowQueue(EventQueuePtr eventQueue, size_t new_nevents) {
+    size_t i, n_enqueued, first_hunk;
+    EventRec *new_events;
+
+    if (!eventQueue) {
+        ErrorF("[mi] mieqGrowQueue called with a NULL eventQueue\n");
+        return FALSE;
+    }
+
+    if (new_nevents <= eventQueue->nevents)
+        return FALSE;
+
+    new_events = calloc(new_nevents, sizeof(EventRec));
+    if (new_events == NULL) {
+        ErrorF("[mi] mieqGrowQueue memory allocation error.\n");
+        return FALSE;
+    }
+
+    n_enqueued = mieqNumEnqueued(eventQueue);
+
+    /* We block signals, so an mieqEnqueue triggered by SIGIO does not
+     * write to our queue as we are modifying it.
+     */
+    OsBlockSignals();
+
+    /* First copy the existing events */
+    first_hunk = eventQueue->nevents - eventQueue->head;
+    memcpy(new_events,
+           &eventQueue->events[eventQueue->head],
+           first_hunk * sizeof(EventRec));
+    memcpy(&new_events[first_hunk],
+           eventQueue->events,
+           eventQueue->head * sizeof(EventRec));
+
+    /* Initialize the new portion */
+    for (i = eventQueue->nevents; i < new_nevents; i++) {
+        InternalEvent* evlist = InitEventList(1);
+        if (!evlist) {
+            size_t j;
+            for (j = 0; j < i; j++)
+                FreeEventList(new_events[j].events, 1);
+            free(new_events);
+            OsReleaseSignals();
+            return FALSE;
+        }
+        new_events[i].events = evlist;
+    }
+
+    /* And update our record */
+    miEventQueue.tail = n_enqueued;
+    miEventQueue.head = 0;
+    miEventQueue.nevents = new_nevents;
+    free(miEventQueue.events);
+    miEventQueue.events = new_events;
+
+    OsReleaseSignals();
+    return TRUE;
+}
+
 Bool
 mieqInit(void)
 {
-    int i;
-
-    miEventQueue.head = miEventQueue.tail = 0;
+    memset(&miEventQueue, 0, sizeof(miEventQueue));
     miEventQueue.lastEventTime = GetTimeInMillis ();
-    miEventQueue.lastMotion = FALSE;
-    for (i = 0; i < 128; i++)
-        miEventQueue.handlers[i] = NULL;
-    for (i = 0; i < QUEUE_SIZE; i++)
-    {
-	if (miEventQueue.events[i].events == NULL) {
-	    InternalEvent* evlist = InitEventList(1);
-	    if (!evlist)
-		FatalError("Could not allocate event queue.\n");
-	    miEventQueue.events[i].events = evlist;
-	}
-    }
+
+    if(!mieqGrowQueue(&miEventQueue, QUEUE_INITIAL_SIZE))
+	FatalError("Could not allocate event queue.\n");
 
     SetInputCheck(&miEventQueue.head, &miEventQueue.tail);
     return TRUE;
@@ -127,13 +195,14 @@ void
 mieqFini(void)
 {
     int i;
-    for (i = 0; i < QUEUE_SIZE; i++)
+    for (i = 0; i < miEventQueue.nevents; i++)
     {
 	if (miEventQueue.events[i].events != NULL) {
 	    FreeEventList(miEventQueue.events[i].events, 1);
 	    miEventQueue.events[i].events = NULL;
 	}
     }
+    free(miEventQueue.events);
 }
 
 /*
@@ -165,26 +234,31 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
 
     if (isMotion && isMotion == miEventQueue.lastMotion &&
         oldtail != miEventQueue.head) {
-        oldtail = (oldtail - 1) % QUEUE_SIZE;
-    }
-    else {
-        static int stuck = 0;
+        oldtail = (oldtail - 1) % miEventQueue.nevents;
+    } else if (((oldtail + 1) % miEventQueue.nevents) == miEventQueue.head) {
         /* Toss events which come in late.  Usually this means your server's
          * stuck in an infinite loop somewhere, but SIGIO is still getting
-         * handled. */
-        if (((oldtail + 1) % QUEUE_SIZE) == miEventQueue.head) {
-            if (!stuck) {
-                ErrorF("[mi] EQ overflowing. The server is probably stuck "
-                        "in an infinite loop.\n");
-                xorg_backtrace();
-                stuck = 1;
+         * handled.
+         */
+        miEventQueue.dropped++;
+        if (miEventQueue.dropped == 1) {
+            ErrorF("[mi] EQ overflowing.  Additional events will be discarded until existing events are processed.\n");
+            xorg_backtrace();
+            ErrorF("[mi] These backtraces from mieqEnqueue may point to a culprit higher up the stack.\n");
+            ErrorF("[mi] mieq is *NOT* the cause.  It is a victim.\n");
+        } else if (miEventQueue.dropped %  QUEUE_DROP_BACKTRACE_FREQUENCY == 0 &&
+                   miEventQueue.dropped /  QUEUE_DROP_BACKTRACE_FREQUENCY <= QUEUE_DROP_BACKTRACE_MAX) {
+            ErrorF("[mi] EQ overflow continuing.  %lu events have been dropped.\n", miEventQueue.dropped);
+            if (miEventQueue.dropped /  QUEUE_DROP_BACKTRACE_FREQUENCY == QUEUE_DROP_BACKTRACE_MAX) {
+                ErrorF("[mi] No further overflow reports will be reported until the clog is cleared.\n");
             }
+            xorg_backtrace();
+        }
+
 #ifdef XQUARTZ
-            pthread_mutex_unlock(&miEventQueueMutex);
+        pthread_mutex_unlock(&miEventQueueMutex);
 #endif
-	        return;
-        }
-        stuck = 0;
+        return;
     }
 
     evlen = e->any.length;
@@ -203,7 +277,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
     miEventQueue.events[oldtail].pDev = pDev;
 
     miEventQueue.lastMotion = isMotion;
-    miEventQueue.tail = (oldtail + 1) % QUEUE_SIZE;
+    miEventQueue.tail = (oldtail + 1) % miEventQueue.nevents;
 #ifdef XQUARTZ
     pthread_mutex_unlock(&miEventQueueMutex);
 #endif
@@ -437,11 +511,28 @@ mieqProcessInputEvents(void)
     static InternalEvent event;
     DeviceIntPtr dev = NULL,
                  master = NULL;
+    size_t n_enqueued;
 
 #ifdef XQUARTZ
     pthread_mutex_lock(&miEventQueueMutex);
 #endif
-    
+
+    /* Grow our queue if we are reaching capacity: > 50% full */
+    n_enqueued = mieqNumEnqueued(&miEventQueue);
+    if (n_enqueued >= (miEventQueue.nevents >> 1) &&
+        miEventQueue.nevents < QUEUE_MAXIMUM_SIZE) {
+        ErrorF("[mi] Increasing EQ size to %lu to prevent dropped events.\n", miEventQueue.nevents << 1);
+        if (!mieqGrowQueue(&miEventQueue, miEventQueue.nevents << 1)) {
+            ErrorF("[mi] Increasing the size of EQ failed.\n");
+        }
+    }
+
+    if (miEventQueue.dropped) {
+        ErrorF("[mi] EQ processing has resumed after %lu dropped events.\n", miEventQueue.dropped);
+        ErrorF("[mi] This may be caused my a misbehaving driver monopolizing the server's resources.\n");
+        miEventQueue.dropped = 0;
+    }
+
     while (miEventQueue.head != miEventQueue.tail) {
         e = &miEventQueue.events[miEventQueue.head];
 
@@ -449,7 +540,7 @@ mieqProcessInputEvents(void)
         dev     = e->pDev;
         screen  = e->pScreen;
 
-        miEventQueue.head = (miEventQueue.head + 1) % QUEUE_SIZE;
+        miEventQueue.head = (miEventQueue.head + 1) % miEventQueue.nevents;
 
 #ifdef XQUARTZ
         pthread_mutex_unlock(&miEventQueueMutex);
commit 30f41957f544dabab8f2a545b1daa9c36453b442
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Sun Oct 16 02:12:38 2011 -0700

    Xnest: Match the host's keymap
    
    This was a regression.
    
    Introduced by: 08363c5830bdea34012dcd954b45ccfdc79a3a7e and
                   32db27a7f867b503c2840ca7b815e96d10be9210
    Masked by: 1e69fd4a60147287b31e53bfc61543fb17bb82c8
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index ec629dc..c20ad12 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -114,11 +114,13 @@ xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
 int
 xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
 {
+  XModifierKeymap *modifier_keymap;
   KeySym *keymap;
   int mapWidth;
   int min_keycode, max_keycode;
   KeySymsRec keySyms;
-  int i;
+  CARD8 modmap[MAP_LENGTH];
+  int i, j;
   XKeyboardState values;
   XkbDescPtr xkb;
   int op, event, error, major, minor;
@@ -130,7 +132,7 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
 #ifdef _XSERVER64
       {
 	KeySym64 *keymap64;
-	int i, len;
+	int len;
 	keymap64 = XGetKeyboardMapping(xnestDisplay,
 				     min_keycode,
 				     max_keycode - min_keycode + 1,
@@ -147,7 +149,17 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
 				   max_keycode - min_keycode + 1,
 				   &mapWidth);
 #endif
-      
+
+      memset(modmap, 0, sizeof(modmap));
+      modifier_keymap = XGetModifierMapping(xnestDisplay);
+      for (j = 0; j < 8; j++)
+            for(i = 0; i < modifier_keymap->max_keypermod; i++) {
+                  CARD8 keycode;
+                  if ((keycode = modifier_keymap->modifiermap[j * modifier_keymap->max_keypermod + i]))
+                      modmap[keycode] |= 1<<j;
+      }
+      XFreeModifiermap(modifier_keymap);
+
       keySyms.minKeyCode = min_keycode;
       keySyms.maxKeyCode = max_keycode;
       keySyms.mapWidth = mapWidth;
@@ -165,7 +177,12 @@ xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
       XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
 
       InitKeyboardDeviceStruct(pDev, NULL,
-			       xnestBell, xnestChangeKeyboardControl);
+                               xnestBell, xnestChangeKeyboardControl);
+ 
+      XkbApplyMappingChange(pDev, &keySyms, keySyms.minKeyCode,
+                            keySyms.maxKeyCode - keySyms.minKeyCode + 1,
+                            modmap, serverClient);
+
       XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
       XkbFreeKeyboard(xkb, 0, False);
       free(keymap);
commit ea0536f4019602df1578bda6337f4cc2f9b78124
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed Oct 19 00:08:07 2011 -0700

    pci: Restore pciTag as a deprecated function
    
    This partially reverts b3d56d06ef840bbbe16ec3c37e170078b7f98b04 to allow
    driver developers time to adjust.
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c
index 0362a00..f1dbfc2 100644
--- a/hw/xfree86/os-support/bus/Pci.c
+++ b/hw/xfree86/os-support/bus/Pci.c
@@ -126,6 +126,12 @@
 
 #include "Pci.h"
 
+PCITAG
+pciTag(int busnum, int devnum, int funcnum)
+{
+	return(PCI_MAKE_TAG(busnum,devnum,funcnum));
+}
+
 Bool
 xf86scanpci(void)
 {
diff --git a/hw/xfree86/os-support/bus/xf86Pci.h b/hw/xfree86/os-support/bus/xf86Pci.h
index 74ead20..55e631c 100644
--- a/hw/xfree86/os-support/bus/xf86Pci.h
+++ b/hw/xfree86/os-support/bus/xf86Pci.h
@@ -251,6 +251,7 @@ typedef enum {
 
 
 /* Public PCI access functions */
+extern _X_EXPORT _X_DEPRECATED PCITAG pciTag(int busnum, int devnum, int funcnum);
 extern _X_EXPORT Bool xf86scanpci(void);
 
 /* Domain access functions.  Some of these probably shouldn't be public */


More information about the Xquartz-changes mailing list