mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-31 20:00:24 +01:00
wgl: Unreference the current framebuffer after the make_current call.
To prevent a dangling pointer dereference.
This commit is contained in:
parent
63c05c96e7
commit
14e2dc9c66
1 changed files with 65 additions and 58 deletions
|
|
@ -264,75 +264,82 @@ stw_make_current(
|
|||
struct stw_context *curctx = NULL;
|
||||
struct stw_context *ctx = NULL;
|
||||
struct stw_framebuffer *fb = NULL;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!stw_dev)
|
||||
goto fail;
|
||||
return FALSE;
|
||||
|
||||
curctx = stw_current_context();
|
||||
if (curctx != NULL) {
|
||||
if (curctx->dhglrc != dhglrc)
|
||||
if (curctx->dhglrc == dhglrc) {
|
||||
if (curctx->hdc == hdc) {
|
||||
/* Return if already current. */
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
curctx->st->flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
||||
|
||||
/* Return if already current. */
|
||||
if (curctx->dhglrc == dhglrc && curctx->hdc == hdc) {
|
||||
ctx = curctx;
|
||||
fb = stw_framebuffer_from_hdc( hdc );
|
||||
goto success;
|
||||
}
|
||||
}
|
||||
|
||||
if (dhglrc) {
|
||||
pipe_mutex_lock( stw_dev->ctx_mutex );
|
||||
ctx = stw_lookup_context_locked( dhglrc );
|
||||
pipe_mutex_unlock( stw_dev->ctx_mutex );
|
||||
if (!ctx) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fb = stw_framebuffer_from_hdc( hdc );
|
||||
if (fb) {
|
||||
stw_framebuffer_update(fb);
|
||||
}
|
||||
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(hdc);
|
||||
if (iPixelFormat)
|
||||
fb = stw_framebuffer_create( hdc, iPixelFormat );
|
||||
if (!fb)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fb->iPixelFormat != ctx->iPixelFormat) {
|
||||
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Bind the new framebuffer */
|
||||
ctx->hdc = hdc;
|
||||
|
||||
ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb);
|
||||
stw_framebuffer_reference(&ctx->current_framebuffer, fb);
|
||||
} else {
|
||||
ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
fail:
|
||||
|
||||
if (fb) {
|
||||
stw_framebuffer_release(fb);
|
||||
}
|
||||
|
||||
/* On failure, make the thread's current rendering context not current
|
||||
* before returning */
|
||||
if (!ret) {
|
||||
stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
|
||||
ctx = NULL;
|
||||
}
|
||||
|
||||
/* Unreference the previous framebuffer if any. It must be done after
|
||||
* make_current, as it can be referenced inside.
|
||||
*/
|
||||
if (curctx && curctx != ctx) {
|
||||
stw_framebuffer_reference(&curctx->current_framebuffer, NULL);
|
||||
}
|
||||
|
||||
if (hdc == NULL || dhglrc == 0) {
|
||||
return stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
pipe_mutex_lock( stw_dev->ctx_mutex );
|
||||
ctx = stw_lookup_context_locked( dhglrc );
|
||||
pipe_mutex_unlock( stw_dev->ctx_mutex );
|
||||
if(!ctx)
|
||||
goto fail;
|
||||
|
||||
fb = stw_framebuffer_from_hdc( hdc );
|
||||
if (fb) {
|
||||
stw_framebuffer_update(fb);
|
||||
}
|
||||
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(hdc);
|
||||
if(iPixelFormat)
|
||||
fb = stw_framebuffer_create( hdc, iPixelFormat );
|
||||
if(!fb)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(fb->iPixelFormat != ctx->iPixelFormat)
|
||||
goto fail;
|
||||
|
||||
/* Bind the new framebuffer */
|
||||
ctx->hdc = hdc;
|
||||
|
||||
if (!stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb))
|
||||
goto fail;
|
||||
|
||||
stw_framebuffer_reference(&ctx->current_framebuffer, fb);
|
||||
|
||||
success:
|
||||
assert(fb);
|
||||
if(fb) {
|
||||
stw_framebuffer_release(fb);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if(fb)
|
||||
stw_framebuffer_release(fb);
|
||||
stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
|
||||
return FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue