Related to #1381.
This commit is contained in:
Camilla Löwy 2018-12-30 18:16:28 +01:00
parent babafc13db
commit 3d748cf530

View File

@ -31,123 +31,33 @@
#include <malloc.h> #include <malloc.h>
#include <assert.h> #include <assert.h>
// array of pixel format attributes we need // Return the value corresponding to the specified attribute
static const int glfwPixelFormatAttribs[] = { //
WGL_SUPPORT_OPENGL_ARB, static int findPixelFormatAttribValue(const int* attribs,
WGL_DRAW_TO_WINDOW_ARB, int attribCount,
WGL_PIXEL_TYPE_ARB, const int* values,
WGL_ACCELERATION_ARB, int attrib)
WGL_RED_BITS_ARB,
WGL_RED_SHIFT_ARB,
WGL_GREEN_BITS_ARB,
WGL_GREEN_SHIFT_ARB,
WGL_BLUE_BITS_ARB,
WGL_BLUE_SHIFT_ARB,
WGL_ALPHA_BITS_ARB,
WGL_ALPHA_SHIFT_ARB,
WGL_DEPTH_BITS_ARB,
WGL_STENCIL_BITS_ARB,
WGL_ACCUM_BITS_ARB,
WGL_ACCUM_RED_BITS_ARB,
WGL_ACCUM_GREEN_BITS_ARB,
WGL_ACCUM_BLUE_BITS_ARB,
WGL_ACCUM_ALPHA_BITS_ARB,
WGL_AUX_BUFFERS_ARB,
WGL_STEREO_ARB,
WGL_DOUBLE_BUFFER_ARB,
// ARB EXT attribs only below this line, see initPixelFormatAttribArry
WGL_SAMPLES_ARB,
WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB,
WGL_COLORSPACE_EXT
};
// initialize array attribs with formatattribs available
// attribs array must be at least of size sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0])
// returns number of valid elemets in array
static int initPixelFormatAttribArry( int* attribs, int api )
{
const int numARBEXTAtrribs = 3; // Update this value when adding ARB EXT attribs
int numAttribs = sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0]) - numARBEXTAtrribs;
memcpy(attribs, glfwPixelFormatAttribs, sizeof(glfwPixelFormatAttribs));
if (_glfw.wgl.ARB_multisample)
{
attribs[numAttribs++] = WGL_SAMPLES_ARB;
}
if (api == GLFW_OPENGL_API)
{
if (_glfw.wgl.ARB_framebuffer_sRGB ||
_glfw.wgl.EXT_framebuffer_sRGB)
{
attribs[numAttribs++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
}
}
else
{
if (_glfw.wgl.EXT_colorspace)
{
attribs[numAttribs++] = WGL_COLORSPACE_EXT;
}
}
return numAttribs;
}
// Returns all formats in glfwPixelFormats attribute of the specified pixel format
// values should be of size GLFW_PFA_COUNT and on return will hold integer values
// which can be indexed using glfwEnumPixelFormatAttribs
// returns 1 on success, 0 on failure
static int getPixelFormatAttribs(_GLFWwindow* window, int pixelFormat, int numAttribs, int* attribs, int* values )
{
assert(_glfw.wgl.ARB_pixel_format);
if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
pixelFormat,
0, numAttribs,
attribs, values))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attributes");
return 0;
}
return 1;
}
static int getPixelFormatAttribFromArray( int* attribs, int* values, int attrib )
{ {
int i; int i;
for (i = 0; i < sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0]); ++i )
for (i = 0; i < attribCount; i++)
{ {
if (attribs[i] == attrib) if (attribs[i] == attrib)
return values[i]; return values[i];
} }
// error
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Unknown attribute requested from attribute array"); "WGL: Unknown pixel format attribute requested");
return 0; return 0;
} }
// Returns the specified attribute of the specified pixel format #define addAttrib(a) \
// { \
static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
{ attribs[attribCount++] = a; \
int value = 0;
assert(_glfw.wgl.ARB_pixel_format);
if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
pixelFormat,
0, 1, &attrib, &value))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute");
return 0;
}
return value;
} }
#define findAttribValue(a) \
findPixelFormatAttribValue(attribs, attribCount, values, a)
// Return a list of available and usable framebuffer configs // Return a list of available and usable framebuffer configs
// //
@ -157,17 +67,60 @@ static int choosePixelFormat(_GLFWwindow* window,
{ {
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, pixelFormat, nativeCount, usableCount, numAttribs, hintPos; int i, pixelFormat, nativeCount, usableCount, attribCount;
int pfAttribs[sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0])]; int attribs[40];
int pfValues[sizeof(glfwPixelFormatAttribs) / sizeof(glfwPixelFormatAttribs[0])]; int values[sizeof(attribs) / sizeof(attribs[0])];
numAttribs = initPixelFormatAttribArry(pfAttribs, ctxconfig->client);
if (_glfw.wgl.ARB_pixel_format) if (_glfw.wgl.ARB_pixel_format)
{ {
nativeCount = getPixelFormatAttrib(window, const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
1,
WGL_NUMBER_PIXEL_FORMATS_ARB); if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
1, 0, 1, &attrib, &nativeCount))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute");
return 0;
}
attribCount = 0;
addAttrib(WGL_SUPPORT_OPENGL_ARB);
addAttrib(WGL_DRAW_TO_WINDOW_ARB);
addAttrib(WGL_PIXEL_TYPE_ARB);
addAttrib(WGL_ACCELERATION_ARB);
addAttrib(WGL_RED_BITS_ARB);
addAttrib(WGL_RED_SHIFT_ARB);
addAttrib(WGL_GREEN_BITS_ARB);
addAttrib(WGL_GREEN_SHIFT_ARB);
addAttrib(WGL_BLUE_BITS_ARB);
addAttrib(WGL_BLUE_SHIFT_ARB);
addAttrib(WGL_ALPHA_BITS_ARB);
addAttrib(WGL_ALPHA_SHIFT_ARB);
addAttrib(WGL_DEPTH_BITS_ARB);
addAttrib(WGL_STENCIL_BITS_ARB);
addAttrib(WGL_ACCUM_BITS_ARB);
addAttrib(WGL_ACCUM_RED_BITS_ARB);
addAttrib(WGL_ACCUM_GREEN_BITS_ARB);
addAttrib(WGL_ACCUM_BLUE_BITS_ARB);
addAttrib(WGL_ACCUM_ALPHA_BITS_ARB);
addAttrib(WGL_AUX_BUFFERS_ARB);
addAttrib(WGL_STEREO_ARB);
addAttrib(WGL_DOUBLE_BUFFER_ARB);
if (_glfw.wgl.ARB_multisample)
addAttrib(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
addAttrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
}
else
{
if (_glfw.wgl.EXT_colorspace)
addAttrib(WGL_COLORSPACE_EXT);
}
} }
else else
{ {
@ -182,62 +135,64 @@ static int choosePixelFormat(_GLFWwindow* window,
for (i = 0; i < nativeCount; i++) for (i = 0; i < nativeCount; i++)
{ {
const int n = i + 1;
_GLFWfbconfig* u = usableConfigs + usableCount; _GLFWfbconfig* u = usableConfigs + usableCount;
pixelFormat = i + 1;
if (_glfw.wgl.ARB_pixel_format) if (_glfw.wgl.ARB_pixel_format)
{ {
// Get pixel format attributes through "modern" extension // Get pixel format attributes through "modern" extension
getPixelFormatAttribs(window, n, numAttribs, pfAttribs, pfValues );
hintPos = 0;
if (!getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_SUPPORT_OPENGL_ARB) || if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
!getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DRAW_TO_WINDOW_ARB)) pixelFormat, 0,
attribCount,
attribs, values))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attributes");
return 0;
}
if (!findAttribValue(WGL_SUPPORT_OPENGL_ARB) ||
!findAttribValue(WGL_DRAW_TO_WINDOW_ARB))
{ {
continue; continue;
} }
if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_PIXEL_TYPE_ARB) != if (findAttribValue(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
WGL_TYPE_RGBA_ARB )
{
continue; continue;
}
if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCELERATION_ARB) == if (findAttribValue(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
WGL_NO_ACCELERATION_ARB )
{
continue; continue;
}
u->redBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_RED_BITS_ARB); u->redBits = findAttribValue(WGL_RED_BITS_ARB);
u->greenBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_GREEN_BITS_ARB); u->greenBits = findAttribValue(WGL_GREEN_BITS_ARB);
u->blueBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_BLUE_BITS_ARB); u->blueBits = findAttribValue(WGL_BLUE_BITS_ARB);
u->alphaBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ALPHA_BITS_ARB); u->alphaBits = findAttribValue(WGL_ALPHA_BITS_ARB);
u->depthBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DEPTH_BITS_ARB); u->depthBits = findAttribValue(WGL_DEPTH_BITS_ARB);
u->stencilBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_STENCIL_BITS_ARB); u->stencilBits = findAttribValue(WGL_STENCIL_BITS_ARB);
u->accumRedBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_RED_BITS_ARB); u->accumRedBits = findAttribValue(WGL_ACCUM_RED_BITS_ARB);
u->accumGreenBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_GREEN_BITS_ARB); u->accumGreenBits = findAttribValue(WGL_ACCUM_GREEN_BITS_ARB);
u->accumBlueBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_BLUE_BITS_ARB); u->accumBlueBits = findAttribValue(WGL_ACCUM_BLUE_BITS_ARB);
u->accumAlphaBits = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_ACCUM_ALPHA_BITS_ARB); u->accumAlphaBits = findAttribValue(WGL_ACCUM_ALPHA_BITS_ARB);
u->auxBuffers = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_AUX_BUFFERS_ARB); u->auxBuffers = findAttribValue(WGL_AUX_BUFFERS_ARB);
if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_STEREO_ARB)) if (findAttribValue(WGL_STEREO_ARB))
u->stereo = GLFW_TRUE; u->stereo = GLFW_TRUE;
if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_DOUBLE_BUFFER_ARB)) if (findAttribValue(WGL_DOUBLE_BUFFER_ARB))
u->doublebuffer = GLFW_TRUE; u->doublebuffer = GLFW_TRUE;
if (_glfw.wgl.ARB_multisample) if (_glfw.wgl.ARB_multisample)
u->samples = getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_SAMPLES_ARB); u->samples = findAttribValue(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API) if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if (_glfw.wgl.ARB_framebuffer_sRGB || if (_glfw.wgl.ARB_framebuffer_sRGB ||
_glfw.wgl.EXT_framebuffer_sRGB) _glfw.wgl.EXT_framebuffer_sRGB)
{ {
if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB)) if (findAttribValue(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE; u->sRGB = GLFW_TRUE;
} }
} }
@ -245,14 +200,11 @@ static int choosePixelFormat(_GLFWwindow* window,
{ {
if (_glfw.wgl.EXT_colorspace) if (_glfw.wgl.EXT_colorspace)
{ {
if (getPixelFormatAttribFromArray(pfAttribs, pfValues, WGL_COLORSPACE_EXT) == if (findAttribValue(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
WGL_COLORSPACE_SRGB_EXT)
{
u->sRGB = GLFW_TRUE; u->sRGB = GLFW_TRUE;
} }
} }
} }
}
else else
{ {
// Get pixel format attributes through legacy PFDs // Get pixel format attributes through legacy PFDs
@ -260,7 +212,7 @@ static int choosePixelFormat(_GLFWwindow* window,
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
if (!DescribePixelFormat(window->context.wgl.dc, if (!DescribePixelFormat(window->context.wgl.dc,
n, pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
&pfd)) &pfd))
{ {
@ -303,7 +255,7 @@ static int choosePixelFormat(_GLFWwindow* window,
u->doublebuffer = GLFW_TRUE; u->doublebuffer = GLFW_TRUE;
} }
u->handle = n; u->handle = pixelFormat;
usableCount++; usableCount++;
} }
@ -332,6 +284,9 @@ static int choosePixelFormat(_GLFWwindow* window,
return pixelFormat; return pixelFormat;
} }
#undef addAttrib
#undef findAttribValue
static void makeContextCurrentWGL(_GLFWwindow* window) static void makeContextCurrentWGL(_GLFWwindow* window)
{ {
if (window) if (window)