xserver: Branch 'master' - 18 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Apr 23 12:54:08 PDT 2014


 dix/dixutils.c            |   25 ++++++
 glamor/Makefile.am        |    3 
 glamor/glamor.c           |   25 ++----
 glamor/glamor_context.h   |    9 --
 glamor/glamor_copyarea.c  |   18 +---
 glamor/glamor_core.c      |    9 --
 glamor/glamor_egl.c       |   61 ++++++---------
 glamor/glamor_fbo.c       |   33 ++++----
 glamor/glamor_fill.c      |   13 +--
 glamor/glamor_font.c      |    7 -
 glamor/glamor_getimage.c  |   96 ------------------------
 glamor/glamor_glx.c       |   26 ++----
 glamor/glamor_glyphblt.c  |   10 --
 glamor/glamor_glyphs.c    |    3 
 glamor/glamor_gradient.c  |   24 +-----
 glamor/glamor_image.c     |  180 ++++++++++++++++++++++++++++++++++++++++++++++
 glamor/glamor_pixmap.c    |   22 +----
 glamor/glamor_points.c    |    5 -
 glamor/glamor_priv.h      |   23 ++---
 glamor/glamor_putimage.c  |  161 -----------------------------------------
 glamor/glamor_rects.c     |    4 -
 glamor/glamor_render.c    |   54 +++++--------
 glamor/glamor_spans.c     |   10 --
 glamor/glamor_text.c      |   10 --
 glamor/glamor_tile.c      |   13 +--
 glamor/glamor_transfer.c  |    6 -
 glamor/glamor_trapezoid.c |   20 +----
 glamor/glamor_utils.h     |   13 +--
 glamor/glamor_vbo.c       |   17 +---
 glamor/glamor_xv.c        |    7 -
 glx/glxcmds.c             |   11 +-
 glx/glxdri2.c             |  124 ++++++++++++++++++++++---------
 glx/glxdriswrast.c        |   10 ++
 glx/glxext.c              |   27 ++----
 glx/glxserver.h           |    1 
 include/dix.h             |    2 
 36 files changed, 478 insertions(+), 604 deletions(-)

New commits:
commit a4d96afdbddb7a636df8e336059d3a5624f2e6ae
Author: Zhigang Gong <zhigang.gong at intel.com>
Date:   Wed Apr 23 18:54:43 2014 +0900

    glamor: Fallback to system memory when fail to allocate one big fbo.
    
    Even when create a pixmap which smaller than the max_fbo_size,
    it may fail due to some low level driver limitation. If that is
    the case, we don't need to crash the xserver. We just need to
    fallback to system memory.
    
    See the related bug at:
    https://bugs.freedesktop.org/show_bug.cgi?id=71190
    
    Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Tested-by: Kai Wasserbach <kai at dev.carbon-project.org>
    Tested-by: Erich Seifert <eseifert at error-reports.org>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 994e923..08f6ba1 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -146,7 +146,7 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
     glamor_pixmap_type_t type = GLAMOR_TEXTURE_ONLY;
     glamor_pixmap_private *pixmap_priv;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
-    glamor_pixmap_fbo *fbo;
+    glamor_pixmap_fbo *fbo = NULL;
     int pitch;
     GLenum format;
 
@@ -199,13 +199,12 @@ glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
         pixmap_priv->base.box.x2 = w;
         pixmap_priv->base.box.y2 = h;
         fbo = glamor_create_fbo(glamor_priv, w, h, format, usage);
-    }
-    else {
-        DEBUGF("Create LARGE pixmap %p width %d height %d\n", pixmap, w, h);
+    } else {
+        int tile_size = glamor_priv->max_fbo_size;
+        DEBUGF("Create LARGE pixmap %p width %d height %d, tile size %d\n", pixmap, w, h, tile_size);
         pixmap_priv->type = GLAMOR_TEXTURE_LARGE;
         fbo = glamor_create_fbo_array(glamor_priv, w, h, format, usage,
-                                      glamor_priv->max_fbo_size,
-                                      glamor_priv->max_fbo_size, pixmap_priv);
+                                      tile_size, tile_size, pixmap_priv);
     }
 
     if (fbo == NULL) {
@@ -658,7 +657,8 @@ glamor_fd_from_pixmap(ScreenPtr screen,
     switch (pixmap_priv->type) {
     case GLAMOR_TEXTURE_DRM:
     case GLAMOR_TEXTURE_ONLY:
-        glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
+        if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
+            return -1;
         return glamor_egl_dri3_fd_name_from_tex(screen,
                                                 pixmap,
                                                 pixmap_priv->base.fbo->tex,
@@ -682,7 +682,8 @@ glamor_name_from_pixmap(PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
     switch (pixmap_priv->type) {
     case GLAMOR_TEXTURE_DRM:
     case GLAMOR_TEXTURE_ONLY:
-        glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0);
+        if (!glamor_pixmap_ensure_fbo(pixmap, GL_RGBA, 0))
+            return -1;
         return glamor_egl_dri3_fd_name_from_tex(pixmap->drawable.pScreen,
                                                 pixmap,
                                                 pixmap_priv->base.fbo->tex,
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index ed4e348..5521683 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -174,10 +174,10 @@ glamor_pixmap_fbo_cache_put(glamor_pixmap_fbo *fbo)
 #endif
 }
 
-static void
+static int
 glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 {
-    int status;
+    int status, err = 0;
 
     glamor_make_current(fbo->glamor_priv);
 
@@ -215,9 +215,11 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
             break;
         }
 
-        FatalError("destination is framebuffer incomplete: %s [%x]\n",
-                   str, status);
+        glamor_fallback("glamor: Failed to create fbo, %s\n", str);
+        err = -1;
     }
+
+    return err;
 }
 
 glamor_pixmap_fbo *
@@ -244,8 +246,12 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
         goto done;
     }
 
-    if (flag != GLAMOR_CREATE_FBO_NO_FBO)
-        glamor_pixmap_ensure_fb(fbo);
+    if (flag != GLAMOR_CREATE_FBO_NO_FBO) {
+        if (glamor_pixmap_ensure_fb(fbo) != 0) {
+            glamor_purge_fbo(fbo);
+            fbo = NULL;
+        }
+    }
 
  done:
     return fbo;
@@ -562,7 +568,8 @@ glamor_pixmap_ensure_fbo(PixmapPtr pixmap, GLenum format, int flag)
                                    pixmap->drawable.height, format);
 
         if (flag != GLAMOR_CREATE_FBO_NO_FBO && pixmap_priv->base.fbo->fb == 0)
-            glamor_pixmap_ensure_fb(pixmap_priv->base.fbo);
+            if (glamor_pixmap_ensure_fb(pixmap_priv->base.fbo) != 0)
+                return FALSE;
     }
 
     return TRUE;
commit 21e0e373858bd7f3458172ebd465397e33b90162
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Apr 23 18:54:42 2014 +0900

    glamor: Fix memory leak in _glamor_copy_n_to_n()
    
    It would leak the memory allocated for the region rects in some cases.
    Found with valgrind.
    
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 6e90e36..e198822 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -367,7 +367,7 @@ _glamor_copy_n_to_n(DrawablePtr src,
             goto fall_back;
         glamor_make_current(glamor_priv);
         if (!glamor_set_alu(screen, gc->alu)) {
-            goto fail;
+            goto fail_noregion;
         }
     }
 
