mirror of https://gitlab.freedesktop.org/mesa/mesa
wgl: Use pfi instead of iPixelFormat more often
Also, support config-less contexts, and surface-less contexts. Acked-by: Daniel Stone <daniels@collabora.com> Acked-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Acked-by: Sidney Just <justsid@x-plane.com> Acked-by: Jason Ekstrand <jason.ekstrand@collabora.com> Tested-by: Yonggang Luo <luoyonggang@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12964>
This commit is contained in:
parent
aeb3147a96
commit
35e9c7e082
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <GL/gl.h>
|
||||
#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,
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue