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