Merge remote-tracking branch 'jturney/master'

This commit is contained in:
Keith Packard 2016-09-15 21:32:46 -07:00
commit 265c4e6653
17 changed files with 808 additions and 201 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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__ */

View File

@ -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
};

View File

@ -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

9
hw/xwin/dri/Makefile.am Normal file
View File

@ -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/

274
hw/xwin/dri/windowsdri.c Normal file
View File

@ -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;
}
}

30
hw/xwin/dri/windowsdri.h Normal file
View File

@ -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 */

View File

@ -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

120
hw/xwin/glx/dri_helpers.c Normal file
View File

@ -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;
}

38
hw/xwin/glx/dri_helpers.h Normal file
View File

@ -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 */

View File

@ -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);

95
hw/xwin/glx/indirect.h Normal file
View File

@ -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 */

View File

@ -119,3 +119,10 @@ winCheckScreenAiglxIsSupported(ScreenPtr pScreen)
return FALSE;
}
void
winSetScreenAiglxIsActive(ScreenPtr pScreen)
{
winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen);
pWinScreen->fNativeGlActive = TRUE;
}

View File

@ -9,3 +9,4 @@
HWND winGetWindowInfo(WindowPtr pWin);
Bool winCheckScreenAiglxIsSupported(ScreenPtr pScreen);
void winSetScreenAiglxIsActive(ScreenPtr pScreen);

View File

@ -533,6 +533,8 @@ typedef struct _winPrivScreenRec {
SetShapeProcPtr SetShape;
winCursorRec cursor;
Bool fNativeGlActive;
} winPrivScreenRec;
#ifdef XWIN_MULTIWINDOWEXTWM

View File

@ -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