@@ -533,7 +533,6 @@ _glamor_copy_n_to_n(DrawablePtr src,
         if (n_dst_region == 0)
             ok = TRUE;
         free(clipped_dst_regions);
-        RegionUninit(&region);
     }
     else {
         ok = __glamor_copy_n_to_n(src, dst, gc, box, nbox, dx, dy,
@@ -541,6 +540,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
     }
 
  fail:
+    RegionUninit(&region);
+ fail_noregion:
     glamor_make_current(glamor_priv);
     glamor_set_alu(screen, GXcopy);
 
commit 4e9aabb6fc15d8052934f20c6a07801c197ec36a
Author: Anthony Waters <awaters1 at gmail.com>
Date:   Wed Apr 23 18:54:41 2014 +0900

    glamor: Fix coordinates handling for composite source/mask pictures
    
    There were actually two issues with the original code I believe, the
    first is that the call to glamor_convert_gradient_picture wasn't
    properly referencing the coordinates of the source/mask pictures.  The
    second, was that the updated references (x_temp/y_temp) were also
    improperly set, they should always be 0 because the temp pictures are
    new ones that start at (0, 0).  The reason it worked in certain cases
    and it didn't in others (notably the tray icons) was due to the
    numbers working out based on the call to glamor_composite.  In the
    cases that it did work extent->x1 would equal x_dest and extent->y1
    would equal y_dest, making it so what was actually passed into
    glamor_convert_gradient_picture and the settings for x_temp/y_temp
    were correct.  However, for the case when extent->x1 wouldn't equal
    x_dest and extent->y1 wouldn't equal y_dest (for example with the tray
    icons) then the wrong parameters get passed into
    glamor_convert_gradient_picture and x_temp/y_temp are set improperly.
    
    Fixes issues with tray icons not appearing properly in certain cases.
    
    Bug:
    https://bugs.freedesktop.org/show_bug.cgi?id=64738
    
    Signed-Off-by: Anthony Waters <awaters1 at gmail.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by: Zhigang Gong <zhigang.gong at linux.intel.com>
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 14ab738..5a7a238 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -1450,8 +1450,8 @@ glamor_composite_clipped_region(CARD8 op,
                     || source_pixmap->drawable.height != height)))) {
         temp_src =
             glamor_convert_gradient_picture(screen, source,
-                                            extent->x1 + x_source - x_dest,
-                                            extent->y1 + y_source - y_dest,
+                                            x_source,
+                                            y_source,
                                             width, height);
         if (!temp_src) {
             temp_src = source;
@@ -1459,8 +1459,8 @@ glamor_composite_clipped_region(CARD8 op,
         }
         temp_src_priv =
             glamor_get_pixmap_private((PixmapPtr) (temp_src->pDrawable));
-        x_temp_src = -extent->x1 + x_dest;
-        y_temp_src = -extent->y1 + y_dest;
+        x_temp_src = 0;
+        y_temp_src = 0;
     }
 
     if (mask
@@ -1474,8 +1474,8 @@ glamor_composite_clipped_region(CARD8 op,
          * to do reduce one convertion. */
         temp_mask =
             glamor_convert_gradient_picture(screen, mask,
-                                            extent->x1 + x_mask - x_dest,
-                                            extent->y1 + y_mask - y_dest,
+                                            x_mask,
+                                            y_mask,
                                             width, height);
         if (!temp_mask) {
             temp_mask = mask;
@@ -1483,8 +1483,8 @@ glamor_composite_clipped_region(CARD8 op,
         }
         temp_mask_priv =
             glamor_get_pixmap_private((PixmapPtr) (temp_mask->pDrawable));
-        x_temp_mask = -extent->x1 + x_dest;
-        y_temp_mask = -extent->y1 + y_dest;
+        x_temp_mask = 0;
+        y_temp_mask = 0;
     }
     /* Do two-pass PictOpOver componentAlpha, until we enable
      * dual source color blending.
commit 5062b4fadd977d044e54b53b7f3e02e466eac9a9
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Mar 16 20:44:48 2014 -0700

    glamor: Add glamor_transfer based glamor_get_image and glamor_put_image
    
    These use the upload_boxes and download_boxes helpers to provide
    reasonably efficient image transfer.
    
    Fixes segfaults in Xephyr with x11perf -reps 1.
    
    Performance improvements:
    
    Improves -putimage10 by 548.218% +/- 88.601% (n=10).
    Improves -putimage500 by 3.71014% +/- 1.5049% (n=10).
    Improves -getimage10 by 8.37004% +/- 4.58274% (n=10).
    No statistically significant difference on -getimage500 (n=10).
    
    v2: Fix rebase failures, don't forget to check/prepare the gc in
        putimage fallbacks (changes by anholt).
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index b7069e0..bde58b6 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -17,8 +17,8 @@ libglamor_la_SOURCES = \
 	glamor_glx.c \
 	glamor_glyphs.c \
 	glamor_polylines.c \
-	glamor_putimage.c \
 	glamor_segment.c \
+	glamor_image.c \
 	glamor_render.c \
 	glamor_gradient.c \
 	glamor_program.c \
@@ -34,7 +34,6 @@ libglamor_la_SOURCES = \
 	glamor_tile.c \
 	glamor_triangles.c\
 	glamor_addtraps.c\
-	glamor_getimage.c\
 	glamor_copyplane.c\
 	glamor_glyphblt.c\
 	glamor_points.c\
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 29f8874..994e923 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -507,7 +507,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
 #ifdef GLAMOR_TRAPEZOID_SHADER
     glamor_init_trapezoid_shader(screen);
 #endif
-    glamor_init_putimage_shaders(screen);
     glamor_init_finish_access_shaders(screen);
 #ifdef GLAMOR_GRADIENT_SHADER
     glamor_init_gradient_shader(screen);
@@ -541,7 +540,6 @@ glamor_release_screen_priv(ScreenPtr screen)
 #ifdef GLAMOR_TRAPEZOID_SHADER
     glamor_fini_trapezoid_shader(screen);
 #endif
-    glamor_fini_putimage_shaders(screen);
     glamor_fini_finish_access_shaders(screen);
 #ifdef GLAMOR_GRADIENT_SHADER
     glamor_fini_gradient_shader(screen);
diff --git a/glamor/glamor_getimage.c b/glamor/glamor_getimage.c
deleted file mode 100644
index a932473..0000000
--- a/glamor/glamor_getimage.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- * Copyright © 1998 Keith Packard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Zhigang Gong <zhigang.gong at gmail.com>
- *
- */
-
-#include "glamor_priv.h"
-
-static Bool
-_glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
-                  unsigned int format, unsigned long planeMask, char *d,
-                  Bool fallback)
-{
-    PixmapPtr pixmap, sub_pixmap;
-    struct glamor_pixmap_private *pixmap_priv;
-    int x_off, y_off;
-    int stride;
-    void *data;
-
-    pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-
-    if (format != ZPixmap)
-        goto fall_back;
-
-    if (!glamor_set_planemask(pixmap, planeMask)) {
-        glamor_fallback("Failedto set planemask  in glamor_solid.\n");
-        goto fall_back;
-    }
-    pixmap_priv = glamor_get_pixmap_private(pixmap);
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
-        goto fall_back;
-    stride = PixmapBytePad(w, drawable->depth);
-
-    x += drawable->x + x_off;
-    y += drawable->y + y_off;
-
-    data = glamor_download_sub_pixmap_to_cpu(pixmap, x, y, w, h, stride,
-                                             d, 0, GLAMOR_ACCESS_RO);
-    if (data != NULL) {
-        assert(data == d);
-        return TRUE;
-    }
- fall_back:
-    sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
-                                       y + y_off + drawable->y, w, h,
-                                       GLAMOR_ACCESS_RO);
-    if (sub_pixmap) {
-        fbGetImage(&sub_pixmap->drawable, 0, 0, w, h, format, planeMask, d);
-        glamor_put_sub_pixmap(sub_pixmap, pixmap,
-                              x + x_off + drawable->x,
-                              y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RO);
-    }
-    else
-        miGetImage(drawable, x, y, w, h, format, planeMask, d);
-
-    return TRUE;
-}
-
-void
-glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
-                 unsigned int format, unsigned long planeMask, char *d)
-{
-    _glamor_get_image(pDrawable, x, y, w, h, format, planeMask, d, TRUE);
-}
-
-Bool
-glamor_get_image_nf(DrawablePtr pDrawable, int x, int y, int w, int h,
-                    unsigned int format, unsigned long planeMask, char *d)
-{
-    return _glamor_get_image(pDrawable, x, y, w,
-                             h, format, planeMask, d, FALSE);
-}
diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c
new file mode 100644
index 0000000..4791d08
--- /dev/null
+++ b/glamor/glamor_image.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright © 2014 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "glamor_priv.h"
+#include "glamor_transfer.h"
+#include "glamor_transform.h"
+
+/*
+ * PutImage. Only does ZPixmap right now as other formats are quite a bit harder
+ */
+
+static Bool
+glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+                    int w, int h, int leftPad, int format, char *bits)
+{
+    ScreenPtr screen = drawable->pScreen;
+    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv;
+    uint32_t    byte_stride = PixmapBytePad(w, drawable->depth);
+    RegionRec   region;
+    BoxRec      box;
+    int         off_x, off_y;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        return FALSE;
+
+    if (gc->alu != GXcopy)
+        goto bail;
+
+    if (!glamor_pm_is_solid(&pixmap->drawable, gc->planemask))
+        goto bail;
+
+    if (format == XYPixmap && drawable->depth == 1 && leftPad == 0)
+        format = ZPixmap;
+
+    if (format != ZPixmap)
+        goto bail;
+
+    x += drawable->x;
+    y += drawable->y;
+    box.x1 = x;
+    box.y1 = y;
+    box.x2 = box.x1 + w;
+    box.y2 = box.y1 + h;
+    RegionInit(&region, &box, 1);
+    RegionIntersect(&region, &region, gc->pCompositeClip);
+
+    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+    if (off_x || off_y) {
+        x += off_x;
+        y += off_y;
+        RegionTranslate(&region, off_x, off_y);
+    }
+
+    glamor_make_current(glamor_priv);
+
+    glamor_upload_region(pixmap, &region, x, y, (uint8_t *) bits, byte_stride);
+
+    RegionUninit(&region);
+    return TRUE;
+bail:
+    return FALSE;
+}
+
+static void
+glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+                      int w, int h, int leftPad, int format, char *bits)
+{
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
+        glamor_prepare_access_gc(gc))
+        fbPutImage(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
+    glamor_finish_access(drawable);
+}
+
+void
+glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+                 int w, int h, int leftPad, int format, char *bits)
+{
+    if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits))
+        return;
+    glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
+}
+
+Bool
+glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+                    int w, int h, int leftPad, int format, char *bits)
+{
+    if (glamor_put_image_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits))
+        return TRUE;
+    if (glamor_ddx_fallback_check_pixmap(drawable) &&
+        glamor_ddx_fallback_check_gc(gc))
+        return FALSE;
+    glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits);
+    return TRUE;
+}
+
+static Bool
+glamor_get_image_gl(DrawablePtr drawable, int x, int y, int w, int h,
+                    unsigned int format, unsigned long plane_mask, char *d)
+{
+    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
+    glamor_pixmap_private *pixmap_priv;
+    uint32_t    byte_stride = PixmapBytePad(w, drawable->depth);
+    BoxRec      box;
+    int         off_x, off_y;
+
+    pixmap_priv = glamor_get_pixmap_private(pixmap);
+    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
+        goto bail;
+
+    if (format != ZPixmap || !glamor_pm_is_solid(drawable, plane_mask))
+        goto bail;
+
+    glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
+    box.x1 = x;
+    box.x2 = x + w;
+    box.y1 = y;
+    box.y2 = y + h;
+    glamor_download_boxes(pixmap, &box, 1,
+                          drawable->x + off_x, drawable->y + off_y,
+                          -x, -y,
+                          (uint8_t *) d, byte_stride);
+    return TRUE;
+bail:
+    return FALSE;
+}
+
+static void
+glamor_get_image_bail(DrawablePtr drawable, int x, int y, int w, int h,
+                      unsigned int format, unsigned long plane_mask, char *d)
+{
+    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RO))
+        fbGetImage(drawable, x, y, w, h, format, plane_mask, d);
+    glamor_finish_access(drawable);
+}
+
+void
+glamor_get_image(DrawablePtr drawable, int x, int y, int w, int h,
+                 unsigned int format, unsigned long plane_mask, char *d)
+{
+    if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d))
+        return;
+    glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
+}
+
+Bool
+glamor_get_image_nf(DrawablePtr drawable, int x, int y, int w, int h,
+                    unsigned int format, unsigned long plane_mask, char *d)
+{
+    if (glamor_get_image_gl(drawable, x, y, w, h, format, plane_mask, d))
+        return TRUE;
+
+    if (glamor_ddx_fallback_check_pixmap(drawable))
+        return FALSE;
+
+    glamor_get_image_bail(drawable, x, y, w, h, format, plane_mask, d);
+    return TRUE;
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 0cafac4..a2a21fc 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -277,11 +277,6 @@ typedef struct glamor_screen_private {
     /* glamor trapezoid shader. */
     GLint trapezoid_prog;
 
-    /* glamor_putimage */
-    GLint put_image_xybitmap_prog;
-    GLint put_image_xybitmap_fg_uniform_location;
-    GLint put_image_xybitmap_bg_uniform_location;
-
     PixmapPtr *back_pixmap;
     int screen_fbo;
     struct glamor_saved_procs saved_procs;
@@ -704,12 +699,6 @@ void glamor_glyphs(CARD8 op,
 void glamor_poly_lines(DrawablePtr drawable, GCPtr gc, int mode, int n,
                        DDXPointPtr points);
 
-/* glamor_putimage.c */
-void glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-                      int w, int h, int leftPad, int format, char *bits);
-void glamor_init_putimage_shaders(ScreenPtr screen);
-void glamor_fini_putimage_shaders(ScreenPtr screen);
-
 /* glamor_render.c */
 Bool glamor_composite_clipped_region(CARD8 op,
                                      PicturePtr source,
@@ -951,9 +940,6 @@ Bool glamor_fixup_pixmap_priv(ScreenPtr screen,
 void glamor_picture_format_fixup(PicturePtr picture,
                                  glamor_pixmap_private *pixmap_priv);
 
-void glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
-                      unsigned int format, unsigned long planeMask, char *d);
-
 void glamor_add_traps(PicturePtr pPicture,
                       INT16 x_off, INT16 y_off, int ntrap, xTrap *traps);
 
@@ -994,6 +980,15 @@ void
 glamor_poly_fill_rect(DrawablePtr drawable,
                       GCPtr gc, int nrect, xRectangle *prect);
 
+/* glamor_image.c */
+void
+glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
+                 int w, int h, int leftPad, int format, char *bits);
+
+void
+glamor_get_image(DrawablePtr pDrawable, int x, int y, int w, int h,
+                 unsigned int format, unsigned long planeMask, char *d);
+
 /* glamor_glyphblt.c */
 void glamor_image_glyph_blt(DrawablePtr pDrawable, GCPtr pGC,
                             int x, int y, unsigned int nglyph,
diff --git a/glamor/glamor_putimage.c b/glamor/glamor_putimage.c
deleted file mode 100644
index cf7197b..0000000
--- a/glamor/glamor_putimage.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright © 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Eric Anholt <eric at anholt.net>
- *    Zhigang Gong <zhigang.gong at linux.intel.com>
- *
- */
-
-/** @file glamor_putaimge.c
- *
- * XPutImage implementation
- */
-#include "glamor_priv.h"
-
-void
-glamor_init_putimage_shaders(ScreenPtr screen)
-{
-}
-
-void
-glamor_fini_putimage_shaders(ScreenPtr screen)
-{
-}
-
-static Bool
-_glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-                  int w, int h, int left_pad, int image_format, char *bits,
-                  Bool fallback)
-{
-    PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
-    glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
-    RegionPtr clip;
-    int x_off, y_off;
-    Bool ret = FALSE;
-    PixmapPtr temp_pixmap, sub_pixmap;
-    glamor_pixmap_private *temp_pixmap_priv;
-    BoxRec box;
-
-    glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
-    clip = fbGetCompositeClip(gc);
-    if (image_format == XYBitmap) {
-        assert(depth == 1);
-        goto fail;
-    }
-
-    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
-        glamor_fallback("has no fbo.\n");
-        goto fail;
-    }
-
-    if (image_format != ZPixmap) {
-        glamor_fallback("non-ZPixmap\n");
-        goto fail;
-    }
-
-    if (!glamor_set_planemask(pixmap, gc->planemask)) {
-        goto fail;
-    }
-    /* create a temporary pixmap and upload the bits to that
-     * pixmap, then apply clip copy it to the destination pixmap.*/
-    box.x1 = x + drawable->x;
-    box.y1 = y + drawable->y;
-    box.x2 = x + w + drawable->x;
-    box.y2 = y + h + drawable->y;
-
-    if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN)
-        || gc->alu != GXcopy) {
-        temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
-        if (temp_pixmap == NULL)
-            goto fail;
-
-        temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);
-
-        if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
-            temp_pixmap_priv->base.picture = pixmap_priv->base.picture;
-            temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
-        }
-
-        glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
-                                            pixmap->devKind, bits, 0);
-
-        glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x,
-                         y);
-        glamor_destroy_pixmap(temp_pixmap);
-    }
-    else
-        glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off,
-                                            y + drawable->y + y_off, w, h,
-                                            PixmapBytePad(w, depth), bits, 0);
-    ret = TRUE;
-    goto done;
-
- fail:
-    glamor_set_planemask(pixmap, ~0);
-
-    if (!fallback && glamor_ddx_fallback_check_pixmap(&pixmap->drawable))
-        goto done;
-
-    glamor_fallback("to %p (%c)\n",
-                    drawable, glamor_get_drawable_location(drawable));
-
-    sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
-                                       y + y_off + drawable->y, w, h,
-                                       GLAMOR_ACCESS_RW);
-    if (sub_pixmap) {
-        if (clip != NULL)
-            pixman_region_translate(clip, -x - drawable->x, -y - drawable->y);
-
-        fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h,
-                   left_pad, image_format, bits);
-
-        glamor_put_sub_pixmap(sub_pixmap, pixmap,
-                              x + x_off + drawable->x,
-                              y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RW);
-        if (clip != NULL)
-            pixman_region_translate(clip, x + drawable->x, y + drawable->y);
-    }
-    else
-        fbPutImage(drawable, gc, depth, x, y, w, h,
-                   left_pad, image_format, bits);
-    ret = TRUE;
-
- done:
-    return ret;
-}
-
-void
-glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-                 int w, int h, int left_pad, int image_format, char *bits)
-{
-    _glamor_put_image(drawable, gc, depth, x, y, w, h,
-                      left_pad, image_format, bits, TRUE);
-}
-
-Bool
-glamor_put_image_nf(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
-                    int w, int h, int left_pad, int image_format, char *bits)
-{
-    return _glamor_put_image(drawable, gc, depth, x, y, w, h,
-                             left_pad, image_format, bits, FALSE);
-}
commit 747160016ba2d0cd42ad6b174cbf927d67c01875
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Apr 22 16:33:45 2014 -0700

    glamor: Wire alpha to 1 for pictures without alpha bits
    
    When sourcing a picture that has no alpha values, make sure any
    texture fetches wire the alpha value to one. This ensures that bits
    beyond the depth of the pixmap, or bits other than the RGB values
    aren't used.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 294a4ae..14ab738 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -870,7 +870,10 @@ glamor_composite_choose_shader(CARD8 op,
             goto fail;
     }
     else {
-        key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+        if (PICT_FORMAT_A(source->format))
+            key.source = SHADER_SOURCE_TEXTURE_ALPHA;
+        else
+            key.source = SHADER_SOURCE_TEXTURE;
     }
 
     if (mask) {
commit a69907288d59792fd783f2f1756cde03d4a06f97
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Mon Apr 21 17:47:15 2014 +0900

    glx: If DRI2GetBuffers changes the GL context, call it again
    
    By changing the context, it may also invalidate the DRI2 buffer
    information, so we need to get that again.
    
    Fixes crashes due to use-after-free with LIBGL_ALWAYS_INDIRECT=1
    glxgears and piglit.
    
    Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 7b368d2..c756bf5 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -676,6 +676,13 @@ dri2GetBuffers(__DRIdrawable * driDrawable,
     if (cx != lastGLContext) {
         lastGLContext = cx;
         cx->makeCurrent(cx);
+
+        /* If DRI2GetBuffers() changed the GL context, it may also have
+         * invalidated the DRI2 buffers, so let's get them again
+         */
+        buffers = DRI2GetBuffers(private->base.pDraw,
+                                 width, height, attachments, count, out_count);
+        assert(lastGLContext == cx);
     }
 
     if (*out_count > MAX_DRAWABLE_BUFFERS) {
@@ -727,6 +734,14 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
     if (cx != lastGLContext) {
         lastGLContext = cx;
         cx->makeCurrent(cx);
+
+        /* If DRI2GetBuffersWithFormat() changed the GL context, it may also have
+         * invalidated the DRI2 buffers, so let's get them again
+         */
+        buffers = DRI2GetBuffersWithFormat(private->base.pDraw,
+                                           width, height, attachments, count,
+                                           out_count);
+        assert(lastGLContext == cx);
     }
 
     if (*out_count > MAX_DRAWABLE_BUFFERS) {
commit f6abfece3e59fa8c2e14a61430133816837855f8
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Apr 17 18:50:13 2014 -0700

    glamor: Move a make_current before the first GL call entrypoint.
    
    Fixes a usage of the wrong context with swrast GLX's GetImage entrypoint.
    
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index 371e486..54b414b 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -1217,6 +1217,7 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
         assert(0);
     }
 
+    glamor_make_current(glamor_priv);
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
     need_post_conversion = (revert > REVERT_NORMAL);
@@ -1249,7 +1250,6 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
         fbo_y_off = 0;
     }
 
-    glamor_make_current(glamor_priv);
     glPixelStorei(GL_PACK_ALIGNMENT, 4);
 
     if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
commit 707726b155a2a086d12e0a6abef7f1e59def5370
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Apr 4 07:03:46 2014 +0100

    glamor: Do the same MakeCurrent(None) for GLX as we do for EGL.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_glx.c b/glamor/glamor_glx.c
index db8e661..7107c7c 100644
--- a/glamor/glamor_glx.c
+++ b/glamor/glamor_glx.c
@@ -36,6 +36,14 @@
 static void
 glamor_glx_make_current(struct glamor_context *glamor_ctx)
 {
+    /* There's only a single global dispatch table in Mesa.  EGL, GLX,
+     * and AIGLX's direct dispatch table manipulation don't talk to
+     * each other.  We need to set the context to NULL first to avoid
+     * GLX's no-op context change fast path when switching back to
+     * GLX.
+     */
+    glXMakeCurrent(glamor_ctx->display, None, None);
+
     glXMakeCurrent(glamor_ctx->display, glamor_ctx->drawable_xid,
                    glamor_ctx->ctx);
 }
commit 482b06a95a0a2c9a58bc196eb3dd928d796853df
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Apr 4 07:03:31 2014 +0100

    glamor: Explain the weird EGL_NO_CONTEXT code.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 1755d23..54af275 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -97,8 +97,15 @@ glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 static void
 glamor_egl_make_current(struct glamor_context *glamor_ctx)
 {
+    /* There's only a single global dispatch table in Mesa.  EGL, GLX,
+     * and AIGLX's direct dispatch table manipulation don't talk to
+     * each other.  We need to set the context to NULL first to avoid
+     * EGL's no-op context change fast path when switching back to
+     * EGL.
+     */
     eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
                    EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
     if (!eglMakeCurrent(glamor_ctx->display,
                         EGL_NO_SURFACE, EGL_NO_SURFACE,
                         glamor_ctx->ctx)) {
commit fab0a4a4c9dad2275bb398d09632f4274b5e16f2
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Mar 14 17:31:18 2014 -0700

    glamor: Replace glamor_get/put_context() with just glamor_make_current().
    
    Now that we have the DIX global state for the current context, we
    don't need to track nesting to try to reduce MakeCurrent overhead.
    
    v2: Fix a mistaken replacement of a put_context with make_current in
        glamor_fill_spans_gl() (caught by keithp).
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com> (v1)
    Reviewed-by: Adam Jackson <ajax at redhat.com> (v1)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index 2c2d976..29f8874 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -248,11 +248,10 @@ glamor_block_handler(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glamor_priv->tick++;
     glFlush();
     glamor_fbo_expire(glamor_priv);
-    glamor_put_context(glamor_priv);
     if (glamor_priv->state == RENDER_STATE
         && glamor_priv->render_idle_cnt++ > RENDER_IDEL_MAX) {
         glamor_priv->state = IDLE_STATE;
@@ -265,9 +264,8 @@ _glamor_block_handler(void *data, OSTimePtr timeout, void *last_select_mask)
 {
     glamor_screen_private *glamor_priv = data;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glFlush();
-    glamor_put_context(glamor_priv);
 }
 
 static void
diff --git a/glamor/glamor_context.h b/glamor/glamor_context.h
index 8781afc..47b87e6 100644
--- a/glamor/glamor_context.h
+++ b/glamor/glamor_context.h
@@ -43,14 +43,7 @@ struct glamor_context {
     /** The GLXDrawable we should MakeCurrent to */
     uint32_t drawable_xid;
 
-    /**
-     * Count of how deep in glamor_get_context() we are, to reduce
-     * MakeCurrent calls.
-     */
-    int get_count;
-
-    void (*get_context)(struct glamor_context *glamor_ctx);
-    void (*put_context)(struct glamor_context *glamor_ctx);
+    void (*make_current)(struct glamor_context *glamor_ctx);
 };
 
 Bool glamor_glx_screen_init(struct glamor_context *glamor_ctx);
diff --git a/glamor/glamor_copyarea.c b/glamor/glamor_copyarea.c
index 996611c..6e90e36 100644
--- a/glamor/glamor_copyarea.c
+++ b/glamor/glamor_copyarea.c
@@ -70,7 +70,7 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
     pixmap_priv_get_fbo_off(dst_pixmap_priv, &fbo_x_off, &fbo_y_off);
     pixmap_priv_get_fbo_off(src_pixmap_priv, &src_fbo_x_off, &src_fbo_y_off);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, src_pixmap_priv->base.fbo->fb);
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
     glamor_get_drawable_deltas(src, src_pixmap, &src_x_off, &src_y_off);
@@ -112,7 +112,6 @@ glamor_copy_n_to_n_fbo_blit(DrawablePtr src,
                               GL_COLOR_BUFFER_BIT, GL_NEAREST);
         }
     }
-    glamor_put_context(glamor_priv);
     glamor_priv->state = BLIT_STATE;
     return TRUE;
 }
@@ -155,7 +154,7 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
 
     glamor_get_drawable_deltas(dst, dst_pixmap, &dst_x_off, &dst_y_off);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
@@ -206,7 +205,6 @@ glamor_copy_n_to_n_textured(DrawablePtr src,
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     /* The source texture is bound to a fbo, we have to flush it here. */
-    glamor_put_context(glamor_priv);
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
     return TRUE;
@@ -367,12 +365,10 @@ _glamor_copy_n_to_n(DrawablePtr src,
     if (gc) {
         if (!glamor_set_planemask(dst_pixmap, gc->planemask))
             goto fall_back;
-        glamor_get_context(glamor_priv);
+        glamor_make_current(glamor_priv);
         if (!glamor_set_alu(screen, gc->alu)) {
-            glamor_put_context(glamor_priv);
             goto fail;
         }
-        glamor_put_context(glamor_priv);
     }
 
     if (!src_pixmap_priv) {
@@ -545,9 +541,8 @@ _glamor_copy_n_to_n(DrawablePtr src,
     }
 
  fail:
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glamor_set_alu(screen, GXcopy);
-    glamor_put_context(glamor_priv);
 
     if (ok)
         return TRUE;
diff --git a/glamor/glamor_core.c b/glamor/glamor_core.c
index 5b341d3..b349437 100644
--- a/glamor/glamor_core.c
+++ b/glamor/glamor_core.c
@@ -241,7 +241,7 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     char *source;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glamor_priv->finish_access_prog[0] = glCreateProgram();
     glamor_priv->finish_access_prog[1] = glCreateProgram();
 
@@ -300,7 +300,6 @@ glamor_init_finish_access_shaders(ScreenPtr screen)
     glUniform1i(glamor_priv->finish_access_revert[1], 0);
     glUniform1i(sampler_uniform_location, 0);
     glUniform1i(glamor_priv->finish_access_swap_rb[1], 0);
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -309,10 +308,9 @@ glamor_fini_finish_access_shaders(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glDeleteProgram(glamor_priv->finish_access_prog[0]);
     glDeleteProgram(glamor_priv->finish_access_prog[1]);
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -341,11 +339,10 @@ glamor_finish_access(DrawablePtr drawable)
     if (pixmap_priv->base.fbo->pbo != 0 && pixmap_priv->base.fbo->pbo_valid) {
         assert(glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP);
 
-        glamor_get_context(glamor_priv);
+        glamor_make_current(glamor_priv);
         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
         glDeleteBuffers(1, &pixmap_priv->base.fbo->pbo);
-        glamor_put_context(glamor_priv);
 
         pixmap_priv->base.fbo->pbo_valid = FALSE;
         pixmap_priv->base.fbo->pbo = 0;
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index a16022b..1755d23 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -95,11 +95,8 @@ glamor_egl_get_screen_private(ScrnInfoPtr scrn)
 }
 
 static void
-glamor_egl_get_context(struct glamor_context *glamor_ctx)
+glamor_egl_make_current(struct glamor_context *glamor_ctx)
 {
-    if (glamor_ctx->get_count++)
-        return;
-
     eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
                    EGL_NO_SURFACE, EGL_NO_CONTEXT);
     if (!eglMakeCurrent(glamor_ctx->display,
@@ -109,12 +106,6 @@ glamor_egl_get_context(struct glamor_context *glamor_ctx)
     }
 }
 
-static void
-glamor_egl_put_context(struct glamor_context *glamor_ctx)
-{
-    --glamor_ctx->get_count;
-}
-
 static EGLImageKHR
 _glamor_egl_create_image(struct glamor_egl_screen_private *glamor_egl,
                          int width, int height, int stride, int name, int depth)
@@ -166,7 +157,7 @@ glamor_create_texture_from_image(ScreenPtr screen,
     struct glamor_screen_private *glamor_priv =
         glamor_get_screen_private(screen);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glGenTextures(1, texture);
     glBindTexture(GL_TEXTURE_2D, *texture);
@@ -176,8 +167,6 @@ glamor_create_texture_from_image(ScreenPtr screen,
     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
     glBindTexture(GL_TEXTURE_2D, 0);
 
-    glamor_put_context(glamor_priv);
-
     return TRUE;
 }
 
@@ -290,7 +279,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     if (glamor_egl->has_gem) {
         if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
             xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -320,7 +309,6 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
     ret = TRUE;
 
  done:
-    glamor_put_context(glamor_priv);
     return ret;
 }
 
@@ -340,7 +328,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     image = eglCreateImageKHR(glamor_egl->display,
                               glamor_egl->context,
@@ -356,7 +344,6 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
     ret = TRUE;
 
  done:
-    glamor_put_context(glamor_priv);
     return ret;
 }
 
@@ -414,7 +401,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 
     glamor_egl = glamor_egl_get_screen_private(scrn);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     image = pixmap_priv->base.image;
     if (!image) {
@@ -449,7 +436,6 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
 
     gbm_bo_destroy(bo);
  failure:
-    glamor_put_context(glamor_priv);
     return fd;
 #else
     return -1;
@@ -679,8 +665,7 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
     glamor_ctx->ctx = glamor_egl->context;
     glamor_ctx->display = glamor_egl->display;
 
-    glamor_ctx->get_context = glamor_egl_get_context;
-    glamor_ctx->put_context = glamor_egl_put_context;
+    glamor_ctx->make_current = glamor_egl_make_current;
 
     if (glamor_egl->dri3_capable) {
         /* Tell the core that we have the interfaces for import/export
diff --git a/glamor/glamor_fbo.c b/glamor/glamor_fbo.c
index d0215be..ed4e348 100644
--- a/glamor/glamor_fbo.c
+++ b/glamor/glamor_fbo.c
@@ -129,7 +129,7 @@ glamor_pixmap_fbo_cache_get(glamor_screen_private *glamor_priv,
 void
 glamor_purge_fbo(glamor_pixmap_fbo *fbo)
 {
-    glamor_get_context(fbo->glamor_priv);
+    glamor_make_current(fbo->glamor_priv);
 
     if (fbo->fb)
         glDeleteFramebuffers(1, &fbo->fb);
@@ -137,7 +137,6 @@ glamor_purge_fbo(glamor_pixmap_fbo *fbo)
         glDeleteTextures(1, &fbo->tex);
     if (fbo->pbo)
         glDeleteBuffers(1, &fbo->pbo);
-    glamor_put_context(fbo->glamor_priv);
 
     free(fbo);
 }
@@ -180,7 +179,7 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
 {
     int status;
 
-    glamor_get_context(fbo->glamor_priv);
+    glamor_make_current(fbo->glamor_priv);
 
     if (fbo->fb == 0)
         glGenFramebuffers(1, &fbo->fb);
@@ -219,7 +218,6 @@ glamor_pixmap_ensure_fb(glamor_pixmap_fbo *fbo)
         FatalError("destination is framebuffer incomplete: %s [%x]\n",
                    str, status);
     }
-    glamor_put_context(fbo->glamor_priv);
 }
 
 glamor_pixmap_fbo *
@@ -241,9 +239,8 @@ glamor_create_fbo_from_tex(glamor_screen_private *glamor_priv,
     fbo->glamor_priv = glamor_priv;
 
     if (flag == GLAMOR_CREATE_PIXMAP_MAP) {
-        glamor_get_context(glamor_priv);
+        glamor_make_current(glamor_priv);
         glGenBuffers(1, &fbo->pbo);
-        glamor_put_context(glamor_priv);
         goto done;
     }
 
@@ -341,14 +338,13 @@ _glamor_create_tex(glamor_screen_private *glamor_priv,
                                                        w, h);
     }
     if (!tex) {
-        glamor_get_context(glamor_priv);
+        glamor_make_current(glamor_priv);
         glGenTextures(1, &tex);
         glBindTexture(GL_TEXTURE_2D, tex);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
                      format, GL_UNSIGNED_BYTE, NULL);
-        glamor_put_context(glamor_priv);
     }
     return tex;
 }
diff --git a/glamor/glamor_fill.c b/glamor/glamor_fill.c
index 2fa726e..073904d 100644
--- a/glamor/glamor_fill.c
+++ b/glamor/glamor_fill.c
@@ -156,7 +156,7 @@ glamor_init_solid_shader(ScreenPtr screen)
     GLint fs_prog, vs_prog;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glamor_priv->solid_prog = glCreateProgram();
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, solid_vs);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, solid_fs);
@@ -169,7 +169,6 @@ glamor_init_solid_shader(ScreenPtr screen)
 
     glamor_priv->solid_color_uniform_location =
         glGetUniformLocation(glamor_priv->solid_prog, "color");
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -178,9 +177,8 @@ glamor_fini_solid_shader(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glDeleteProgram(glamor_priv->solid_prog);
-    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -196,7 +194,7 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glUseProgram(glamor_priv->solid_prog);
 
     glUniform4fv(glamor_priv->solid_color_uniform_location, 1, color);
@@ -255,7 +253,6 @@ _glamor_solid_boxes(PixmapPtr pixmap, BoxPtr box, int nbox, float *color)
         free(vertices);
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glamor_put_context(glamor_priv);
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
 }
@@ -338,13 +335,12 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
         return FALSE;
     }
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     if (!glamor_set_alu(screen, alu)) {
         if (alu == GXclear)
             fg_pixel = 0;
         else {
             glamor_fallback("unsupported alu %x\n", alu);
-            glamor_put_context(glamor_priv);
             return FALSE;
         }
     }
@@ -355,7 +351,6 @@ glamor_solid(PixmapPtr pixmap, int x, int y, int width, int height,
     glamor_solid_boxes(pixmap, &box, 1, fg_pixel);
 
     glamor_set_alu(screen, GXcopy);
-    glamor_put_context(glamor_priv);
 
     return TRUE;
 }
diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index 47dfe2a..f747d59 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -89,7 +89,7 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     glamor_font->default_col = font->info.defaultCh;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glGenTextures(1, &glamor_font->texture_id);
     glActiveTexture(GL_TEXTURE0);
@@ -119,8 +119,6 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
         }
     }
 
-    glamor_put_context(glamor_priv);
-
     return glamor_font;
 }
 
@@ -150,9 +148,8 @@ glamor_unrealize_font(ScreenPtr screen, FontPtr font)
     glamor_font->realized = FALSE;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glDeleteTextures(1, &glamor_font->texture_id);
-    glamor_put_context(glamor_priv);
 
     /* Check to see if all of the screens are  done with this font
      * and free the private when that happens
diff --git a/glamor/glamor_glx.c b/glamor/glamor_glx.c
index d56581c..db8e661 100644
--- a/glamor/glamor_glx.c
+++ b/glamor/glamor_glx.c
@@ -34,22 +34,13 @@
  */
 
 static void
-glamor_glx_get_context(struct glamor_context *glamor_ctx)
+glamor_glx_make_current(struct glamor_context *glamor_ctx)
 {
-    if (glamor_ctx->get_count++)
-        return;
-
     glXMakeCurrent(glamor_ctx->display, glamor_ctx->drawable_xid,
                    glamor_ctx->ctx);
 }
 
 
-static void
-glamor_glx_put_context(struct glamor_context *glamor_ctx)
-{
-    --glamor_ctx->get_count;
-}
-
 Bool
 glamor_glx_screen_init(struct glamor_context *glamor_ctx)
 {
@@ -63,8 +54,7 @@ glamor_glx_screen_init(struct glamor_context *glamor_ctx)
 
     glamor_ctx->drawable_xid = glXGetCurrentDrawable();
 
-    glamor_ctx->get_context = glamor_glx_get_context;
-    glamor_ctx->put_context = glamor_glx_put_context;
+    glamor_ctx->make_current = glamor_glx_make_current;
 
     return True;
 }
diff --git a/glamor/glamor_glyphblt.c b/glamor/glamor_glyphblt.c
index c031747..1c511ff 100644
--- a/glamor/glamor_glyphblt.c
+++ b/glamor/glamor_glyphblt.c
@@ -54,7 +54,7 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         goto bail;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_glyph_blt_progs,
                                    &glamor_facet_poly_glyph_blt);
@@ -137,11 +137,9 @@ glamor_poly_glyph_blt_gl(DrawablePtr drawable, GCPtr gc,
     glDisable(GL_COLOR_LOGIC_OP);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-    glamor_put_context(glamor_priv);
     return TRUE;
 bail_ctx:
     glDisable(GL_COLOR_LOGIC_OP);
-    glamor_put_context(glamor_priv);
 bail:
     return FALSE;
 }
@@ -212,20 +210,18 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         return FALSE;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     if (!glamor_set_alu(screen, gc->alu)) {
         if (gc->alu == GXclear)
             fg_pixel = 0;
         else {
             glamor_fallback("unsupported alu %x\n", gc->alu);
-            glamor_put_context(glamor_priv);
             return FALSE;
         }
     }
 
     if (!glamor_set_planemask(pixmap, gc->planemask)) {
         glamor_fallback("Failed to set planemask in %s.\n", __FUNCTION__);
-        glamor_put_context(glamor_priv);
         return FALSE;
     }
 
@@ -281,8 +277,6 @@ glamor_push_pixels_points(GCPtr gc, PixmapPtr bitmap,
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-    glamor_put_context(glamor_priv);
-
     return TRUE;
 }
 
diff --git a/glamor/glamor_glyphs.c b/glamor/glamor_glyphs.c
index a04ae82..42f5f65 100644
--- a/glamor/glamor_glyphs.c
+++ b/glamor/glamor_glyphs.c
@@ -1285,9 +1285,8 @@ glamor_buffer_glyph(glamor_screen_private *glamor_priv,
                  * thus we have to composite from the cache picture
                  * to the cache picture, we need a flush here to make
                  * sure latter we get the corret glyphs data.*/
-                glamor_get_context(glamor_priv);
+                glamor_make_current(glamor_priv);
                 glFlush();
-                glamor_put_context(glamor_priv);
             }
         }
         else {
diff --git a/glamor/glamor_gradient.c b/glamor/glamor_gradient.c
index c24f342..28d6691 100644
--- a/glamor/glamor_gradient.c
+++ b/glamor/glamor_gradient.c
@@ -324,7 +324,7 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
         return;
     }
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
         glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]);
@@ -371,8 +371,6 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count,
     }
 
     glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
-
-    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -519,7 +517,7 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
         return;
     }
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
         glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]);
         glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
@@ -562,8 +560,6 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count,
     }
 
     glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
-
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -595,7 +591,7 @@ glamor_fini_gradient_shader(ScreenPtr screen)
     int i = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     for (i = 0; i < 3; i++) {
         /* Linear Gradient */
@@ -607,8 +603,6 @@ glamor_fini_gradient_shader(ScreenPtr screen)
             glDeleteProgram(glamor_priv->gradient_prog
                             [SHADER_GRADIENT_RADIAL][i]);
     }
-
-    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -739,7 +733,7 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
            tex_vertices[0], tex_vertices[1], tex_vertices[2], tex_vertices[3],
            tex_vertices[4], tex_vertices[5], tex_vertices[6], tex_vertices[7]);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
                           GL_FALSE, 0, vertices);
@@ -749,8 +743,6 @@ _glamor_gradient_set_pixmap_destination(ScreenPtr screen,
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
     glEnableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    glamor_put_context(glamor_priv);
-
     return 1;
 }
 
@@ -892,7 +884,7 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     GLint r2_uniform_location = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     /* Create a pixmap with VBO. */
     pixmap = glamor_create_pixmap(screen,
@@ -1123,7 +1115,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    glamor_put_context(glamor_priv);
     return dst_picture;
 
  GRADIENT_FAIL:
@@ -1140,7 +1131,6 @@ glamor_generate_radial_gradient_picture(ScreenPtr screen,
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    glamor_put_context(glamor_priv);
     return NULL;
 }
 
@@ -1204,7 +1194,7 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     GLint pt_distance_uniform_location = 0;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     /* Create a pixmap with VBO. */
     pixmap = glamor_create_pixmap(screen,
@@ -1468,7 +1458,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    glamor_put_context(glamor_priv);
     return dst_picture;
 
  GRADIENT_FAIL:
@@ -1485,7 +1474,6 @@ glamor_generate_linear_gradient_picture(ScreenPtr screen,
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    glamor_put_context(glamor_priv);
     return NULL;
 }
 
diff --git a/glamor/glamor_pixmap.c b/glamor/glamor_pixmap.c
index a811f60..371e486 100644
--- a/glamor/glamor_pixmap.c
+++ b/glamor/glamor_pixmap.c
@@ -66,12 +66,10 @@ void
 glamor_set_destination_pixmap_fbo(glamor_pixmap_fbo *fbo, int x0, int y0,
                                   int width, int height)
 {
-    glamor_get_context(fbo->glamor_priv);
+    glamor_make_current(fbo->glamor_priv);
 
     glBindFramebuffer(GL_FRAMEBUFFER, fbo->fb);
     glViewport(x0, y0, width, height);
-
-    glamor_put_context(fbo->glamor_priv);
 }
 
 void
@@ -707,7 +705,7 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
     int non_sub = 0;
     unsigned int iformat = 0;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     if (*tex == 0) {
         glGenTextures(1, tex);
         if (glamor_priv->gl_flavor == GLAMOR_GL_DESKTOP)
@@ -735,7 +733,6 @@ __glamor_upload_pixmap_to_texture(PixmapPtr pixmap, unsigned int *tex,
 
     if (bits == NULL)
         glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
-    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -832,7 +829,7 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
                                  x + w, y + h,
                                  glamor_priv->yInverted, vertices);
     /* Slow path, we need to flip y or wire alpha to 1. */
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT,
                           GL_FALSE, 2 * sizeof(float), vertices);
     glEnableVertexAttribArray(GLAMOR_VERTEX_POS);
@@ -859,8 +856,6 @@ _glamor_upload_bits_to_pixmap_texture(PixmapPtr pixmap, GLenum format,
     glDeleteTextures(1, &tex);
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
-    glamor_put_context(glamor_priv);
-
     if (need_free_bits)
         free(bits);
     return TRUE;
@@ -1140,7 +1135,7 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
     if (temp_fbo == NULL)
         return NULL;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     temp_xscale = 1.0 / w;
     temp_yscale = 1.0 / h;
 
@@ -1177,7 +1172,6 @@ glamor_es2_pixmap_read_prepare(PixmapPtr source, int x, int y, int w, int h,
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
-    glamor_put_context(glamor_priv);
     return temp_fbo;
 }
 
@@ -1255,7 +1249,7 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
         fbo_y_off = 0;
     }
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glPixelStorei(GL_PACK_ALIGNMENT, 4);
 
     if (glamor_priv->has_pack_invert || glamor_priv->yInverted) {
@@ -1286,7 +1280,7 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
         unsigned int temp_pbo;
         int yy;
 
-        glamor_get_context(glamor_priv);
+        glamor_make_current(glamor_priv);
         glGenBuffers(1, &temp_pbo);
         glBindBuffer(GL_PIXEL_PACK_BUFFER, temp_pbo);
         glBufferData(GL_PIXEL_PACK_BUFFER, stride * h, NULL, GL_STREAM_READ);
@@ -1301,7 +1295,6 @@ _glamor_download_sub_pixmap_to_cpu(PixmapPtr pixmap, GLenum format,
     }
 
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
-    glamor_put_context(glamor_priv);
 
     if (need_post_conversion) {
         /* As OpenGL desktop version never enters here.
@@ -1473,10 +1466,9 @@ glamor_download_pixmap_to_cpu(PixmapPtr pixmap, glamor_access_t access)
         data = malloc(stride * pixmap->drawable.height);
     }
     else {
-        glamor_get_context(glamor_priv);
+        glamor_make_current(glamor_priv);
         if (pixmap_priv->base.fbo->pbo == 0)
             glGenBuffers(1, &pixmap_priv->base.fbo->pbo);
-        glamor_put_context(glamor_priv);
         pbo = pixmap_priv->base.fbo->pbo;
     }
 
diff --git a/glamor/glamor_points.c b/glamor/glamor_points.c
index 0d58e55..d4525e2 100644
--- a/glamor/glamor_points.c
+++ b/glamor/glamor_points.c
@@ -52,7 +52,7 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         goto bail;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (prog->failed)
         goto bail_ctx;
@@ -105,8 +105,6 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
     glDisable(GL_COLOR_LOGIC_OP);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-    glamor_put_context(glamor_priv);
-
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
 
@@ -114,7 +112,6 @@ glamor_poly_point_gl(DrawablePtr drawable, GCPtr gc, int mode, int npt, DDXPoint
 
 bail_ctx:
     glDisable(GL_COLOR_LOGIC_OP);
-    glamor_put_context(glamor_priv);
 bail:
     return FALSE;
 }
diff --git a/glamor/glamor_rects.c b/glamor/glamor_rects.c
index 7731ede..3a5c3f3 100644
--- a/glamor/glamor_rects.c
+++ b/glamor/glamor_rects.c
@@ -57,7 +57,7 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         goto bail;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (glamor_priv->glsl_version >= 130) {
         prog = glamor_use_program_fill(pixmap, gc,
@@ -144,11 +144,9 @@ glamor_poly_fill_rect_gl(DrawablePtr drawable,
         glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-    glamor_put_context(glamor_priv);
     return TRUE;
 bail_ctx:
     glDisable(GL_COLOR_LOGIC_OP);
-    glamor_put_context(glamor_priv);
 bail:
     return FALSE;
 }
diff --git a/glamor/glamor_render.c b/glamor/glamor_render.c
index 2f3d950..294a4ae 100644
--- a/glamor/glamor_render.c
+++ b/glamor/glamor_render.c
@@ -316,13 +316,13 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
     GLint source_sampler_uniform_location, mask_sampler_uniform_location;
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     vs = glamor_create_composite_vs(key);
     if (vs == 0)
-        goto out;
+        return;
     fs = glamor_create_composite_fs(key);
     if (fs == 0)
-        goto out;
+        return;
 
     prog = glCreateProgram();
     glAttachShader(prog, vs);
@@ -363,9 +363,6 @@ glamor_create_composite_shader(ScreenPtr screen, struct shader_key *key,
                 glGetUniformLocation(prog, "mask_repeat_mode");
         }
     }
-
- out:
-    glamor_put_context(glamor_priv);
 }
 
 static glamor_composite_shader *
@@ -406,7 +403,7 @@ glamor_init_composite_shaders(ScreenPtr screen)
     int eb_size;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glGenBuffers(1, &glamor_priv->ebo);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glamor_priv->ebo);
 
@@ -416,8 +413,6 @@ glamor_init_composite_shaders(ScreenPtr screen)
     glamor_init_eb(eb, GLAMOR_COMPOSITE_VBO_VERT_CNT);
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, eb_size, eb, GL_STATIC_DRAW);
     free(eb);
-
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -428,7 +423,7 @@ glamor_fini_composite_shaders(ScreenPtr screen)
     int i, j, k;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
     glDeleteBuffers(1, &glamor_priv->ebo);
 
@@ -439,8 +434,6 @@ glamor_fini_composite_shaders(ScreenPtr screen)
                 if (shader->prog)
                     glDeleteProgram(shader->prog);
             }
-
-    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -496,7 +489,7 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
     float wh[4];
     int repeat_type;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glActiveTexture(GL_TEXTURE0 + unit);
     glBindTexture(GL_TEXTURE_2D, pixmap_priv->base.fbo->tex);
     repeat_type = picture->repeatType;
@@ -564,7 +557,6 @@ glamor_set_composite_texture(glamor_screen_private *glamor_priv, int unit,
             repeat_type -= RepeatFix;
     }
     glUniform1i(repeat_location, repeat_type);
-    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -685,7 +677,7 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
 
     vert_size = n_verts * glamor_priv->vb_stride;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     vb = glamor_get_vbo_space(screen, vert_size, &vbo_offset);
 
     glVertexAttribPointer(GLAMOR_VERTEX_POS, 2, GL_FLOAT, GL_FALSE,
@@ -707,7 +699,6 @@ glamor_setup_composite_vbo(ScreenPtr screen, int n_verts)
                                             4 : 2) * sizeof(float));
         glEnableVertexAttribArray(GLAMOR_VERTEX_MASK);
     }
-    glamor_put_context(glamor_priv);
 
     return vb;
 }
@@ -717,7 +708,7 @@ glamor_flush_composite_rects(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (!glamor_priv->render_nr_verts)
         return;
@@ -730,7 +721,6 @@ glamor_flush_composite_rects(ScreenPtr screen)
         glDrawElements(GL_TRIANGLES, (glamor_priv->render_nr_verts * 3) / 2,
                        GL_UNSIGNED_SHORT, NULL);
     }
-    glamor_put_context(glamor_priv);
 }
 
 int pict_format_combine_tab[][3] = {
@@ -1112,7 +1102,7 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
 
     glamor_priv = dest_priv->base.glamor_priv;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glUseProgram(shader->prog);
 
     if (key->source == SHADER_SOURCE_SOLID) {
@@ -1146,8 +1136,6 @@ glamor_composite_set_shader_blend(glamor_pixmap_private *dest_priv,
         glEnable(GL_BLEND);
         glBlendFunc(op_info->source_blend, op_info->dest_blend);
     }
-
-    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -1202,7 +1190,7 @@ glamor_composite_with_shader(CARD8 op,
     glamor_set_destination_pixmap_priv_nc(dest_pixmap_priv);
     glamor_composite_set_shader_blend(dest_pixmap_priv, &key, shader, &op_info);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glamor_priv->has_source_coords = key.source != SHADER_SOURCE_SOLID;
     glamor_priv->has_mask_coords = (key.mask != SHADER_MASK_NONE &&
@@ -1328,7 +1316,6 @@ glamor_composite_with_shader(CARD8 op,
     glamor_priv->render_idle_cnt = 0;
     if (saved_source_format)
         source->format = saved_source_format;
-    glamor_put_context(glamor_priv);
 
     ret = TRUE;
     return ret;
diff --git a/glamor/glamor_spans.c b/glamor/glamor_spans.c
index 98842cd..46ba6c3 100644
--- a/glamor/glamor_spans.c
+++ b/glamor/glamor_spans.c
@@ -61,7 +61,7 @@ glamor_fill_spans_gl(DrawablePtr drawable,
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         goto bail;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (glamor_priv->glsl_version >= 130) {
         prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->fill_spans_program,
@@ -152,11 +152,9 @@ glamor_fill_spans_gl(DrawablePtr drawable,
         glVertexAttribDivisor(GLAMOR_VERTEX_POS, 0);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
 
-    glamor_put_context(glamor_priv);
     return TRUE;
 bail_ctx:
     glDisable(GL_COLOR_LOGIC_OP);
-    glamor_put_context(glamor_priv);
 bail:
     return FALSE;
 }
@@ -222,7 +220,7 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
 
     glamor_format_for_pixmap(pixmap, &format, &type);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glamor_pixmap_loop(pixmap_priv, box_x, box_y) {
         BoxPtr                  box = glamor_pixmap_box_at(pixmap_priv, box_x, box_y);
@@ -261,7 +259,6 @@ glamor_get_spans_gl(DrawablePtr drawable, int wmax,
         }
     }
 
-    glamor_put_context(glamor_priv);
     return TRUE;
 bail:
     return FALSE;
@@ -327,7 +324,7 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
     glamor_get_drawable_deltas(drawable, pixmap, &off_x, &off_y);
     glamor_format_for_pixmap(pixmap, &format, &type);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -397,7 +394,6 @@ glamor_set_spans_gl(DrawablePtr drawable, GCPtr gc, char *src,
         }
     }
 
-    glamor_put_context(glamor_priv);
     return TRUE;
 
 bail:
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index 0e4b74c..395116d 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -267,7 +267,7 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
     if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv))
         goto bail;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     prog = glamor_use_program_fill(pixmap, gc, &glamor_priv->poly_text_progs, &glamor_facet_poly_text);
 
@@ -279,8 +279,6 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
 
     glDisable(GL_COLOR_LOGIC_OP);
 
-    glamor_put_context(glamor_priv);
-
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
 
@@ -289,7 +287,6 @@ glamor_poly_text(DrawablePtr drawable, GCPtr gc,
 
 bail_ctx:
     glDisable(GL_COLOR_LOGIC_OP);
-    glamor_put_context(glamor_priv);
 bail:
     return FALSE;
 }
@@ -420,7 +417,7 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
 
     glamor_get_glyphs(gc->font, glamor_font, count, chars, sixteen, charinfo);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (TERMINALFONT(gc->font))
         prog = &glamor_priv->te_text_prog;
@@ -482,8 +479,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
     (void) glamor_text(drawable, gc, glamor_font, prog,
                        x, y, count, chars, charinfo, sixteen);
 
-    glamor_put_context(glamor_priv);
-
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
 
@@ -491,7 +486,6 @@ glamor_image_text(DrawablePtr drawable, GCPtr gc,
 
 bail:
     glDisable(GL_COLOR_LOGIC_OP);
-    glamor_put_context(glamor_priv);
     return FALSE;
 }
 
diff --git a/glamor/glamor_tile.c b/glamor/glamor_tile.c
index 9e115ca..4e47976 100644
--- a/glamor/glamor_tile.c
+++ b/glamor/glamor_tile.c
@@ -62,7 +62,7 @@ glamor_init_tile_shader(ScreenPtr screen)
     GLint sampler_uniform_location;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glamor_priv->tile_prog = glCreateProgram();
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, tile_vs);
     fs_prog = glamor_compile_glsl_prog(GL_FRAGMENT_SHADER, tile_fs);
@@ -82,7 +82,6 @@ glamor_init_tile_shader(ScreenPtr screen)
 
     glamor_priv->tile_wh =
         glGetUniformLocation(glamor_priv->tile_prog, "wh");
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -91,9 +90,8 @@ glamor_fini_tile_shader(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glDeleteProgram(glamor_priv->tile_prog);
-    glamor_put_context(glamor_priv);
 }
 
 static void
@@ -123,7 +121,7 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
     glamor_set_destination_pixmap_priv_nc(dst_pixmap_priv);
     pixmap_priv_get_dest_scale(dst_pixmap_priv, &dst_xscale, &dst_yscale);
     pixmap_priv_get_scale(src_pixmap_priv, &src_xscale, &src_yscale);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glUseProgram(glamor_priv->tile_prog);
 
     glamor_pixmap_fbo_fix_wh_ratio(wh, src_pixmap_priv);
@@ -155,7 +153,6 @@ _glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
-    glamor_put_context(glamor_priv);
 
     glamor_priv->state = RENDER_STATE;
     glamor_priv->render_idle_cnt = 0;
@@ -193,10 +190,9 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
         goto fail;
     }
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     if (!glamor_set_alu(screen, alu)) {
         glamor_fallback("unsupported alu %x\n", alu);
-        glamor_put_context(glamor_priv);
         goto fail;
     }
 
@@ -290,7 +286,6 @@ glamor_tile(PixmapPtr pixmap, PixmapPtr tile,
         _glamor_tile(pixmap, tile, x, y, width, height, tile_x, tile_y);
 
     glamor_set_alu(screen, GXcopy);
-    glamor_put_context(glamor_priv);
     return TRUE;
  fail:
     return FALSE;
diff --git a/glamor/glamor_transfer.c b/glamor/glamor_transfer.c
index 0378bb0..ad875c9 100644
--- a/glamor/glamor_transfer.c
+++ b/glamor/glamor_transfer.c
@@ -70,7 +70,7 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
 
     glamor_format_for_pixmap(pixmap, &format, &type);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -127,7 +127,6 @@ glamor_upload_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
     glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
     glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
-    glamor_put_context(glamor_priv);
 }
 
 /*
@@ -180,7 +179,7 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
 
     glamor_format_for_pixmap(pixmap, &format, &type);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glPixelStorei(GL_PACK_ALIGNMENT, 4);
     glPixelStorei(GL_PACK_ROW_LENGTH, byte_stride / bytes_per_pixel);
@@ -226,7 +225,6 @@ glamor_download_boxes(PixmapPtr pixmap, BoxPtr in_boxes, int in_nbox,
     glPixelStorei(GL_PACK_ROW_LENGTH, 0);
     glPixelStorei(GL_PACK_SKIP_ROWS, 0);
     glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
-    glamor_put_context(glamor_priv);
 }
 
 /*
diff --git a/glamor/glamor_trapezoid.c b/glamor/glamor_trapezoid.c
index c76b8bb..4aba469 100644
--- a/glamor/glamor_trapezoid.c
+++ b/glamor/glamor_trapezoid.c
@@ -235,14 +235,13 @@ glamor_flush_composite_triangles(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glamor_put_vbo_space(screen);
 
     if (!glamor_priv->render_nr_verts)
         return;
 
     glDrawArrays(GL_TRIANGLES, 0, glamor_priv->render_nr_verts);
-    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -627,7 +626,7 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
 
     vert_size = n_verts * glamor_priv->vb_stride;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
@@ -667,8 +666,6 @@ glamor_setup_composite_vbo_for_trapezoid(ScreenPtr screen, int n_verts)
                           vbo_offset + stride * sizeof(float));
     glEnableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
 
-    glamor_put_context(glamor_priv);
-
     return vb;
 }
 
@@ -811,7 +808,7 @@ _glamor_trapezoids_with_shader(CARD8 op,
         goto TRAPEZOID_OUT;
     }
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     box = REGION_RECTS(&region);
     nbox = REGION_NUM_RECTS(&region);
@@ -979,7 +976,6 @@ _glamor_trapezoids_with_shader(CARD8 op,
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
     glDisableVertexAttribArray(GLAMOR_VERTEX_MASK);
     glDisable(GL_BLEND);
-    glamor_put_context(glamor_priv);
 
  TRAPEZOID_OUT:
     if (box) {
@@ -1332,7 +1328,7 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
         "}\n";
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glamor_priv->trapezoid_prog = glCreateProgram();
 
@@ -1354,8 +1350,6 @@ glamor_init_trapezoid_shader(ScreenPtr screen)
                          GLAMOR_VERTEX_RIGHT_PARAM, "v_right_param");
 
     glamor_link_glsl_prog(screen, glamor_priv->trapezoid_prog, "trapezoid");
-
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -1364,9 +1358,8 @@ glamor_fini_trapezoid_shader(ScreenPtr screen)
     glamor_screen_private *glamor_priv;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glDeleteProgram(glamor_priv->trapezoid_prog);
-    glamor_put_context(glamor_priv);
 }
 
 static Bool
@@ -1406,7 +1399,7 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
         return FALSE;
     }
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glamor_set_destination_pixmap_priv_nc(pixmap_priv);
 
@@ -1564,7 +1557,6 @@ _glamor_generate_trapezoid_with_shader(ScreenPtr screen, PicturePtr picture,
     glDisableVertexAttribArray(GLAMOR_VERTEX_TOP_BOTTOM);
     glDisableVertexAttribArray(GLAMOR_VERTEX_LEFT_PARAM);
     glDisableVertexAttribArray(GLAMOR_VERTEX_RIGHT_PARAM);
-    glamor_put_context(glamor_priv);
     return TRUE;
 }
 
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 56ef6a9..4c1581e 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1499,18 +1499,12 @@ __fls(unsigned long x)
 #endif
 
 static inline void
-glamor_get_context(glamor_screen_private * glamor_priv)
+glamor_make_current(glamor_screen_private *glamor_priv)
 {
     if (lastGLContext != &glamor_priv->ctx) {
         lastGLContext = &glamor_priv->ctx;
-        glamor_priv->ctx.get_context(&glamor_priv->ctx);
+        glamor_priv->ctx.make_current(&glamor_priv->ctx);
     }
 }
 
-static inline void
-glamor_put_context(glamor_screen_private * glamor_priv)
-{
-    glamor_priv->ctx.put_context(&glamor_priv->ctx);
-}
-
 #endif
diff --git a/glamor/glamor_vbo.c b/glamor/glamor_vbo.c
index 2731692..c678559 100644
--- a/glamor/glamor_vbo.c
+++ b/glamor/glamor_vbo.c
@@ -48,7 +48,7 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
     void *data;
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glBindBuffer(GL_ARRAY_BUFFER, glamor_priv->vbo);
 
@@ -79,7 +79,6 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
                      */
                     glamor_priv->has_buffer_storage = false;
                     glamor_priv->vbo_size = 0;
-                    glamor_put_context(glamor_priv);
 
                     return glamor_get_vbo_space(screen, size, vbo_offset);
                 }
@@ -130,8 +129,6 @@ glamor_get_vbo_space(ScreenPtr screen, unsigned size, char **vbo_offset)
         data = glamor_priv->vb;
     }
 
-    glamor_put_context(glamor_priv);
-
     return data;
 }
 
@@ -140,7 +137,7 @@ glamor_put_vbo_space(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     if (glamor_priv->has_buffer_storage) {
         /* If we're in the ARB_buffer_storage path, we have a
@@ -155,8 +152,6 @@ glamor_put_vbo_space(ScreenPtr screen)
     }
 
     glBindBuffer(GL_ARRAY_BUFFER, 0);
-
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -164,11 +159,9 @@ glamor_init_vbo(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glGenBuffers(1, &glamor_priv->vbo);
-
-    glamor_put_context(glamor_priv);
 }
 
 void
@@ -176,11 +169,9 @@ glamor_fini_vbo(ScreenPtr screen)
 {
     glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
 
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
 
     glDeleteBuffers(1, &glamor_priv->vbo);
     if (!glamor_priv->has_map_buffer_range)
         free(glamor_priv->vb);
-
-    glamor_put_context(glamor_priv);
 }
diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
index 4e60fa3..369b02b 100644
--- a/glamor/glamor_xv.c
+++ b/glamor/glamor_xv.c
@@ -97,7 +97,7 @@ glamor_init_xv_shader(ScreenPtr screen)
     GLint fs_prog, vs_prog;
 
     glamor_priv = glamor_get_screen_private(screen);
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glamor_priv->xv_prog = glCreateProgram();
 
     vs_prog = glamor_compile_glsl_prog(GL_VERTEX_SHADER, xv_vs);
@@ -110,8 +110,6 @@ glamor_init_xv_shader(ScreenPtr screen)
     glBindAttribLocation(glamor_priv->xv_prog,
                          GLAMOR_VERTEX_SOURCE, "v_texcoord0");
     glamor_link_glsl_prog(screen, glamor_priv->xv_prog, "xv");
-
-    glamor_put_context(glamor_priv);
 }
 
 #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
@@ -316,7 +314,7 @@ glamor_display_textured_video(glamor_port_private *port_priv)
                                   &src_yscale[i]);
         }
     }
-    glamor_get_context(glamor_priv);
+    glamor_make_current(glamor_priv);
     glUseProgram(glamor_priv->xv_prog);
 
     uloc = glGetUniformLocation(glamor_priv->xv_prog, "offsetyco");
@@ -404,7 +402,6 @@ glamor_display_textured_video(glamor_port_private *port_priv)
     glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
     glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
 
-    glamor_put_context(glamor_priv);
     DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
 }
 
commit 11ff12d4e74c0b514cb62cc47df9770c91e5002a
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Mar 14 17:29:31 2014 -0700

    glamor: Stop unsetting the EGL context in put_context().
    
    This matches the Xephyr behavior.  Now that we know when to reset the
    context in the presence of GLX, we don't need to try to keep our stuff
    from being smashed by GLX.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 33a95a0..a16022b 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -112,11 +112,7 @@ glamor_egl_get_context(struct glamor_context *glamor_ctx)
 static void
 glamor_egl_put_context(struct glamor_context *glamor_ctx)
 {
-    if (--glamor_ctx->get_count)
-        return;
-
-    eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
-                   EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    --glamor_ctx->get_count;
 }
 
 static EGLImageKHR
commit b5e394b3f5d80749af0148611df2eb009e7bf823
Author: Eric Anholt <eric at anholt.net>
Date:   Fri Mar 14 17:20:12 2014 -0700

    glamor: Use lastGLContext to coordinate the context with GLX.
    
    This gets us some more context changes that are needed to make sure
    the two sides render to the right drawables and manipulate the right
    objects.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 9b6b323..33a95a0 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -100,14 +100,12 @@ glamor_egl_get_context(struct glamor_context *glamor_ctx)
     if (glamor_ctx->get_count++)
         return;
 
-    if (glamor_ctx->ctx != eglGetCurrentContext()) {
-        eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
-                       EGL_NO_SURFACE, EGL_NO_CONTEXT);
-        if (!eglMakeCurrent(glamor_ctx->display,
-                            EGL_NO_SURFACE, EGL_NO_SURFACE,
-                            glamor_ctx->ctx)) {
-            FatalError("Failed to make EGL context current\n");
-        }
+    eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
+                   EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    if (!eglMakeCurrent(glamor_ctx->display,
+                        EGL_NO_SURFACE, EGL_NO_SURFACE,
+                        glamor_ctx->ctx)) {
+        FatalError("Failed to make EGL context current\n");
     }
 }
 
diff --git a/glamor/glamor_glx.c b/glamor/glamor_glx.c
index 8f47c3d..d56581c 100644
--- a/glamor/glamor_glx.c
+++ b/glamor/glamor_glx.c
@@ -36,15 +36,9 @@
 static void
 glamor_glx_get_context(struct glamor_context *glamor_ctx)
 {
-    GLXContext old_ctx;
-
     if (glamor_ctx->get_count++)
         return;
 
-    old_ctx = glXGetCurrentContext();
-    if (old_ctx == glamor_ctx->ctx)
-        return;
-
     glXMakeCurrent(glamor_ctx->display, glamor_ctx->drawable_xid,
                    glamor_ctx->ctx);
 }
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index 53b7d9b..56ef6a9 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1501,7 +1501,10 @@ __fls(unsigned long x)
 static inline void
 glamor_get_context(glamor_screen_private * glamor_priv)
 {
-    glamor_priv->ctx.get_context(&glamor_priv->ctx);
+    if (lastGLContext != &glamor_priv->ctx) {
+        lastGLContext = &glamor_priv->ctx;
+        glamor_priv->ctx.get_context(&glamor_priv->ctx);
+    }
 }
 
 static inline void
commit ab6e958a2e611b03e475c16d10beb9961d8dffc8
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Apr 9 10:23:01 2014 -0700

    glx: Make sure that DRI2/swrast calls haven't changed the GL context.
    
    These functions are called from the GL driver, in some series of GL
    calls by GLX.  If some server component (like glamor CreatePixmap for
    GetBuffers()) changes the GL context on us, we need to set it back or
    the later GL calls will land in the glamor context instead of the GLX
    context.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 94476dd..7b368d2 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -121,6 +121,7 @@ copy_box(__GLXdrawable * drawable,
 {
     BoxRec box;
     RegionRec region;
+    __GLXcontext *cx = lastGLContext;
 
     box.x1 = x;
     box.y1 = y;
@@ -129,6 +130,10 @@ copy_box(__GLXdrawable * drawable,
     RegionInit(&region, &box, 0);
 
     DRI2CopyRegion(drawable->pDraw, &region, dst, src);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
 }
 
 static void
@@ -198,26 +203,37 @@ __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable * drawable)
     __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable;
     __GLXDRIscreen *screen = priv->screen;
     CARD64 unused;
+    __GLXcontext *cx = lastGLContext;
+    int status;
 
     if (screen->flush) {
         (*screen->flush->flush) (priv->driDrawable);
         (*screen->flush->invalidate) (priv->driDrawable);
     }
 
-    if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused,
-                        __glXdriSwapEvent, drawable) != Success)
-        return FALSE;
+    status = DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused,
+                             __glXdriSwapEvent, drawable);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
 
-    return TRUE;
+    return status == Success;
 }
 
 static int
 __glXDRIdrawableSwapInterval(__GLXdrawable * drawable, int interval)
 {
+    __GLXcontext *cx = lastGLContext;
+
     if (interval <= 0)          /* || interval > BIGNUM? */
         return GLX_BAD_VALUE;
 
     DRI2SwapInterval(drawable->pDraw, interval);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
 
     return 0;
 }
@@ -270,7 +286,16 @@ static Bool
 __glXDRIcontextWait(__GLXcontext * baseContext,
                     __GLXclientState * cl, int *error)
 {
-    if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) {
+    __GLXcontext *cx = lastGLContext;
+    Bool ret;
+
+    ret = DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
+
+    if (ret) {
         *error = cl->client->noClientException;
         return TRUE;
     }
@@ -594,6 +619,8 @@ __glXDRIscreenCreateDrawable(ClientPtr client,
     __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
     __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
     __GLXDRIdrawable *private;
+    __GLXcontext *cx = lastGLContext;
+    Bool ret;
 
     private = calloc(1, sizeof *private);
     if (private == NULL)
@@ -612,9 +639,15 @@ __glXDRIscreenCreateDrawable(ClientPtr client,
     private->base.waitGL = __glXDRIdrawableWaitGL;
     private->base.waitX = __glXDRIdrawableWaitX;
 
-    if (DRI2CreateDrawable2(client, pDraw, drawId,
-                            __glXDRIinvalidateBuffers, private,
-                            &private->dri2_id)) {
+    ret = DRI2CreateDrawable2(client, pDraw, drawId,
+                              __glXDRIinvalidateBuffers, private,
+                              &private->dri2_id);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
+
+    if (ret) {
         free(private);
         return NULL;
     }
@@ -636,9 +669,15 @@ dri2GetBuffers(__DRIdrawable * driDrawable,
     DRI2BufferPtr *buffers;
     int i;
     int j;
+    __GLXcontext *cx = lastGLContext;
 
     buffers = DRI2GetBuffers(private->base.pDraw,
                              width, height, attachments, count, out_count);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
+
     if (*out_count > MAX_DRAWABLE_BUFFERS) {
         *out_count = 0;
         return NULL;
@@ -680,10 +719,16 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
     DRI2BufferPtr *buffers;
     int i;
     int j = 0;
+    __GLXcontext *cx = lastGLContext;
 
     buffers = DRI2GetBuffersWithFormat(private->base.pDraw,
                                        width, height, attachments, count,
                                        out_count);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
+
     if (*out_count > MAX_DRAWABLE_BUFFERS) {
         *out_count = 0;
         return NULL;
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 6fa3288..c30ce9a 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -337,6 +337,7 @@ swrastPutImage(__DRIdrawable * draw, int op,
     __GLXDRIdrawable *drawable = loaderPrivate;
     DrawablePtr pDraw = drawable->base.pDraw;
     GCPtr gc;
+    __GLXcontext *cx = lastGLContext;
 
     switch (op) {
     case __DRI_SWRAST_IMAGE_OP_DRAW:
@@ -352,6 +353,10 @@ swrastPutImage(__DRIdrawable * draw, int op,
     ValidateGC(pDraw, gc);
 
     gc->ops->PutImage(pDraw, gc, pDraw->depth, x, y, w, h, 0, ZPixmap, data);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
 }
 
 static void
@@ -361,8 +366,13 @@ swrastGetImage(__DRIdrawable * draw,
     __GLXDRIdrawable *drawable = loaderPrivate;
     DrawablePtr pDraw = drawable->base.pDraw;
     ScreenPtr pScreen = pDraw->pScreen;
+    __GLXcontext *cx = lastGLContext;
 
     pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data);
+    if (cx != lastGLContext) {
+        lastGLContext = cx;
+        cx->makeCurrent(cx);
+    }
 }
 
 static const __DRIswrastLoaderExtension swrastLoaderExtension = {
commit f3f2fb6baac3d2b248eb4b0da13fe95e9dc3de7d
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Apr 9 11:25:32 2014 -0700

    glx: Refactor DRI2CopyRegion calls.
    
    I needed to add some code to each one, so it's a good time to make a
    helper func.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 5d1a45b..94476dd 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -115,55 +115,49 @@ __glXDRIdrawableDestroy(__GLXdrawable * drawable)
 }
 
 static void
-__glXDRIdrawableCopySubBuffer(__GLXdrawable * drawable,
-                              int x, int y, int w, int h)
+copy_box(__GLXdrawable * drawable,
+         int dst, int src,
+         int x, int y, int w, int h)
 {
-    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
     BoxRec box;
     RegionRec region;
 
     box.x1 = x;
-    box.y1 = private->height - y - h;
+    box.y1 = y;
     box.x2 = x + w;
-    box.y2 = private->height - y;
+    box.y2 = y + h;
     RegionInit(&region, &box, 0);
 
-    DRI2CopyRegion(drawable->pDraw, &region,
-                   DRI2BufferFrontLeft, DRI2BufferBackLeft);
+    DRI2CopyRegion(drawable->pDraw, &region, dst, src);
 }
 
 static void
-__glXDRIdrawableWaitX(__GLXdrawable * drawable)
+__glXDRIdrawableCopySubBuffer(__GLXdrawable * drawable,
+                              int x, int y, int w, int h)
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
-    BoxRec box;
-    RegionRec region;
 
-    box.x1 = 0;
-    box.y1 = 0;
-    box.x2 = private->width;
-    box.y2 = private->height;
-    RegionInit(&region, &box, 0);
+    copy_box(drawable, x, private->height - y - h,
+             w, h,
+             DRI2BufferFrontLeft, DRI2BufferBackLeft);
+}
 
-    DRI2CopyRegion(drawable->pDraw, &region,
-                   DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+static void
+__glXDRIdrawableWaitX(__GLXdrawable * drawable)
+{
+    __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+
+    copy_box(drawable, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft,
+             0, 0, private->width, private->height);
 }
 
 static void
 __glXDRIdrawableWaitGL(__GLXdrawable * drawable)
 {
     __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
-    BoxRec box;
-    RegionRec region;
-
-    box.x1 = 0;
-    box.y1 = 0;
-    box.x2 = private->width;
-    box.y2 = private->height;
-    RegionInit(&region, &box, 0);
 
-    DRI2CopyRegion(drawable->pDraw, &region,
-                   DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+    copy_box(drawable, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft,
+             0, 0, private->width, private->height);
 }
 
 static void
commit 008f1ab31e8ac6be8f3fb11f19cdf8674be318dd
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Apr 17 18:28:54 2014 -0700

    glx: Unconditionally clear lastGLContext on loseCurrent().
    
    This hook calls unbindContext in the DRI driver interface, which
    unsets the dispatch table, regardless of whether the context argument
    was the current one or not.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxext.c b/glx/glxext.c
index 9855767..c0142fe 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -135,8 +135,7 @@ DrawableGone(__GLXdrawable * glxPriv, XID xid)
 		(c->drawPriv == glxPriv || c->readPriv == glxPriv)) {
             /* just force a re-bind the next time through */
             (*c->loseCurrent) (c);
-            if (c == lastGLContext)
-                lastGLContext = NULL;
+            lastGLContext = NULL;
         }
         if (c->drawPriv == glxPriv)
             c->drawPriv = NULL;
@@ -290,6 +289,7 @@ glxClientCallback(CallbackListPtr *list, void *closure, void *data)
             next = c->next;
             if (c->currentClient == pClient) {
                 c->loseCurrent(c);
+                lastGLContext = NULL;
                 c->currentClient = NULL;
                 __glXFreeContext(c);
             }
commit 789509ef5324ce9141222fa92dea51b5cc777209
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Apr 17 18:23:51 2014 -0700

    glx: Move GLX MakeCurrent lastGLContext updates next to makeCurrent().
    
    We want to make sure that lastGLContext is set correctly during
    makeCurrent, because we may have recursive GL context changes in the
    DRI2 interfaces due to glamor.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index a451d2b..fb236b6 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -434,9 +434,6 @@ static void
 StopUsingContext(__GLXcontext * glxc)
 {
     if (glxc) {
-        if (glxc == lastGLContext) {
-            lastGLContext = NULL;
-        }
         glxc->currentClient = NULL;
         if (!glxc->idExists) {
             FreeResourceByType(glxc->id, __glXContextRes, FALSE);
@@ -447,7 +444,6 @@ StopUsingContext(__GLXcontext * glxc)
 static void
 StartUsingContext(__GLXclientState * cl, __GLXcontext * glxc)
 {
-    lastGLContext = glxc;
     glxc->currentClient = cl->client;
 }
 
@@ -639,7 +635,9 @@ DoMakeCurrent(__GLXclientState * cl,
         glxc->readPriv = readPriv;
 
         /* make the context current */
+        lastGLContext = glxc;
         if (!(*glxc->makeCurrent) (glxc)) {
+            lastGLContext = NULL;
             glxc->drawPriv = NULL;
             glxc->readPriv = NULL;
             return __glXError(GLXBadContext);
diff --git a/glx/glxext.c b/glx/glxext.c
index 85fd219..9855767 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -444,14 +444,15 @@ __glXForceCurrent(__GLXclientState * cl, GLXContextTag tag, int *error)
 
     /* Make this context the current one for the GL. */
     if (!cx->isDirect) {
+        lastGLContext = cx;
         if (!(*cx->makeCurrent) (cx)) {
             /* Bind failed, and set the error code.  Bummer */
+            lastGLContext = NULL;
             cl->client->errorValue = cx->id;
             *error = __glXError(GLXBadContextState);
             return 0;
         }
     }
-    lastGLContext = cx;
     return cx;
 }
 
commit abf12027063dbe22bec1d055ad8db365cf07395a
Author: Eric Anholt <eric at anholt.net>
Date:   Thu Apr 17 18:18:49 2014 -0700

    glx: Move the GLX variable caching what GL context is current to dix.
    
    GLX is trying to track whether the context it wants is current, to
    avoid the glFlush() (and the rest of the overhead) that occurs on all
    MakeCurrent calls.  However, its cache can be incorrect now that
    glamor exists.  This is a step toward getting glamor to coordinate
    with GLX.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/dix/dixutils.c b/dix/dixutils.c
index 5de74c8..cdd370b 100644
--- a/dix/dixutils.c
+++ b/dix/dixutils.c
@@ -866,3 +866,28 @@ InitCallbackManager(void)
 {
     DeleteCallbackManager();
 }
+
+/**
+ * Coordinates the global GL context used by modules in the X Server
+ * doing rendering with OpenGL.
+ *
+ * When setting a GL context (glXMakeCurrent() or eglMakeCurrent()),
+ * there is an expensive implied glFlush() required by the GLX and EGL
+ * APIs, so modules don't want to have to do it on every request.  But
+ * the individual modules using GL also don't know about each other,
+ * so they have to coordinate who owns the current context.
+ *
+ * When you're about to do a MakeCurrent, you should set this variable
+ * to your context's address, and you can skip MakeCurrent if it's
+ * already set to yours.
+ *
+ * When you're about to do a DestroyContext, you should set this to
+ * NULL if it's set to your context.
+ *
+ * When you're about to do an unbindContext on a DRI driver, you
+ * should set this to NULL.  Despite the unbindContext interface
+ * sounding like it only unbinds the passed in context, it actually
+ * unconditionally clears the dispatch table even if the given
+ * context wasn't current.
+ */
+void *lastGLContext = NULL;
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 187e426..a451d2b 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -188,7 +188,7 @@ validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
 void
 __glXContextDestroy(__GLXcontext * context)
 {
-    __glXFlushContextCache();
+    lastGLContext = NULL;
 }
 
 static void
@@ -434,9 +434,8 @@ static void
 StopUsingContext(__GLXcontext * glxc)
 {
     if (glxc) {
-        if (glxc == __glXLastContext) {
-            /* Tell server GL library */
-            __glXLastContext = 0;
+        if (glxc == lastGLContext) {
+            lastGLContext = NULL;
         }
         glxc->currentClient = NULL;
         if (!glxc->idExists) {
@@ -448,7 +447,7 @@ StopUsingContext(__GLXcontext * glxc)
 static void
 StartUsingContext(__GLXclientState * cl, __GLXcontext * glxc)
 {
-    __glXLastContext = glxc;
+    lastGLContext = glxc;
     glxc->currentClient = cl->client;
 }
 
@@ -627,7 +626,7 @@ DoMakeCurrent(__GLXclientState * cl,
         if (!(*prevglxc->loseCurrent) (prevglxc)) {
             return __glXError(GLXBadContext);
         }
-        __glXFlushContextCache();
+        lastGLContext = NULL;
         if (!prevglxc->isDirect) {
             prevglxc->drawPriv = NULL;
             prevglxc->readPriv = NULL;
diff --git a/glx/glxext.c b/glx/glxext.c
index c9b8cc5..85fd219 100644
--- a/glx/glxext.c
+++ b/glx/glxext.c
@@ -48,12 +48,6 @@
 #include "indirect_util.h"
 
 /*
-** The last context used by the server.  It is the context that is current
-** from the server's perspective.
-*/
-__GLXcontext *__glXLastContext;
-
-/*
 ** X resources.
 */
 RESTYPE __glXContextRes;
@@ -79,7 +73,7 @@ static int __glXDispatch(ClientPtr);
 static void
 ResetExtension(ExtensionEntry * extEntry)
 {
-    __glXFlushContextCache();
+    lastGLContext = NULL;
 }
 
 /*
@@ -141,8 +135,8 @@ DrawableGone(__GLXdrawable * glxPriv, XID xid)
 		(c->drawPriv == glxPriv || c->readPriv == glxPriv)) {
             /* just force a re-bind the next time through */
             (*c->loseCurrent) (c);
-            if (c == __glXLastContext)
-                __glXFlushContextCache();
+            if (c == lastGLContext)
+                lastGLContext = NULL;
         }
         if (c->drawPriv == glxPriv)
             c->drawPriv = NULL;
@@ -203,8 +197,8 @@ __glXFreeContext(__GLXcontext * cx)
 
     free(cx->feedbackBuf);
     free(cx->selectBuf);
-    if (cx == __glXLastContext) {
-        __glXFlushContextCache();
+    if (cx == lastGLContext) {
+        lastGLContext = NULL;
     }
 
     /* We can get here through both regular dispatching from
@@ -406,12 +400,6 @@ GlxExtensionInit(void)
 
 /************************************************************************/
 
-void
-__glXFlushContextCache(void)
-{
-    __glXLastContext = 0;
-}
-
 /*
 ** Make a context the current one for the GL (in this implementation, there
 ** is only one instance of the GL, and we use it to serve all GL clients by
@@ -449,7 +437,7 @@ __glXForceCurrent(__GLXclientState * cl, GLXContextTag tag, int *error)
     if (cx->wait && (*cx->wait) (cx, cl, error))
         return NULL;
 
-    if (cx == __glXLastContext) {
+    if (cx == lastGLContext) {
         /* No need to re-bind */
         return cx;
     }
@@ -463,7 +451,7 @@ __glXForceCurrent(__GLXclientState * cl, GLXContextTag tag, int *error)
             return 0;
         }
     }
-    __glXLastContext = cx;
+    lastGLContext = cx;
     return cx;
 }
 
diff --git a/glx/glxserver.h b/glx/glxserver.h
index 3f2ae35..a324b29 100644
--- a/glx/glxserver.h
+++ b/glx/glxserver.h
@@ -84,7 +84,6 @@ void __glXScreenInitVisuals(__GLXscreen * screen);
 /*
 ** The last context used (from the server's persective) is cached.
 */
-extern __GLXcontext *__glXLastContext;
 extern __GLXcontext *__glXForceCurrent(__GLXclientState *, GLXContextTag,
                                        int *);
 
diff --git a/include/dix.h b/include/dix.h
index 8371df0..f42e236 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -608,4 +608,6 @@ CorePointerProc(DeviceIntPtr dev, int what);
 extern _X_HIDDEN int
 CoreKeyboardProc(DeviceIntPtr dev, int what);
 
+extern _X_EXPORT void *lastGLContext;
+
 #endif                          /* DIX_H */
commit f12221cbd8ff33070fa2ca086bccf7ed32115f0e
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Apr 16 16:16:21 2014 -0700

    glamor: Fix a missing set of the GL context.
    
    Signed-off-by: Eric Anholt <eric at anholt.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Michel Dänzer <michel.daenzer at amd.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index d37de9b..9b6b323 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -166,10 +166,14 @@ glamor_get_flink_name(int fd, int handle, int *name)
 }
 
 static Bool
-glamor_create_texture_from_image(struct glamor_egl_screen_private
-                                 *glamor_egl,
+glamor_create_texture_from_image(ScreenPtr screen,
                                  EGLImageKHR image, GLuint * texture)
 {
+    struct glamor_screen_private *glamor_priv =
+        glamor_get_screen_private(screen);
+
+    glamor_get_context(glamor_priv);
+
     glGenTextures(1, texture);
     glBindTexture(GL_TEXTURE_2D, *texture);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -177,6 +181,9 @@ glamor_create_texture_from_image(struct glamor_egl_screen_private
 
     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
     glBindTexture(GL_TEXTURE_2D, 0);
+
+    glamor_put_context(glamor_priv);
+
     return TRUE;
 }
 
@@ -211,7 +218,7 @@ glamor_egl_create_argb8888_based_texture(ScreenPtr screen, int w, int h)
     gbm_bo_destroy(bo);
     if (image == EGL_NO_IMAGE_KHR)
         return 0;
-    glamor_create_texture_from_image(glamor_egl, image, &texture);
+    glamor_create_texture_from_image(screen, image, &texture);
     eglDestroyImageKHR(glamor_egl->display, image);
 
     return texture;
@@ -312,7 +319,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
         glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
         goto done;
     }
-    glamor_create_texture_from_image(glamor_egl, image, &texture);
+    glamor_create_texture_from_image(screen, image, &texture);
     glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_texture(pixmap, texture);
     pixmap_priv->base.image = image;
@@ -348,7 +355,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
         glamor_set_pixmap_type(pixmap, GLAMOR_DRM_ONLY);
         goto done;
     }
-    glamor_create_texture_from_image(glamor_egl, image, &texture);
+    glamor_create_texture_from_image(screen, image, &texture);
     glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
     glamor_set_pixmap_texture(pixmap, texture);
     pixmap_priv->base.image = image;


More information about the xorg-commit mailing list