summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Turney <jon.turney@dronecode.org.uk>2014-07-24 12:29:41 +0100
committerJon Turney <jon.turney@dronecode.org.uk>2016-09-15 20:10:29 +0100
commitf5f4d32ac7c250cfbfb94883ce7d7e46151e89f0 (patch)
tree77243281387f60da6743694bb7153e1508910046
parent52d6a1e832a5e62289dd4f32824ae16a78dfd7e8 (diff)
Add Windows-DRI extension
If windowsdriproto headers are available, build a Windows-DRI extension, which supports requests to enable local clients to directly render GL to a Windows drawable: - a query to check if WGL is being used on a screen - a query to map a fbconfigID to a native pixelformatindex - a query to map a drawable to a native handle Windows-DRI can only be useful if we are using WGL, so make an note if WGL is active on a screen. Make validGlxDrawable() public Adjust glxWinSetPixelFormat() so it doesn't require a context, just a screen and config. That enables factoring out the deferred drawable creation code as glxWinDeferredCreateDrawable() Enhance glxWinDeferredCreateDrawable(), so that pixmaps are placed into a file mapping, so they exist in memory which can be shared with the direct rendering process. Currently, this file mapping is accessed by a name generated from the XID. This will not be unique across multiple server instances. It would perhaps be better, although more complicated, to use an anonymous file mapping, and then duplicate the handle for the direct rendering process. Use glxWinDeferredCreateDrawable() to ensure the native handle exists for the Windows-DRI query to map a drawable to native handle. v2: Various printf format warning fixes v3: Fix format warnings on x86 Move some uninteresting windows-dri output to debug log level v4: check for windowsdriproto when --enable-windowsdri use windowsdriproto_CFLAGS Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk> Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
-rw-r--r--configure.ac10
-rw-r--r--glx/glxcmds.c2
-rw-r--r--glx/glxdrawable.h3
-rw-r--r--hw/xwin/InitOutput.c4
-rw-r--r--hw/xwin/Makefile.am14
-rw-r--r--hw/xwin/dri/Makefile.am9
-rw-r--r--hw/xwin/dri/windowsdri.c274
-rw-r--r--hw/xwin/dri/windowsdri.h30
-rw-r--r--hw/xwin/glx/Makefile.am7
-rw-r--r--hw/xwin/glx/dri_helpers.c120
-rw-r--r--hw/xwin/glx/dri_helpers.h38
-rw-r--r--hw/xwin/glx/indirect.c388
-rw-r--r--hw/xwin/glx/indirect.h95
-rw-r--r--hw/xwin/glx/winpriv.c7
-rw-r--r--hw/xwin/glx/winpriv.h1
-rw-r--r--hw/xwin/win.h2
-rw-r--r--include/protocol-versions.h5
17 files changed, 808 insertions, 201 deletions
diff --git a/configure.ac b/configure.ac
index 4ff317f53..4b2b4f67f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -637,6 +637,7 @@ AC_ARG_ENABLE(vgahw, AS_HELP_STRING([--enable-vgahw], [Build Xorg with
AC_ARG_ENABLE(vbe, AS_HELP_STRING([--enable-vbe], [Build Xorg with VBE module (default: enabled)]), [VBE=$enableval], [VBE=yes])
AC_ARG_ENABLE(int10-module, AS_HELP_STRING([--enable-int10-module], [Build Xorg with int10 module (default: enabled)]), [INT10MODULE=$enableval], [INT10MODULE=yes])
AC_ARG_ENABLE(windowswm, AS_HELP_STRING([--enable-windowswm], [Build XWin with WindowsWM extension (default: no)]), [WINDOWSWM=$enableval], [WINDOWSWM=no])
+AC_ARG_ENABLE(windowsdri, AS_HELP_STRING([--enable-windowsdri], [Build XWin with WindowsDRI extension (default: auto)]), [WINDOWSDRI=$enableval], [WINDOWSDRI=auto])
AC_ARG_ENABLE(libdrm, AS_HELP_STRING([--enable-libdrm], [Build Xorg with libdrm support (default: enabled)]), [DRM=$enableval],[DRM=yes])
AC_ARG_ENABLE(clientids, AS_HELP_STRING([--disable-clientids], [Build Xorg with client ID tracking (default: enabled)]), [CLIENTIDS=$enableval], [CLIENTIDS=yes])
AC_ARG_ENABLE(pciaccess, AS_HELP_STRING([--enable-pciaccess], [Build Xorg with pciaccess library (default: enabled)]), [PCI=$enableval], [PCI=yes])
@@ -2230,6 +2231,13 @@ if test "x$XWIN" = xyes; then
AC_DEFINE(ROOTLESS,1,[Build Rootless code])
fi
+ if test "x$WINDOWSDRI" = xauto; then
+ PKG_CHECK_EXISTS([windowsdriproto], [WINDOWSDRI=yes], [WINDOWSDRI=no])
+ fi
+ if test "x$WINDOWSDRI" = xyes ; then
+ PKG_CHECK_MODULES(WINDOWSDRI, [windowsdriproto])
+ fi
+
case $host_os in
cygwin*)
XWIN_SERVER_NAME=XWin
@@ -2283,6 +2291,7 @@ AM_CONDITIONAL(XWIN_MULTIWINDOW, [test "x$XWIN" = xyes])
AM_CONDITIONAL(XWIN_MULTIWINDOWEXTWM, [test "x$XWIN" = xyes && test "x$WINDOWSWM" = xyes])
AM_CONDITIONAL(XWIN_CLIPBOARD, [test "x$XWIN" = xyes])
AM_CONDITIONAL(XWIN_GLX_WINDOWS, [test "x$XWIN" = xyes && test "x$AIGLX" = xyes])
+AM_CONDITIONAL(XWIN_WINDOWS_DRI, [test "x$XWIN" = xyes && test "x$WINDOWSDRI" = xyes])
AM_CONDITIONAL(XWIN_RANDR, [test "x$XWIN" = xyes])
AM_CONDITIONAL(XWIN_XV, [test "x$XWIN" = xyes && test "x$XV" = xyes])
@@ -2685,6 +2694,7 @@ hw/vfb/man/Makefile
hw/xnest/Makefile
hw/xnest/man/Makefile
hw/xwin/Makefile
+hw/xwin/dri/Makefile
hw/xwin/glx/Makefile
hw/xwin/man/Makefile
hw/xwin/winclipboard/Makefile
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 481dfb9e3..5873cb49c 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -146,7 +146,7 @@ validGlxContext(ClientPtr client, XID id, int access_mode,
return TRUE;
}
-static int
+int
validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
__GLXdrawable ** drawable, int *err)
{
diff --git a/glx/glxdrawable.h b/glx/glxdrawable.h
index 007658961..441d72dd7 100644
--- a/glx/glxdrawable.h
+++ b/glx/glxdrawable.h
@@ -74,4 +74,7 @@ struct __GLXdrawable {
unsigned long eventMask;
};
+extern int validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
+ __GLXdrawable **drawable, int *err);
+
#endif /* !__GLX_drawable_h__ */
diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c
index 462101262..edd526647 100644
--- a/hw/xwin/InitOutput.c
+++ b/hw/xwin/InitOutput.c
@@ -66,6 +66,7 @@ typedef WINAPI HRESULT(*SHGETFOLDERPATHPROC) (HWND hwndOwner,
#include "glx_extinit.h"
#ifdef XWIN_GLX_WINDOWS
#include "glx/glwindows.h"
+#include "dri/windowsdri.h"
#endif
/*
@@ -117,6 +118,9 @@ const int NUMFORMATS = sizeof(g_PixmapFormats) / sizeof(g_PixmapFormats[0]);
static const ExtensionModule xwinExtensions[] = {
#ifdef GLXEXT
{ GlxExtensionInit, "GLX", &noGlxExtension },
+#ifdef XWIN_WINDOWS_DRI
+ { WindowsDRIExtensionInit, "Windows-DRI", &noDriExtension },
+#endif
#endif
};
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am
index 4da3d12a4..50b4d9f6b 100644
--- a/hw/xwin/Makefile.am
+++ b/hw/xwin/Makefile.am
@@ -9,9 +9,17 @@ CLIPBOARD_LIBS = $(top_builddir)/hw/xwin/winclipboard/libXWinclipboard.la
endif
if XWIN_GLX_WINDOWS
-GLX_DIR = glx
-DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS
-XWIN_GLX_LIBS = $(top_builddir)/hw/xwin/glx/libXwinGLX.la
+GLX_DIR =
+DEFS_GLX_WINDOWS =
+XWIN_GLX_LIBS =
+if XWIN_WINDOWS_DRI
+GLX_DIR += dri
+DEFS_GLX_WINDOWS += -DXWIN_WINDOWS_DRI
+XWIN_GLX_LIBS += $(top_builddir)/hw/xwin/dri/libWindowsDRI.la
+endif
+GLX_DIR += glx
+DEFS_GLX_WINDOWS += -DXWIN_GLX_WINDOWS
+XWIN_GLX_LIBS += $(top_builddir)/hw/xwin/glx/libXwinGLX.la
XWIN_GLX_SYS_LIBS = -lopengl32
endif
diff --git a/hw/xwin/dri/Makefile.am b/hw/xwin/dri/Makefile.am
new file mode 100644
index 000000000..948c2b5c6
--- /dev/null
+++ b/hw/xwin/dri/Makefile.am
@@ -0,0 +1,9 @@
+noinst_LTLIBRARIES = libWindowsDRI.la
+
+libWindowsDRI_la_SOURCES = \
+ windowsdri.c \
+ windowsdri.h
+
+AM_CFLAGS = $(DIX_CFLAGS) \
+ @WINDOWSDRI_CFLAGS@ \
+ -I$(top_srcdir)/hw/xwin/
diff --git a/hw/xwin/dri/windowsdri.c b/hw/xwin/dri/windowsdri.c
new file mode 100644
index 000000000..3666e97dd
--- /dev/null
+++ b/hw/xwin/dri/windowsdri.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright © 2014 Jon Turney
+ *
+ * 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/windowsdristr.h>
+
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "scrnintstr.h"
+#include "swaprep.h"
+#include "protocol-versions.h"
+#include "windowsdri.h"
+#include "glx/dri_helpers.h"
+
+static int WindowsDRIErrorBase = 0;
+static unsigned char WindowsDRIReqCode = 0;
+static int WindowsDRIEventBase = 0;
+
+static void
+WindowsDRIResetProc(ExtensionEntry* extEntry)
+{
+}
+
+static int
+ProcWindowsDRIQueryVersion(ClientPtr client)
+{
+ xWindowsDRIQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xWindowsDRIQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_WINDOWSDRI_MAJOR_VERSION;
+ rep.minorVersion = SERVER_WINDOWSDRI_MINOR_VERSION;
+ rep.patchVersion = SERVER_WINDOWSDRI_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swaps(&rep.majorVersion);
+ swaps(&rep.minorVersion);
+ swapl(&rep.patchVersion);
+ }
+ WriteToClient(client, sizeof(xWindowsDRIQueryVersionReply), &rep);
+ return Success;
+}
+
+static int
+ProcWindowsDRIQueryDirectRenderingCapable(ClientPtr client)
+{
+ xWindowsDRIQueryDirectRenderingCapableReply rep;
+
+ REQUEST(xWindowsDRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xWindowsDRIQueryDirectRenderingCapableReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!client->local)
+ rep.isCapable = 0;
+ else
+ rep.isCapable = glxWinGetScreenAiglxIsActive(screenInfo.screens[stuff->screen]);
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ }
+
+ WriteToClient(client,
+ sizeof(xWindowsDRIQueryDirectRenderingCapableReply),
+ &rep);
+ return Success;
+}
+
+static int
+ProcWindowsDRIQueryDrawable(ClientPtr client)
+{
+ xWindowsDRIQueryDrawableReply rep;
+ int rc;
+
+ REQUEST(xWindowsDRIQueryDrawableReq);
+ REQUEST_SIZE_MATCH(xWindowsDRIQueryDrawableReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = glxWinQueryDrawable(client, stuff->drawable, &(rep.drawable_type), &(rep.handle));
+
+ if (rc)
+ return rc;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.handle);
+ swapl(&rep.drawable_type);
+ }
+
+ WriteToClient(client, sizeof(xWindowsDRIQueryDrawableReply), &rep);
+ return Success;
+}
+
+static int
+ProcWindowsDRIFBConfigToPixelFormat(ClientPtr client)
+{
+ xWindowsDRIFBConfigToPixelFormatReply rep;
+
+ REQUEST(xWindowsDRIFBConfigToPixelFormatReq);
+ REQUEST_SIZE_MATCH(xWindowsDRIFBConfigToPixelFormatReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rep.pixelFormatIndex = glxWinFBConfigIDToPixelFormatIndex(stuff->screen, stuff->fbConfigID);
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber);
+ swapl(&rep.length);
+ swapl(&rep.pixelFormatIndex);
+ }
+
+ WriteToClient(client, sizeof(xWindowsDRIFBConfigToPixelFormatReply), &rep);
+ return Success;
+}
+
+/* dispatch */
+
+static int
+ProcWindowsDRIDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data) {
+ case X_WindowsDRIQueryVersion:
+ return ProcWindowsDRIQueryVersion(client);
+
+ case X_WindowsDRIQueryDirectRenderingCapable:
+ return ProcWindowsDRIQueryDirectRenderingCapable(client);
+ }
+
+ if (!client->local)
+ return WindowsDRIErrorBase + WindowsDRIClientNotLocal;
+
+ switch (stuff->data) {
+ case X_WindowsDRIQueryDrawable:
+ return ProcWindowsDRIQueryDrawable(client);
+
+ case X_WindowsDRIFBConfigToPixelFormat:
+ return ProcWindowsDRIFBConfigToPixelFormat(client);
+
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SNotifyEvent(xWindowsDRINotifyEvent *from,
+ xWindowsDRINotifyEvent *to)
+{
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->time, to->time);
+}
+
+static int
+SProcWindowsDRIQueryVersion(ClientPtr client)
+{
+ REQUEST(xWindowsDRIQueryVersionReq);
+ swaps(&stuff->length);
+ return ProcWindowsDRIQueryVersion(client);
+}
+
+static int
+SProcWindowsDRIQueryDirectRenderingCapable(ClientPtr client)
+{
+ REQUEST(xWindowsDRIQueryDirectRenderingCapableReq);
+ swaps(&stuff->length);
+ swapl(&stuff->screen);
+ return ProcWindowsDRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcWindowsDRIQueryDrawable(ClientPtr client)
+{
+ REQUEST(xWindowsDRIQueryDrawableReq);
+ swaps(&stuff->length);
+ swapl(&stuff->screen);
+ swapl(&stuff->drawable);
+ return ProcWindowsDRIQueryDrawable(client);
+}
+
+static int
+SProcWindowsDRIFBConfigToPixelFormat(ClientPtr client)
+{
+ REQUEST(xWindowsDRIFBConfigToPixelFormatReq);
+ swaps(&stuff->length);
+ swapl(&stuff->screen);
+ swapl(&stuff->fbConfigID);
+ return ProcWindowsDRIFBConfigToPixelFormat(client);
+}
+
+static int
+SProcWindowsDRIDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data) {
+ case X_WindowsDRIQueryVersion:
+ return SProcWindowsDRIQueryVersion(client);
+
+ case X_WindowsDRIQueryDirectRenderingCapable:
+ return SProcWindowsDRIQueryDirectRenderingCapable(client);
+ }
+
+ if (!client->local)
+ return WindowsDRIErrorBase + WindowsDRIClientNotLocal;
+
+ switch (stuff->data) {
+ case X_WindowsDRIQueryDrawable:
+ return SProcWindowsDRIQueryDrawable(client);
+
+ case X_WindowsDRIFBConfigToPixelFormat:
+ return SProcWindowsDRIFBConfigToPixelFormat(client);
+
+ default:
+ return BadRequest;
+ }
+}
+
+void
+WindowsDRIExtensionInit(void)
+{
+ ExtensionEntry* extEntry;
+
+ if ((extEntry = AddExtension(WINDOWSDRINAME,
+ WindowsDRINumberEvents,
+ WindowsDRINumberErrors,
+ ProcWindowsDRIDispatch,
+ SProcWindowsDRIDispatch,
+ WindowsDRIResetProc,
+ StandardMinorOpcode))) {
+ size_t i;
+ WindowsDRIReqCode = (unsigned char)extEntry->base;
+ WindowsDRIErrorBase = extEntry->errorBase;
+ WindowsDRIEventBase = extEntry->eventBase;
+ for (i = 0; i < WindowsDRINumberEvents; i++)
+ EventSwapVector[WindowsDRIEventBase + i] = (EventSwapPtr)SNotifyEvent;
+ }
+}
diff --git a/hw/xwin/dri/windowsdri.h b/hw/xwin/dri/windowsdri.h
new file mode 100644
index 000000000..852b716b0
--- /dev/null
+++ b/hw/xwin/dri/windowsdri.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2014 Jon Turney
+ *
+ * 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.
+ */
+
+#ifndef windowsdri_h
+#define windowsdri_h
+
+void WindowsDRIExtensionInit(void);
+Bool noDriExtension;
+
+#endif /* windowsdri_h */
diff --git a/hw/xwin/glx/Makefile.am b/hw/xwin/glx/Makefile.am
index f2dffbffb..599ec37cc 100644
--- a/hw/xwin/glx/Makefile.am
+++ b/hw/xwin/glx/Makefile.am
@@ -7,9 +7,16 @@ libXwinGLX_la_SOURCES = \
glwindows.h \
glshim.c \
indirect.c \
+ indirect.h \
wgl_ext_api.c \
wgl_ext_api.h
+if XWIN_WINDOWS_DRI
+libXwinGLX_la_SOURCES += \
+ dri_helpers.c \
+ dri_helpers.h
+endif
+
libnativeGLthunk_la_SOURCES = \
glthunk.c
diff --git a/hw/xwin/glx/dri_helpers.c b/hw/xwin/glx/dri_helpers.c
new file mode 100644
index 000000000..5ccec74b6
--- /dev/null
+++ b/hw/xwin/glx/dri_helpers.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2014 Jon Turney
+ *
+ * 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.
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
+#include <glx/glxserver.h>
+#include <glx/glxutil.h>
+#include <X11/extensions/windowsdriconst.h>
+
+#include "indirect.h"
+#include "winpriv.h"
+#include "dri_helpers.h"
+#include "win.h"
+
+int
+glxWinQueryDrawable(ClientPtr client, XID drawId, unsigned int *type, unsigned int *handle)
+{
+ __GLXWinDrawable *pDrawable;
+ int err;
+
+ if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
+ DixReadAccess, (__GLXdrawable **)&pDrawable, &err)) {
+
+ switch (pDrawable->base.type)
+ {
+ case GLX_DRAWABLE_WINDOW:
+ {
+ HWND h = winGetWindowInfo((WindowPtr)(pDrawable->base.pDraw));
+ *handle = (uintptr_t)h;
+ *type = WindowsDRIDrawableWindow;
+ }
+ break;
+
+ case GLX_DRAWABLE_PIXMAP:
+ glxWinDeferredCreateDrawable(pDrawable, pDrawable->base.config);
+ *handle = pDrawable->base.pDraw->id;
+ // The XID is used to create a unique name for a file mapping
+ // shared with the requesting process
+ //
+ // XXX: Alternatively, we could use an anonymous file mapping
+ // and use DuplicateHandle to make pDrawable->hSection available
+ // to the requesting process... ?
+ *type = WindowsDRIDrawablePixmap;
+ break;
+
+ case GLX_DRAWABLE_PBUFFER:
+ glxWinDeferredCreateDrawable(pDrawable, pDrawable->base.config);
+ *handle = (uintptr_t)(pDrawable->hPbuffer);
+ *type = WindowsDRIDrawablePbuffer;
+ break;
+
+ default:
+ assert(FALSE);
+ *handle = 0;
+ }
+ }
+ else {
+ HWND h;
+ /* The drawId XID doesn't identify a GLX drawable. The only other valid
+ alternative is that it is the XID of a window drawable that is being
+ used by the pre-GLX 1.3 interface */
+ DrawablePtr pDraw;
+ int rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
+ if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
+ return err;
+ }
+
+ h = winGetWindowInfo((WindowPtr)(pDraw));
+ *handle = (uintptr_t)h;
+ *type = WindowsDRIDrawableWindow;
+ }
+
+ winDebug("glxWinQueryDrawable: type %d, handle %p\n", *type, (void *)(uintptr_t)*handle);
+ return Success;
+}
+
+int
+glxWinFBConfigIDToPixelFormatIndex(int scr, int fbConfigID)
+{
+ __GLXscreen *screen = glxGetScreen(screenInfo.screens[scr]);
+ __GLXconfig *c;
+
+ for (c = screen->fbconfigs;
+ c != NULL;
+ c = c->next) {
+ if (c->fbconfigID == fbConfigID)
+ return ((GLXWinConfig *)c)->pixelFormatIndex;
+ }
+
+ return 0;
+}
+
+Bool
+glxWinGetScreenAiglxIsActive(ScreenPtr pScreen)
+{
+ winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen);
+ return pWinScreen->fNativeGlActive;
+}
diff --git a/hw/xwin/glx/dri_helpers.h b/hw/xwin/glx/dri_helpers.h
new file mode 100644
index 000000000..a32c965d7
--- /dev/null
+++ b/hw/xwin/glx/dri_helpers.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2014 Jon Turney
+ *
+ * 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.
+ */
+
+#ifndef dri_helpers_h
+#define dri_helpers_h
+
+#include "dixstruct.h"
+
+int
+glxWinQueryDrawable(ClientPtr client, XID drawId, unsigned int *type, unsigned int *handle);
+
+int
+glxWinFBConfigIDToPixelFormatIndex(int scr, int fbConfigID);
+
+Bool
+glxWinGetScreenAiglxIsActive(ScreenPtr pScreen);
+
+#endif /* dri_helpers_h */
diff --git a/hw/xwin/glx/indirect.c b/hw/xwin/glx/indirect.c
index 918425245..239327ed4 100644
--- a/hw/xwin/glx/indirect.c
+++ b/hw/xwin/glx/indirect.c
@@ -81,12 +81,12 @@
#include "glwindows.h"
#include <glx/glxserver.h>
#include <glx/glxutil.h>
-#include <glx/extension_string.h>
#include <GL/glxtokens.h>
#include <winpriv.h>
#include <wgl_ext_api.h>
#include <winglobals.h>
+#include <indirect.h>
#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1]))
@@ -101,57 +101,6 @@
#define PFD_SUPPORT_COMPOSITION 0x00008000
#endif
-/* ---------------------------------------------------------------------- */
-/*
- * structure definitions
- */
-
-typedef struct __GLXWinContext __GLXWinContext;
-typedef struct __GLXWinDrawable __GLXWinDrawable;
-typedef struct __GLXWinScreen glxWinScreen;
-typedef struct __GLXWinConfig GLXWinConfig;
-
-struct __GLXWinContext {
- __GLXcontext base;
- HGLRC ctx; /* Windows GL Context */
- __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */
- HWND hwnd; /* For detecting when HWND has changed */
-};
-
-struct __GLXWinDrawable {
- __GLXdrawable base;
- __GLXWinContext *drawContext;
- __GLXWinContext *readContext;
-
- /* If this drawable is GLX_DRAWABLE_PBUFFER */
- HPBUFFERARB hPbuffer;
-
- /* If this drawable is GLX_DRAWABLE_PIXMAP */
- HDC dibDC;
- HBITMAP hDIB;
- HBITMAP hOldDIB; /* original DIB for DC */
- void *pOldBits; /* original pBits for this drawable's pixmap */
-};
-
-struct __GLXWinScreen {
- __GLXscreen base;
-
- Bool has_WGL_ARB_multisample;
- Bool has_WGL_ARB_pixel_format;
- Bool has_WGL_ARB_pbuffer;
- Bool has_WGL_ARB_render_texture;
- Bool has_WGL_ARB_make_current_read;
-
- /* wrapped screen functions */
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- CopyWindowProcPtr CopyWindow;
-};
-
-struct __GLXWinConfig {
- __GLXconfig base;
- int pixelFormatIndex;
-};
/* ---------------------------------------------------------------------- */
/*
@@ -417,7 +366,8 @@ static Bool glxWinRealizeWindow(WindowPtr pWin);
static Bool glxWinUnrealizeWindow(WindowPtr pWin);
static void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg,
RegionPtr prgnSrc);
-
+static Bool glxWinSetPixelFormat(HDC hdc, int bppOverride, int drawableTypeOverride,
+ __GLXscreen *screen, __GLXconfig *config);
static HDC glxWinMakeDC(__GLXWinContext * gc, __GLXWinDrawable * draw,
HDC * hdc, HWND * hwnd);
static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable * draw);
@@ -724,6 +674,9 @@ glxWinScreenProbe(ScreenPtr pScreen)
screen->CopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = glxWinCopyWindow;
+ // Note that WGL is active on this screen
+ winSetScreenAiglxIsActive(pScreen);
+
return &screen->base;
error:
@@ -870,6 +823,10 @@ glxWinDrawableDestroy(__GLXdrawable * base)
}
if (glxPriv->hDIB) {
+ if (!CloseHandle(glxPriv->hSection)) {
+ ErrorF("CloseHandle failed: %s\n", glxWinErrorMessage());
+ }
+
if (!DeleteObject(glxPriv->hDIB)) {
ErrorF("DeleteObject failed: %s\n", glxWinErrorMessage());
}
@@ -913,6 +870,179 @@ glxWinCreateDrawable(ClientPtr client,
return &glxPriv->base;
}
+void
+glxWinDeferredCreateDrawable(__GLXWinDrawable *draw, __GLXconfig *config)
+{
+ switch (draw->base.type) {
+ case GLX_DRAWABLE_WINDOW:
+ {
+ WindowPtr pWin = (WindowPtr) draw->base.pDraw;
+
+ if (!(config->drawableType & GLX_WINDOW_BIT)) {
+ ErrorF
+ ("glxWinDeferredCreateDrawable: tried to create a GLX_DRAWABLE_WINDOW drawable with a fbConfig which doesn't have drawableType GLX_WINDOW_BIT\n");
+ }
+
+ if (pWin == NULL) {
+ GLWIN_DEBUG_MSG("Deferring until X window is created");
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateDrawable: pWin %p", pWin);
+
+ if (winGetWindowInfo(pWin) == NULL) {
+ GLWIN_DEBUG_MSG("Deferring until native window is created");
+ return;
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PBUFFER:
+ {
+ if (draw->hPbuffer == NULL) {
+ __GLXscreen *screen;
+ glxWinScreen *winScreen;
+ int pixelFormat;
+
+ // XXX: which DC are we supposed to use???
+ HDC screenDC = GetDC(NULL);
+
+ if (!(config->drawableType & GLX_PBUFFER_BIT)) {
+ ErrorF
+ ("glxWinDeferredCreateDrawable: tried to create a GLX_DRAWABLE_PBUFFER drawable with a fbConfig which doesn't have drawableType GLX_PBUFFER_BIT\n");
+ }
+
+ screen = glxGetScreen(screenInfo.screens[draw->base.pDraw->pScreen->myNum]);
+ winScreen = (glxWinScreen *) screen;
+
+ pixelFormat =
+ fbConfigToPixelFormatIndex(screenDC, config,
+ GLX_PBUFFER_BIT, winScreen);
+ if (pixelFormat == 0) {
+ return;
+ }
+
+ draw->hPbuffer =
+ wglCreatePbufferARBWrapper(screenDC, pixelFormat,
+ draw->base.pDraw->width,
+ draw->base.pDraw->height, NULL);
+ ReleaseDC(NULL, screenDC);
+
+ if (draw->hPbuffer == NULL) {
+ ErrorF("wglCreatePbufferARBWrapper error: %s\n",
+ glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG
+ ("glxWinDeferredCreateDrawable: pBuffer %p created for drawable %p",
+ draw->hPbuffer, draw);
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PIXMAP:
+ {
+ if (draw->dibDC == NULL) {
+ BITMAPINFOHEADER bmpHeader;
+ void *pBits;
+ __GLXscreen *screen;
+ DWORD size;
+ char name[MAX_PATH];
+
+ memset(&bmpHeader, 0, sizeof(BITMAPINFOHEADER));
+ bmpHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmpHeader.biWidth = draw->base.pDraw->width;
+ bmpHeader.biHeight = draw->base.pDraw->height;
+ bmpHeader.biPlanes = 1;
+ bmpHeader.biBitCount = draw->base.pDraw->bitsPerPixel;
+ bmpHeader.biCompression = BI_RGB;
+
+ if (!(config->drawableType & GLX_PIXMAP_BIT)) {
+ ErrorF
+ ("glxWinDeferredCreateDrawable: tried to create a GLX_DRAWABLE_PIXMAP drawable with a fbConfig which doesn't have drawableType GLX_PIXMAP_BIT\n");
+ }
+
+ draw->dibDC = CreateCompatibleDC(NULL);
+ if (draw->dibDC == NULL) {
+ ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+#define RASTERWIDTHBYTES(bmi) (((((bmi)->biWidth*(bmi)->biBitCount)+31)&~31)>>3)
+ size = bmpHeader.biHeight * RASTERWIDTHBYTES(&bmpHeader);
+ GLWIN_DEBUG_MSG("shared memory region size %zu + %u\n", sizeof(BITMAPINFOHEADER), (unsigned int)size);
+
+ // Create unique name for mapping based on XID
+ //
+ // XXX: not quite unique as potentially this name could be used in
+ // another server instance. Not sure how to deal with that.
+ snprintf(name, sizeof(name), "Local\\CYGWINX_WINDOWSDRI_%08x", (unsigned int)draw->base.pDraw->id);
+ GLWIN_DEBUG_MSG("shared memory region name %s\n", name);
+
+ // Create a file mapping backed by the pagefile
+ draw->hSection = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
+ PAGE_READWRITE, 0, sizeof(BITMAPINFOHEADER) + size, name);
+ if (draw->hSection == NULL) {
+ ErrorF("CreateFileMapping error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ draw->hDIB =
+ CreateDIBSection(draw->dibDC, (BITMAPINFO *) &bmpHeader,
+ DIB_RGB_COLORS, &pBits, draw->hSection, sizeof(BITMAPINFOHEADER));
+ if (draw->dibDC == NULL) {
+ ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ // Store a copy of the BITMAPINFOHEADER at the start of the shared
+ // memory for the information of the receiving process
+ {
+ LPVOID pData = MapViewOfFile(draw->hSection, FILE_MAP_WRITE, 0, 0, 0);
+ memcpy(pData, (void *)&bmpHeader, sizeof(BITMAPINFOHEADER));
+ UnmapViewOfFile(pData);
+ }
+
+ // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to
+ // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits
+ // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are
+ // even compatible ...
+ draw->pOldBits = ((PixmapPtr) draw->base.pDraw)->devPrivate.ptr;
+ ((PixmapPtr) draw->base.pDraw)->devPrivate.ptr = pBits;
+
+ // Select the DIB into the DC
+ draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB);
+ if (!draw->hOldDIB) {
+ ErrorF("SelectObject error: %s\n", glxWinErrorMessage());
+ }
+
+ screen = glxGetScreen(screenInfo.screens[draw->base.pDraw->pScreen->myNum]);
+
+ // Set the pixel format of the bitmap
+ glxWinSetPixelFormat(draw->dibDC,
+ draw->base.pDraw->bitsPerPixel,
+ GLX_PIXMAP_BIT,
+ screen,
+ config);
+
+ GLWIN_DEBUG_MSG
+ ("glxWinDeferredCreateDrawable: DIB bitmap %p created for drawable %p",
+ draw->hDIB, draw);
+ }
+ }
+ break;
+
+ default:
+ {
+ ErrorF
+ ("glxWinDeferredCreateDrawable: tried to attach unhandled drawable type %d\n",
+ draw->base.type);
+ return;
+ }
+ }
+}
+
/* ---------------------------------------------------------------------- */
/*
* Texture functions
@@ -956,13 +1086,10 @@ glxWinReleaseTexImage(__GLXcontext * baseContext,
*/
static Bool
-glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
- int drawableTypeOverride)
+glxWinSetPixelFormat(HDC hdc, int bppOverride, int drawableTypeOverride,
+ __GLXscreen *screen, __GLXconfig *config)
{
- __GLXscreen *screen = gc->base.pGlxScreen;
glxWinScreen *winScreen = (glxWinScreen *) screen;
-
- __GLXconfig *config = gc->base.config;
GLXWinConfig *winConfig = (GLXWinConfig *) config;
GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d",
@@ -1013,7 +1140,7 @@ glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
int pixelFormat;
/* convert fbConfig to PFD */
- if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride)) {
+ if (fbConfigToPixelFormat(config, &pfd, drawableTypeOverride)) {
ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n");
return FALSE;
}
@@ -1045,9 +1172,9 @@ glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
}
}
else {
- int pixelFormat =
- fbConfigToPixelFormatIndex(hdc, gc->base.config,
- drawableTypeOverride, winScreen);
+ int pixelFormat = fbConfigToPixelFormatIndex(hdc, config,
+ drawableTypeOverride,
+ winScreen);
if (pixelFormat == 0) {
return FALSE;
}
@@ -1114,7 +1241,7 @@ glxWinMakeDC(__GLXWinContext * gc, __GLXWinDrawable * draw, HDC * hdc,
gc->hwnd = *hwnd;
/* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */
- if (!glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT)) {
+ if (!glxWinSetPixelFormat(*hdc, 0, GLX_WINDOW_BIT, gc->base.pGlxScreen, gc->base.config)) {
ErrorF("glxWinSetPixelFormat error: %s\n",
glxWinErrorMessage());
ReleaseDC(*hwnd, *hdc);
@@ -1200,140 +1327,7 @@ glxWinDeferredCreateContext(__GLXWinContext * gc, __GLXWinDrawable * draw)
("glxWinDeferredCreateContext: attach context %p to drawable %p", gc,
draw);
- switch (draw->base.type) {
- case GLX_DRAWABLE_WINDOW:
- {
- WindowPtr pWin = (WindowPtr) draw->base.pDraw;
-
- if (!(gc->base.config->drawableType & GLX_WINDOW_BIT)) {
- ErrorF
- ("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_WINDOW_BIT to a GLX_DRAWABLE_WINDOW drawable\n");
- }
-
- if (pWin == NULL) {
- GLWIN_DEBUG_MSG("Deferring until X window is created");
- return;
- }
-
- GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pWin %p", pWin);
-
- if (winGetWindowInfo(pWin) == NULL) {
- GLWIN_DEBUG_MSG("Deferring until native window is created");
- return;
- }
- }
- break;
-
- case GLX_DRAWABLE_PBUFFER:
- {
- if (draw->hPbuffer == NULL) {
- __GLXscreen *screen;
- glxWinScreen *winScreen;
- int pixelFormat;
-
- // XXX: which DC are we supposed to use???
- HDC screenDC = GetDC(NULL);
-
- if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT)) {
- ErrorF
- ("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PBUFFER_BIT to a GLX_DRAWABLE_PBUFFER drawable\n");
- }
-
- screen = gc->base.pGlxScreen;
- winScreen = (glxWinScreen *) screen;
-
- pixelFormat =
- fbConfigToPixelFormatIndex(screenDC, gc->base.config,
- GLX_PBUFFER_BIT, winScreen);
- if (pixelFormat == 0) {
- return;
- }
-
- draw->hPbuffer =
- wglCreatePbufferARBWrapper(screenDC, pixelFormat,
- draw->base.pDraw->width,
- draw->base.pDraw->height, NULL);
- ReleaseDC(NULL, screenDC);
-
- if (draw->hPbuffer == NULL) {
- ErrorF("wglCreatePbufferARBWrapper error: %s\n",
- glxWinErrorMessage());
- return;
- }
-
- GLWIN_DEBUG_MSG
- ("glxWinDeferredCreateContext: pBuffer %p created for drawable %p",
- draw->hPbuffer, draw);
- }
- }
- break;
-
- case GLX_DRAWABLE_PIXMAP:
- {
- if (draw->dibDC == NULL) {
- BITMAPINFOHEADER bmpHeader;
- void *pBits;
-
- memset(&bmpHeader, 0, sizeof(BITMAPINFOHEADER));
- bmpHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmpHeader.biWidth = draw->base.pDraw->width;
- bmpHeader.biHeight = draw->base.pDraw->height;
- bmpHeader.biPlanes = 1;
- bmpHeader.biBitCount = draw->base.pDraw->bitsPerPixel;
- bmpHeader.biCompression = BI_RGB;
-
- if (!(gc->base.config->drawableType & GLX_PIXMAP_BIT)) {
- ErrorF
- ("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PIXMAP_BIT to a GLX_DRAWABLE_PIXMAP drawable\n");
- }
-
- draw->dibDC = CreateCompatibleDC(NULL);
- if (draw->dibDC == NULL) {
- ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage());
- return;
- }
-
- draw->hDIB =
- CreateDIBSection(draw->dibDC, (BITMAPINFO *) &bmpHeader,
- DIB_RGB_COLORS, &pBits, 0, 0);
- if (draw->dibDC == NULL) {
- ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage());
- return;
- }
-
- // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to
- // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits
- // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are
- // even compatible ...
- draw->pOldBits = ((PixmapPtr) draw->base.pDraw)->devPrivate.ptr;
- ((PixmapPtr) draw->base.pDraw)->devPrivate.ptr = pBits;
-
- // Select the DIB into the DC
- draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB);
- if (!draw->hOldDIB) {
- ErrorF("SelectObject error: %s\n", glxWinErrorMessage());
- }
-
- // Set the pixel format of the bitmap
- glxWinSetPixelFormat(gc, draw->dibDC,
- draw->base.pDraw->bitsPerPixel,
- GLX_PIXMAP_BIT);
-
- GLWIN_DEBUG_MSG
- ("glxWinDeferredCreateContext: DIB bitmap %p created for drawable %p",
- draw->hDIB, draw);
- }
- }
- break;
-
- default:
- {
- ErrorF
- ("glxWinDeferredCreateContext: tried to attach unhandled drawable type %d\n",
- draw->base.type);
- return;
- }
- }
+ glxWinDeferredCreateDrawable(draw, gc->base.config);
dc = glxWinMakeDC(gc, draw, &dc, &hwnd);
gc->ctx = wglCreateContext(dc);
diff --git a/hw/xwin/glx/indirect.h b/hw/xwin/glx/indirect.h
new file mode 100644
index 000000000..8a66121ac
--- /dev/null
+++ b/hw/xwin/glx/indirect.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2014 Jon TURNEY
+ *
+ * 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.
+ */
+
+#ifndef indirect_h
+#define indirect_h
+
+#include <X11/Xwindows.h>
+#include <GL/wglext.h>
+#include <glx/extension_string.h>
+
+/* ---------------------------------------------------------------------- */
+/*
+ * structure definitions
+ */
+
+typedef struct __GLXWinContext __GLXWinContext;
+typedef struct __GLXWinDrawable __GLXWinDrawable;
+typedef struct __GLXWinScreen glxWinScreen;
+typedef struct __GLXWinConfig GLXWinConfig;
+
+struct __GLXWinContext {
+ __GLXcontext base;
+ HGLRC ctx; /* Windows GL Context */
+ __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */
+ HWND hwnd; /* For detecting when HWND has changed */
+};
+
+struct __GLXWinDrawable {
+ __GLXdrawable base;
+ __GLXWinContext *drawContext;
+ __GLXWinContext *readContext;
+
+ /* If this drawable is GLX_DRAWABLE_PBUFFER */
+ HPBUFFERARB hPbuffer;
+
+ /* If this drawable is GLX_DRAWABLE_PIXMAP */
+ HDC dibDC;
+ HANDLE hSection; /* file mapping handle */
+ HBITMAP hDIB;
+ HBITMAP hOldDIB; /* original DIB for DC */
+ void *pOldBits; /* original pBits for this drawable's pixmap */
+};
+
+struct __GLXWinScreen {
+ __GLXscreen base;
+
+ /* Supported GLX extensions */
+ unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+
+ Bool has_WGL_ARB_multisample;
+ Bool has_WGL_ARB_pixel_format;
+ Bool has_WGL_ARB_pbuffer;
+ Bool has_WGL_ARB_render_texture;
+ Bool has_WGL_ARB_make_current_read;
+
+ /* wrapped screen functions */
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ CopyWindowProcPtr CopyWindow;
+};
+
+struct __GLXWinConfig {
+ __GLXconfig base;
+ int pixelFormatIndex;
+};
+
+/* ---------------------------------------------------------------------- */
+/*
+ * function prototypes
+ */
+
+void
+glxWinDeferredCreateDrawable(__GLXWinDrawable *draw, __GLXconfig *config);
+
+#endif /* indirect_h */
diff --git a/hw/xwin/glx/winpriv.c b/hw/xwin/glx/winpriv.c
index e6afbff01..c98ad9099 100644
--- a/hw/xwin/glx/winpriv.c
+++ b/hw/xwin/glx/winpriv.c
@@ -119,3 +119,10 @@ winCheckScreenAiglxIsSupported(ScreenPtr pScreen)
return FALSE;
}
+
+void
+winSetScreenAiglxIsActive(ScreenPtr pScreen)
+{
+ winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen);
+ pWinScreen->fNativeGlActive = TRUE;
+}
diff --git a/hw/xwin/glx/winpriv.h b/hw/xwin/glx/winpriv.h
index dce1edf48..6f695a971 100644
--- a/hw/xwin/glx/winpriv.h
+++ b/hw/xwin/glx/winpriv.h
@@ -9,3 +9,4 @@
HWND winGetWindowInfo(WindowPtr pWin);
Bool winCheckScreenAiglxIsSupported(ScreenPtr pScreen);
+void winSetScreenAiglxIsActive(ScreenPtr pScreen);
diff --git a/hw/xwin/win.h b/hw/xwin/win.h
index e89f730b0..103c4b9a9 100644
--- a/hw/xwin/win.h
+++ b/hw/xwin/win.h
@@ -533,6 +533,8 @@ typedef struct _winPrivScreenRec {
SetShapeProcPtr SetShape;
winCursorRec cursor;
+
+ Bool fNativeGlActive;
} winPrivScreenRec;
#ifdef XWIN_MULTIWINDOWEXTWM
diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index be532ff55..b4498927b 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -111,6 +111,11 @@
#define SERVER_SYNC_MAJOR_VERSION 3
#define SERVER_SYNC_MINOR_VERSION 1
+/* Windows DRI */
+#define SERVER_WINDOWSDRI_MAJOR_VERSION 1
+#define SERVER_WINDOWSDRI_MINOR_VERSION 0
+#define SERVER_WINDOWSDRI_PATCH_VERSION 0
+
/* Windows WM */
#define SERVER_WINDOWSWM_MAJOR_VERSION 1
#define SERVER_WINDOWSWM_MINOR_VERSION 0