st/wgl: add support for WGL_ARB_make_current_read
This adds the wglMakeContextCurrentARB() and wglGetCurrentReadDCARB() functions. Signed-off-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
parent
7753f040fa
commit
7d0aac2392
|
@ -187,6 +187,7 @@ stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
|
||||||
goto no_ctx;
|
goto no_ctx;
|
||||||
|
|
||||||
ctx->hdc = hdc;
|
ctx->hdc = hdc;
|
||||||
|
ctx->hReadDC = hdc;
|
||||||
ctx->iPixelFormat = iPixelFormat;
|
ctx->iPixelFormat = iPixelFormat;
|
||||||
ctx->shared = shareCtx != NULL;
|
ctx->shared = shareCtx != NULL;
|
||||||
|
|
||||||
|
@ -357,7 +358,7 @@ DrvReleaseContext(DHGLRC dhglrc)
|
||||||
if (ctx != stw_current_context())
|
if (ctx != stw_current_context())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (stw_make_current( NULL, 0 ) == FALSE)
|
if (stw_make_current( NULL, NULL, 0 ) == FALSE)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -389,9 +390,20 @@ stw_get_current_dc( void )
|
||||||
return ctx->hdc;
|
return ctx->hdc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HDC
|
||||||
|
stw_get_current_read_dc( void )
|
||||||
|
{
|
||||||
|
struct stw_context *ctx;
|
||||||
|
|
||||||
|
ctx = stw_current_context();
|
||||||
|
if (!ctx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return ctx->hReadDC;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
stw_make_current(HDC hdc, DHGLRC dhglrc)
|
stw_make_current(HDC hdc, HDC hReadDC, DHGLRC dhglrc)
|
||||||
{
|
{
|
||||||
struct stw_context *old_ctx = NULL;
|
struct stw_context *old_ctx = NULL;
|
||||||
struct stw_context *ctx = NULL;
|
struct stw_context *ctx = NULL;
|
||||||
|
@ -403,7 +415,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
|
||||||
old_ctx = stw_current_context();
|
old_ctx = stw_current_context();
|
||||||
if (old_ctx != NULL) {
|
if (old_ctx != NULL) {
|
||||||
if (old_ctx->dhglrc == dhglrc) {
|
if (old_ctx->dhglrc == dhglrc) {
|
||||||
if (old_ctx->hdc == hdc) {
|
if (old_ctx->hdc == hdc && old_ctx->hReadDC == hReadDC) {
|
||||||
/* Return if already current. */
|
/* Return if already current. */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -421,6 +433,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
|
||||||
|
|
||||||
if (dhglrc) {
|
if (dhglrc) {
|
||||||
struct stw_framebuffer *fb = NULL;
|
struct stw_framebuffer *fb = NULL;
|
||||||
|
struct stw_framebuffer *fbRead = NULL;
|
||||||
stw_lock_contexts(stw_dev);
|
stw_lock_contexts(stw_dev);
|
||||||
ctx = stw_lookup_context_locked( dhglrc );
|
ctx = stw_lookup_context_locked( dhglrc );
|
||||||
stw_unlock_contexts(stw_dev);
|
stw_unlock_contexts(stw_dev);
|
||||||
|
@ -454,6 +467,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
|
||||||
|
|
||||||
/* Bind the new framebuffer */
|
/* Bind the new framebuffer */
|
||||||
ctx->hdc = hdc;
|
ctx->hdc = hdc;
|
||||||
|
ctx->hReadDC = hReadDC;
|
||||||
|
|
||||||
struct stw_framebuffer *old_fb = ctx->current_framebuffer;
|
struct stw_framebuffer *old_fb = ctx->current_framebuffer;
|
||||||
if (old_fb != fb) {
|
if (old_fb != fb) {
|
||||||
|
@ -462,12 +476,47 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
|
||||||
}
|
}
|
||||||
stw_framebuffer_unlock(fb);
|
stw_framebuffer_unlock(fb);
|
||||||
|
|
||||||
/* Note: when we call this function we will wind up in the
|
if (hReadDC) {
|
||||||
* stw_st_framebuffer_validate_locked() function which will incur
|
if (hReadDC == hDrawDC) {
|
||||||
* a recursive fb->mutex lock.
|
fbRead = fb;
|
||||||
*/
|
}
|
||||||
ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
|
else {
|
||||||
fb->stfb, fb->stfb);
|
fbRead = stw_framebuffer_from_hdc( hReadDC );
|
||||||
|
|
||||||
|
if (fbRead) {
|
||||||
|
stw_framebuffer_update(fbRead);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Applications should call SetPixelFormat before creating a
|
||||||
|
* context, but not all do, and the opengl32 runtime seems to
|
||||||
|
* use a default pixel format in some cases, so we must create
|
||||||
|
* a framebuffer for those here.
|
||||||
|
*/
|
||||||
|
int iPixelFormat = GetPixelFormat(hReadDC);
|
||||||
|
if (iPixelFormat)
|
||||||
|
fbRead = stw_framebuffer_create( hReadDC, iPixelFormat );
|
||||||
|
if (!fbRead)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbRead->iPixelFormat != ctx->iPixelFormat) {
|
||||||
|
stw_framebuffer_unlock(fbRead);
|
||||||
|
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
stw_framebuffer_unlock(fbRead);
|
||||||
|
}
|
||||||
|
ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
|
||||||
|
fb->stfb, fbRead->stfb);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Note: when we call this function we will wind up in the
|
||||||
|
* stw_st_framebuffer_validate_locked() function which will incur
|
||||||
|
* a recursive fb->mutex lock.
|
||||||
|
*/
|
||||||
|
ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
|
||||||
|
fb->stfb, fb->stfb);
|
||||||
|
}
|
||||||
|
|
||||||
if (old_fb && old_fb != fb) {
|
if (old_fb && old_fb != fb) {
|
||||||
stw_lock_framebuffers(stw_dev);
|
stw_lock_framebuffers(stw_dev);
|
||||||
|
@ -477,14 +526,16 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* fb must be unlocked at this point. */
|
if (fb) {
|
||||||
assert(!stw_own_mutex(&fb->mutex));
|
/* fb must be unlocked at this point. */
|
||||||
|
assert(!stw_own_mutex(&fb->mutex));
|
||||||
|
}
|
||||||
|
|
||||||
/* On failure, make the thread's current rendering context not current
|
/* On failure, make the thread's current rendering context not current
|
||||||
* before returning.
|
* before returning.
|
||||||
*/
|
*/
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
stw_make_current(NULL, 0);
|
stw_make_current(NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
|
ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
|
||||||
|
@ -870,7 +921,7 @@ DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)
|
||||||
{
|
{
|
||||||
PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
|
PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
|
||||||
|
|
||||||
if (!stw_make_current(hdc, dhglrc))
|
if (!stw_make_current(hdc, hdc, dhglrc))
|
||||||
r = NULL;
|
r = NULL;
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct stw_context
|
||||||
DHGLRC dhglrc;
|
DHGLRC dhglrc;
|
||||||
int iPixelFormat;
|
int iPixelFormat;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
HDC hReadDC;
|
||||||
BOOL shared;
|
BOOL shared;
|
||||||
|
|
||||||
struct stw_framebuffer *current_framebuffer;
|
struct stw_framebuffer *current_framebuffer;
|
||||||
|
@ -59,7 +60,9 @@ struct stw_context *stw_current_context(void);
|
||||||
|
|
||||||
HDC stw_get_current_dc( void );
|
HDC stw_get_current_dc( void );
|
||||||
|
|
||||||
BOOL stw_make_current( HDC hdc, DHGLRC dhglrc );
|
HDC stw_get_current_read_dc( void );
|
||||||
|
|
||||||
|
BOOL stw_make_current( HDC hdc, HDC hReadDC, DHGLRC dhglrc );
|
||||||
|
|
||||||
void stw_notify_current_locked( struct stw_framebuffer *fb );
|
void stw_notify_current_locked( struct stw_framebuffer *fb );
|
||||||
|
|
||||||
|
|
|
@ -195,3 +195,18 @@ wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Defined by WGL_ARB_make_current_read */
|
||||||
|
BOOL APIENTRY
|
||||||
|
wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
|
||||||
|
{
|
||||||
|
DHGLRC dhglrc = 0;
|
||||||
|
|
||||||
|
if (stw_dev && stw_dev->callbacks.wglCbGetDhglrc) {
|
||||||
|
/* Convert HGLRC to DHGLRC */
|
||||||
|
dhglrc = stw_dev->callbacks.wglCbGetDhglrc(hglrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stw_make_current(hDrawDC, hReadDC, dhglrc);
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ static const char *stw_extension_string =
|
||||||
"WGL_ARB_render_texture "
|
"WGL_ARB_render_texture "
|
||||||
"WGL_EXT_create_context_es_profile "
|
"WGL_EXT_create_context_es_profile "
|
||||||
"WGL_EXT_create_context_es2_profile "
|
"WGL_EXT_create_context_es2_profile "
|
||||||
|
"WGL_ARB_make_current_read "
|
||||||
/* "WGL_EXT_swap_interval " */
|
/* "WGL_EXT_swap_interval " */
|
||||||
"WGL_EXT_extensions_string";
|
"WGL_EXT_extensions_string";
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,7 @@ BOOL WINAPI
|
||||||
wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
|
wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
|
||||||
{
|
{
|
||||||
HDC prevDrawable = stw_get_current_dc();
|
HDC prevDrawable = stw_get_current_dc();
|
||||||
|
HDC prevReadable = stw_get_current_read_dc();
|
||||||
HDC dc;
|
HDC dc;
|
||||||
struct stw_context *curctx = stw_current_context();
|
struct stw_context *curctx = stw_current_context();
|
||||||
struct stw_framebuffer *fb;
|
struct stw_framebuffer *fb;
|
||||||
|
@ -172,7 +173,7 @@ wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
|
||||||
pixelFormatSave = fb->iPixelFormat;
|
pixelFormatSave = fb->iPixelFormat;
|
||||||
fb->iPixelFormat = curctx->iPixelFormat;
|
fb->iPixelFormat = curctx->iPixelFormat;
|
||||||
dc = wglGetPbufferDCARB(hPbuffer);
|
dc = wglGetPbufferDCARB(hPbuffer);
|
||||||
retVal = stw_make_current(dc, curctx->dhglrc);
|
retVal = stw_make_current(dc, dc, curctx->dhglrc);
|
||||||
fb->iPixelFormat = pixelFormatSave;
|
fb->iPixelFormat = pixelFormatSave;
|
||||||
if (!retVal) {
|
if (!retVal) {
|
||||||
debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n");
|
debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n");
|
||||||
|
@ -185,7 +186,7 @@ wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
|
||||||
fb->textureFace, texFormat);
|
fb->textureFace, texFormat);
|
||||||
|
|
||||||
/* rebind previous drawing surface */
|
/* rebind previous drawing surface */
|
||||||
retVal = stw_make_current(prevDrawable, curctx->dhglrc);
|
retVal = stw_make_current(prevDrawable, prevReadable, curctx->dhglrc);
|
||||||
if (!retVal) {
|
if (!retVal) {
|
||||||
debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n");
|
debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,9 @@ static const struct stw_extension_entry stw_extension_entries[] = {
|
||||||
STW_EXTENSION_ENTRY( wglReleaseTexImageARB ),
|
STW_EXTENSION_ENTRY( wglReleaseTexImageARB ),
|
||||||
STW_EXTENSION_ENTRY( wglSetPbufferAttribARB ),
|
STW_EXTENSION_ENTRY( wglSetPbufferAttribARB ),
|
||||||
|
|
||||||
|
/* WGL_ARB_make_current_read */
|
||||||
|
STW_EXTENSION_ENTRY( wglMakeContextCurrentARB ),
|
||||||
|
STW_EXTENSION_ENTRY( wglGetCurrentReadDCARB ),
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,13 @@ wglGetCurrentDC( VOID )
|
||||||
return stw_get_current_dc();
|
return stw_get_current_dc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WINGDIAPI HDC APIENTRY
|
||||||
|
wglGetCurrentReadDCARB( VOID )
|
||||||
|
{
|
||||||
|
return stw_get_current_read_dc();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WINGDIAPI BOOL APIENTRY
|
WINGDIAPI BOOL APIENTRY
|
||||||
wglMakeCurrent(
|
wglMakeCurrent(
|
||||||
HDC hdc,
|
HDC hdc,
|
||||||
|
|
|
@ -59,6 +59,16 @@ wglSetPixelFormat(HDC hdc,
|
||||||
int iPixelFormat,
|
int iPixelFormat,
|
||||||
CONST PIXELFORMATDESCRIPTOR *ppfd);
|
CONST PIXELFORMATDESCRIPTOR *ppfd);
|
||||||
|
|
||||||
|
WINGDIAPI HDC APIENTRY
|
||||||
|
wglGetCurrentReadDCARB( VOID );
|
||||||
|
|
||||||
|
WINGDIAPI BOOL APIENTRY
|
||||||
|
wglMakeContextCurrentARB(
|
||||||
|
HDC hDrawDC,
|
||||||
|
HDC hReadDC,
|
||||||
|
HGLRC hglrc );
|
||||||
|
|
||||||
|
|
||||||
#ifndef WGL_SWAPMULTIPLE_MAX
|
#ifndef WGL_SWAPMULTIPLE_MAX
|
||||||
|
|
||||||
typedef struct _WGLSWAP
|
typedef struct _WGLSWAP
|
||||||
|
|
Loading…
Reference in New Issue