xref: /OK3568_Linux_fs/external/xserver/glamor/glamor_prepare.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright © 2014 Keith Packard
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission to use, copy, modify, distribute, and sell this software and its
5*4882a593Smuzhiyun  * documentation for any purpose is hereby granted without fee, provided that
6*4882a593Smuzhiyun  * the above copyright notice appear in all copies and that both that copyright
7*4882a593Smuzhiyun  * notice and this permission notice appear in supporting documentation, and
8*4882a593Smuzhiyun  * that the name of the copyright holders not be used in advertising or
9*4882a593Smuzhiyun  * publicity pertaining to distribution of the software without specific,
10*4882a593Smuzhiyun  * written prior permission.  The copyright holders make no representations
11*4882a593Smuzhiyun  * about the suitability of this software for any purpose.  It is provided "as
12*4882a593Smuzhiyun  * is" without express or implied warranty.
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15*4882a593Smuzhiyun  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16*4882a593Smuzhiyun  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17*4882a593Smuzhiyun  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18*4882a593Smuzhiyun  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19*4882a593Smuzhiyun  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20*4882a593Smuzhiyun  * OF THIS SOFTWARE.
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include "glamor_priv.h"
24*4882a593Smuzhiyun #include "glamor_prepare.h"
25*4882a593Smuzhiyun #include "glamor_transfer.h"
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun /*
28*4882a593Smuzhiyun  * Make a pixmap ready to draw with fb by
29*4882a593Smuzhiyun  * creating a PBO large enough for the whole object
30*4882a593Smuzhiyun  * and downloading all of the FBOs into it.
31*4882a593Smuzhiyun  */
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun static Bool
glamor_prep_pixmap_box(PixmapPtr pixmap,glamor_access_t access,BoxPtr box)34*4882a593Smuzhiyun glamor_prep_pixmap_box(PixmapPtr pixmap, glamor_access_t access, BoxPtr box)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun     ScreenPtr                   screen = pixmap->drawable.pScreen;
37*4882a593Smuzhiyun     glamor_screen_private       *glamor_priv = glamor_get_screen_private(screen);
38*4882a593Smuzhiyun     glamor_pixmap_private       *priv = glamor_get_pixmap_private(pixmap);
39*4882a593Smuzhiyun     int                         gl_access, gl_usage;
40*4882a593Smuzhiyun     RegionRec                   region;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun     if (priv->type == GLAMOR_DRM_ONLY)
43*4882a593Smuzhiyun         return FALSE;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
46*4882a593Smuzhiyun         return TRUE;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun     glamor_make_current(glamor_priv);
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun     RegionInit(&region, box, 1);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun     /* See if it's already mapped */
53*4882a593Smuzhiyun     if (pixmap->devPrivate.ptr) {
54*4882a593Smuzhiyun         /*
55*4882a593Smuzhiyun          * Someone else has mapped this pixmap;
56*4882a593Smuzhiyun          * we'll assume that it's directly mapped
57*4882a593Smuzhiyun          * by a lower level driver
58*4882a593Smuzhiyun          */
59*4882a593Smuzhiyun         if (!priv->prepared)
60*4882a593Smuzhiyun             goto done;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun         /* In X, multiple Drawables can be stored in the same Pixmap (such as
63*4882a593Smuzhiyun          * each individual window in a non-composited screen pixmap, or the
64*4882a593Smuzhiyun          * reparented window contents inside the window-manager-decorated window
65*4882a593Smuzhiyun          * pixmap on a composited screen).
66*4882a593Smuzhiyun          *
67*4882a593Smuzhiyun          * As a result, when doing a series of mappings for a fallback, we may
68*4882a593Smuzhiyun          * need to add more boxes to the set of data we've downloaded, as we go.
69*4882a593Smuzhiyun          */
70*4882a593Smuzhiyun         RegionSubtract(&region, &region, &priv->prepare_region);
71*4882a593Smuzhiyun         if (!RegionNotEmpty(&region))
72*4882a593Smuzhiyun             goto done;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun         if (access == GLAMOR_ACCESS_RW)
75*4882a593Smuzhiyun             FatalError("attempt to remap buffer as writable");
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun         if (priv->pbo) {
78*4882a593Smuzhiyun             glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo);
79*4882a593Smuzhiyun             glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
80*4882a593Smuzhiyun             pixmap->devPrivate.ptr = NULL;
81*4882a593Smuzhiyun         }
82*4882a593Smuzhiyun     } else {
83*4882a593Smuzhiyun #ifdef GLAMOR_HAS_GBM_MAP
84*4882a593Smuzhiyun         struct gbm_bo *gbm = NULL;
85*4882a593Smuzhiyun         uint32_t stride;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun         RegionInit(&priv->prepare_region, box, 1);
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun         if (!priv->exporting)
90*4882a593Smuzhiyun             gbm = glamor_gbm_bo_from_pixmap(screen, pixmap);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun         if (gbm) {
93*4882a593Smuzhiyun             pixmap->devPrivate.ptr =
94*4882a593Smuzhiyun                 gbm_bo_map(gbm, 0, 0, pixmap->drawable.width,
95*4882a593Smuzhiyun                            pixmap->drawable.height,
96*4882a593Smuzhiyun                            (access == GLAMOR_ACCESS_RW) ?
97*4882a593Smuzhiyun                            GBM_BO_TRANSFER_READ_WRITE : GBM_BO_TRANSFER_READ,
98*4882a593Smuzhiyun                            &stride, &priv->map_data);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun             if (pixmap->devPrivate.ptr) {
101*4882a593Smuzhiyun                 pixmap->devKind = stride;
102*4882a593Smuzhiyun                 priv->bo_mapped = TRUE;
103*4882a593Smuzhiyun                 priv->map_access = access;
104*4882a593Smuzhiyun                 goto done;
105*4882a593Smuzhiyun             }
106*4882a593Smuzhiyun         }
107*4882a593Smuzhiyun #endif
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun         if (glamor_priv->has_rw_pbo) {
110*4882a593Smuzhiyun             if (priv->pbo == 0)
111*4882a593Smuzhiyun                 glGenBuffers(1, &priv->pbo);
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun             gl_usage = GL_STREAM_READ;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun             glamor_priv->suppress_gl_out_of_memory_logging = true;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun             glBindBuffer(GL_PIXEL_PACK_BUFFER, priv->pbo);
118*4882a593Smuzhiyun             glBufferData(GL_PIXEL_PACK_BUFFER,
119*4882a593Smuzhiyun                          pixmap->devKind * pixmap->drawable.height, NULL,
120*4882a593Smuzhiyun                          gl_usage);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun             glamor_priv->suppress_gl_out_of_memory_logging = false;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun             if (glGetError() == GL_OUT_OF_MEMORY) {
125*4882a593Smuzhiyun                 if (!glamor_priv->logged_any_pbo_allocation_failure) {
126*4882a593Smuzhiyun                     LogMessageVerb(X_WARNING, 0, "glamor: Failed to allocate %d "
127*4882a593Smuzhiyun                                    "bytes PBO due to GL_OUT_OF_MEMORY.\n",
128*4882a593Smuzhiyun                                    pixmap->devKind * pixmap->drawable.height);
129*4882a593Smuzhiyun                     glamor_priv->logged_any_pbo_allocation_failure = true;
130*4882a593Smuzhiyun                 }
131*4882a593Smuzhiyun                 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
132*4882a593Smuzhiyun                 glDeleteBuffers(1, &priv->pbo);
133*4882a593Smuzhiyun                 priv->pbo = 0;
134*4882a593Smuzhiyun             }
135*4882a593Smuzhiyun         }
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun         if (!priv->pbo) {
138*4882a593Smuzhiyun             pixmap->devPrivate.ptr = xallocarray(pixmap->devKind,
139*4882a593Smuzhiyun                                                  pixmap->drawable.height);
140*4882a593Smuzhiyun             if (!pixmap->devPrivate.ptr)
141*4882a593Smuzhiyun                 return FALSE;
142*4882a593Smuzhiyun         }
143*4882a593Smuzhiyun         priv->map_access = access;
144*4882a593Smuzhiyun     }
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun     glamor_download_boxes(pixmap, RegionRects(&region), RegionNumRects(&region),
147*4882a593Smuzhiyun                           0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun     if (priv->pbo) {
150*4882a593Smuzhiyun         if (priv->map_access == GLAMOR_ACCESS_RW)
151*4882a593Smuzhiyun             gl_access = GL_READ_WRITE;
152*4882a593Smuzhiyun         else
153*4882a593Smuzhiyun             gl_access = GL_READ_ONLY;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun         pixmap->devPrivate.ptr = glMapBuffer(GL_PIXEL_PACK_BUFFER, gl_access);
156*4882a593Smuzhiyun         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
157*4882a593Smuzhiyun     }
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun done:
160*4882a593Smuzhiyun     RegionUninit(&region);
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun     if (priv->bo_mapped) {
163*4882a593Smuzhiyun         /* Finish all gpu commands before accessing the buffer */
164*4882a593Smuzhiyun         if (!priv->gl_synced && !glamor_priv->gl_synced)
165*4882a593Smuzhiyun             glamor_finish(screen);
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun         priv->gl_synced = TRUE;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun         /* No prepared flag for directly mapping */
170*4882a593Smuzhiyun         return TRUE;
171*4882a593Smuzhiyun     }
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun     priv->prepared = TRUE;
174*4882a593Smuzhiyun     return TRUE;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun /*
178*4882a593Smuzhiyun  * When we're done with the drawable, unmap the PBO, reupload
179*4882a593Smuzhiyun  * if we were writing to it and then unbind it to release the memory
180*4882a593Smuzhiyun  */
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun void
glamor_finish_access_pixmap(PixmapPtr pixmap,Bool force)183*4882a593Smuzhiyun glamor_finish_access_pixmap(PixmapPtr pixmap, Bool force)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun     glamor_pixmap_private       *priv = glamor_get_pixmap_private(pixmap);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(priv))
188*4882a593Smuzhiyun         return;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun #ifdef GLAMOR_HAS_GBM
191*4882a593Smuzhiyun     if (priv->bo_mapped) {
192*4882a593Smuzhiyun         if (priv->prepared)
193*4882a593Smuzhiyun             FatalError("something wrong during buffer mapping");
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun         /* Delay unmap to finalize when not forced */
196*4882a593Smuzhiyun         if (force) {
197*4882a593Smuzhiyun             pixmap->devPrivate.ptr = NULL;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun             gbm_bo_unmap(priv->bo, priv->map_data);
200*4882a593Smuzhiyun             priv->bo_mapped = FALSE;
201*4882a593Smuzhiyun         }
202*4882a593Smuzhiyun     }
203*4882a593Smuzhiyun #endif
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun     if (!priv->prepared)
206*4882a593Smuzhiyun         return;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun     if (priv->pbo) {
209*4882a593Smuzhiyun         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, priv->pbo);
210*4882a593Smuzhiyun         glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
211*4882a593Smuzhiyun         pixmap->devPrivate.ptr = NULL;
212*4882a593Smuzhiyun     }
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun     if (priv->map_access == GLAMOR_ACCESS_RW) {
215*4882a593Smuzhiyun         glamor_upload_boxes(pixmap,
216*4882a593Smuzhiyun                             RegionRects(&priv->prepare_region),
217*4882a593Smuzhiyun                             RegionNumRects(&priv->prepare_region),
218*4882a593Smuzhiyun                             0, 0, 0, 0, pixmap->devPrivate.ptr, pixmap->devKind);
219*4882a593Smuzhiyun     }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun     RegionUninit(&priv->prepare_region);
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun     if (priv->pbo) {
224*4882a593Smuzhiyun         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
225*4882a593Smuzhiyun         glDeleteBuffers(1, &priv->pbo);
226*4882a593Smuzhiyun         priv->pbo = 0;
227*4882a593Smuzhiyun     } else {
228*4882a593Smuzhiyun         free(pixmap->devPrivate.ptr);
229*4882a593Smuzhiyun         pixmap->devPrivate.ptr = NULL;
230*4882a593Smuzhiyun     }
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun     priv->prepared = FALSE;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun Bool
glamor_prepare_access(DrawablePtr drawable,glamor_access_t access)236*4882a593Smuzhiyun glamor_prepare_access(DrawablePtr drawable, glamor_access_t access)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
239*4882a593Smuzhiyun     BoxRec box;
240*4882a593Smuzhiyun     int off_x, off_y;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun     glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun     box.x1 = drawable->x + off_x;
245*4882a593Smuzhiyun     box.x2 = box.x1 + drawable->width;
246*4882a593Smuzhiyun     box.y1 = drawable->y + off_y;
247*4882a593Smuzhiyun     box.y2 = box.y1 + drawable->height;
248*4882a593Smuzhiyun     return glamor_prep_pixmap_box(pixmap, access, &box);
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun Bool
glamor_prepare_access_box(DrawablePtr drawable,glamor_access_t access,int x,int y,int w,int h)252*4882a593Smuzhiyun glamor_prepare_access_box(DrawablePtr drawable, glamor_access_t access,
253*4882a593Smuzhiyun                          int x, int y, int w, int h)
254*4882a593Smuzhiyun {
255*4882a593Smuzhiyun     PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
256*4882a593Smuzhiyun     BoxRec box;
257*4882a593Smuzhiyun     int off_x, off_y;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun     glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
260*4882a593Smuzhiyun     box.x1 = drawable->x + x + off_x;
261*4882a593Smuzhiyun     box.x2 = box.x1 + w;
262*4882a593Smuzhiyun     box.y1 = drawable->y + y + off_y;
263*4882a593Smuzhiyun     box.y2 = box.y1 + h;
264*4882a593Smuzhiyun     return glamor_prep_pixmap_box(pixmap, access, &box);
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun void
glamor_finish_access(DrawablePtr drawable)268*4882a593Smuzhiyun glamor_finish_access(DrawablePtr drawable)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun     glamor_finish_access_pixmap(glamor_get_drawable_pixmap(drawable), FALSE);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun /*
274*4882a593Smuzhiyun  * Make a picture ready to use with fb.
275*4882a593Smuzhiyun  */
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun Bool
glamor_prepare_access_picture(PicturePtr picture,glamor_access_t access)278*4882a593Smuzhiyun glamor_prepare_access_picture(PicturePtr picture, glamor_access_t access)
279*4882a593Smuzhiyun {
280*4882a593Smuzhiyun     if (!picture || !picture->pDrawable)
281*4882a593Smuzhiyun         return TRUE;
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun     return glamor_prepare_access(picture->pDrawable, access);
284*4882a593Smuzhiyun }
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun Bool
glamor_prepare_access_picture_box(PicturePtr picture,glamor_access_t access,int x,int y,int w,int h)287*4882a593Smuzhiyun glamor_prepare_access_picture_box(PicturePtr picture, glamor_access_t access,
288*4882a593Smuzhiyun                         int x, int y, int w, int h)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun     if (!picture || !picture->pDrawable)
291*4882a593Smuzhiyun         return TRUE;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun     /* If a transform is set, we don't know what the bounds is on the
294*4882a593Smuzhiyun      * source, so just prepare the whole pixmap.  XXX: We could
295*4882a593Smuzhiyun      * potentially work out where in the source would be sampled based
296*4882a593Smuzhiyun      * on the transform, and we don't need do do this for destination
297*4882a593Smuzhiyun      * pixmaps at all.
298*4882a593Smuzhiyun      */
299*4882a593Smuzhiyun     if (picture->transform) {
300*4882a593Smuzhiyun         return glamor_prepare_access_box(picture->pDrawable, access,
301*4882a593Smuzhiyun                                          0, 0,
302*4882a593Smuzhiyun                                          picture->pDrawable->width,
303*4882a593Smuzhiyun                                          picture->pDrawable->height);
304*4882a593Smuzhiyun     } else {
305*4882a593Smuzhiyun         return glamor_prepare_access_box(picture->pDrawable, access,
306*4882a593Smuzhiyun                                          x, y, w, h);
307*4882a593Smuzhiyun     }
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun void
glamor_finish_access_picture(PicturePtr picture)311*4882a593Smuzhiyun glamor_finish_access_picture(PicturePtr picture)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun     if (!picture || !picture->pDrawable)
314*4882a593Smuzhiyun         return;
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun     glamor_finish_access(picture->pDrawable);
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun /*
320*4882a593Smuzhiyun  * Make a GC ready to use with fb. This just
321*4882a593Smuzhiyun  * means making sure the appropriate fill pixmap is
322*4882a593Smuzhiyun  * in CPU memory again
323*4882a593Smuzhiyun  */
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun Bool
glamor_prepare_access_gc(GCPtr gc)326*4882a593Smuzhiyun glamor_prepare_access_gc(GCPtr gc)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun     switch (gc->fillStyle) {
329*4882a593Smuzhiyun     case FillTiled:
330*4882a593Smuzhiyun         return glamor_prepare_access(&gc->tile.pixmap->drawable,
331*4882a593Smuzhiyun                                      GLAMOR_ACCESS_RO);
332*4882a593Smuzhiyun     case FillStippled:
333*4882a593Smuzhiyun     case FillOpaqueStippled:
334*4882a593Smuzhiyun         return glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RO);
335*4882a593Smuzhiyun     }
336*4882a593Smuzhiyun     return TRUE;
337*4882a593Smuzhiyun }
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun /*
340*4882a593Smuzhiyun  * Free any temporary CPU pixmaps for the GC
341*4882a593Smuzhiyun  */
342*4882a593Smuzhiyun void
glamor_finish_access_gc(GCPtr gc)343*4882a593Smuzhiyun glamor_finish_access_gc(GCPtr gc)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun     switch (gc->fillStyle) {
346*4882a593Smuzhiyun     case FillTiled:
347*4882a593Smuzhiyun         glamor_finish_access(&gc->tile.pixmap->drawable);
348*4882a593Smuzhiyun         break;
349*4882a593Smuzhiyun     case FillStippled:
350*4882a593Smuzhiyun     case FillOpaqueStippled:
351*4882a593Smuzhiyun         glamor_finish_access(&gc->stipple->drawable);
352*4882a593Smuzhiyun         break;
353*4882a593Smuzhiyun     }
354*4882a593Smuzhiyun }
355