ephyr/glamor: Port to EGL
There's no real benefit to using GLX, and the other DDXes are using EGL already, so let's converge on EGL so we can concentrate the fixes in one place. We go to some effort to avoid being the thing that requires libX11 here. We prefer EGL_EXT_platform_xcb over _x11, and if forced to use the latter we'll ask the dynamic linker for XGetXCBConnection and XOpenDisplay rather than link against xlib stuff ourselves. Xephyr is now a pure XCB application if it can be. Reviewed-by: Emma Anholt <emma@anholt.net>
This commit is contained in:
parent
2906ee5e4a
commit
07fa12ad1d
|
@ -2192,9 +2192,6 @@ if test "$KDRIVE" = yes; then
|
||||||
if test "x$DRI" = xyes && test "x$GLX" = xyes; then
|
if test "x$DRI" = xyes && test "x$GLX" = xyes; then
|
||||||
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBDRM xcb-glx xcb-xf86dri > 1.6"
|
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBDRM xcb-glx xcb-xf86dri > 1.6"
|
||||||
fi
|
fi
|
||||||
if test "x$GLAMOR" = xyes; then
|
|
||||||
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS x11-xcb"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "x$XEPHYR" = xauto; then
|
if test "x$XEPHYR" = xauto; then
|
||||||
PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [XEPHYR="yes"], [XEPHYR="no"])
|
PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [XEPHYR="yes"], [XEPHYR="no"])
|
||||||
|
|
|
@ -13,7 +13,6 @@ libglamor_la_SOURCES = \
|
||||||
glamor_debug.h \
|
glamor_debug.h \
|
||||||
glamor_font.c \
|
glamor_font.c \
|
||||||
glamor_font.h \
|
glamor_font.h \
|
||||||
glamor_glx.c \
|
|
||||||
glamor_composite_glyphs.c \
|
glamor_composite_glyphs.c \
|
||||||
glamor_image.c \
|
glamor_image.c \
|
||||||
glamor_lines.c \
|
glamor_lines.c \
|
||||||
|
|
|
@ -670,9 +670,6 @@ glamor_init(ScreenPtr screen, unsigned int flags)
|
||||||
* register correct close screen function. */
|
* register correct close screen function. */
|
||||||
if (flags & GLAMOR_USE_EGL_SCREEN) {
|
if (flags & GLAMOR_USE_EGL_SCREEN) {
|
||||||
glamor_egl_screen_init(screen, &glamor_priv->ctx);
|
glamor_egl_screen_init(screen, &glamor_priv->ctx);
|
||||||
} else {
|
|
||||||
if (!glamor_glx_screen_init(&glamor_priv->ctx))
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glamor_make_current(glamor_priv);
|
glamor_make_current(glamor_priv);
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
/*
|
|
||||||
* 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_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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->make_current = glamor_glx_make_current;
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
|
|
@ -4,7 +4,6 @@ srcs_glamor = [
|
||||||
'glamor_core.c',
|
'glamor_core.c',
|
||||||
'glamor_dash.c',
|
'glamor_dash.c',
|
||||||
'glamor_font.c',
|
'glamor_font.c',
|
||||||
'glamor_glx.c',
|
|
||||||
'glamor_composite_glyphs.c',
|
'glamor_composite_glyphs.c',
|
||||||
'glamor_image.c',
|
'glamor_image.c',
|
||||||
'glamor_lines.c',
|
'glamor_lines.c',
|
||||||
|
|
|
@ -41,8 +41,8 @@ GLAMOR_XV_SRCS = ephyr_glamor_xv.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
GLAMOR_SRCS = \
|
GLAMOR_SRCS = \
|
||||||
ephyr_glamor_glx.c \
|
ephyr_glamor.c \
|
||||||
ephyr_glamor_glx.h \
|
ephyr_glamor.h \
|
||||||
$(GLAMOR_XV_SRCS) \
|
$(GLAMOR_XV_SRCS) \
|
||||||
$()
|
$()
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#ifdef GLAMOR
|
#ifdef GLAMOR
|
||||||
#include "glamor.h"
|
#include "glamor.h"
|
||||||
#endif
|
#endif
|
||||||
#include "ephyr_glamor_glx.h"
|
#include "ephyr_glamor.h"
|
||||||
#include "glx_extinit.h"
|
#include "glx_extinit.h"
|
||||||
#include "xkbsrv.h"
|
#include "xkbsrv.h"
|
||||||
|
|
||||||
|
@ -1171,9 +1171,6 @@ ephyrXcbProcessEvents(Bool queued_only)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xev) {
|
if (xev) {
|
||||||
if (ephyr_glamor)
|
|
||||||
ephyr_glamor_process_event(xev);
|
|
||||||
|
|
||||||
free(xev);
|
free(xev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ typedef struct _ephyrScrPriv {
|
||||||
xcb_window_t win;
|
xcb_window_t win;
|
||||||
xcb_window_t win_pre_existing; /* Set via -parent option like xnest */
|
xcb_window_t win_pre_existing; /* Set via -parent option like xnest */
|
||||||
xcb_window_t peer_win; /* Used for GL; should be at most one */
|
xcb_window_t peer_win; /* Used for GL; should be at most one */
|
||||||
|
xcb_visualid_t vid;
|
||||||
xcb_image_t *ximg;
|
xcb_image_t *ximg;
|
||||||
Bool win_explicit_position;
|
Bool win_explicit_position;
|
||||||
int win_x, win_y;
|
int win_x, win_y;
|
||||||
|
@ -87,10 +88,6 @@ typedef struct _ephyrScrPriv {
|
||||||
|
|
||||||
ScreenBlockHandlerProcPtr BlockHandler;
|
ScreenBlockHandlerProcPtr BlockHandler;
|
||||||
|
|
||||||
/**
|
|
||||||
* Per-screen Xlib-using state for glamor (private to
|
|
||||||
* ephyr_glamor_glx.c)
|
|
||||||
*/
|
|
||||||
struct ephyr_glamor *glamor;
|
struct ephyr_glamor *glamor;
|
||||||
} EphyrScrPriv;
|
} EphyrScrPriv;
|
||||||
|
|
||||||
|
|
|
@ -21,25 +21,20 @@
|
||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file ephyr_glamor_glx.c
|
/** @file ephyr_glamor.c
|
||||||
*
|
*
|
||||||
* Separate file for hiding Xlib and GLX-using parts of xephyr from
|
* Glamor support and EGL setup.
|
||||||
* the rest of the server-struct-aware build.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <X11/Xlib.h>
|
#include <stdint.h>
|
||||||
#include <X11/Xlibint.h>
|
#include <xcb/xcb.h>
|
||||||
#undef Xcalloc
|
|
||||||
#undef Xrealloc
|
|
||||||
#undef Xfree
|
|
||||||
#include <X11/Xlib-xcb.h>
|
|
||||||
#include <xcb/xcb_aux.h>
|
#include <xcb/xcb_aux.h>
|
||||||
#include <pixman.h>
|
#include <pixman.h>
|
||||||
#include <epoxy/glx.h>
|
#include "glamor_egl.h"
|
||||||
#include "ephyr_glamor_glx.h"
|
#include "glamor_priv.h"
|
||||||
|
#include "ephyr_glamor.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include <X11/Xproto.h>
|
|
||||||
|
|
||||||
/* until we need geometry shaders GL3.1 should suffice. */
|
/* until we need geometry shaders GL3.1 should suffice. */
|
||||||
/* Xephyr has its own copy of this for build reasons */
|
/* Xephyr has its own copy of this for build reasons */
|
||||||
|
@ -47,15 +42,8 @@
|
||||||
#define GLAMOR_GL_CORE_VER_MINOR 1
|
#define GLAMOR_GL_CORE_VER_MINOR 1
|
||||||
/** @{
|
/** @{
|
||||||
*
|
*
|
||||||
* global state for Xephyr with glamor.
|
* global state for Xephyr with glamor, all of which is arguably a bug.
|
||||||
*
|
|
||||||
* Xephyr can render with multiple windows, but all the windows have
|
|
||||||
* to be on the same X connection and all have to have the same
|
|
||||||
* visual.
|
|
||||||
*/
|
*/
|
||||||
static Display *dpy;
|
|
||||||
static XVisualInfo *visual_info;
|
|
||||||
static GLXFBConfig fb_config;
|
|
||||||
Bool ephyr_glamor_gles2;
|
Bool ephyr_glamor_gles2;
|
||||||
Bool ephyr_glamor_skip_present;
|
Bool ephyr_glamor_skip_present;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -64,9 +52,10 @@ Bool ephyr_glamor_skip_present;
|
||||||
* Per-screen state for Xephyr with glamor.
|
* Per-screen state for Xephyr with glamor.
|
||||||
*/
|
*/
|
||||||
struct ephyr_glamor {
|
struct ephyr_glamor {
|
||||||
GLXContext ctx;
|
EGLDisplay dpy;
|
||||||
Window win;
|
EGLContext ctx;
|
||||||
GLXWindow glx_win;
|
xcb_window_t win;
|
||||||
|
EGLSurface egl_win;
|
||||||
|
|
||||||
GLuint tex;
|
GLuint tex;
|
||||||
|
|
||||||
|
@ -178,16 +167,86 @@ ephyr_glamor_setup_texturing_shader(struct ephyr_glamor *glamor)
|
||||||
assert(glamor->texture_shader_texcoord_loc != -1);
|
assert(glamor->texture_shader_texcoord_loc != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef EGL_PLATFORM_XCB_EXT
|
||||||
|
#define EGL_PLATFORM_XCB_EXT 0x31DC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#ifndef RTLD_DEFAULT
|
||||||
|
#define RTLD_DEFAULT NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* (loud booing)
|
||||||
|
*
|
||||||
|
* keeping this as a static variable is bad form, we _could_ have zaphod heads
|
||||||
|
* on different displays (for example). but other bits of Xephyr are already
|
||||||
|
* broken for that case, and fixing that would entail fixing the rest of the
|
||||||
|
* contortions with hostx.c anyway, so this works for now.
|
||||||
|
*/
|
||||||
|
static EGLDisplay edpy = EGL_NO_DISPLAY;
|
||||||
|
|
||||||
xcb_connection_t *
|
xcb_connection_t *
|
||||||
ephyr_glamor_connect(void)
|
ephyr_glamor_connect(void)
|
||||||
{
|
{
|
||||||
dpy = XOpenDisplay(NULL);
|
int major = 0, minor = 0;
|
||||||
if (!dpy)
|
|
||||||
|
/*
|
||||||
|
* Try pure xcb first. If that doesn't work but we can find XOpenDisplay,
|
||||||
|
* fall back to xlib. This lets us potentially not load libX11 at all, if
|
||||||
|
* the EGL is also pure xcb.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (epoxy_has_egl_extension(EGL_NO_DISPLAY, "EGL_EXT_platform_xcb")) {
|
||||||
|
xcb_connection_t *conn = xcb_connect(NULL, NULL);
|
||||||
|
EGLDisplay dpy = glamor_egl_get_display(EGL_PLATFORM_XCB_EXT, conn);
|
||||||
|
|
||||||
|
if (dpy == EGL_NO_DISPLAY) {
|
||||||
|
xcb_disconnect(conn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
edpy = dpy;
|
||||||
|
eglInitialize(dpy, &major, &minor);
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (epoxy_has_egl_extension(EGL_NO_DISPLAY, "EGL_EXT_platform_x11") ||
|
||||||
|
epoxy_has_egl_extension(EGL_NO_DISPLAY, "EGL_KHR_platform_x11)")) {
|
||||||
|
void *lib = NULL;
|
||||||
|
xcb_connection_t *ret = NULL;
|
||||||
|
void *(*x_open_display)(void *) =
|
||||||
|
(void *) dlsym(RTLD_DEFAULT, "XOpenDisplay");
|
||||||
|
xcb_connection_t *(*x_get_xcb_connection)(void *) =
|
||||||
|
(void *) dlsym(RTLD_DEFAULT, "XGetXCBConnection");
|
||||||
|
|
||||||
|
if (x_open_display == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
|
if (x_get_xcb_connection == NULL) {
|
||||||
|
lib = dlopen("libX11-xcb.so.1", RTLD_LOCAL | RTLD_LAZY);
|
||||||
|
x_get_xcb_connection =
|
||||||
|
(void *) dlsym(lib, "XGetXCBConnection");
|
||||||
|
}
|
||||||
|
|
||||||
return XGetXCBConnection(dpy);
|
if (x_get_xcb_connection == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
void *xdpy = x_open_display(NULL);
|
||||||
|
EGLDisplay dpy = glamor_egl_get_display(EGL_PLATFORM_X11_KHR, xdpy);
|
||||||
|
if (dpy == EGL_NO_DISPLAY)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
edpy = dpy;
|
||||||
|
eglInitialize(dpy, &major, &minor);
|
||||||
|
ret = x_get_xcb_connection(xdpy);
|
||||||
|
out:
|
||||||
|
if (lib)
|
||||||
|
dlclose(lib);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -221,7 +280,7 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
|
||||||
if (ephyr_glamor_skip_present)
|
if (ephyr_glamor_skip_present)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glXMakeCurrent(dpy, glamor->glx_win, glamor->ctx);
|
eglMakeCurrent(glamor->dpy, glamor->egl_win, glamor->egl_win, glamor->ctx);
|
||||||
|
|
||||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
|
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &old_vao);
|
||||||
glBindVertexArray(glamor->vao);
|
glBindVertexArray(glamor->vao);
|
||||||
|
@ -238,53 +297,12 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
|
||||||
|
|
||||||
glBindVertexArray(old_vao);
|
glBindVertexArray(old_vao);
|
||||||
|
|
||||||
glXSwapBuffers(dpy, glamor->glx_win);
|
eglSwapBuffers(glamor->dpy, glamor->egl_win);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Xlib-based handling of xcb events for glamor.
|
|
||||||
*
|
|
||||||
* We need to let the Xlib event filtering run on the event so that
|
|
||||||
* Mesa's dri2_glx.c userspace event mangling gets run, and we
|
|
||||||
* correctly get our invalidate events propagated into the driver.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ephyr_glamor_process_event(xcb_generic_event_t *xev)
|
|
||||||
{
|
|
||||||
|
|
||||||
uint32_t response_type = xev->response_type & 0x7f;
|
|
||||||
/* Note the types on wire_to_event: there's an Xlib XEvent (with
|
|
||||||
* the broken types) that it returns, and a protocol xEvent that
|
|
||||||
* it inspects.
|
|
||||||
*/
|
|
||||||
Bool (*wire_to_event)(Display *dpy, XEvent *ret, xEvent *event);
|
|
||||||
|
|
||||||
XLockDisplay(dpy);
|
|
||||||
/* Set the event handler to NULL to get access to the current one. */
|
|
||||||
wire_to_event = XESetWireToEvent(dpy, response_type, NULL);
|
|
||||||
if (wire_to_event) {
|
|
||||||
XEvent processed_event;
|
|
||||||
|
|
||||||
/* OK they had an event handler. Plug it back in, and call
|
|
||||||
* through to it.
|
|
||||||
*/
|
|
||||||
XESetWireToEvent(dpy, response_type, wire_to_event);
|
|
||||||
xev->sequence = LastKnownRequestProcessed(dpy);
|
|
||||||
wire_to_event(dpy, &processed_event, (xEvent *)xev);
|
|
||||||
}
|
|
||||||
XUnlockDisplay(dpy);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
ephyr_glx_error_handler(Display * _dpy, XErrorEvent * ev)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ephyr_glamor *
|
struct ephyr_glamor *
|
||||||
ephyr_glamor_glx_screen_init(xcb_window_t win)
|
ephyr_glamor_screen_init(xcb_window_t win, xcb_visualid_t vid)
|
||||||
{
|
{
|
||||||
int (*oldErrorHandler) (Display *, XErrorEvent *);
|
|
||||||
static const float position[] = {
|
static const float position[] = {
|
||||||
-1, -1,
|
-1, -1,
|
||||||
1, -1,
|
1, -1,
|
||||||
|
@ -297,9 +315,9 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
|
||||||
};
|
};
|
||||||
GLint old_vao;
|
GLint old_vao;
|
||||||
|
|
||||||
GLXContext ctx;
|
EGLContext ctx;
|
||||||
struct ephyr_glamor *glamor;
|
struct ephyr_glamor *glamor;
|
||||||
GLXWindow glx_win;
|
EGLSurface egl_win;
|
||||||
|
|
||||||
glamor = calloc(1, sizeof(struct ephyr_glamor));
|
glamor = calloc(1, sizeof(struct ephyr_glamor));
|
||||||
if (!glamor) {
|
if (!glamor) {
|
||||||
|
@ -307,56 +325,49 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
glx_win = glXCreateWindow(dpy, fb_config, win, NULL);
|
const EGLint config_attribs[] = {
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
if (ephyr_glamor_gles2) {
|
EGL_NATIVE_VISUAL_ID, vid,
|
||||||
static const int context_attribs[] = {
|
EGL_NONE,
|
||||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
|
|
||||||
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
|
|
||||||
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT,
|
|
||||||
0,
|
|
||||||
};
|
};
|
||||||
if (epoxy_has_glx_extension(dpy, DefaultScreen(dpy),
|
EGLConfig config = EGL_NO_CONFIG_KHR;
|
||||||
"GLX_EXT_create_context_es2_profile")) {
|
int num_configs = 0;
|
||||||
ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True,
|
|
||||||
context_attribs);
|
/* (loud booing (see above)) */
|
||||||
} else {
|
glamor->dpy = edpy;
|
||||||
FatalError("Xephyr -glamor_gles2 requires "
|
|
||||||
"GLX_EXT_create_context_es2_profile\n");
|
eglChooseConfig(glamor->dpy, config_attribs, &config, 1, &num_configs);
|
||||||
}
|
if (num_configs != 1)
|
||||||
} else {
|
FatalError("Unable to find an EGLConfig for vid %#x\n", vid);
|
||||||
if (epoxy_has_glx_extension(dpy, DefaultScreen(dpy),
|
|
||||||
"GLX_ARB_create_context")) {
|
egl_win = eglCreatePlatformWindowSurfaceEXT(glamor->dpy, config,
|
||||||
static const int context_attribs[] = {
|
&win, NULL);
|
||||||
GLX_CONTEXT_PROFILE_MASK_ARB,
|
|
||||||
GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
if (ephyr_glamor_gles2)
|
||||||
GLX_CONTEXT_MAJOR_VERSION_ARB,
|
eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
GLAMOR_GL_CORE_VER_MAJOR,
|
else
|
||||||
GLX_CONTEXT_MINOR_VERSION_ARB,
|
eglBindAPI(EGL_OPENGL_API);
|
||||||
GLAMOR_GL_CORE_VER_MINOR,
|
|
||||||
0,
|
EGLint context_attribs[5];
|
||||||
};
|
int i = 0;
|
||||||
oldErrorHandler = XSetErrorHandler(ephyr_glx_error_handler);
|
context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
|
||||||
ctx = glXCreateContextAttribsARB(dpy, fb_config, NULL, True,
|
context_attribs[i++] = ephyr_glamor_gles2 ? 2 : 3;
|
||||||
context_attribs);
|
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
|
||||||
XSync(dpy, False);
|
context_attribs[i++] = ephyr_glamor_gles2 ? 0 : 1;
|
||||||
XSetErrorHandler(oldErrorHandler);
|
context_attribs[i++] = EGL_NONE;
|
||||||
} else {
|
|
||||||
ctx = NULL;
|
ctx = eglCreateContext(glamor->dpy, config, EGL_NO_CONTEXT,
|
||||||
}
|
context_attribs);
|
||||||
|
|
||||||
if (!ctx)
|
|
||||||
ctx = glXCreateContext(dpy, visual_info, NULL, True);
|
|
||||||
}
|
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
FatalError("glXCreateContext failed\n");
|
FatalError("eglCreateContext failed\n");
|
||||||
|
|
||||||
if (!glXMakeCurrent(dpy, glx_win, ctx))
|
if (!eglMakeCurrent(glamor->dpy, egl_win, egl_win, ctx))
|
||||||
FatalError("glXMakeCurrent failed\n");
|
FatalError("eglMakeCurrent failed\n");
|
||||||
|
|
||||||
glamor->ctx = ctx;
|
glamor->ctx = ctx;
|
||||||
glamor->win = win;
|
glamor->win = win;
|
||||||
glamor->glx_win = glx_win;
|
glamor->egl_win = egl_win;
|
||||||
ephyr_glamor_setup_texturing_shader(glamor);
|
ephyr_glamor_setup_texturing_shader(glamor);
|
||||||
|
|
||||||
glGenVertexArrays(1, &glamor->vao);
|
glGenVertexArrays(1, &glamor->vao);
|
||||||
|
@ -375,48 +386,17 @@ ephyr_glamor_glx_screen_init(xcb_window_t win)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor)
|
ephyr_glamor_screen_fini(struct ephyr_glamor *glamor)
|
||||||
{
|
{
|
||||||
glXMakeCurrent(dpy, None, NULL);
|
eglMakeCurrent(glamor->dpy,
|
||||||
glXDestroyContext(dpy, glamor->ctx);
|
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||||
glXDestroyWindow(dpy, glamor->glx_win);
|
EGL_NO_CONTEXT);
|
||||||
|
eglDestroyContext(glamor->dpy, glamor->ctx);
|
||||||
|
eglDestroySurface(glamor->dpy, glamor->egl_win);
|
||||||
|
|
||||||
free(glamor);
|
free(glamor);
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_visualtype_t *
|
|
||||||
ephyr_glamor_get_visual(void)
|
|
||||||
{
|
|
||||||
xcb_screen_t *xscreen =
|
|
||||||
xcb_aux_get_screen(XGetXCBConnection(dpy), DefaultScreen(dpy));
|
|
||||||
int attribs[] = {
|
|
||||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
|
||||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
|
||||||
GLX_RED_SIZE, 1,
|
|
||||||
GLX_GREEN_SIZE, 1,
|
|
||||||
GLX_BLUE_SIZE, 1,
|
|
||||||
GLX_DOUBLEBUFFER, 1,
|
|
||||||
None
|
|
||||||
};
|
|
||||||
int event_base = 0, error_base = 0, nelements;
|
|
||||||
GLXFBConfig *fbconfigs;
|
|
||||||
|
|
||||||
if (!glXQueryExtension (dpy, &error_base, &event_base))
|
|
||||||
FatalError("Couldn't find GLX extension\n");
|
|
||||||
|
|
||||||
fbconfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &nelements);
|
|
||||||
if (!nelements)
|
|
||||||
FatalError("Couldn't choose an FBConfig\n");
|
|
||||||
fb_config = fbconfigs[0];
|
|
||||||
free(fbconfigs);
|
|
||||||
|
|
||||||
visual_info = glXGetVisualFromFBConfig(dpy, fb_config);
|
|
||||||
if (visual_info == NULL)
|
|
||||||
FatalError("Couldn't get RGB visual\n");
|
|
||||||
|
|
||||||
return xcb_aux_find_visual_by_id(xscreen, visual_info->visualid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ephyr_glamor_set_window_size(struct ephyr_glamor *glamor,
|
ephyr_glamor_set_window_size(struct ephyr_glamor *glamor,
|
||||||
unsigned width, unsigned height)
|
unsigned width, unsigned height)
|
|
@ -21,13 +21,6 @@
|
||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* ephyr_glamor_glx.h
|
|
||||||
*
|
|
||||||
* Prototypes exposed by ephyr_glamor_glx.c, without including any
|
|
||||||
* server headers.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include "dix-config.h"
|
#include "dix-config.h"
|
||||||
|
|
||||||
|
@ -40,14 +33,11 @@ ephyr_glamor_connect(void);
|
||||||
void
|
void
|
||||||
ephyr_glamor_set_texture(struct ephyr_glamor *ephyr_glamor, uint32_t tex);
|
ephyr_glamor_set_texture(struct ephyr_glamor *ephyr_glamor, uint32_t tex);
|
||||||
|
|
||||||
xcb_visualtype_t *
|
|
||||||
ephyr_glamor_get_visual(void);
|
|
||||||
|
|
||||||
struct ephyr_glamor *
|
struct ephyr_glamor *
|
||||||
ephyr_glamor_glx_screen_init(xcb_window_t win);
|
ephyr_glamor_screen_init(xcb_window_t win, xcb_visualid_t vid);
|
||||||
|
|
||||||
void
|
void
|
||||||
ephyr_glamor_glx_screen_fini(struct ephyr_glamor *glamor);
|
ephyr_glamor_screen_fini(struct ephyr_glamor *glamor);
|
||||||
|
|
||||||
#ifdef GLAMOR
|
#ifdef GLAMOR
|
||||||
void
|
void
|
||||||
|
@ -58,9 +48,6 @@ void
|
||||||
ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
|
ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
|
||||||
struct pixman_region16 *damage);
|
struct pixman_region16 *damage);
|
||||||
|
|
||||||
void
|
|
||||||
ephyr_glamor_process_event(xcb_generic_event_t *xev);
|
|
||||||
|
|
||||||
#else /* !GLAMOR */
|
#else /* !GLAMOR */
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -75,9 +62,4 @@ ephyr_glamor_damage_redisplay(struct ephyr_glamor *glamor,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
ephyr_glamor_process_event(xcb_generic_event_t *xev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !GLAMOR */
|
#endif /* !GLAMOR */
|
|
@ -57,7 +57,7 @@
|
||||||
#ifdef GLAMOR
|
#ifdef GLAMOR
|
||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
#include "glamor.h"
|
#include "glamor.h"
|
||||||
#include "ephyr_glamor_glx.h"
|
#include "ephyr_glamor.h"
|
||||||
#endif
|
#endif
|
||||||
#include "ephyrlog.h"
|
#include "ephyrlog.h"
|
||||||
#include "ephyr.h"
|
#include "ephyr.h"
|
||||||
|
@ -556,21 +556,7 @@ hostx_init(void)
|
||||||
HostX.winroot = xscreen->root;
|
HostX.winroot = xscreen->root;
|
||||||
HostX.gc = xcb_generate_id(HostX.conn);
|
HostX.gc = xcb_generate_id(HostX.conn);
|
||||||
HostX.depth = xscreen->root_depth;
|
HostX.depth = xscreen->root_depth;
|
||||||
#ifdef GLAMOR
|
HostX.visual = xcb_aux_find_visual_by_id(xscreen, xscreen->root_visual);
|
||||||
if (ephyr_glamor) {
|
|
||||||
HostX.visual = ephyr_glamor_get_visual();
|
|
||||||
if (HostX.visual->visual_id != xscreen->root_visual) {
|
|
||||||
attrs[1] = xcb_generate_id(HostX.conn);
|
|
||||||
attr_mask |= XCB_CW_COLORMAP;
|
|
||||||
xcb_create_colormap(HostX.conn,
|
|
||||||
XCB_COLORMAP_ALLOC_NONE,
|
|
||||||
attrs[1],
|
|
||||||
HostX.winroot,
|
|
||||||
HostX.visual->visual_id);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
HostX.visual = xcb_aux_find_visual_by_id(xscreen,xscreen->root_visual);
|
|
||||||
|
|
||||||
xcb_create_gc(HostX.conn, HostX.gc, HostX.winroot, 0, NULL);
|
xcb_create_gc(HostX.conn, HostX.gc, HostX.winroot, 0, NULL);
|
||||||
cookie_WINDOW_STATE = xcb_intern_atom(HostX.conn, FALSE,
|
cookie_WINDOW_STATE = xcb_intern_atom(HostX.conn, FALSE,
|
||||||
|
@ -586,6 +572,7 @@ hostx_init(void)
|
||||||
EphyrScrPriv *scrpriv = screen->driver;
|
EphyrScrPriv *scrpriv = screen->driver;
|
||||||
|
|
||||||
scrpriv->win = xcb_generate_id(HostX.conn);
|
scrpriv->win = xcb_generate_id(HostX.conn);
|
||||||
|
scrpriv->vid = xscreen->root_visual;
|
||||||
scrpriv->server_depth = HostX.depth;
|
scrpriv->server_depth = HostX.depth;
|
||||||
scrpriv->ximg = NULL;
|
scrpriv->ximg = NULL;
|
||||||
scrpriv->win_x = 0;
|
scrpriv->win_x = 0;
|
||||||
|
@ -1570,11 +1557,11 @@ ephyr_glamor_init(ScreenPtr screen)
|
||||||
KdScreenInfo *kd_screen = pScreenPriv->screen;
|
KdScreenInfo *kd_screen = pScreenPriv->screen;
|
||||||
EphyrScrPriv *scrpriv = kd_screen->driver;
|
EphyrScrPriv *scrpriv = kd_screen->driver;
|
||||||
|
|
||||||
scrpriv->glamor = ephyr_glamor_glx_screen_init(scrpriv->win);
|
scrpriv->glamor = ephyr_glamor_screen_init(scrpriv->win, scrpriv->vid);
|
||||||
ephyr_glamor_set_window_size(scrpriv->glamor,
|
ephyr_glamor_set_window_size(scrpriv->glamor,
|
||||||
scrpriv->win_width, scrpriv->win_height);
|
scrpriv->win_width, scrpriv->win_height);
|
||||||
|
|
||||||
if (!glamor_init(screen, 0)) {
|
if (!glamor_init(screen, GLAMOR_USE_EGL_SCREEN)) {
|
||||||
FatalError("Failed to initialize glamor\n");
|
FatalError("Failed to initialize glamor\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -1660,7 +1647,7 @@ ephyr_glamor_fini(ScreenPtr screen)
|
||||||
EphyrScrPriv *scrpriv = kd_screen->driver;
|
EphyrScrPriv *scrpriv = kd_screen->driver;
|
||||||
|
|
||||||
glamor_fini(screen);
|
glamor_fini(screen);
|
||||||
ephyr_glamor_glx_screen_fini(scrpriv->glamor);
|
ephyr_glamor_screen_fini(scrpriv->glamor);
|
||||||
scrpriv->glamor = NULL;
|
scrpriv->glamor = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,13 +23,12 @@ xephyr_dep = [
|
||||||
|
|
||||||
xephyr_glamor = []
|
xephyr_glamor = []
|
||||||
if build_glamor
|
if build_glamor
|
||||||
srcs += 'ephyr_glamor_glx.c'
|
srcs += 'ephyr_glamor.c'
|
||||||
if build_xv
|
if build_xv
|
||||||
srcs += 'ephyr_glamor_xv.c'
|
srcs += 'ephyr_glamor_xv.c'
|
||||||
endif
|
endif
|
||||||
xephyr_glamor += glamor
|
xephyr_glamor += glamor
|
||||||
xephyr_glamor += glamor_egl_stubs
|
xephyr_glamor += glamor_egl_stubs
|
||||||
xephyr_dep += dependency('x11-xcb')
|
|
||||||
xephyr_dep += epoxy_dep
|
xephyr_dep += epoxy_dep
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue