summaryrefslogtreecommitdiff
path: root/hw/xwin/glx
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xwin/glx')
-rw-r--r--hw/xwin/glx/Makefile.am7
-rw-r--r--hw/xwin/glx/dri_helpers.c118
-rw-r--r--hw/xwin/glx/dri_helpers.h38
-rw-r--r--hw/xwin/glx/indirect.c429
-rw-r--r--hw/xwin/glx/indirect.h94
-rw-r--r--hw/xwin/glx/winpriv.c7
-rw-r--r--hw/xwin/glx/winpriv.h1
7 files changed, 477 insertions, 217 deletions
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..d69802ffd
--- /dev/null
+++ b/hw/xwin/glx/dri_helpers.c
@@ -0,0 +1,118 @@
+/*
+ * 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"
+
+extern int validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
+ __GLXdrawable ** drawable, int *err);
+
+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;
+ // XXX: We could use DuplicateHandle to make pDrawble->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, *handle);
+ return Success;
+}
+
+int
+glxWinFBConfigIDToPixelFormatIndex(int scr, int fbConfigID)
+{
+ __GLXscreen *screen = glxGetScreen(screenInfo.screens[scr]);
+
+ for (__GLXconfig *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..05bc9bc93
--- /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 454173666..6db6a48c4 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,60 +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;
-
- /* 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;
-
- /* wrapped screen functions */
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- CopyWindowProcPtr CopyWindow;
-};
-
-struct __GLXWinConfig {
- __GLXconfig base;
- int pixelFormatIndex;
-};
-
typedef struct {
int notOpenGL;
int rgbaFloat;
@@ -430,7 +376,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);
@@ -803,6 +750,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:
@@ -949,6 +899,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());
}
@@ -992,6 +946,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);
+ ErrorF("shared memory region size %d + %d\n", sizeof(BITMAPINFOHEADER), 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", draw->base.pDraw->id);
+ ErrorF("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
@@ -1035,13 +1162,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",
@@ -1087,12 +1211,35 @@ glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
(config->redBits + config->greenBits + config->blueBits), bppOverride,
config->drawableType, drawableTypeOverride);
- if (!winScreen->has_WGL_ARB_pixel_format) {
+ if (winScreen->has_WGL_ARB_pixel_format) {
+ int pixelFormat =
+ fbConfigToPixelFormatIndex(hdc, config,
+ drawableTypeOverride, winScreen);
+ if (pixelFormat != 0) {
+ GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d",
+ pixelFormat);
+ ErrorF
+ ("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n",
+ pixelFormat, winConfig->pixelFormatIndex);
+
+ if (!SetPixelFormat(hdc, pixelFormat, NULL)) {
+ ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+ return FALSE;
+ }
+ }
+ }
+
+ /*
+ For some drivers, wglChoosePixelFormatARB() can fail when the provided
+ DC doesn't belong to the driver (e.g. it's a compatible DC for a bitmap,
+ so allow fallback to ChoosePixelFormat()
+ */
+ {
PIXELFORMATDESCRIPTOR pfd;
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;
}
@@ -1123,25 +1270,6 @@ glxWinSetPixelFormat(__GLXWinContext * gc, HDC hdc, int bppOverride,
return FALSE;
}
}
- else {
- int pixelFormat =
- fbConfigToPixelFormatIndex(hdc, gc->base.config,
- drawableTypeOverride, winScreen);
- if (pixelFormat == 0) {
- return FALSE;
- }
-
- GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d",
- pixelFormat);
- ErrorF
- ("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n",
- pixelFormat, winConfig->pixelFormatIndex);
-
- if (!SetPixelFormat(hdc, pixelFormat, NULL)) {
- ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
- return FALSE;
- }
- }
return TRUE;
}
@@ -1193,7 +1321,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);
@@ -1279,140 +1407,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..163375556
--- /dev/null
+++ b/hw/xwin/glx/indirect.h
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+ /* 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 4604f4495..f27c7e56a 100644
--- a/hw/xwin/glx/winpriv.c
+++ b/hw/xwin/glx/winpriv.c
@@ -154,3 +154,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);