[PATCH 05/18] Don't use GetScratchPixmapHeader for shadow pixmaps

Keith Packard keithp at keithp.com
Sat Aug 16 23:13:08 PDT 2014


GetScratchPixmapHeader should only be used for local memory pixmaps,
as used by PutImage and friends. That's because when you free the
scratch pixmap header, it doesn't actually free the pixmap; instead,
it gets stuffed in pScreen->pScratchPixmap and any private data stored
on it will be left hanging around forever.

In the case of glamor, that private data includes all of the GL
state. Using that scratch pixmap later results in glamor getting
mightily confused as the pixmap and underlying objects do not match.

Avoid this by allocating pixmap headers explicitly for this purpose.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 src/uxa/intel_display.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/src/uxa/intel_display.c b/src/uxa/intel_display.c
index cd5f80c..c9e7669 100644
--- a/src/uxa/intel_display.c
+++ b/src/uxa/intel_display.c
@@ -550,6 +550,26 @@ intel_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
 }
 
 static PixmapPtr
+intel_create_pixmap_header(ScreenPtr pScreen, int width, int height, int depth,
+                           int bitsPerPixel, int devKind, void *pPixData)
+{
+        PixmapPtr pixmap;
+
+        /* width and height of 0 means don't allocate any pixmap data */
+        pixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, 0);
+
+        if (pixmap) {
+                if ((*pScreen->ModifyPixmapHeader) (pixmap, width, height, depth,
+                                                    bitsPerPixel, devKind, pPixData))
+                {
+                        return pixmap;
+                }
+                (*pScreen->DestroyPixmap) (pixmap);
+        }
+        return NullPixmap;
+}
+
+static PixmapPtr
 intel_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 {
 	ScrnInfoPtr scrn = crtc->scrn;
@@ -571,12 +591,12 @@ intel_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 		return NULL;
 	}
 
-	rotate_pixmap = GetScratchPixmapHeader(scrn->pScreen,
-					       width, height,
-					       scrn->depth,
-					       scrn->bitsPerPixel,
-					       intel_crtc->rotate_pitch,
-					       NULL);
+	rotate_pixmap = intel_create_pixmap_header(scrn->pScreen,
+                                                   width, height,
+                                                   scrn->depth,
+                                                   scrn->bitsPerPixel,
+                                                   intel_crtc->rotate_pitch,
+                                                   NULL);
 
 	if (rotate_pixmap == NULL) {
 		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -600,8 +620,8 @@ intel_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
 	struct intel_mode *mode = intel_crtc->mode;
 
 	if (rotate_pixmap) {
-		intel_set_pixmap_bo(rotate_pixmap, NULL);
-		FreeScratchPixmapHeader(rotate_pixmap);
+                intel_set_pixmap_bo(rotate_pixmap, NULL);
+                rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap);
 	}
 
 	if (data) {
@@ -1413,7 +1433,6 @@ intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 	int	    i, old_width, old_height, old_pitch;
 	int pitch;
 	uint32_t tiling;
-	ScreenPtr screen;
 
 	if (scrn->virtualX == width && scrn->virtualY == height)
 		return TRUE;
@@ -1428,8 +1447,7 @@ intel_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 	old_front = intel->front_buffer;
 
 	if (intel->back_pixmap) {
-		screen = intel->back_pixmap->drawable.pScreen;
-		screen->DestroyPixmap(intel->back_pixmap);
+		scrn->pScreen->DestroyPixmap(intel->back_pixmap);
 		intel->back_pixmap = NULL;
 	}
 
@@ -2201,6 +2219,7 @@ Bool intel_crtc_on(xf86CrtcPtr crtc)
 	return ret;
 }
 
+
 static PixmapPtr
 intel_create_pixmap_for_bo(ScreenPtr pScreen, dri_bo *bo,
 			   int width, int height,
-- 
2.0.1



More information about the xorg-devel mailing list