1 From 3d511ad85744b88158d6dbcaa51eb8860cde8dd4 Mon Sep 17 00:00:00 2001
2 From: Chris Wilson <chris@chris-wilson.co.uk>
3 Date: Mon, 6 Jun 2011 05:36:07 +0000
4 Subject: [PATCH 2/4] Remove the cacheing of the last scratch PixmapRec
6 In order for the driver to be notified of when the resource backing the
7 scratch pixmap becomes no longer accessible, it needs to be called on
8 every FreeScratchPixmapHeader(). As we instead maybe cached the
9 PixmapRec (to avoid the free and malloc overhead), this notification
10 went astray, and the driver would fail to insert the correct barriers on
11 the backing resource. That resource would then be reused by the Xserver,
12 leading to rampant memory corruption as the GPU flushed it write caches
13 at some point in the future and overwriting random structures.
15 In addition we introduce a new hint, CREATE_PIXMAP_USAGE_SCRATCH_HEADER,
16 so that the driver can be warned during pixmap creation (and lifetime)
17 if the pixmap points to other data.
19 A side-effect of removing the cache is that several members of the
20 ScreenInfo structure and associated routines become redundant and
21 deleted as well. So we bump the ABI version as well.
23 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
27 dix/pixmap.c | 58 ++++++++++++++++------------------------
29 hw/xfree86/common/xf86Module.h | 2 +-
30 include/pixmap.h | 7 +---
31 include/scrnintstr.h | 8 +++---
32 7 files changed, 32 insertions(+), 50 deletions(-)
34 diff --git a/dix/dispatch.c b/dix/dispatch.c
35 index 192c8c3..3f73175 100644
38 @@ -3855,7 +3855,6 @@ AddScreen(
42 - pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */
43 pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
44 pScreen->CreateScreenResources = 0;
46 diff --git a/dix/main.c b/dix/main.c
47 index 955b7ea..7eadf36 100644
50 @@ -206,12 +206,11 @@ int main(int argc, char *argv[], char *envp[])
51 if (screenInfo.numScreens < 1)
52 FatalError("no screens found");
53 InitExtensions(argc, argv);
56 for (i = 0; i < screenInfo.numScreens; i++)
58 ScreenPtr pScreen = screenInfo.screens[i];
59 - if (!CreateScratchPixmapsForScreen(i))
60 - FatalError("failed to create scratch pixmaps");
61 if (pScreen->CreateScreenResources &&
62 !(*pScreen->CreateScreenResources)(pScreen))
63 FatalError("failed to create screen resources");
64 @@ -321,7 +320,6 @@ int main(int argc, char *argv[], char *envp[])
66 for (i = screenInfo.numScreens - 1; i >= 0; i--)
68 - FreeScratchPixmapsForScreen(i);
70 FreeDefaultStipple(i);
71 (* screenInfo.screens[i]->CloseScreen)(i, screenInfo.screens[i]);
72 diff --git a/dix/pixmap.c b/dix/pixmap.c
73 index cbb5e7f..0b43592 100644
76 @@ -53,20 +53,19 @@ PixmapPtr
77 GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth,
78 int bitsPerPixel, int devKind, pointer pPixData)
80 - PixmapPtr pPixmap = pScreen->pScratchPixmap;
84 - pScreen->pScratchPixmap = NULL;
86 - /* width and height of 0 means don't allocate any pixmap data */
87 - pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0);
90 - if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
91 - bitsPerPixel, devKind, pPixData))
93 - (*pScreen->DestroyPixmap)(pPixmap);
95 + /* width and height of 0 means don't allocate any pixmap data */
96 + pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth,
97 + CREATE_PIXMAP_USAGE_SCRATCH_HEADER);
98 + if (pPixmap == NullPixmap)
101 + if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
102 + bitsPerPixel, devKind, pPixData))
105 + (*pScreen->DestroyPixmap)(pPixmap);
109 @@ -79,33 +78,22 @@ FreeScratchPixmapHeader(PixmapPtr pPixmap)
111 ScreenPtr pScreen = pPixmap->drawable.pScreen;
113 - pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */
114 - if (pScreen->pScratchPixmap)
115 - (*pScreen->DestroyPixmap)(pPixmap);
117 - pScreen->pScratchPixmap = pPixmap;
118 + if (pPixmap->refcnt != 1)
119 + FatalError("Scratch pixmap still in use when finalized, refcnt=%d\n",
122 + (*pScreen->DestroyPixmap)(pPixmap);
128 -CreateScratchPixmapsForScreen(int scrnum)
132 unsigned int pixmap_size;
134 pixmap_size = sizeof(PixmapRec) + dixPrivatesSize(PRIVATE_PIXMAP);
135 - screenInfo.screens[scrnum]->totalPixmapSize = BitmapBytePad(pixmap_size * 8);
137 - /* let it be created on first use */
138 - screenInfo.screens[scrnum]->pScratchPixmap = NULL;
144 -FreeScratchPixmapsForScreen(int scrnum)
146 - FreeScratchPixmapHeader(screenInfo.screens[scrnum]->pScratchPixmap);
147 + screenInfo.totalPixmapSize = BitmapBytePad(pixmap_size * 8);
151 @@ -115,12 +103,12 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
155 - assert(pScreen->totalPixmapSize > 0);
156 + assert(screenInfo.totalPixmapSize > 0);
158 - if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize)
159 + if (screenInfo.totalPixmapSize > ((size_t)-1) - pixDataSize)
162 - pPixmap = malloc(pScreen->totalPixmapSize + pixDataSize);
163 + pPixmap = malloc(screenInfo.totalPixmapSize + pixDataSize);
167 diff --git a/fb/fbpixmap.c b/fb/fbpixmap.c
168 index a356c67..aebdff0 100644
171 @@ -42,7 +42,7 @@ fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp,
172 if (paddedWidth / 4 > 32767 || height > 32767)
174 datasize = height * paddedWidth;
175 - base = pScreen->totalPixmapSize;
176 + base = screenInfo.totalPixmapSize;
179 adjust = 8 - (base & 7);
180 diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
181 index 2a5c805..cf7557e 100644
182 --- a/hw/xfree86/common/xf86Module.h
183 +++ b/hw/xfree86/common/xf86Module.h
184 @@ -82,7 +82,7 @@ typedef enum {
185 * mask is 0xFFFF0000.
187 #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
188 -#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(11, 0)
189 +#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(12, 0)
190 #define ABI_XINPUT_VERSION SET_ABI_VERSION(13, 0)
191 #define ABI_EXTENSION_VERSION SET_ABI_VERSION(5, 0)
192 #define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
193 diff --git a/include/pixmap.h b/include/pixmap.h
194 index 014a111..daab76c 100644
195 --- a/include/pixmap.h
196 +++ b/include/pixmap.h
197 @@ -103,11 +103,8 @@ extern _X_EXPORT PixmapPtr GetScratchPixmapHeader(
198 extern _X_EXPORT void FreeScratchPixmapHeader(
199 PixmapPtr /*pPixmap*/);
201 -extern _X_EXPORT Bool CreateScratchPixmapsForScreen(
204 -extern _X_EXPORT void FreeScratchPixmapsForScreen(
206 +extern _X_EXPORT void InitPixmaps(
209 extern _X_EXPORT PixmapPtr AllocatePixmap(
210 ScreenPtr /*pScreen*/,
211 diff --git a/include/scrnintstr.h b/include/scrnintstr.h
212 index a9357e8..617eadb 100644
213 --- a/include/scrnintstr.h
214 +++ b/include/scrnintstr.h
215 @@ -202,6 +202,8 @@ typedef void (* ClipNotifyProcPtr)(
216 #define CREATE_PIXMAP_USAGE_BACKING_PIXMAP 2
217 /* pixmap will contain a glyph */
218 #define CREATE_PIXMAP_USAGE_GLYPH_PICTURE 3
219 +/* pixmap will only be as a header for transient (e.g. on-stack) pixels */
220 +#define CREATE_PIXMAP_USAGE_SCRATCH_HEADER 4
222 typedef PixmapPtr (* CreatePixmapProcPtr)(
223 ScreenPtr /*pScreen*/,
224 @@ -518,10 +520,6 @@ typedef struct _Screen {
225 GetScreenPixmapProcPtr GetScreenPixmap;
226 SetScreenPixmapProcPtr SetScreenPixmap;
228 - PixmapPtr pScratchPixmap; /* scratch pixmap "pool" */
230 - unsigned int totalPixmapSize;
232 MarkWindowProcPtr MarkWindow;
233 MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
234 ConfigNotifyProcPtr ConfigNotify;
235 @@ -556,6 +554,8 @@ typedef struct _ScreenInfo {
236 int bitmapScanlineUnit;
237 int bitmapScanlinePad;
239 + unsigned int totalPixmapSize;
241 int numPixmapFormats;