xref: /OK3568_Linux_fs/external/xserver/glamor/glamor.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright © 2008,2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Eric Anholt <eric@anholt.net>
25  *    Zhigang Gong <zhigang.gong@linux.intel.com>
26  *    Chad Versace <chad.versace@linux.intel.com>
27  */
28 
29 /** @file glamor.c
30  * This file covers the initialization and teardown of glamor, and has various
31  * functions not responsible for performing rendering.
32  */
33 
34 #include <stdlib.h>
35 #include <unistd.h>
36 
37 #include "glamor_priv.h"
38 #include "mipict.h"
39 
40 DevPrivateKeyRec glamor_screen_private_key;
41 DevPrivateKeyRec glamor_pixmap_private_key;
42 DevPrivateKeyRec glamor_gc_private_key;
43 
44 glamor_screen_private *
glamor_get_screen_private(ScreenPtr screen)45 glamor_get_screen_private(ScreenPtr screen)
46 {
47     return (glamor_screen_private *)
48         dixLookupPrivate(&screen->devPrivates, &glamor_screen_private_key);
49 }
50 
51 void
glamor_set_screen_private(ScreenPtr screen,glamor_screen_private * priv)52 glamor_set_screen_private(ScreenPtr screen, glamor_screen_private *priv)
53 {
54     dixSetPrivate(&screen->devPrivates, &glamor_screen_private_key, priv);
55 }
56 
57 /**
58  * glamor_get_drawable_pixmap() returns a backing pixmap for a given drawable.
59  *
60  * @param drawable the drawable being requested.
61  *
62  * This function returns the backing pixmap for a drawable, whether it is a
63  * redirected window, unredirected window, or already a pixmap.  Note that
64  * coordinate translation is needed when drawing to the backing pixmap of a
65  * redirected window, and the translation coordinates are provided by calling
66  * exaGetOffscreenPixmap() on the drawable.
67  */
68 PixmapPtr
glamor_get_drawable_pixmap(DrawablePtr drawable)69 glamor_get_drawable_pixmap(DrawablePtr drawable)
70 {
71     if (drawable->type == DRAWABLE_WINDOW)
72         return drawable->pScreen->GetWindowPixmap((WindowPtr) drawable);
73     else
74         return (PixmapPtr) drawable;
75 }
76 
77 static void
glamor_init_pixmap_private_small(PixmapPtr pixmap,glamor_pixmap_private * pixmap_priv)78 glamor_init_pixmap_private_small(PixmapPtr pixmap, glamor_pixmap_private *pixmap_priv)
79 {
80     pixmap_priv->box.x1 = 0;
81     pixmap_priv->box.x2 = pixmap->drawable.width;
82     pixmap_priv->box.y1 = 0;
83     pixmap_priv->box.y2 = pixmap->drawable.height;
84     pixmap_priv->block_w = pixmap->drawable.width;
85     pixmap_priv->block_h = pixmap->drawable.height;
86     pixmap_priv->block_hcnt = 1;
87     pixmap_priv->block_wcnt = 1;
88     pixmap_priv->box_array = &pixmap_priv->box;
89     pixmap_priv->fbo_array = &pixmap_priv->fbo;
90 }
91 
92 _X_EXPORT void
glamor_set_pixmap_type(PixmapPtr pixmap,glamor_pixmap_type_t type)93 glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
94 {
95     glamor_pixmap_private *pixmap_priv;
96 
97     pixmap_priv = glamor_get_pixmap_private(pixmap);
98     pixmap_priv->type = type;
99     glamor_init_pixmap_private_small(pixmap, pixmap_priv);
100 }
101 
102 _X_EXPORT Bool
glamor_set_pixmap_texture(PixmapPtr pixmap,unsigned int tex)103 glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
104 {
105     ScreenPtr screen = pixmap->drawable.pScreen;
106     glamor_pixmap_private *pixmap_priv;
107     glamor_screen_private *glamor_priv;
108     glamor_pixmap_fbo *fbo;
109 
110     glamor_priv = glamor_get_screen_private(screen);
111     pixmap_priv = glamor_get_pixmap_private(pixmap);
112 
113     if (pixmap_priv->fbo) {
114         fbo = glamor_pixmap_detach_fbo(pixmap_priv);
115         glamor_destroy_fbo(glamor_priv, fbo);
116     }
117 
118     fbo = glamor_create_fbo_from_tex(glamor_priv, pixmap,
119                                      pixmap->drawable.width,
120                                      pixmap->drawable.height, tex, 0);
121 
122     if (fbo == NULL) {
123         ErrorF("XXX fail to create fbo.\n");
124         return FALSE;
125     }
126 
127     glamor_pixmap_attach_fbo(pixmap, fbo);
128 
129     return TRUE;
130 }
131 
132 _X_EXPORT void
glamor_clear_pixmap(PixmapPtr pixmap)133 glamor_clear_pixmap(PixmapPtr pixmap)
134 {
135     ScreenPtr screen = pixmap->drawable.pScreen;
136     glamor_screen_private *glamor_priv;
137     glamor_pixmap_private *pixmap_priv;
138 
139     glamor_priv = glamor_get_screen_private(screen);
140     pixmap_priv = glamor_get_pixmap_private(pixmap);
141 
142     assert(pixmap_priv->fbo != NULL);
143 
144     glamor_pixmap_clear_fbo(glamor_priv, pixmap_priv->fbo);
145 }
146 
147 uint32_t
glamor_get_pixmap_texture(PixmapPtr pixmap)148 glamor_get_pixmap_texture(PixmapPtr pixmap)
149 {
150     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
151 
152     if (!pixmap_priv)
153         return 0;
154 
155     if (!pixmap_priv->fbo)
156         return 0;
157 
158     if (pixmap_priv->type != GLAMOR_TEXTURE_ONLY)
159         return 0;
160 
161     return pixmap_priv->fbo->tex;
162 }
163 
164 void
glamor_bind_texture(glamor_screen_private * glamor_priv,GLenum texture,glamor_pixmap_fbo * fbo,Bool destination_red)165 glamor_bind_texture(glamor_screen_private *glamor_priv, GLenum texture,
166                     glamor_pixmap_fbo *fbo, Bool destination_red)
167 {
168     glActiveTexture(texture);
169     glBindTexture(GL_TEXTURE_2D, fbo->tex);
170 
171     /* If we're pulling data from a GL_RED texture, then whether we
172      * want to make it an A,0,0,0 result or a 0,0,0,R result depends
173      * on whether the destination is also a GL_RED texture.
174      *
175      * For GL_RED destinations, we need to leave the bits in the R
176      * channel. For all other destinations, we need to clear out the R
177      * channel so that it returns zero for R, G and B.
178      *
179      * Note that we're leaving the SWIZZLE_A value alone; for GL_RED
180      * destinations, that means we'll actually be returning R,0,0,R,
181      * but it doesn't matter as the bits in the alpha channel aren't
182      * going anywhere.
183      */
184 
185     /* Is the operand a GL_RED fbo?
186      */
187 
188     if (fbo->is_red) {
189         /* If destination is also GL_RED, then preserve the bits in
190          * the R channel */
191 
192         if (destination_red)
193             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
194         else
195             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
196     }
197 }
198 
199 PixmapPtr
glamor_create_pixmap(ScreenPtr screen,int w,int h,int depth,unsigned int usage)200 glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
201                      unsigned int usage)
202 {
203     PixmapPtr pixmap;
204     glamor_pixmap_private *pixmap_priv;
205     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
206     glamor_pixmap_fbo *fbo = NULL;
207     int pitch;
208 
209     if (w > 32767 || h > 32767)
210         return NullPixmap;
211 
212     if ((usage == GLAMOR_CREATE_PIXMAP_CPU
213          || (usage == CREATE_PIXMAP_USAGE_GLYPH_PICTURE &&
214              w <= glamor_priv->glyph_max_dim &&
215              h <= glamor_priv->glyph_max_dim)
216          || (w == 0 && h == 0)
217          || !glamor_priv->formats[depth].format))
218         return fbCreatePixmap(screen, w, h, depth, usage);
219     else
220         pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
221 
222     pixmap_priv = glamor_get_pixmap_private(pixmap);
223 
224     pixmap_priv->is_cbcr = (usage == GLAMOR_CREATE_FORMAT_CBCR);
225 
226     pitch = (((w * pixmap->drawable.bitsPerPixel + 7) / 8) + 3) & ~3;
227     screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
228 
229     pixmap_priv->type = GLAMOR_TEXTURE_ONLY;
230 
231     if (usage == GLAMOR_CREATE_PIXMAP_NO_TEXTURE) {
232         glamor_init_pixmap_private_small(pixmap, pixmap_priv);
233         return pixmap;
234     }
235     else if (usage == GLAMOR_CREATE_NO_LARGE ||
236         glamor_check_fbo_size(glamor_priv, w, h))
237     {
238         glamor_init_pixmap_private_small(pixmap, pixmap_priv);
239         fbo = glamor_create_fbo(glamor_priv, pixmap, w, h, usage);
240     } else {
241         int tile_size = glamor_priv->max_fbo_size;
242         DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n",
243                pixmap, w, h, tile_size);
244         fbo = glamor_create_fbo_array(glamor_priv, pixmap, usage,
245                                       tile_size, tile_size, pixmap_priv);
246     }
247 
248     if (fbo == NULL) {
249         fbDestroyPixmap(pixmap);
250         return fbCreatePixmap(screen, w, h, depth, usage);
251     }
252 
253     glamor_pixmap_attach_fbo(pixmap, fbo);
254 
255     return pixmap;
256 }
257 
258 Bool
glamor_destroy_pixmap(PixmapPtr pixmap)259 glamor_destroy_pixmap(PixmapPtr pixmap)
260 {
261     if (pixmap->refcnt == 1) {
262         glamor_pixmap_destroy_fbo(pixmap);
263     }
264 
265     return fbDestroyPixmap(pixmap);
266 }
267 
268 void
glamor_block_handler(ScreenPtr screen)269 glamor_block_handler(ScreenPtr screen)
270 {
271     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
272 
273     glamor_make_current(glamor_priv);
274 
275     if (glamor_priv->is_gles) {
276 #ifdef GLAMOR_HAS_GL_FENCE
277         GLsync sync;
278 
279         sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
280         glFlush();
281         glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
282         glDeleteSync(sync);
283 #else
284         glamor_finish(screen);
285 #endif
286     } else {
287         glFlush();
288     }
289 }
290 
291 static void
_glamor_block_handler(ScreenPtr screen,void * timeout)292 _glamor_block_handler(ScreenPtr screen, void *timeout)
293 {
294     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
295 
296     glamor_block_handler(screen);
297 
298     screen->BlockHandler = glamor_priv->saved_procs.block_handler;
299     screen->BlockHandler(screen, timeout);
300     glamor_priv->saved_procs.block_handler = screen->BlockHandler;
301     screen->BlockHandler = _glamor_block_handler;
302 }
303 
304 static void
glamor_set_debug_level(int * debug_level)305 glamor_set_debug_level(int *debug_level)
306 {
307     char *debug_level_string;
308 
309     debug_level_string = getenv("GLAMOR_DEBUG");
310     if (debug_level_string
311         && sscanf(debug_level_string, "%d", debug_level) == 1)
312         return;
313     *debug_level = 0;
314 }
315 
316 int glamor_debug_level;
317 
318 void
glamor_gldrawarrays_quads_using_indices(glamor_screen_private * glamor_priv,unsigned count)319 glamor_gldrawarrays_quads_using_indices(glamor_screen_private *glamor_priv,
320                                         unsigned count)
321 {
322     unsigned i;
323 
324     /* For a single quad, don't bother with an index buffer. */
325     if (count ==  1)
326         goto fallback;
327 
328     if (glamor_priv->ib_size < count) {
329         /* Basic GLES2 doesn't have any way to map buffer objects for
330          * writing, but it's long past time for drivers to have
331          * MapBufferRange.
332          */
333         if (!glamor_priv->has_map_buffer_range)
334             goto fallback;
335 
336         /* Lazy create the buffer name, and only bind it once since
337          * none of the glamor code binds it to anything else.
338          */
339         if (!glamor_priv->ib) {
340             glGenBuffers(1, &glamor_priv->ib);
341             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ib);
342         }
343 
344         /* For now, only support GL_UNSIGNED_SHORTs. */
345         if (count > ((1 << 16) - 1) / 4) {
346             goto fallback;
347         } else {
348             uint16_t *data;
349             size_t size = count * 6 * sizeof(GLushort);
350 
351             glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, NULL, GL_STATIC_DRAW);
352             data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER,
353                                     0, size,
354                                     GL_MAP_WRITE_BIT |
355                                     GL_MAP_INVALIDATE_BUFFER_BIT);
356             for (i = 0; i < count; i++) {
357                 data[i * 6 + 0] = i * 4 + 0;
358                 data[i * 6 + 1] = i * 4 + 1;
359                 data[i * 6 + 2] = i * 4 + 2;
360                 data[i * 6 + 3] = i * 4 + 0;
361                 data[i * 6 + 4] = i * 4 + 2;
362                 data[i * 6 + 5] = i * 4 + 3;
363             }
364             glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
365 
366             glamor_priv->ib_size = count;
367             glamor_priv->ib_type = GL_UNSIGNED_SHORT;
368         }
369     }
370 
371     glDrawElements(GL_TRIANGLES, count * 6, glamor_priv->ib_type, NULL);
372     return;
373 
374 fallback:
375     for (i = 0; i < count; i++)
376         glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
377 }
378 
379 
380 static Bool
glamor_check_instruction_count(int gl_version)381 glamor_check_instruction_count(int gl_version)
382 {
383     GLint max_native_alu_instructions;
384 
385     /* Avoid using glamor if the reported instructions limit is too low,
386      * as this would cause glamor to fallback on sw due to large shaders
387      * which ends up being unbearably slow.
388      */
389     if (gl_version < 30) {
390         if (!epoxy_has_gl_extension("GL_ARB_fragment_program")) {
391             ErrorF("GL_ARB_fragment_program required\n");
392             return FALSE;
393         }
394 
395         glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB,
396                           GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB,
397                           &max_native_alu_instructions);
398         if (max_native_alu_instructions < GLAMOR_MIN_ALU_INSTRUCTIONS) {
399             LogMessage(X_WARNING,
400                        "glamor requires at least %d instructions (%d reported)\n",
401                        GLAMOR_MIN_ALU_INSTRUCTIONS, max_native_alu_instructions);
402             return FALSE;
403         }
404     }
405 
406     return TRUE;
407 }
408 
409 static void GLAPIENTRY
glamor_debug_output_callback(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,const void * userParam)410 glamor_debug_output_callback(GLenum source,
411                              GLenum type,
412                              GLuint id,
413                              GLenum severity,
414                              GLsizei length,
415                              const GLchar *message,
416                              const void *userParam)
417 {
418     ScreenPtr screen = (void *)userParam;
419     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
420 
421     if (glamor_priv->suppress_gl_out_of_memory_logging &&
422         source == GL_DEBUG_SOURCE_API && type == GL_DEBUG_TYPE_ERROR) {
423         return;
424     }
425 
426     LogMessageVerb(X_ERROR, 0, "glamor%d: GL error: %*s\n",
427                screen->myNum, length, message);
428 }
429 
430 /**
431  * Configures GL_ARB_debug_output to give us immediate callbacks when
432  * GL errors occur, so that we can log them.
433  */
434 static void
glamor_setup_debug_output(ScreenPtr screen)435 glamor_setup_debug_output(ScreenPtr screen)
436 {
437     if (!epoxy_has_gl_extension("GL_ARB_debug_output"))
438         return;
439 
440     glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
441     /* Disable debugging messages other than GL API errors */
442     glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL,
443                           GL_FALSE);
444     glDebugMessageControl(GL_DEBUG_SOURCE_API,
445                           GL_DEBUG_TYPE_ERROR,
446                           GL_DONT_CARE,
447                           0, NULL, GL_TRUE);
448     glDebugMessageCallback(glamor_debug_output_callback,
449                            screen);
450 
451     /* If KHR_debug is present, all debug output is disabled by
452      * default on non-debug contexts.
453      */
454     if (epoxy_has_gl_extension("GL_KHR_debug"))
455         glEnable(GL_DEBUG_OUTPUT);
456 }
457 
458 const struct glamor_format *
glamor_format_for_pixmap(PixmapPtr pixmap)459 glamor_format_for_pixmap(PixmapPtr pixmap)
460 {
461     ScreenPtr pScreen = pixmap->drawable.pScreen;
462     glamor_screen_private *glamor_priv = glamor_get_screen_private(pScreen);
463     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
464 
465     if (pixmap_priv->is_cbcr)
466         return &glamor_priv->cbcr_format;
467     else
468         return &glamor_priv->formats[pixmap->drawable.depth];
469 }
470 
471 static void
glamor_add_format(ScreenPtr screen,int depth,CARD32 render_format,GLenum internalformat,GLenum format,GLenum type)472 glamor_add_format(ScreenPtr screen, int depth, CARD32 render_format,
473                   GLenum internalformat, GLenum format, GLenum type)
474 {
475     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
476     struct glamor_format *f = &glamor_priv->formats[depth];
477 
478     /* If we're trying to run on GLES, make sure that we get the read
479      * formats that we're expecting, since glamor_transfer relies on
480      * them matching to get data back out.  To avoid this limitation, we
481      * would need to have a more general glReadPixels() path in
482      * glamor_transfer that re-encoded the bits to the pixel format that
483      * we intended after.
484      *
485      * Note that we can't just create a pixmap because we're in
486      * screeninit.
487      */
488     if (glamor_priv->is_gles) {
489         unsigned fbo, tex;
490         int read_format, read_type;
491         GLenum status;
492 
493         glGenTextures(1, &tex);
494         glBindTexture(GL_TEXTURE_2D, tex);
495         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
496         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
497         glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0,
498                      format, type, NULL);
499 
500         glGenFramebuffers(1, &fbo);
501         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
502         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
503                                GL_TEXTURE_2D, tex, 0);
504         status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
505         if (status != GL_FRAMEBUFFER_COMPLETE) {
506             ErrorF("glamor: Test fbo for depth %d incomplete.  "
507                    "Falling back to software.\n", depth);
508             glDeleteTextures(1, &tex);
509             glDeleteFramebuffers(1, &fbo);
510             return;
511         }
512 
513         glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &read_format);
514         glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &read_type);
515 
516         glDeleteTextures(1, &tex);
517         glDeleteFramebuffers(1, &fbo);
518 
519         if (format != read_format || type != read_type) {
520             ErrorF("glamor: Implementation returned 0x%x/0x%x read format/type "
521                    "for depth %d, expected 0x%x/0x%x.  "
522                    "Falling back to software.\n",
523                    read_format, read_type, depth, format, type);
524             return;
525         }
526     }
527 
528     f->depth = depth;
529     f->render_format = render_format;
530     f->internalformat = internalformat;
531     f->format = format;
532     f->type = type;
533 }
534 
535 /* Set up the GL format/types that glamor will use for the various depths
536  *
537  * X11's pixel data doesn't have channels, but to store our data in GL
538  * we have to pick some sort of format to move X11 pixel data in and
539  * out with in glamor_transfer.c.  For X11 core operations, other than
540  * GL logic ops (non-GXcopy GC ops) what the driver chooses internally
541  * doesn't matter as long as it doesn't drop any bits (we expect them
542  * to generally expand, if anything).  For Render, we can expect
543  * clients to tend to render with PictFormats matching our channel
544  * layouts here since ultimately X11 pixels tend to end up on the
545  * screen.  The render implementation will fall back to fb if the
546  * channels don't match.
547  *
548  * Note that these formats don't affect what glamor_egl.c or
549  * Xwayland's EGL layer choose for surfaces exposed through DRI or
550  * scanout.  For now, those layers need to match what we're choosing
551  * here, or channels will end up swizzled around.  Similarly, the
552  * driver's visual masks also need to match what we're doing here.
553  */
554 static void
glamor_setup_formats(ScreenPtr screen)555 glamor_setup_formats(ScreenPtr screen)
556 {
557     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
558 
559     /* Prefer r8 textures since they're required by GLES3 and core,
560      * only falling back to a8 if we can't do them.
561      */
562     if (glamor_priv->is_gles || epoxy_has_gl_extension("GL_ARB_texture_rg")) {
563         glamor_add_format(screen, 8, PICT_a8,
564                           GL_R8, GL_RED, GL_UNSIGNED_BYTE);
565     } else {
566         glamor_add_format(screen, 8, PICT_a8,
567                           GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
568     }
569 
570     if (glamor_priv->is_gles) {
571         /* For 15bpp, GLES supports format/type RGBA/5551, rather than
572          * bgra/1555_rev.  GL_EXT_bgra lets the impl say the color
573          * read format/type is bgra/1555 even if we had to create it
574          * with rgba/5551, with Mesa does.  That means we can't use
575          * the same format/type for TexSubImage and readpixels.
576          *
577          * Instead, just store 16 bits using the trusted 565 path, and
578          * disable render accel for now.
579          */
580         glamor_add_format(screen, 15, PICT_x1r5g5b5,
581                           GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
582     } else {
583         glamor_add_format(screen, 15, PICT_x1r5g5b5,
584                           GL_RGBA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV);
585     }
586 
587     glamor_add_format(screen, 16, PICT_r5g6b5,
588                       GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
589 
590     if (glamor_priv->is_gles) {
591         assert(X_BYTE_ORDER == X_LITTLE_ENDIAN);
592         glamor_add_format(screen, 24, PICT_x8r8g8b8,
593                           GL_BGRA, GL_BGRA, GL_UNSIGNED_BYTE);
594         glamor_add_format(screen, 32, PICT_a8r8g8b8,
595                           GL_BGRA, GL_BGRA, GL_UNSIGNED_BYTE);
596     } else {
597         glamor_add_format(screen, 24, PICT_x8r8g8b8,
598                           GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
599         glamor_add_format(screen, 32, PICT_a8r8g8b8,
600                           GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV);
601     }
602 
603     if (glamor_priv->is_gles) {
604         glamor_add_format(screen, 30, PICT_x2b10g10r10,
605                           GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
606     } else {
607         glamor_add_format(screen, 30, PICT_x2r10g10b10,
608                           GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV);
609     }
610 
611     glamor_priv->cbcr_format.depth = 16;
612     glamor_priv->cbcr_format.internalformat = GL_RG8;
613     glamor_priv->cbcr_format.format = GL_RG;
614     glamor_priv->cbcr_format.type = GL_UNSIGNED_BYTE;
615 }
616 
617 /** Set up glamor for an already-configured GL context. */
618 Bool
glamor_init(ScreenPtr screen,unsigned int flags)619 glamor_init(ScreenPtr screen, unsigned int flags)
620 {
621     glamor_screen_private *glamor_priv;
622     int gl_version;
623     int glsl_major, glsl_minor;
624     int max_viewport_size[2];
625     const char *shading_version_string;
626     int shading_version_offset;
627 
628     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
629 
630     if (flags & ~GLAMOR_VALID_FLAGS) {
631         ErrorF("glamor_init: Invalid flags %x\n", flags);
632         return FALSE;
633     }
634     glamor_priv = calloc(1, sizeof(*glamor_priv));
635     if (glamor_priv == NULL)
636         return FALSE;
637 
638     glamor_priv->flags = flags;
639 
640     if (!dixRegisterPrivateKey(&glamor_screen_private_key, PRIVATE_SCREEN, 0)) {
641         LogMessage(X_WARNING,
642                    "glamor%d: Failed to allocate screen private\n",
643                    screen->myNum);
644         goto free_glamor_private;
645     }
646 
647     glamor_set_screen_private(screen, glamor_priv);
648 
649     if (!dixRegisterPrivateKey(&glamor_pixmap_private_key, PRIVATE_PIXMAP,
650                                sizeof(struct glamor_pixmap_private))) {
651         LogMessage(X_WARNING,
652                    "glamor%d: Failed to allocate pixmap private\n",
653                    screen->myNum);
654         goto free_glamor_private;
655     }
656 
657     if (!dixRegisterPrivateKey(&glamor_gc_private_key, PRIVATE_GC,
658                                sizeof (glamor_gc_private))) {
659         LogMessage(X_WARNING,
660                    "glamor%d: Failed to allocate gc private\n",
661                    screen->myNum);
662         goto free_glamor_private;
663     }
664 
665     glamor_priv->saved_procs.close_screen = screen->CloseScreen;
666     screen->CloseScreen = glamor_close_screen;
667 
668     glamor_priv->saved_procs.destroy_pixmap = screen->DestroyPixmap;
669     screen->DestroyPixmap = glamor_destroy_pixmap;
670 
671     /* If we are using egl screen, call egl screen init to
672      * register correct close screen function. */
673     if (flags & GLAMOR_USE_EGL_SCREEN) {
674         glamor_egl_screen_init(screen, &glamor_priv->ctx);
675     } else {
676 #ifdef GLXEXT
677         if (!glamor_glx_screen_init(&glamor_priv->ctx))
678             goto fail;
679 #endif
680     }
681 
682     glamor_make_current(glamor_priv);
683 
684     if (!epoxy_is_desktop_gl())
685         glamor_priv->is_gles = TRUE;
686 
687     gl_version = epoxy_gl_version();
688 
689     /* assume a core profile if we are GL 3.1 and don't have ARB_compatibility */
690     glamor_priv->is_core_profile =
691         gl_version >= 31 && !epoxy_has_gl_extension("GL_ARB_compatibility");
692 
693     shading_version_string = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
694 
695     if (!shading_version_string) {
696         LogMessage(X_WARNING,
697                    "glamor%d: Failed to get GLSL version\n",
698                    screen->myNum);
699         goto fail;
700     }
701 
702     shading_version_offset = 0;
703     if (strncmp("OpenGL ES GLSL ES ", shading_version_string, 18) == 0)
704         shading_version_offset = 18;
705 
706     if (sscanf(shading_version_string + shading_version_offset,
707                "%i.%i",
708                &glsl_major,
709                &glsl_minor) != 2) {
710         LogMessage(X_WARNING,
711                    "glamor%d: Failed to parse GLSL version string %s\n",
712                    screen->myNum, shading_version_string);
713         goto fail;
714     }
715     glamor_priv->glsl_version = glsl_major * 100 + glsl_minor;
716 
717     if (glamor_priv->is_gles) {
718         /* Force us back to the base version of our programs on an ES
719          * context, anyway.  Basically glamor only uses desktop 1.20
720          * or 1.30 currently.  1.30's new features are also present in
721          * ES 3.0, but our glamor_program.c constructions use a lot of
722          * compatibility features (to reduce the diff between 1.20 and
723          * 1.30 programs).
724          */
725         glamor_priv->glsl_version = 120;
726     }
727 
728     /* We'd like to require GL_ARB_map_buffer_range or
729      * GL_OES_map_buffer_range, since it offers more information to
730      * the driver than plain old glMapBuffer() or glBufferSubData().
731      * It's been supported on Mesa on the desktop since 2009 and on
732      * GLES2 since October 2012.  It's supported on Apple's iOS
733      * drivers for SGX535 and A7, but apparently not on most Android
734      * devices (the OES extension spec wasn't released until June
735      * 2012).
736      *
737      * 82% of 0 A.D. players (desktop GL) submitting hardware reports
738      * have support for it, with most of the ones lacking it being on
739      * Windows with Intel 4-series (G45) graphics or older.
740      */
741     if (!glamor_priv->is_gles) {
742         if (gl_version < 21) {
743             ErrorF("Require OpenGL version 2.1 or later.\n");
744             goto fail;
745         }
746 
747         if (!glamor_priv->is_core_profile &&
748             !epoxy_has_gl_extension("GL_ARB_texture_border_clamp")) {
749             ErrorF("GL_ARB_texture_border_clamp required\n");
750             goto fail;
751         }
752 
753         if (!glamor_check_instruction_count(gl_version))
754             goto fail;
755 
756         /* Glamor rendering assumes that platforms with GLSL 130+
757          * have instanced arrays, but this is not always the case.
758          * etnaviv offers GLSL 140 with OpenGL 2.1.
759          */
760         if (glamor_priv->glsl_version >= 130 &&
761             !epoxy_has_gl_extension("GL_ARB_instanced_arrays"))
762                 glamor_priv->glsl_version = 120;
763     } else {
764         if (gl_version < 20) {
765             ErrorF("Require Open GLES2.0 or later.\n");
766             goto fail;
767         }
768 
769         if (!epoxy_has_gl_extension("GL_EXT_texture_format_BGRA8888")) {
770             ErrorF("GL_EXT_texture_format_BGRA8888 required\n");
771             goto fail;
772         }
773 
774         if (!epoxy_has_gl_extension("GL_OES_texture_border_clamp")) {
775             ErrorF("GL_OES_texture_border_clamp required\n");
776             goto fail;
777         }
778     }
779 
780     if (!epoxy_has_gl_extension("GL_ARB_vertex_array_object") &&
781         !epoxy_has_gl_extension("GL_OES_vertex_array_object")) {
782         ErrorF("GL_{ARB,OES}_vertex_array_object required\n");
783         goto fail;
784     }
785 
786     glamor_priv->has_rw_pbo = FALSE;
787     if (!glamor_priv->is_gles)
788         glamor_priv->has_rw_pbo = TRUE;
789 
790     glamor_priv->has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug");
791     glamor_priv->has_pack_invert =
792         epoxy_has_gl_extension("GL_MESA_pack_invert");
793     glamor_priv->has_fbo_blit =
794         epoxy_has_gl_extension("GL_EXT_framebuffer_blit");
795     glamor_priv->has_map_buffer_range =
796         epoxy_has_gl_extension("GL_ARB_map_buffer_range") ||
797         epoxy_has_gl_extension("GL_EXT_map_buffer_range");
798     glamor_priv->has_buffer_storage =
799         epoxy_has_gl_extension("GL_ARB_buffer_storage");
800     glamor_priv->has_mesa_tile_raster_order =
801         epoxy_has_gl_extension("GL_MESA_tile_raster_order");
802     glamor_priv->has_nv_texture_barrier =
803         epoxy_has_gl_extension("GL_NV_texture_barrier");
804     glamor_priv->has_unpack_subimage =
805         !glamor_priv->is_gles ||
806         epoxy_gl_version() >= 30 ||
807         epoxy_has_gl_extension("GL_EXT_unpack_subimage");
808     glamor_priv->has_pack_subimage =
809         !glamor_priv->is_gles ||
810         epoxy_gl_version() >= 30 ||
811         epoxy_has_gl_extension("GL_NV_pack_subimage");
812     glamor_priv->has_dual_blend =
813         glamor_priv->glsl_version >= 130 &&
814         epoxy_has_gl_extension("GL_ARB_blend_func_extended");
815 
816     glamor_priv->can_copyplane = (gl_version >= 30);
817 
818     glamor_setup_debug_output(screen);
819 
820     glamor_priv->use_quads = !glamor_priv->is_gles &&
821                              !glamor_priv->is_core_profile;
822 
823     /* Driver-specific hack: Avoid using GL_QUADS on VC4, where
824      * they'll be emulated more expensively than we can with our
825      * cached IB.
826      */
827     if (strstr((char *)glGetString(GL_VENDOR), "Broadcom") &&
828         strstr((char *)glGetString(GL_RENDERER), "VC4"))
829         glamor_priv->use_quads = FALSE;
830 
831     glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &glamor_priv->max_fbo_size);
832     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glamor_priv->max_fbo_size);
833     glGetIntegerv(GL_MAX_VIEWPORT_DIMS, max_viewport_size);
834     glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[0]);
835     glamor_priv->max_fbo_size = MIN(glamor_priv->max_fbo_size, max_viewport_size[1]);
836 #ifdef MAX_FBO_SIZE
837     glamor_priv->max_fbo_size = MAX_FBO_SIZE;
838 #endif
839 
840     glamor_priv->has_texture_swizzle =
841         (epoxy_has_gl_extension("GL_ARB_texture_swizzle") ||
842          (glamor_priv->is_gles && gl_version >= 30));
843 
844     glamor_setup_formats(screen);
845 
846     glamor_set_debug_level(&glamor_debug_level);
847 
848     if (!glamor_font_init(screen))
849         goto fail;
850 
851     glamor_priv->saved_procs.block_handler = screen->BlockHandler;
852     screen->BlockHandler = _glamor_block_handler;
853 
854     if (!glamor_composite_glyphs_init(screen)) {
855         ErrorF("Failed to initialize composite masks\n");
856         goto fail;
857     }
858 
859     glamor_priv->saved_procs.create_gc = screen->CreateGC;
860     screen->CreateGC = glamor_create_gc;
861 
862     glamor_priv->saved_procs.create_pixmap = screen->CreatePixmap;
863     screen->CreatePixmap = glamor_create_pixmap;
864 
865     glamor_priv->saved_procs.get_spans = screen->GetSpans;
866     screen->GetSpans = glamor_get_spans;
867 
868     glamor_priv->saved_procs.get_image = screen->GetImage;
869     screen->GetImage = glamor_get_image;
870 
871     glamor_priv->saved_procs.change_window_attributes =
872         screen->ChangeWindowAttributes;
873     screen->ChangeWindowAttributes = glamor_change_window_attributes;
874 
875     glamor_priv->saved_procs.copy_window = screen->CopyWindow;
876     screen->CopyWindow = glamor_copy_window;
877 
878     glamor_priv->saved_procs.bitmap_to_region = screen->BitmapToRegion;
879     screen->BitmapToRegion = glamor_bitmap_to_region;
880 
881     glamor_priv->saved_procs.composite = ps->Composite;
882     ps->Composite = glamor_composite;
883 
884     glamor_priv->saved_procs.trapezoids = ps->Trapezoids;
885     ps->Trapezoids = glamor_trapezoids;
886 
887     glamor_priv->saved_procs.triangles = ps->Triangles;
888     ps->Triangles = glamor_triangles;
889 
890     glamor_priv->saved_procs.addtraps = ps->AddTraps;
891     ps->AddTraps = glamor_add_traps;
892 
893     glamor_priv->saved_procs.composite_rects = ps->CompositeRects;
894     ps->CompositeRects = glamor_composite_rectangles;
895 
896     glamor_priv->saved_procs.glyphs = ps->Glyphs;
897     ps->Glyphs = glamor_composite_glyphs;
898 
899     glamor_init_vbo(screen);
900     glamor_init_gradient_shader(screen);
901     glamor_pixmap_init(screen);
902     glamor_sync_init(screen);
903 
904     glamor_priv->screen = screen;
905 
906     return TRUE;
907 
908  fail:
909     /* Restore default CloseScreen and DestroyPixmap handlers */
910     screen->CloseScreen = glamor_priv->saved_procs.close_screen;
911     screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
912 
913  free_glamor_private:
914     free(glamor_priv);
915     glamor_set_screen_private(screen, NULL);
916     return FALSE;
917 }
918 
919 static void
glamor_release_screen_priv(ScreenPtr screen)920 glamor_release_screen_priv(ScreenPtr screen)
921 {
922     glamor_screen_private *glamor_priv;
923 
924     glamor_priv = glamor_get_screen_private(screen);
925     glamor_fini_vbo(screen);
926     glamor_pixmap_fini(screen);
927     free(glamor_priv);
928 
929     glamor_set_screen_private(screen, NULL);
930 }
931 
932 Bool
glamor_close_screen(ScreenPtr screen)933 glamor_close_screen(ScreenPtr screen)
934 {
935     glamor_screen_private *glamor_priv;
936     PixmapPtr screen_pixmap;
937     PictureScreenPtr ps = GetPictureScreenIfSet(screen);
938 
939     glamor_priv = glamor_get_screen_private(screen);
940     glamor_sync_close(screen);
941     glamor_composite_glyphs_fini(screen);
942     screen->CloseScreen = glamor_priv->saved_procs.close_screen;
943 
944     screen->CreateGC = glamor_priv->saved_procs.create_gc;
945     screen->CreatePixmap = glamor_priv->saved_procs.create_pixmap;
946     screen->DestroyPixmap = glamor_priv->saved_procs.destroy_pixmap;
947     screen->GetSpans = glamor_priv->saved_procs.get_spans;
948     screen->ChangeWindowAttributes =
949         glamor_priv->saved_procs.change_window_attributes;
950     screen->CopyWindow = glamor_priv->saved_procs.copy_window;
951     screen->BitmapToRegion = glamor_priv->saved_procs.bitmap_to_region;
952     screen->BlockHandler = glamor_priv->saved_procs.block_handler;
953 
954     ps->Composite = glamor_priv->saved_procs.composite;
955     ps->Trapezoids = glamor_priv->saved_procs.trapezoids;
956     ps->Triangles = glamor_priv->saved_procs.triangles;
957     ps->CompositeRects = glamor_priv->saved_procs.composite_rects;
958     ps->Glyphs = glamor_priv->saved_procs.glyphs;
959 
960     screen_pixmap = screen->GetScreenPixmap(screen);
961     glamor_pixmap_destroy_fbo(screen_pixmap);
962 
963     glamor_release_screen_priv(screen);
964 
965     return screen->CloseScreen(screen);
966 }
967 
968 void
glamor_fini(ScreenPtr screen)969 glamor_fini(ScreenPtr screen)
970 {
971     /* Do nothing currently. */
972 }
973 
974 void
glamor_enable_dri3(ScreenPtr screen)975 glamor_enable_dri3(ScreenPtr screen)
976 {
977     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
978 
979     glamor_priv->dri3_enabled = TRUE;
980 }
981 
982 Bool
glamor_supports_pixmap_import_export(ScreenPtr screen)983 glamor_supports_pixmap_import_export(ScreenPtr screen)
984 {
985     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
986 
987     return glamor_priv->dri3_enabled;
988 }
989 
990 _X_EXPORT void
glamor_set_drawable_modifiers_func(ScreenPtr screen,GetDrawableModifiersFuncPtr func)991 glamor_set_drawable_modifiers_func(ScreenPtr screen,
992                                    GetDrawableModifiersFuncPtr func)
993 {
994     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
995 
996     glamor_priv->get_drawable_modifiers = func;
997 }
998 
999 _X_EXPORT Bool
glamor_get_drawable_modifiers(DrawablePtr draw,uint32_t format,uint32_t * num_modifiers,uint64_t ** modifiers)1000 glamor_get_drawable_modifiers(DrawablePtr draw, uint32_t format,
1001                               uint32_t *num_modifiers, uint64_t **modifiers)
1002 {
1003     struct glamor_screen_private *glamor_priv =
1004         glamor_get_screen_private(draw->pScreen);
1005 
1006     if (glamor_priv->get_drawable_modifiers) {
1007         return glamor_priv->get_drawable_modifiers(draw, format,
1008                                                    num_modifiers, modifiers);
1009     }
1010     *num_modifiers = 0;
1011     *modifiers = NULL;
1012     return TRUE;
1013 }
1014 
1015 static int
_glamor_fds_from_pixmap(ScreenPtr screen,PixmapPtr pixmap,int * fds,uint32_t * strides,uint32_t * offsets,CARD32 * size,uint64_t * modifier)1016 _glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
1017                         uint32_t *strides, uint32_t *offsets,
1018                         CARD32 *size, uint64_t *modifier)
1019 {
1020     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
1021     glamor_screen_private *glamor_priv =
1022         glamor_get_screen_private(pixmap->drawable.pScreen);
1023 
1024     if (!glamor_priv->dri3_enabled)
1025         return 0;
1026     switch (pixmap_priv->type) {
1027     case GLAMOR_TEXTURE_DRM:
1028     case GLAMOR_TEXTURE_ONLY:
1029         if (!glamor_pixmap_ensure_fbo(pixmap, 0))
1030             return 0;
1031 
1032         if (modifier) {
1033             return glamor_egl_fds_from_pixmap(screen, pixmap, fds,
1034                                               strides, offsets,
1035                                               modifier);
1036         } else {
1037             CARD16 stride;
1038 
1039             fds[0] = glamor_egl_fd_from_pixmap(screen, pixmap, &stride, size);
1040             strides[0] = stride;
1041 
1042             return fds[0] >= 0;
1043         }
1044     default:
1045         break;
1046     }
1047     return 0;
1048 }
1049 
1050 _X_EXPORT int
glamor_fds_from_pixmap(ScreenPtr screen,PixmapPtr pixmap,int * fds,uint32_t * strides,uint32_t * offsets,uint64_t * modifier)1051 glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
1052                        uint32_t *strides, uint32_t *offsets,
1053                        uint64_t *modifier)
1054 {
1055     return _glamor_fds_from_pixmap(screen, pixmap, fds, strides, offsets,
1056                                    NULL, modifier);
1057 }
1058 
1059 _X_EXPORT int
glamor_fd_from_pixmap(ScreenPtr screen,PixmapPtr pixmap,CARD16 * stride,CARD32 * size)1060 glamor_fd_from_pixmap(ScreenPtr screen,
1061                       PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
1062 {
1063     int fd;
1064     int ret;
1065     uint32_t stride32;
1066 
1067     ret = _glamor_fds_from_pixmap(screen, pixmap, &fd, &stride32, NULL, size,
1068                                   NULL);
1069     if (ret != 1)
1070         return -1;
1071 
1072     *stride = stride32;
1073     return fd;
1074 }
1075 
1076 _X_EXPORT int
glamor_shareable_fd_from_pixmap(ScreenPtr screen,PixmapPtr pixmap,CARD16 * stride,CARD32 * size)1077 glamor_shareable_fd_from_pixmap(ScreenPtr screen,
1078                                 PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
1079 {
1080     unsigned orig_usage_hint = pixmap->usage_hint;
1081     int ret;
1082 
1083     /*
1084      * The actual difference between a sharable and non sharable buffer
1085      * is decided 4 call levels deep in glamor_make_pixmap_exportable()
1086      * based on pixmap->usage_hint == CREATE_PIXMAP_USAGE_SHARED
1087      * 2 of those calls are also exported API, so we cannot just add a flag.
1088      */
1089     pixmap->usage_hint = CREATE_PIXMAP_USAGE_SHARED;
1090 
1091     ret = glamor_fd_from_pixmap(screen, pixmap, stride, size);
1092 
1093     pixmap->usage_hint = orig_usage_hint;
1094     return ret;
1095 }
1096 
1097 int
glamor_name_from_pixmap(PixmapPtr pixmap,CARD16 * stride,CARD32 * size)1098 glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
1099 {
1100     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
1101 
1102     switch (pixmap_priv->type) {
1103     case GLAMOR_TEXTURE_DRM:
1104     case GLAMOR_TEXTURE_ONLY:
1105         if (!glamor_pixmap_ensure_fbo(pixmap, 0))
1106             return -1;
1107         return glamor_egl_fd_name_from_pixmap(pixmap->drawable.pScreen,
1108                                               pixmap, stride, size);
1109     default:
1110         break;
1111     }
1112     return -1;
1113 }
1114 
1115 void
glamor_finish(ScreenPtr screen)1116 glamor_finish(ScreenPtr screen)
1117 {
1118     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
1119 
1120     glamor_make_current(glamor_priv);
1121     glFinish();
1122 
1123     glamor_priv->gl_synced = TRUE;
1124 }
1125 
1126 void
glamor_pixmap_invalid(PixmapPtr pixmap)1127 glamor_pixmap_invalid(PixmapPtr pixmap)
1128 {
1129     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
1130     glamor_screen_private *glamor_priv =
1131         glamor_get_screen_private(pixmap->drawable.pScreen);
1132 
1133     pixmap_priv->gl_synced = FALSE;
1134     glamor_priv->gl_synced = FALSE;
1135 }
1136