diff --git a/src/egl/drivers/wgl/egl_wgl.c b/src/egl/drivers/wgl/egl_wgl.c index 9922965149c..381c554970a 100644 --- a/src/egl/drivers/wgl/egl_wgl.c +++ b/src/egl/drivers/wgl/egl_wgl.c @@ -498,7 +498,7 @@ wgl_create_context(_EGLDisplay *disp, _EGLConfig *conf, wgl_ctx->base.ClientMinorVersion, flags, profile_mask, - stw_config->iPixelFormat, + stw_config, resetStrategy); if (!wgl_ctx->ctx) @@ -727,7 +727,7 @@ wgl_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, const struct stw_pixelformat_info *stw_conf = wgl_conf->stw_config[1] ? wgl_conf->stw_config[1] : wgl_conf->stw_config[0]; - wgl_surf->fb = stw_framebuffer_create(native_window, stw_conf->iPixelFormat, STW_FRAMEBUFFER_EGL_WINDOW, &wgl_dpy->base); + wgl_surf->fb = stw_framebuffer_create(native_window, stw_conf, STW_FRAMEBUFFER_EGL_WINDOW, &wgl_dpy->base); if (!wgl_surf->fb) { free(wgl_surf); return NULL; @@ -757,7 +757,7 @@ wgl_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf, const struct stw_pixelformat_info *stw_conf = wgl_conf->stw_config[1] ? wgl_conf->stw_config[1] : wgl_conf->stw_config[0]; - wgl_surf->fb = stw_pbuffer_create(stw_conf->iPixelFormat, wgl_surf->base.Width, wgl_surf->base.Height, &wgl_dpy->base); + wgl_surf->fb = stw_pbuffer_create(stw_conf, wgl_surf->base.Width, wgl_surf->base.Height, &wgl_dpy->base); if (!wgl_surf->fb) { free(wgl_surf); return NULL; diff --git a/src/gallium/frontends/wgl/stw_context.c b/src/gallium/frontends/wgl/stw_context.c index a622bf3ad64..b0fe3216d3f 100644 --- a/src/gallium/frontends/wgl/stw_context.c +++ b/src/gallium/frontends/wgl/stw_context.c @@ -129,9 +129,13 @@ DrvCreateLayerContext(HDC hdc, INT iLayerPlane) if (!stw_dev) return 0; + const struct stw_pixelformat_info *pfi = stw_pixelformat_get_info_from_hdc(hdc); + if (!pfi) + return 0; + struct stw_context *ctx = stw_create_context_attribs(hdc, iLayerPlane, NULL, stw_dev->smapi, 1, 0, 0, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - 0, WGL_NO_RESET_NOTIFICATION_ARB); + pfi, WGL_NO_RESET_NOTIFICATION_ARB); if (!ctx) return 0; @@ -142,26 +146,6 @@ DrvCreateLayerContext(HDC hdc, INT iLayerPlane) return ret; } - -/** - * Return the stw pixel format that most closely matches the pixel format - * on HDC. - * Used to get a pixel format when SetPixelFormat() hasn't been called before. - */ -static int -get_matching_pixel_format(HDC hdc) -{ - int iPixelFormat = GetPixelFormat(hdc); - PIXELFORMATDESCRIPTOR pfd; - - if (!iPixelFormat) - return 0; - if (!DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd)) - return 0; - return stw_pixelformat_choose(hdc, &pfd); -} - - /** * Called via DrvCreateContext(), DrvCreateLayerContext() and * wglCreateContextAttribsARB() to actually create a rendering context. @@ -171,9 +155,9 @@ stw_create_context_attribs(HDC hdc, INT iLayerPlane, struct stw_context *shareCt struct st_manager *smapi, int majorVersion, int minorVersion, int contextFlags, int profileMask, - int iPixelFormat, int resetStrategy) + const struct stw_pixelformat_info *pfi, + int resetStrategy) { - const struct stw_pixelformat_info *pfi; struct st_context_attribs attribs; struct stw_context *ctx = NULL; enum st_context_error ctx_err = 0; @@ -184,32 +168,6 @@ stw_create_context_attribs(HDC hdc, INT iLayerPlane, struct stw_context *shareCt if (iLayerPlane != 0) return 0; - if (!iPixelFormat) { - /* - * GDI only knows about displayable pixel formats, so determine the pixel - * format from the framebuffer. - * - * This also allows to use a OpenGL DLL / ICD without installing. - */ - struct stw_framebuffer *fb; - fb = stw_framebuffer_from_hdc(hdc); - if (fb) { - iPixelFormat = fb->iPixelFormat; - stw_framebuffer_unlock(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 use that. - */ - iPixelFormat = get_matching_pixel_format(hdc); - if (!iPixelFormat) - return 0; - } - } - - pfi = stw_pixelformat_get_info( iPixelFormat ); - if (shareCtx != NULL) shareCtx->shared = TRUE; @@ -219,11 +177,12 @@ stw_create_context_attribs(HDC hdc, INT iLayerPlane, struct stw_context *shareCt ctx->hDrawDC = hdc; ctx->hReadDC = hdc; - ctx->iPixelFormat = iPixelFormat; + ctx->pfi = pfi; ctx->shared = shareCtx != NULL; memset(&attribs, 0, sizeof(attribs)); - attribs.visual = pfi->stvis; + if (pfi) + attribs.visual = pfi->stvis; attribs.major = majorVersion; attribs.minor = minorVersion; if (contextFlags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) @@ -500,29 +459,28 @@ stw_make_current(struct stw_framebuffer *fb, struct stw_framebuffer *fbRead, str } if (ctx) { - if (!fb || !fbRead) - goto fail; - - if (fb->iPixelFormat != ctx->iPixelFormat) { + if (ctx->pfi && fb && fb->pfi != ctx->pfi) { SetLastError(ERROR_INVALID_PIXEL_FORMAT); goto fail; } - if (fbRead->iPixelFormat != ctx->iPixelFormat) { + if (ctx->pfi && fbRead && fbRead->pfi != ctx->pfi) { SetLastError(ERROR_INVALID_PIXEL_FORMAT); goto fail; } - stw_framebuffer_lock(fb); - stw_framebuffer_update(fb); - stw_framebuffer_reference_locked(fb); - stw_framebuffer_unlock(fb); + if (fb) { + stw_framebuffer_lock(fb); + stw_framebuffer_update(fb); + stw_framebuffer_reference_locked(fb); + stw_framebuffer_unlock(fb); + } - stw_framebuffer_lock(fbRead); - if (fbRead != fb) { + if (fbRead && fbRead != fb) { + stw_framebuffer_lock(fbRead); stw_framebuffer_update(fbRead); stw_framebuffer_reference_locked(fbRead); + stw_framebuffer_unlock(fbRead); } - stw_framebuffer_unlock(fbRead); struct stw_framebuffer *old_fb = ctx->current_framebuffer; struct stw_framebuffer *old_fbRead = ctx->current_read_framebuffer; @@ -530,7 +488,8 @@ stw_make_current(struct stw_framebuffer *fb, struct stw_framebuffer *fbRead, str ctx->current_read_framebuffer = fbRead; ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, - fb->stfb, fbRead->stfb); + fb ? fb->stfb : NULL, + fbRead ? fbRead->stfb : NULL); /* Release the old framebuffers from this context. */ release_old_framebuffers(old_fb, old_fbRead, ctx); @@ -578,9 +537,9 @@ get_unlocked_refd_framebuffer_from_dc(HDC hDC) * pixel format in some cases, so we must create a framebuffer for * those here. */ - int iPixelFormat = get_matching_pixel_format(hDC); + int iPixelFormat = stw_pixelformat_guess(hDC); if (iPixelFormat) - fb = stw_framebuffer_create(WindowFromDC(hDC), iPixelFormat, STW_FRAMEBUFFER_WGL_WINDOW, stw_dev->smapi); + fb = stw_framebuffer_create(WindowFromDC(hDC), stw_pixelformat_get_info(iPixelFormat), STW_FRAMEBUFFER_WGL_WINDOW, stw_dev->smapi); if (!fb) return NULL; } diff --git a/src/gallium/frontends/wgl/stw_context.h b/src/gallium/frontends/wgl/stw_context.h index 5f4096f362c..7faf4c14c87 100644 --- a/src/gallium/frontends/wgl/stw_context.h +++ b/src/gallium/frontends/wgl/stw_context.h @@ -41,7 +41,7 @@ struct stw_context { struct st_context_iface *st; DHGLRC dhglrc; - int iPixelFormat; + const struct stw_pixelformat_info *pfi; HDC hDrawDC; HDC hReadDC; BOOL shared; @@ -57,7 +57,8 @@ struct stw_context *stw_create_context_attribs(HDC hdc, INT iLayerPlane, struct st_manager *smapi, int majorVersion, int minorVersion, int contextFlags, int profileMask, - int iPixelFormat, int resetStrategy); + const struct stw_pixelformat_info *pfi, + int resetStrategy); DHGLRC stw_create_context_handle(struct stw_context *context, DHGLRC handle); diff --git a/src/gallium/frontends/wgl/stw_ext_context.c b/src/gallium/frontends/wgl/stw_ext_context.c index 2156726f339..0bc5b03e4d5 100644 --- a/src/gallium/frontends/wgl/stw_ext_context.c +++ b/src/gallium/frontends/wgl/stw_ext_context.c @@ -213,10 +213,14 @@ wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList) struct stw_context *share_stw = stw_lookup_context(share_dhglrc); + const struct stw_pixelformat_info *pfi = stw_pixelformat_get_info_from_hdc(hDC); + if (!pfi) + return 0; + struct stw_context *stw_ctx = stw_create_context_attribs(hDC, layerPlane, share_stw, stw_dev->smapi, majorVersion, minorVersion, - contextFlags, profileMask, 0, + contextFlags, profileMask, pfi, resetStrategy); if (!stw_ctx) { diff --git a/src/gallium/frontends/wgl/stw_ext_pbuffer.c b/src/gallium/frontends/wgl/stw_ext_pbuffer.c index f0613913022..e9f904be188 100644 --- a/src/gallium/frontends/wgl/stw_ext_pbuffer.c +++ b/src/gallium/frontends/wgl/stw_ext_pbuffer.c @@ -66,7 +66,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } struct stw_framebuffer * -stw_pbuffer_create(int iPixelFormat, int iWidth, int iHeight, struct st_manager *smapi) +stw_pbuffer_create(const struct stw_pixelformat_info *pfi, int iWidth, int iHeight, struct st_manager *smapi) { static boolean first = TRUE; @@ -143,7 +143,7 @@ stw_pbuffer_create(int iPixelFormat, int iWidth, int iHeight, struct st_manager assert(rect.bottom - rect.top == iHeight); #endif - return stw_framebuffer_create(hWnd, iPixelFormat, STW_FRAMEBUFFER_PBUFFER, smapi); + return stw_framebuffer_create(hWnd, pfi, STW_FRAMEBUFFER_PBUFFER, smapi); } @@ -164,8 +164,9 @@ wglCreatePbufferARB(HDC hCurrentDC, int textureFormat = WGL_NO_TEXTURE_ARB; int textureTarget = WGL_NO_TEXTURE_ARB; BOOL textureMipmap = FALSE; + const struct stw_pixelformat_info *pfi = stw_pixelformat_get_info(iPixelFormat); - if (!stw_pixelformat_get_info(iPixelFormat)) { + if (!pfi) { SetLastError(ERROR_INVALID_PIXEL_FORMAT); return 0; } @@ -241,7 +242,7 @@ wglCreatePbufferARB(HDC hCurrentDC, * We can't pass non-displayable pixel formats to GDI, which is why we * create the framebuffer object before calling SetPixelFormat(). */ - fb = stw_pbuffer_create(iPixelFormat, iWidth, iHeight, stw_dev->smapi); + fb = stw_pbuffer_create(pfi, iWidth, iHeight, stw_dev->smapi); if (!fb) { SetLastError(ERROR_NO_SYSTEM_RESOURCES); return NULL; diff --git a/src/gallium/frontends/wgl/stw_ext_rendertexture.c b/src/gallium/frontends/wgl/stw_ext_rendertexture.c index 2b7d90eeea8..746727ec40e 100644 --- a/src/gallium/frontends/wgl/stw_ext_rendertexture.c +++ b/src/gallium/frontends/wgl/stw_ext_rendertexture.c @@ -107,7 +107,7 @@ wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) struct stw_framebuffer *fb, *old_fb, *old_fbRead; GLenum texFormat, srcBuffer, target; boolean retVal; - int pixelFormatSave; + const struct stw_pixelformat_info *pfiSave; /* * Implementation notes: @@ -170,10 +170,10 @@ wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) * an error condition. After the stw_make_current() we restore the * buffer's pixel format. */ - pixelFormatSave = fb->iPixelFormat; - fb->iPixelFormat = curctx->iPixelFormat; + pfiSave = fb->pfi; + fb->pfi = curctx->pfi; retVal = stw_make_current(fb, fb, curctx); - fb->iPixelFormat = pixelFormatSave; + fb->pfi = pfiSave; if (!retVal) { debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n"); return FALSE; diff --git a/src/gallium/frontends/wgl/stw_framebuffer.c b/src/gallium/frontends/wgl/stw_framebuffer.c index 768f2fa7e1f..02fed21c6b4 100644 --- a/src/gallium/frontends/wgl/stw_framebuffer.c +++ b/src/gallium/frontends/wgl/stw_framebuffer.c @@ -269,32 +269,30 @@ stw_call_window_proc(int nCode, WPARAM wParam, LPARAM lParam) * with its mutex locked. */ struct stw_framebuffer * -stw_framebuffer_create(HWND hWnd, int iPixelFormat, enum stw_framebuffer_owner owner, +stw_framebuffer_create(HWND hWnd, const struct stw_pixelformat_info *pfi, enum stw_framebuffer_owner owner, struct st_manager *smapi) { struct stw_framebuffer *fb; - const struct stw_pixelformat_info *pfi; fb = CALLOC_STRUCT( stw_framebuffer ); if (fb == NULL) return NULL; fb->hWnd = hWnd; - fb->iPixelFormat = iPixelFormat; if (stw_dev->stw_winsys->create_framebuffer) fb->winsys_framebuffer = - stw_dev->stw_winsys->create_framebuffer(stw_dev->screen, hWnd, iPixelFormat); + stw_dev->stw_winsys->create_framebuffer(stw_dev->screen, hWnd, pfi->iPixelFormat); /* * We often need a displayable pixel format to make GDI happy. Set it * here (always 1, i.e., out first pixel format) where appropriate. */ - fb->iDisplayablePixelFormat = iPixelFormat <= stw_dev->pixelformat_count - ? iPixelFormat : 1; + fb->iDisplayablePixelFormat = pfi->iPixelFormat <= stw_dev->pixelformat_count + ? pfi->iPixelFormat : 1; fb->owner = owner; - fb->pfi = pfi = stw_pixelformat_get_info( iPixelFormat ); + fb->pfi = pfi; fb->stfb = stw_st_create_framebuffer( fb, smapi ); if (!fb->stfb) { FREE( fb ); @@ -499,7 +497,9 @@ DrvSetPixelFormat(HDC hdc, LONG iPixelFormat) return bPbuffer; } - fb = stw_framebuffer_create(WindowFromDC(hdc), iPixelFormat, STW_FRAMEBUFFER_WGL_WINDOW, stw_dev->smapi); + const struct stw_pixelformat_info *pfi = stw_pixelformat_get_info(iPixelFormat); + + fb = stw_framebuffer_create(WindowFromDC(hdc), pfi, STW_FRAMEBUFFER_WGL_WINDOW, stw_dev->smapi); if (!fb) { return FALSE; } @@ -528,7 +528,7 @@ stw_pixelformat_get(HDC hdc) fb = stw_framebuffer_from_hdc(hdc); if (fb) { - iPixelFormat = fb->iPixelFormat; + iPixelFormat = fb->pfi->iPixelFormat; stw_framebuffer_unlock(fb); } diff --git a/src/gallium/frontends/wgl/stw_framebuffer.h b/src/gallium/frontends/wgl/stw_framebuffer.h index de45f340fee..d3366ce9889 100644 --- a/src/gallium/frontends/wgl/stw_framebuffer.h +++ b/src/gallium/frontends/wgl/stw_framebuffer.h @@ -84,7 +84,6 @@ struct stw_framebuffer HWND hWnd; - int iPixelFormat; const struct stw_pixelformat_info *pfi; /* A pixel format that can be used by GDI */ @@ -154,11 +153,11 @@ struct stw_framebuffer * must be called when done */ struct stw_framebuffer * -stw_framebuffer_create(HWND hwnd, int iPixelFormat, enum stw_framebuffer_owner owner, +stw_framebuffer_create(HWND hwnd, const struct stw_pixelformat_info *pfi, enum stw_framebuffer_owner owner, struct st_manager *smapi); struct stw_framebuffer * -stw_pbuffer_create(int iPixelFormat, int iWidth, int iHeight, struct st_manager *smapi); +stw_pbuffer_create(const struct stw_pixelformat_info *pfi, int iWidth, int iHeight, struct st_manager *smapi); /** diff --git a/src/gallium/frontends/wgl/stw_pixelformat.c b/src/gallium/frontends/wgl/stw_pixelformat.c index 3994ab0766c..2c0d1561c32 100644 --- a/src/gallium/frontends/wgl/stw_pixelformat.c +++ b/src/gallium/frontends/wgl/stw_pixelformat.c @@ -36,6 +36,7 @@ #include #include "gldrv.h" #include "stw_device.h" +#include "stw_framebuffer.h" #include "stw_pixelformat.h" #include "stw_tls.h" #include "stw_winsys.h" @@ -382,6 +383,52 @@ stw_pixelformat_get_info(int iPixelFormat) index); } +/** + * Return the stw pixel format that most closely matches the pixel format + * on HDC. + * Used to get a pixel format when SetPixelFormat() hasn't been called before. + */ +int +stw_pixelformat_guess(HDC hdc) +{ + int iPixelFormat = GetPixelFormat(hdc); + PIXELFORMATDESCRIPTOR pfd; + + if (!iPixelFormat) + return 0; + if (!DescribePixelFormat(hdc, iPixelFormat, sizeof(pfd), &pfd)) + return 0; + return stw_pixelformat_choose(hdc, &pfd); +} + +const struct stw_pixelformat_info * +stw_pixelformat_get_info_from_hdc(HDC hdc) +{ + /* + * GDI only knows about displayable pixel formats, so determine the pixel + * format from the framebuffer. + * + * This also allows to use a OpenGL DLL / ICD without installing. + */ + struct stw_framebuffer *fb; + fb = stw_framebuffer_from_hdc(hdc); + if (fb) { + const struct stw_pixelformat_info *pfi = fb->pfi; + stw_framebuffer_unlock(fb); + return pfi; + } + + /* 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 use that. + */ + int iPixelFormat = stw_pixelformat_guess(hdc); + if (!iPixelFormat) + return 0; + + return stw_pixelformat_get_info( iPixelFormat ); +} + LONG APIENTRY DrvDescribePixelFormat(HDC hdc, INT iPixelFormat, ULONG cjpfd, diff --git a/src/gallium/frontends/wgl/stw_pixelformat.h b/src/gallium/frontends/wgl/stw_pixelformat.h index 036baeb8045..3999c8e4ab4 100644 --- a/src/gallium/frontends/wgl/stw_pixelformat.h +++ b/src/gallium/frontends/wgl/stw_pixelformat.h @@ -67,6 +67,12 @@ stw_pixelformat_get_extended_count( HDC hdc ); const struct stw_pixelformat_info * stw_pixelformat_get_info( int iPixelFormat ); +const struct stw_pixelformat_info * +stw_pixelformat_get_info_from_hdc( HDC hdc ); + +int +stw_pixelformat_guess( HDC ); + int stw_pixelformat_choose( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd );