summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--glamor/Makefile.am2
-rw-r--r--glamor/glamor.c8
-rw-r--r--glamor/glamor.h7
-rw-r--r--glamor/glamor_context.h56
-rw-r--r--glamor/glamor_egl.c58
-rw-r--r--glamor/glamor_egl_stubs.c12
-rw-r--r--glamor/glamor_glx.c82
-rw-r--r--glamor/glamor_priv.h6
-rw-r--r--glamor/glamor_utils.h18
9 files changed, 189 insertions, 60 deletions
diff --git a/glamor/Makefile.am b/glamor/Makefile.am
index 17cae97f5..12a57c441 100644
--- a/glamor/Makefile.am
+++ b/glamor/Makefile.am
@@ -6,6 +6,7 @@ AM_CFLAGS = $(CWARNFLAGS) $(DIX_CFLAGS) $(GLAMOR_CFLAGS)
libglamor_la_SOURCES = \
glamor.c \
+ glamor_context.h \
glamor_copyarea.c \
glamor_copywindow.c \
glamor_core.c \
@@ -13,6 +14,7 @@ libglamor_la_SOURCES = \
glamor_fill.c \
glamor_fillspans.c \
glamor_getspans.c \
+ glamor_glx.c \
glamor_glyphs.c \
glamor_polyfillrect.c \
glamor_polylines.c \
diff --git a/glamor/glamor.c b/glamor/glamor.c
index 410ebd296..5947d7ff0 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -340,8 +340,12 @@ glamor_init(ScreenPtr screen, unsigned int flags)
#endif
/* If we are using egl screen, call egl screen init to
* register correct close screen function. */
- if (flags & GLAMOR_USE_EGL_SCREEN)
- glamor_egl_screen_init(screen);
+ if (flags & GLAMOR_USE_EGL_SCREEN) {
+ glamor_egl_screen_init(screen, &glamor_priv->ctx);
+ } else {
+ if (!glamor_glx_screen_init(&glamor_priv->ctx))
+ goto fail;
+ }
glamor_priv->saved_procs.close_screen = screen->CloseScreen;
screen->CloseScreen = glamor_close_screen;
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 05f565b12..eec687256 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -36,6 +36,8 @@
#include <fb.h>
#include <fbpict.h>
+struct glamor_context;
+
/*
* glamor_pixmap_type : glamor pixmap's type.
* @MEMORY: pixmap is in memory.
@@ -142,11 +144,6 @@ extern _X_EXPORT void glamor_block_handler(ScreenPtr screen);
extern _X_EXPORT PixmapPtr glamor_create_pixmap(ScreenPtr screen, int w, int h,
int depth, unsigned int usage);
-extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen);
-
-extern _X_EXPORT void glamor_egl_make_current(ScreenPtr screen);
-extern _X_EXPORT void glamor_egl_restore_context(ScreenPtr screen);
-
/* @glamor_egl_exchange_buffers: Exchange the underlying buffers(KHR image,fbo).
*
* @front: front pixmap.
diff --git a/glamor/glamor_context.h b/glamor/glamor_context.h
new file mode 100644
index 000000000..8781afc48
--- /dev/null
+++ b/glamor/glamor_context.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+/**
+ * @file glamor_context.h
+ *
+ * This is the struct of state required for context switching in
+ * glamor. It has to use types that don't require including either
+ * server headers or Xlib headers, since it will be included by both
+ * the server and the GLX (xlib) code.
+ */
+
+struct glamor_context {
+ /** Either an EGLDisplay or an Xlib Display */
+ void *display;
+
+ /** Either a GLXContext or an EGLContext. */
+ void *ctx;
+
+ /** The EGLSurface we should MakeCurrent to */
+ void *drawable;
+
+ /** 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);
+};
+
+Bool glamor_glx_screen_init(struct glamor_context *glamor_ctx);
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 906598aeb..81e697b0d 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -49,6 +49,7 @@
#include <epoxy/egl.h>
#include "glamor.h"
+#include "glamor_priv.h"
static const char glamor_name[] = "glamor";
@@ -87,6 +88,7 @@ struct glamor_egl_screen_private {
int xf86GlamorEGLPrivateIndex = -1;
+
static struct glamor_egl_screen_private *
glamor_egl_get_screen_private(ScrnInfoPtr scrn)
{
@@ -94,38 +96,30 @@ glamor_egl_get_screen_private(ScrnInfoPtr scrn)
scrn->privates[xf86GlamorEGLPrivateIndex].ptr;
}
-_X_EXPORT void
-glamor_egl_make_current(ScreenPtr screen)
+static void
+glamor_egl_get_context(struct glamor_context *glamor_ctx)
{
- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
- struct glamor_egl_screen_private *glamor_egl =
- glamor_egl_get_screen_private(scrn);
-
- if (glamor_egl->gl_context_depth++)
+ if (glamor_ctx->get_count++)
return;
- if (glamor_egl->context != eglGetCurrentContext()) {
- eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
+ if (glamor_ctx->ctx != eglGetCurrentContext()) {
+ eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (!eglMakeCurrent(glamor_egl->display,
+ if (!eglMakeCurrent(glamor_ctx->display,
EGL_NO_SURFACE, EGL_NO_SURFACE,
- glamor_egl->context)) {
+ glamor_ctx->ctx)) {
FatalError("Failed to make EGL context current\n");
}
}
}
-_X_EXPORT void
-glamor_egl_restore_context(ScreenPtr screen)
+static void
+glamor_egl_put_context(struct glamor_context *glamor_ctx)
{
- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
- struct glamor_egl_screen_private *glamor_egl =
- glamor_egl_get_screen_private(scrn);
-
- if (--glamor_egl->gl_context_depth)
+ if (--glamor_ctx->get_count)
return;
- eglMakeCurrent(glamor_egl->display, EGL_NO_SURFACE,
+ eglMakeCurrent(glamor_ctx->display, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
@@ -284,6 +278,8 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
{
ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(screen);
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
GLuint texture;
@@ -292,7 +288,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
glamor_egl = glamor_egl_get_screen_private(scrn);
- glamor_egl_make_current(screen);
+ glamor_get_context(glamor_priv);
if (glamor_egl->has_gem) {
if (!glamor_get_flink_name(glamor_egl->fd, handle, &name)) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
@@ -322,7 +318,7 @@ glamor_egl_create_textured_pixmap(PixmapPtr pixmap, int handle, int stride)
ret = TRUE;
done:
- glamor_egl_restore_context(screen);
+ glamor_put_context(glamor_priv);
return ret;
}
@@ -331,6 +327,8 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
{
ScreenPtr screen = pixmap->drawable.pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(screen);
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
GLuint texture;
@@ -338,7 +336,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
glamor_egl = glamor_egl_get_screen_private(scrn);
- glamor_egl_make_current(screen);
+ glamor_get_context(glamor_priv);
image = eglCreateImageKHR(glamor_egl->display,
glamor_egl->context,
@@ -354,7 +352,7 @@ glamor_egl_create_textured_pixmap_from_gbm_bo(PixmapPtr pixmap, void *bo)
ret = TRUE;
done:
- glamor_egl_restore_context(screen);
+ glamor_put_context(glamor_priv);
return ret;
}
@@ -395,6 +393,8 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
{
#ifdef GLAMOR_HAS_DRI3_SUPPORT
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ struct glamor_screen_private *glamor_priv =
+ glamor_get_screen_private(screen);
struct glamor_egl_screen_private *glamor_egl;
EGLImageKHR image;
struct gbm_bo *bo;
@@ -408,7 +408,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
glamor_egl = glamor_egl_get_screen_private(scrn);
- glamor_egl_make_current(screen);
+ glamor_get_context(glamor_priv);
image = dixLookupPrivate(&pixmap->devPrivates,
glamor_egl_pixmap_private_key);
@@ -446,7 +446,7 @@ glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
gbm_bo_destroy(bo);
failure:
- glamor_egl_restore_context(screen);
+ glamor_put_context(glamor_priv);
return fd;
#else
return -1;
@@ -628,7 +628,7 @@ glamor_egl_has_extension(struct glamor_egl_screen_private *glamor_egl,
}
void
-glamor_egl_screen_init(ScreenPtr screen)
+glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct glamor_egl_screen_private *glamor_egl =
@@ -636,6 +636,12 @@ glamor_egl_screen_init(ScreenPtr screen)
glamor_egl->saved_close_screen = screen->CloseScreen;
screen->CloseScreen = glamor_egl_close_screen;
+
+ 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;
}
static void
diff --git a/glamor/glamor_egl_stubs.c b/glamor/glamor_egl_stubs.c
index 1449d0874..4fd9e8016 100644
--- a/glamor/glamor_egl_stubs.c
+++ b/glamor/glamor_egl_stubs.c
@@ -29,7 +29,7 @@
#include "glamor_priv.h"
void
-glamor_egl_screen_init(ScreenPtr screen)
+glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
{
}
@@ -38,16 +38,6 @@ glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
{
}
-void
-glamor_egl_make_current(ScreenPtr screen)
-{
-}
-
-void
-glamor_egl_restore_context(ScreenPtr screen)
-{
-}
-
int
glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen,
PixmapPtr pixmap,
diff --git a/glamor/glamor_glx.c b/glamor/glamor_glx.c
new file mode 100644
index 000000000..311bf758d
--- /dev/null
+++ b/glamor/glamor_glx.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+#include <epoxy/glx.h>
+#include "glamor_context.h"
+
+/**
+ * @file glamor_glx.c
+ *
+ * GLX context management for glamor.
+ *
+ * This has to be kept separate from the server sources because of
+ * Xlib's conflicting definition of CARD32 and similar typedefs.
+ */
+
+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);
+}
+
+
+static void
+glamor_glx_put_context(struct glamor_context *glamor_ctx)
+{
+ if (--glamor_ctx->get_count)
+ return;
+
+ /* We actually reset the context, so that indirect GLX's EGL usage
+ * won't get confused by ours.
+ */
+ glXMakeCurrent(glamor_ctx->display, None, NULL);
+}
+
+Bool
+glamor_glx_screen_init(struct glamor_context *glamor_ctx)
+{
+ glamor_ctx->ctx = glXGetCurrentContext();
+ if (!glamor_ctx->ctx)
+ return False;
+
+ glamor_ctx->display = glXGetCurrentDisplay();
+ if (!glamor_ctx->display)
+ return False;
+
+ glamor_ctx->drawable_xid = glXGetCurrentDrawable();
+
+ glamor_ctx->get_context = glamor_glx_get_context;
+ glamor_ctx->put_context = glamor_glx_put_context;
+
+ return True;
+}
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 847709197..f2bc00255 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -48,6 +48,7 @@
#endif
#include "glamor_debug.h"
+#include "glamor_context.h"
#include <list.h>
@@ -281,6 +282,8 @@ typedef struct glamor_screen_private {
/* xv */
GLint xv_prog;
+
+ struct glamor_context ctx;
} glamor_screen_private;
typedef enum glamor_access {
@@ -927,6 +930,9 @@ void glamor_composite_rectangles(CARD8 op,
xRenderColor *color,
int num_rects, xRectangle *rects);
+extern _X_EXPORT void glamor_egl_screen_init(ScreenPtr screen,
+ struct glamor_context *glamor_ctx);
+
/* glamor_xv */
typedef struct {
uint32_t transform_index;
diff --git a/glamor/glamor_utils.h b/glamor/glamor_utils.h
index b82517a83..eafd2bc06 100644
--- a/glamor/glamor_utils.h
+++ b/glamor/glamor_utils.h
@@ -1817,29 +1817,15 @@ __fls(unsigned long x)
#endif
static inline void
-glamor_make_current(ScreenPtr screen)
-{
- glamor_egl_make_current(screen);
-}
-
-static inline void
-glamor_restore_current(ScreenPtr screen)
-{
- glamor_egl_restore_context(screen);
-}
-
-static inline void
glamor_get_context(glamor_screen_private * glamor_priv)
{
- if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
- glamor_make_current(glamor_priv->screen);
+ glamor_priv->ctx.get_context(&glamor_priv->ctx);
}
static inline void
glamor_put_context(glamor_screen_private * glamor_priv)
{
- if (glamor_priv->flags & GLAMOR_USE_EGL_SCREEN)
- glamor_restore_current(glamor_priv->screen);
+ glamor_priv->ctx.put_context(&glamor_priv->ctx);
}
#endif