Browse Source

wgl: Unreference the current framebuffer after the make_current call.

To prevent a dangling pointer dereference.
tags/android-x86-2.2
José Fonseca 15 years ago
parent
commit
14e2dc9c66
1 changed files with 58 additions and 51 deletions
  1. 58
    51
      src/gallium/state_trackers/wgl/stw_context.c

+ 58
- 51
src/gallium/state_trackers/wgl/stw_context.c View File

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

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)
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;
}
if(fb->iPixelFormat != ctx->iPixelFormat)
goto fail;
}

/* Bind the new framebuffer */
ctx->hdc = hdc;
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 (!stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb))
goto fail;
if (fb->iPixelFormat != ctx->iPixelFormat) {
SetLastError(ERROR_INVALID_PIXEL_FORMAT);
goto fail;
}

stw_framebuffer_reference(&ctx->current_framebuffer, fb);
/* Bind the new framebuffer */
ctx->hdc = hdc;

success:
assert(fb);
if(fb) {
stw_framebuffer_release(fb);
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);
}
return TRUE;

fail:
if(fb)

if (fb) {
stw_framebuffer_release(fb);
stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
return FALSE;
}

/* 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);
}

return ret;
}

/**

Loading…
Cancel
Save