BOOL APIENTRY DrvReleaseContext( DHGLRC dhglrc ) { struct stw_context *ctx; if (!stw_dev) return FALSE; pipe_mutex_lock( stw_dev->ctx_mutex ); ctx = stw_lookup_context_locked( dhglrc ); pipe_mutex_unlock( stw_dev->ctx_mutex ); if (!ctx) return FALSE; /* The expectation is that ctx is the same context which is * current for this thread. We should check that and return False * if not the case. */ if (ctx != stw_current_context()) return FALSE; if (stw_make_current( NULL, 0 ) == FALSE) return FALSE; return TRUE; }
PGLCLTPROCTABLE APIENTRY DrvSetContext( HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable ) { PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt; if (!stw_make_current( hdc, dhglrc )) r = NULL; return r; }
BOOL WINAPI wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) { HDC prevDrawable = stw_get_current_dc(); HDC prevReadable = stw_get_current_read_dc(); HDC dc; struct stw_context *curctx = stw_current_context(); struct stw_framebuffer *fb; GLenum texFormat, srcBuffer, target; boolean retVal; int pixelFormatSave; /* * Implementation notes: * Ideally, we'd implement this function with the * st_context_iface::teximage() function which replaces a specific * texture image with a different resource (the pbuffer). * The main problem however, is the pbuffer image is upside down relative * to the texture image. * Window system drawing surfaces (windows & pbuffers) are "top to bottom" * while OpenGL texture images are "bottom to top". One possible solution * to this is to invert rendering to pbuffers (as we do for renderbuffers) * but that could lead to other issues (and would require extensive * testing). * * The simple alternative is to use a copy-based approach which copies the * pbuffer image into the texture via glCopyTex[Sub]Image. That's what * we do here. */ if (!curctx) { debug_printf("No rendering context in wglBindTexImageARB()\n"); SetLastError(ERROR_INVALID_OPERATION); return FALSE; } fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer); if (!fb) { debug_printf("Invalid pbuffer handle in wglBindTexImageARB()\n"); SetLastError(ERROR_INVALID_HANDLE); return FALSE; } srcBuffer = translate_ibuffer(iBuffer); if (srcBuffer == GL_NONE) { debug_printf("Invalid buffer 0x%x in wglBindTexImageARB()\n", iBuffer); SetLastError(ERROR_INVALID_DATA); return FALSE; } target = translate_target(fb->textureTarget); if (target == GL_NONE) { debug_printf("no texture target in wglBindTexImageARB()\n"); return FALSE; } texFormat = translate_texture_format(fb->textureFormat); if (texFormat == GL_NONE) { debug_printf("no texture format in wglBindTexImageARB()\n"); return FALSE; } /* * Bind the pbuffer surface so we can read/copy from it. * * Before we can call stw_make_current() we have to temporarily * change the pbuffer's pixel format to match the context to avoid * an error condition. After the stw_make_current() we restore the * buffer's pixel format. */ pixelFormatSave = fb->iPixelFormat; fb->iPixelFormat = curctx->iPixelFormat; dc = wglGetPbufferDCARB(hPbuffer); retVal = stw_make_current(dc, dc, curctx->dhglrc); fb->iPixelFormat = pixelFormatSave; if (!retVal) { debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n"); wglReleasePbufferDCARB(hPbuffer, dc); return FALSE; } st_copy_framebuffer_to_texture(srcBuffer, fb->width, fb->height, target, fb->textureLevel, fb->textureFace, texFormat); /* rebind previous drawing surface */ retVal = stw_make_current(prevDrawable, prevReadable, curctx->dhglrc); if (!retVal) { debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n"); } wglReleasePbufferDCARB(hPbuffer, dc); return retVal; }