]> git.draconx.ca Git - gentoo-draconx.git/blob - x11-base/xorg-server/files/0002-Remove-the-cacheing-of-the-last-scratch-PixmapRec.patch
8b1ff08395b12a0df00cb0c75e365dd208ac7600
[gentoo-draconx.git] / x11-base / xorg-server / files / 0002-Remove-the-cacheing-of-the-last-scratch-PixmapRec.patch
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
5
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.
14
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.
18
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.
22
23 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
24 ---
25  dix/dispatch.c                 |    1 -
26  dix/main.c                     |    4 +--
27  dix/pixmap.c                   |   58 ++++++++++++++++------------------------
28  fb/fbpixmap.c                  |    2 +-
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(-)
33
34 diff --git a/dix/dispatch.c b/dix/dispatch.c
35 index 192c8c3..3f73175 100644
36 --- a/dix/dispatch.c
37 +++ b/dix/dispatch.c
38 @@ -3855,7 +3855,6 @@ AddScreen(
39         return -1;
40      }
41      pScreen->myNum = i;
42 -    pScreen->totalPixmapSize = 0;      /* computed in CreateScratchPixmapForScreen */
43      pScreen->ClipNotify = 0;   /* for R4 ddx compatibility */
44      pScreen->CreateScreenResources = 0;
45  
46 diff --git a/dix/main.c b/dix/main.c
47 index 955b7ea..7eadf36 100644
48 --- a/dix/main.c
49 +++ b/dix/main.c
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);
54 +       InitPixmaps();
55  
56         for (i = 0; i < screenInfo.numScreens; i++)
57         {
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[])
65  
66         for (i = screenInfo.numScreens - 1; i >= 0; i--)
67         {
68 -           FreeScratchPixmapsForScreen(i);
69             FreeGCperDepth(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
74 --- a/dix/pixmap.c
75 +++ b/dix/pixmap.c
76 @@ -53,20 +53,19 @@ PixmapPtr
77  GetScratchPixmapHeader(ScreenPtr pScreen, int width, int height, int depth, 
78                         int bitsPerPixel, int devKind, pointer pPixData)
79  {
80 -    PixmapPtr pPixmap = pScreen->pScratchPixmap;
81 +    PixmapPtr pPixmap;
82  
83 -    if (pPixmap)
84 -       pScreen->pScratchPixmap = NULL;
85 -    else
86 -       /* width and height of 0 means don't allocate any pixmap data */
87 -       pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0);
88 -
89 -    if (pPixmap) {
90 -       if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
91 -                                          bitsPerPixel, devKind, pPixData))
92 -           return pPixmap;
93 -       (*pScreen->DestroyPixmap)(pPixmap);
94 -    }
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)
99 +       return NullPixmap;
100 +
101 +    if ((*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
102 +                                      bitsPerPixel, devKind, pPixData))
103 +       return pPixmap;
104 +
105 +    (*pScreen->DestroyPixmap)(pPixmap);
106      return NullPixmap;
107  }
108  
109 @@ -79,33 +78,22 @@ FreeScratchPixmapHeader(PixmapPtr pPixmap)
110      {
111         ScreenPtr pScreen = pPixmap->drawable.pScreen;
112  
113 -       pPixmap->devPrivate.ptr = NULL; /* lest ddx chases bad ptr */
114 -       if (pScreen->pScratchPixmap)
115 -           (*pScreen->DestroyPixmap)(pPixmap);
116 -       else
117 -           pScreen->pScratchPixmap = pPixmap;
118 +       if (pPixmap->refcnt != 1)
119 +               FatalError("Scratch pixmap still in use when finalized, refcnt=%d\n",
120 +                          pPixmap->refcnt);
121 +
122 +       (*pScreen->DestroyPixmap)(pPixmap);
123      }
124  }
125  
126  
127 -Bool
128 -CreateScratchPixmapsForScreen(int scrnum)
129 +void
130 +InitPixmaps(void)
131  {
132      unsigned int       pixmap_size;
133  
134      pixmap_size = sizeof(PixmapRec) + dixPrivatesSize(PRIVATE_PIXMAP);
135 -    screenInfo.screens[scrnum]->totalPixmapSize = BitmapBytePad(pixmap_size * 8);
136 -
137 -    /* let it be created on first use */
138 -    screenInfo.screens[scrnum]->pScratchPixmap = NULL;
139 -    return TRUE;
140 -}
141 -
142 -
143 -void
144 -FreeScratchPixmapsForScreen(int scrnum)
145 -{
146 -    FreeScratchPixmapHeader(screenInfo.screens[scrnum]->pScratchPixmap);
147 +    screenInfo.totalPixmapSize = BitmapBytePad(pixmap_size * 8);
148  }
149  
150  
151 @@ -115,12 +103,12 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize)
152  {
153      PixmapPtr pPixmap;
154  
155 -    assert(pScreen->totalPixmapSize > 0);
156 +    assert(screenInfo.totalPixmapSize > 0);
157  
158 -    if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize)
159 +    if (screenInfo.totalPixmapSize > ((size_t)-1) - pixDataSize)
160         return NullPixmap;
161      
162 -    pPixmap = malloc(pScreen->totalPixmapSize + pixDataSize);
163 +    pPixmap = malloc(screenInfo.totalPixmapSize + pixDataSize);
164      if (!pPixmap)
165         return NullPixmap;
166  
167 diff --git a/fb/fbpixmap.c b/fb/fbpixmap.c
168 index a356c67..aebdff0 100644
169 --- a/fb/fbpixmap.c
170 +++ b/fb/fbpixmap.c
171 @@ -42,7 +42,7 @@ fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp,
172      if (paddedWidth / 4 > 32767 || height > 32767)
173         return NullPixmap;
174      datasize = height * paddedWidth;
175 -    base = pScreen->totalPixmapSize;
176 +    base = screenInfo.totalPixmapSize;
177      adjust = 0;
178      if (base & 7)
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.
186   */
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*/);
200  
201 -extern _X_EXPORT Bool CreateScratchPixmapsForScreen(
202 -    int /*scrnum*/);
203 -
204 -extern _X_EXPORT void FreeScratchPixmapsForScreen(
205 -    int /*scrnum*/);
206 +extern _X_EXPORT void InitPixmaps(
207 +    void);
208  
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
221  
222  typedef    PixmapPtr (* CreatePixmapProcPtr)(
223         ScreenPtr /*pScreen*/,
224 @@ -518,10 +520,6 @@ typedef struct _Screen {
225      GetScreenPixmapProcPtr     GetScreenPixmap;
226      SetScreenPixmapProcPtr     SetScreenPixmap;
227  
228 -    PixmapPtr pScratchPixmap;          /* scratch pixmap "pool" */
229 -
230 -    unsigned int               totalPixmapSize;
231 -
232      MarkWindowProcPtr          MarkWindow;
233      MarkOverlappedWindowsProcPtr MarkOverlappedWindows;
234      ConfigNotifyProcPtr                ConfigNotify;
235 @@ -556,6 +554,8 @@ typedef struct _ScreenInfo {
236      int                bitmapScanlineUnit;
237      int                bitmapScanlinePad;
238      int                bitmapBitOrder;
239 +    unsigned int totalPixmapSize;
240 +
241      int                numPixmapFormats;
242      PixmapFormatRec
243                 formats[MAXFORMATS];
244 -- 
245 1.7.3.4
246