9#include <QtCore/qdebug.h>
10#include <QtCore/qsysinfo.h>
11#include <QtGui/qcolorspace.h>
12#include <QtGui/qguiapplication.h>
13#include <qpa/qplatformnativeinterface.h>
14#include <private/qsystemlibrary_p.h>
23#ifndef WGL_ARB_multisample
24#define WGL_SAMPLE_BUFFERS_ARB 0x2041
25#define WGL_SAMPLES_ARB 0x2042
28#ifndef WGL_ARB_pixel_format
29#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
30#define WGL_DRAW_TO_WINDOW_ARB 0x2001
31#define WGL_DRAW_TO_BITMAP_ARB 0x2002
32#define WGL_ACCELERATION_ARB 0x2003
33#define WGL_NEED_PALETTE_ARB 0x2004
34#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
35#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
36#define WGL_SWAP_METHOD_ARB 0x2007
37#define WGL_NUMBER_OVERLAYS_ARB 0x2008
38#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
39#define WGL_TRANSPARENT_ARB 0x200A
40#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
41#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
42#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
43#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
44#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
45#define WGL_SHARE_DEPTH_ARB 0x200C
46#define WGL_SHARE_STENCIL_ARB 0x200D
47#define WGL_SHARE_ACCUM_ARB 0x200E
48#define WGL_SUPPORT_GDI_ARB 0x200F
49#define WGL_SUPPORT_OPENGL_ARB 0x2010
50#define WGL_DOUBLE_BUFFER_ARB 0x2011
51#define WGL_STEREO_ARB 0x2012
52#define WGL_PIXEL_TYPE_ARB 0x2013
53#define WGL_COLOR_BITS_ARB 0x2014
54#define WGL_RED_BITS_ARB 0x2015
55#define WGL_RED_SHIFT_ARB 0x2016
56#define WGL_GREEN_BITS_ARB 0x2017
57#define WGL_GREEN_SHIFT_ARB 0x2018
58#define WGL_BLUE_BITS_ARB 0x2019
59#define WGL_BLUE_SHIFT_ARB 0x201A
60#define WGL_ALPHA_BITS_ARB 0x201B
61#define WGL_ALPHA_SHIFT_ARB 0x201C
62#define WGL_ACCUM_BITS_ARB 0x201D
63#define WGL_ACCUM_RED_BITS_ARB 0x201E
64#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
65#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
66#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
67#define WGL_DEPTH_BITS_ARB 0x2022
68#define WGL_STENCIL_BITS_ARB 0x2023
69#define WGL_AUX_BUFFERS_ARB 0x2024
70#define WGL_NO_ACCELERATION_ARB 0x2025
71#define WGL_GENERIC_ACCELERATION_ARB 0x2026
72#define WGL_FULL_ACCELERATION_ARB 0x2027
73#define WGL_SWAP_EXCHANGE_ARB 0x2028
74#define WGL_SWAP_COPY_ARB 0x2029
75#define WGL_SWAP_UNDEFINED_ARB 0x202A
76#define WGL_TYPE_RGBA_ARB 0x202B
77#define WGL_TYPE_COLORINDEX_ARB 0x202C
80#ifndef WGL_ARB_create_context
81#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
82#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
83#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
84#define WGL_CONTEXT_FLAGS_ARB 0x2094
85#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
86#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
87#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
88#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001
89#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x0002
91#define ERROR_INVALID_VERSION_ARB 0x2095
92#define ERROR_INVALID_PROFILE_ARB 0x2096
96#define GL_CONTEXT_PROFILE_MASK 0x9126
97#define GL_MAJOR_VERSION 0x821B
98#define GL_MINOR_VERSION 0x821C
99#define GL_NUM_EXTENSIONS 0x821D
100#define GL_CONTEXT_FLAGS 0x821E
101#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
104#ifndef GL_CONTEXT_FLAG_DEBUG_BIT
105#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
109#define RESET_NOTIFICATION_STRATEGY_ARB 0x8256
110#define LOSE_CONTEXT_ON_RESET_ARB 0x8252
112#ifndef WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT
113#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
123 ?
reinterpret_cast<QFunctionPointer
>(::GetProcAddress(m_lib,
name))
131 bool useSystemLib =
false;
135 openglDll = softwareRendering ? swopengl : opengl32;
136 useSystemLib = !softwareRendering;
139 openglDll = openglDll.
toLower();
140 m_nonOpengl32 = openglDll != opengl32;
142 qCDebug(lcQpaGl) <<
"Qt: Using WGL and OpenGL from" << openglDll;
147 m_lib = LoadLibraryA(openglDll.
constData());
157 QSystemLibrary::load(L
"opengl32");
160 wglCreateContext =
reinterpret_cast<HGLRC (WINAPI *)(
HDC)
>(
resolve(
"wglCreateContext"));
161 wglDeleteContext =
reinterpret_cast<BOOL (WINAPI *)(
HGLRC)
>(
resolve(
"wglDeleteContext"));
162 wglGetCurrentContext =
reinterpret_cast<HGLRC (WINAPI *)()
>(
resolve(
"wglGetCurrentContext"));
163 wglGetCurrentDC =
reinterpret_cast<HDC (WINAPI *)()
>(
resolve(
"wglGetCurrentDC"));
164 wglGetProcAddress =
reinterpret_cast<PROC (WINAPI *)(LPCSTR)
>(
resolve(
"wglGetProcAddress"));
167 wglSwapBuffers =
reinterpret_cast<BOOL (WINAPI *)(
HDC)
>(
resolve(
"wglSwapBuffers"));
168 wglSetPixelFormat =
reinterpret_cast<BOOL (WINAPI *)(
HDC,
int,
const PIXELFORMATDESCRIPTOR *)
>(
resolve(
"wglSetPixelFormat"));
169 wglDescribePixelFormat =
reinterpret_cast<int (WINAPI *)(
HDC,
int, UINT, PIXELFORMATDESCRIPTOR *)
>(
resolve(
"wglDescribePixelFormat"));
175 return wglCreateContext && glGetError &&
glGetString;
185 return moduleIsNotOpengl32() ? wglSetPixelFormat(dc, pf, pfd) : SetPixelFormat(dc, pf, pfd);
203template <
class MaskType,
class FlagType>
inline bool testFlag(MaskType
mask, FlagType flag)
205 return (
mask & MaskType(flag)) != 0;
209{
return (pd.bReserved & 0x0f) != 0; }
212{
return (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || !(pfd.dwFlags & PFD_GENERIC_FORMAT); }
216 memset(
d, 0,
sizeof(PIXELFORMATDESCRIPTOR));
217 d->nSize =
sizeof(PIXELFORMATDESCRIPTOR);
221#ifndef QT_NO_DEBUG_STREAM
226 d <<
"PIXELFORMATDESCRIPTOR "
228 if (pd.dwFlags & PFD_DRAW_TO_WINDOW)
d <<
" PFD_DRAW_TO_WINDOW";
229 if (pd.dwFlags & PFD_DRAW_TO_BITMAP)
d <<
" PFD_DRAW_TO_BITMAP";
230 if (pd.dwFlags & PFD_SUPPORT_GDI)
d <<
" PFD_SUPPORT_GDI";
231 if (pd.dwFlags & PFD_SUPPORT_OPENGL)
d <<
" PFD_SUPPORT_OPENGL";
232 if (pd.dwFlags & PFD_GENERIC_ACCELERATED)
d <<
" PFD_GENERIC_ACCELERATED";
233 if (pd.dwFlags & PFD_SUPPORT_DIRECTDRAW)
d <<
" PFD_SUPPORT_DIRECTDRAW";
234 if (pd.dwFlags & PFD_DIRECT3D_ACCELERATED)
d <<
" PFD_DIRECT3D_ACCELERATED";
235 if (pd.dwFlags & PFD_SUPPORT_COMPOSITION)
d <<
" PFD_SUPPORT_COMPOSITION";
236 if (pd.dwFlags & PFD_GENERIC_FORMAT)
d <<
" PFD_GENERIC_FORMAT";
237 if (pd.dwFlags & PFD_NEED_PALETTE)
d <<
" PFD_NEED_PALETTE";
238 if (pd.dwFlags & PFD_NEED_SYSTEM_PALETTE)
d <<
" PFD_NEED_SYSTEM_PALETTE";
239 if (pd.dwFlags & PFD_DOUBLEBUFFER)
d <<
" PFD_DOUBLEBUFFER";
240 if (pd.dwFlags & PFD_STEREO)
d <<
" PFD_STEREO";
241 if (pd.dwFlags & PFD_SWAP_LAYER_BUFFERS)
d <<
" PFD_SWAP_LAYER_BUFFERS";
243 d <<
" iPixelType=" << pd.iPixelType <<
" cColorBits=" << pd.cColorBits
244 <<
" cRedBits=" << pd.cRedBits <<
" cRedShift=" << pd.cRedShift
245 <<
" cGreenBits=" << pd.cGreenBits <<
" cGreenShift=" << pd.cGreenShift
246 <<
" cBlueBits=" << pd.cBlueBits <<
" cBlueShift=" << pd.cBlueShift;
247 d <<
" cDepthBits=" << pd.cDepthBits;
249 d <<
" cStencilBits=" << pd.cStencilBits;
251 d <<
" cAuxBuffers=" << pd.cAuxBuffers;
252 d <<
" iLayerType=" << pd.iLayerType;
253 if (pd.dwVisibleMask)
254 d <<
" dwVisibleMask=" << pd.dwVisibleMask;
256 d <<
" cAlphaBits=" << pd.cAlphaBits <<
" cAlphaShift=" << pd.cAlphaShift;
258 d <<
" cAccumBits=" << pd.cAccumBits <<
" cAccumRedBits=" << pd.cAccumRedBits
259 <<
" cAccumGreenBits=" << pd.cAccumGreenBits <<
" cAccumBlueBits=" << pd.cAccumBlueBits
260 <<
" cAccumAlphaBits=" << pd.cAccumAlphaBits;
268 d <<
"OpenGL: " <<
s.vendor <<
',' <<
s.renderer <<
" default "
271 d <<
",SampleBuffers";
272 if (
s.hasExtensions())
273 d <<
", Extension-API present";
274 d <<
"\nExtensions: " << (
s.extensionNames.count(
' ') + 1);
276 d <<
s.extensionNames;
284 d <<
"ContextFormat: v" << (
f.version >> 8) <<
'.' << (
f.version & 0xFF)
285 <<
" profile: " <<
f.profile <<
" options: " <<
f.options;
293 const PIXELFORMATDESCRIPTOR &pfd,
294 bool ignoreGLSupport =
false)
297 const bool pixmapOk = !pixmapRequested ||
testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP);
298 const bool colorOk = !pixmapRequested || pfd.cColorBits == additional.
pixmapDepth;
299 const bool glOk = ignoreGLSupport ||
testFlag(pfd.dwFlags, PFD_SUPPORT_OPENGL);
301 return pixmapOk && glOk && overlayOk && colorOk;
307 for (
int i = 1;
i <= pfiMax;
i++) {
308 PIXELFORMATDESCRIPTOR pfd;
311 qCDebug(lcQpaGl) <<
'#' <<
i <<
'/' << pfiMax <<
':' << pfd;
323 if (pfd.dwFlags & PFD_DOUBLEBUFFER)
325 format.setDepthBufferSize(pfd.cDepthBits);
327 if (pfd.iPixelType == PFD_TYPE_RGBA)
328 format.setAlphaBufferSize(pfd.cAlphaBits);
329 format.setRedBufferSize(pfd.cRedBits);
330 format.setGreenBufferSize(pfd.cGreenBits);
331 format.setBlueBufferSize(pfd.cBlueBits);
332 format.setStencilBufferSize(pfd.cStencilBits);
333 format.setStereo(pfd.dwFlags & PFD_STEREO);
340 if (pfd.cAccumRedBits)
342 if (
testFlag(pfd.dwFlags, PFD_DRAW_TO_BITMAP)) {
346 *additionalIn = additional;
351static PIXELFORMATDESCRIPTOR
355 PIXELFORMATDESCRIPTOR pfd;
357 pfd.iPixelType = PFD_TYPE_RGBA;
358 pfd.iLayerType = PFD_MAIN_PLANE;
359 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_SUPPORT_COMPOSITION;
361 pfd.dwFlags |= isPixmap ? PFD_DRAW_TO_BITMAP : PFD_DRAW_TO_WINDOW;
363 pfd.dwFlags |= PFD_GENERIC_FORMAT;
366 pfd.dwFlags |= PFD_STEREO;
368 pfd.dwFlags |= PFD_DOUBLEBUFFER;
370 format.depthBufferSize() >= 0 ?
format.depthBufferSize() : 32;
371 const int redBufferSize =
format.redBufferSize();
372 if (redBufferSize != -1)
373 pfd.cRedBits = BYTE(redBufferSize);
374 const int greenBufferSize =
format.greenBufferSize();
375 if (greenBufferSize != -1)
376 pfd.cGreenBits = BYTE(greenBufferSize);
377 const int blueBufferSize =
format.blueBufferSize();
378 if (blueBufferSize != -1)
379 pfd.cBlueBits = BYTE(blueBufferSize);
380 pfd.cAlphaBits =
format.alphaBufferSize() > 0 ?
format.alphaBufferSize() : 8;
381 pfd.cStencilBits =
format.stencilBufferSize() > 0 ?
format.stencilBufferSize() : 8;
383 pfd.cAccumRedBits = pfd.cAccumGreenBits = pfd.cAccumBlueBits = pfd.cAccumAlphaBits = 16;
404 PIXELFORMATDESCRIPTOR *obtainedPfd)
407 qWarning(
"Attempted to use GDI functions with a non-opengl32.dll library");
414 int pixelFormat = ChoosePixelFormat(hdc, &requestedPfd);
415 if (pixelFormat >= 0) {
416 DescribePixelFormat(hdc, pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
421 const int pfiMax = DescribePixelFormat(hdc, 0, 0,
nullptr);
424 const bool stereoRequested =
format.stereo();
428 for (
int pfi = 1; pfi <= pfiMax; pfi++) {
429 PIXELFORMATDESCRIPTOR checkPfd;
431 DescribePixelFormat(hdc, pfi,
sizeof(PIXELFORMATDESCRIPTOR), &checkPfd);
433 int score = checkPfd.cColorBits + checkPfd.cAlphaBits + checkPfd.cStencilBits;
434 if (accumBufferRequested)
435 score += checkPfd.cAccumBits;
436 if (doubleBufferRequested ==
testFlag(checkPfd.dwFlags, PFD_DOUBLEBUFFER))
438 if (stereoRequested ==
testFlag(checkPfd.dwFlags, PFD_STEREO))
442 if (checkPfd.iPixelType == PFD_TYPE_RGBA)
444 if (score > bestScore) {
447 *obtainedPfd = checkPfd;
449 qCDebug(lcQpaGl) << __FUNCTION__ <<
" checking " << pfi <<
'/' << pfiMax
450 <<
" score=" << score <<
" (best " << bestPfi <<
'/' << bestScore <<
") " << checkPfd;
454 pixelFormat = bestPfi;
478 PIXELFORMATDESCRIPTOR *obtainedPfd)
480 enum { attribSize = 42 };
484 int iAttributes[attribSize];
485 std::fill(iAttributes, iAttributes + attribSize,
int(0));
491 iAttributes[
i++] = TRUE;
493 iAttributes[
i++] = TRUE;
496 iAttributes[
i++] = (
format.redBufferSize() > 0)
497 && (
format.greenBufferSize() > 0)
498 && (
format.blueBufferSize() > 0) ?
501 switch (
format.swapBehavior()) {
504 iAttributes[
i++] = FALSE;
510 iAttributes[
i++] = TRUE;
515 iAttributes[
i++] = TRUE;
517 if (
format.depthBufferSize() >= 0) {
519 iAttributes[
i++] =
format.depthBufferSize();
523 if (
format.redBufferSize() >= 0) {
525 iAttributes[
i++] =
format.redBufferSize();
527 if (
format.greenBufferSize() >= 0) {
529 iAttributes[
i++] =
format.greenBufferSize();
531 if (
format.blueBufferSize() >= 0) {
533 iAttributes[
i++] =
format.blueBufferSize();
536 iAttributes[
i++] =
format.alphaBufferSize() >= 0 ?
format.alphaBufferSize() : 8;
539 iAttributes[
i++] = 16;
542 iAttributes[
i++] = 8;
545 iAttributes[
i++] = 1;
549 const bool sampleBuffersRequested =
samples > 1
551 int sampleBuffersKeyPosition = 0;
552 int samplesValuePosition = 0;
553 if (sampleBuffersRequested) {
554 sampleBuffersKeyPosition =
i;
556 iAttributes[
i++] = TRUE;
558 samplesValuePosition =
i;
559 iAttributes[
i++] =
format.samples();
562 iAttributes[
i++] = FALSE;
566 int srgbCapableKeyPosition = 0;
568 srgbCapableKeyPosition =
i;
570 iAttributes[
i++] = TRUE;
578 &pixelFormat, &numFormats)
580 if (valid || (!sampleBuffersRequested && !srgbRequested))
584 iAttributes[srgbCapableKeyPosition] = 0;
585 srgbRequested =
false;
586 }
else if (sampleBuffersRequested) {
587 if (iAttributes[samplesValuePosition] > 1) {
588 iAttributes[samplesValuePosition] /= 2;
589 }
else if (iAttributes[samplesValuePosition] == 1) {
592 iAttributes[sampleBuffersKeyPosition] = 0;
593 iAttributes[samplesValuePosition] = 0;
604 qCDebug(lcQpaGl) << __FUNCTION__ <<
" obtained px #" << pixelFormat
605 <<
" not acceptable=" << *obtainedPfd;
609#ifndef QT_NO_DEBUG_OUTPUT
610 if (lcQpaGl().isDebugEnabled()) {
614 if (sampleBuffersRequested)
615 nsp <<
" samples=" << iAttributes[samplesValuePosition];
617 for (
int ii = 0; ii <
i; ++ii)
618 nsp << iAttributes[ii] <<
',';
620 <<
" of " << numFormats <<
"\n " << *obtainedPfd;
630 HDC hdc,
int pixelFormat,
633 enum { attribSize = 42 };
639 int iAttributes[attribSize];
640 int iValues[attribSize];
641 std::fill(iAttributes, iAttributes + attribSize,
int(0));
642 std::fill(iValues, iValues + attribSize,
int(0));
660 if (hasSampleBuffers) {
668 iAttributes, iValues)) {
669 qErrnoWarning(
"%s: wglGetPixelFormatAttribIVARB() failed for basic parameters.", __FUNCTION__);
673 result.setDepthBufferSize(iValues[1]);
674 result.setRedBufferSize(iValues[3]);
675 result.setGreenBufferSize(iValues[4]);
676 result.setBlueBufferSize(iValues[5]);
677 result.setAlphaBufferSize(iValues[6]);
678 result.setStencilBufferSize(iValues[8]);
682 if (hasSampleBuffers) {
683 result.setSamples(iValues[13]);
684 if (hasSrgbSupport && iValues[14])
687 if (hasSrgbSupport && iValues[12])
705 HGLRC shared =
nullptr)
707 enum { attribSize = 11 };
711 int attributes[attribSize];
713 std::fill(attributes, attributes + attribSize,
int(0));
719 const int requestedVersion =
qMin((
format.majorVersion() << 8) +
format.minorVersion(),
721 const int majorVersion = requestedVersion >> 8;
722 const int minorVersion = requestedVersion & 0xFF;
724 if (requestedVersion > 0x0101) {
726 attributes[attribIndex++] = majorVersion;
728 attributes[attribIndex++] = minorVersion;
734 if (requestedVersion >= 0x0300) {
739 attributes[attribIndex++] =
flags;
741 if (requestedVersion >= 0x0302) {
742 switch (
format.profile()) {
761 qCDebug(lcQpaGl) << __FUNCTION__ <<
"Creating context version"
762 << majorVersion <<
'.' << minorVersion << attribIndex / 2 <<
"attributes";
768 QDebug(&
message).nospace() << __FUNCTION__ <<
": wglCreateContextAttribsARB() failed (GL error code: 0x"
782 L
"OpenGLDummyWindow",
nullptr, WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
790 PIXELFORMATDESCRIPTOR pixelFormDescriptor;
792 pixelFormDescriptor.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_GENERIC_FORMAT;
793 pixelFormDescriptor.iPixelType = PFD_TYPE_RGBA;
795 const int pixelFormat = ChoosePixelFormat(dc, &pixelFormDescriptor);
797 qErrnoWarning(
"%s: ChoosePixelFormat failed.", __FUNCTION__);
845 result.version = (major << 8) + minor;
849 if (
result.version < 0x0300) {
860 if (
result.version < 0x0302)
915 ReleaseDC(m_current.
hwnd, m_current.
hdc);
916 DestroyWindow(m_current.
hwnd);
942#define SAMPLE_BUFFER_EXTENSION "GL_ARB_multisample"
943#define ROBUSTNESS_EXTENSION "GL_ARB_robustness"
945QOpenGLStaticContext::QOpenGLStaticContext() :
951 wglGetPixelFormatAttribIVARB(reinterpret_cast<WglGetPixelFormatAttribIVARB>(
952 reinterpret_cast<QFunctionPointer>(
QOpenGLStaticContext::opengl32.wglGetProcAddress(
"wglGetPixelFormatAttribivARB")))),
953 wglChoosePixelFormatARB(reinterpret_cast<WglChoosePixelFormatARB>(
954 reinterpret_cast<QFunctionPointer>(
QOpenGLStaticContext::opengl32.wglGetProcAddress(
"wglChoosePixelFormatARB")))),
955 wglCreateContextAttribsARB(reinterpret_cast<WglCreateContextAttribsARB>(
956 reinterpret_cast<QFunctionPointer>(
QOpenGLStaticContext::opengl32.wglGetProcAddress(
"wglCreateContextAttribsARB")))),
957 wglSwapInternalExt(reinterpret_cast<WglSwapInternalExt>(
958 reinterpret_cast<QFunctionPointer>(
QOpenGLStaticContext::opengl32.wglGetProcAddress(
"wglSwapIntervalEXT")))),
959 wglGetSwapInternalExt(reinterpret_cast<WglGetSwapInternalExt>(
960 reinterpret_cast<QFunctionPointer>(
QOpenGLStaticContext::opengl32.wglGetProcAddress(
"wglGetSwapIntervalEXT")))),
961 wglGetExtensionsStringARB(reinterpret_cast<WglGetExtensionsStringARB>(
962 reinterpret_cast<QFunctionPointer>(
QOpenGLStaticContext::opengl32.wglGetProcAddress(
"wglGetExtensionsStringARB"))))
964 if (defaultFormat.version < 0x0300) {
967 extensions |= SampleBuffers;
970 extensions |= Robustness;
973 auto glGetStringi =
reinterpret_cast<glGetStringi_t
>(
979 const char *
p =
reinterpret_cast<const char *
>(glGetStringi(GL_EXTENSIONS,
i));
982 extensions |= SampleBuffers;
984 extensions |= Robustness;
994 return QByteArray(
reinterpret_cast<const char*
>(
s));
1001 qWarning(
"Failed to load and resolve WGL/OpenGL functions");
1030 m_staticContext(staticContext)
1032 if (!m_staticContext)
1043 static bool opengl32dll =
false;
1054 HWND dummyWindow =
nullptr;
1056 bool tryExtensions =
false;
1057 int obtainedSwapInterval = -1;
1062 hdc = GetDC(dummyWindow);
1076 if (tryExtensions) {
1080 qCDebug(lcQpaGl) << __FUNCTION__ <<
"WGL extensions:" << exts;
1081 if (strstr(exts,
"WGL_EXT_framebuffer_sRGB"))
1087 requestedAdditional, &m_obtainedPixelFormatDescriptor);
1088 if (m_pixelFormat > 0) {
1091 &obtainedAdditional);
1092 m_extensionsUsed =
true;
1095 if (!m_pixelFormat) {
1097 &m_obtainedPixelFormatDescriptor);
1101 &obtainedAdditional);
1103 if (!m_pixelFormat) {
1104 qWarning(
"%s: Unable find a suitable pixel format.", __FUNCTION__);
1112 HGLRC sharingRenderingContext =
nullptr;
1116 if (m_extensionsUsed)
1117 m_renderingContext =
1120 requestedAdditional,
1121 sharingRenderingContext);
1122 if (!m_renderingContext)
1125 if (!m_renderingContext) {
1126 qWarning(
"Unable to create a GL Context.");
1131 if (!updateObtainedParams(hdc, &obtainedSwapInterval))
1137 ReleaseDC(dummyWindow, hdc);
1139 DestroyWindow(dummyWindow);
1141 qCDebug(lcQpaGl) << __FUNCTION__ <<
this << (tryExtensions ?
"ARB" :
"GDI")
1143 <<
"\n obtained #" << m_pixelFormat << (m_extensionsUsed ?
"ARB" :
"GDI") << m_obtainedFormat
1144 <<
"\n " << m_obtainedPixelFormatDescriptor <<
" swap interval: " << obtainedSwapInterval
1146 <<
"\n HGLRC=" << m_renderingContext;
1150 : m_staticContext(staticContext)
1152 if (!m_staticContext)
1155 HDC dc = GetDC(wnd);
1158 m_pixelFormat = GetPixelFormat(dc);
1159 bool ok = m_pixelFormat != 0;
1161 qWarning(
"QWindowsGLContext: Failed to get pixel format");
1162 ok = DescribePixelFormat(dc, m_pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), &m_obtainedPixelFormatDescriptor);
1164 qWarning(
"QWindowsGLContext: Failed to describe pixel format");
1168 m_renderingContext = wglcontext;
1169 ok = updateObtainedParams(dc);
1175 m_ownsContext =
false;
1177 m_renderingContext =
nullptr;
1182 if (m_renderingContext && m_ownsContext)
1187bool QWindowsGLContext::updateObtainedParams(HDC hdc,
int *obtainedSwapInterval)
1193 qWarning(
"Failed to make context current.");
1207 m_getGraphicsResetStatus =
reinterpret_cast<GlGetGraphicsResetStatusArbType
>(
1215void QWindowsGLContext::releaseDCs()
1217 for (
const auto &
e : m_windowContexts)
1218 ReleaseDC(
e.hwnd,
e.hdc);
1219 m_windowContexts.clear();
1236 for (
const auto &
e :
data) {
1246 qCDebug(lcQpaGl) << __FUNCTION__ << surface;
1258 qCDebug(lcQpaGl) << __FUNCTION__ <<
this << m_windowContexts.size() <<
"contexts";
1265 window->aboutToMakeCurrent();
1266 const HWND hwnd =
window->handle();
1277 qErrnoWarning(
"%s: wglMakeCurrent() failed for existing context data", __FUNCTION__);
1282 if (!newContext.
hdc)
1289 ReleaseDC(newContext.
hwnd, newContext.
hdc);
1296 m_windowContexts.push_back(newContext);
1301 if (m_getGraphicsResetStatus && m_getGraphicsResetStatus()) {
1303 qCDebug(lcQpaGl) <<
"makeCurrent(): context loss detected" <<
this;
1305 window->invalidateSurface();
1314 if (m_swapInterval != interval)
1315 m_swapInterval = interval;
1327 qCDebug(lcQpaGl) << __FUNCTION__ <<
this << m_windowContexts.size() <<
"contexts";
1345 if (procAddress ==
nullptr ||
reinterpret_cast<quintptr>(procAddress) < 4u
1346 || procAddress ==
reinterpret_cast<QFunctionPointer
>(-1)) {
1353 return reinterpret_cast<QFunctionPointer
>(procAddress);
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
QByteArray toLower() const &
QSurfaceFormat format() const
Returns the format of the underlying platform context, if create() has been called.
QPlatformOpenGLContext * shareHandle() const
Returns the underlying platform context with which this context is sharing.
Static Open GL context containing version information, extension function pointers,...
const QWindowsOpenGLContextFormat defaultFormat
WglChoosePixelFormatARB wglChoosePixelFormatARB
WglCreateContextAttribsARB wglCreateContextAttribsARB
static QByteArray getGlString(unsigned int which)
WglGetExtensionsStringARB wglGetExtensionsStringARB
WglGetSwapInternalExt wglGetSwapInternalExt
bool hasExtensions() const
QWindowsOpenGLContext * createContext(QOpenGLContext *context) override
WglGetPixelFormatAttribIVARB wglGetPixelFormatAttribIVARB
WglSwapInternalExt wglSwapInternalExt
static QWindowsOpengl32DLL opengl32
A temporary context that can be instantiated on the stack.
~QOpenGLTemporaryContext()
QOpenGLTemporaryContext()
The QPlatformOpenGLContext class provides an abstraction for native GL contexts.
QOpenGLContext * context() const
static bool parseOpenGLVersion(const QByteArray &versionString, int &major, int &minor)
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool supportsOpenGL() const
Returns true if the surface is OpenGL compatible and can be used in conjunction with QOpenGLContext; ...
static QWindowsContext * instance()
void doneCurrent() override
QFunctionPointer getProcAddress(const char *procName) override
Reimplement in subclass to allow dynamic querying of OpenGL symbols.
bool makeCurrent(QPlatformSurface *surface) override
QWindowsGLContext(QOpenGLStaticContext *staticContext, QOpenGLContext *context)
void swapBuffers(QPlatformSurface *surface) override
Reimplement in subclass to native swap buffers calls.
HGLRC renderingContext() const
~QWindowsGLContext() override
static QWindowsIntegration * instance()
static QWindowsStaticOpenGLContext * create()
@ OpenGlPixelFormatInitialized
HWND handle() const override
void qErrnoWarning(const char *msg,...)
static HGLRC createContext(const QOpenGLStaticContext &staticContext, HDC hdc, const QSurfaceFormat &format, const QWindowsOpenGLAdditionalFormat &, HGLRC shared=nullptr)
static int choosePixelFormat(HDC hdc, const QOpenGLStaticContext &staticContext, const QSurfaceFormat &format, const QWindowsOpenGLAdditionalFormat &additional, PIXELFORMATDESCRIPTOR *obtainedPfd)
static QSurfaceFormat qSurfaceFormatFromHDC(const QOpenGLStaticContext &staticContext, HDC hdc, int pixelFormat, QWindowsOpenGLAdditionalFormat *additionalIn=nullptr)
static PIXELFORMATDESCRIPTOR qPixelFormatFromSurfaceFormat(const QSurfaceFormat &format, const QWindowsOpenGLAdditionalFormat &additional)
static QSurfaceFormat qSurfaceFormatFromPixelFormat(const PIXELFORMATDESCRIPTOR &pfd, QWindowsOpenGLAdditionalFormat *additionalIn=nullptr)
static HGLRC createContext(HDC hdc, HGLRC shared)
static int choosePixelFormat(HDC hdc, const QSurfaceFormat &format, const QWindowsOpenGLAdditionalFormat &additional, PIXELFORMATDESCRIPTOR *obtainedPfd)
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
QTextStream & showbase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::ShowBase) on stream and r...
QTextStream & noshowbase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() & ~QTextStream::ShowBase) on stream and ...
QTextStream & dec(QTextStream &stream)
Calls QTextStream::setIntegerBase(10) on stream and returns stream.
#define QByteArrayLiteral(str)
static QByteArray getGlString(GLenum param)
#define GL_CONTEXT_PROFILE_MASK
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT
#define GL_CONTEXT_CORE_PROFILE_BIT
#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT
#define GL_CONTEXT_FLAG_DEBUG_BIT
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static Window createDummyWindow(Display *dpy, XVisualInfo *visualInfo, int screenNumber, Window rootWin)
#define qCDebug(category,...)
constexpr const T & qMin(const T &a, const T &b)
typedef GLint(GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program
GLenum GLuint GLintptr GLsizeiptr size
[1]
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLuint GLsizei const GLchar * message
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
#define qPrintable(string)
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
#define WGL_CONTEXT_MINOR_VERSION_ARB
#define WGL_STENCIL_BITS_ARB
#define WGL_ACCELERATION_ARB
static const QOpenGLContextData * findByHWND(const std::vector< QOpenGLContextData > &data, HWND hwnd)
static bool isDirectRendering(const PIXELFORMATDESCRIPTOR &pfd)
#define WGL_BLUE_BITS_ARB
#define RESET_NOTIFICATION_STRATEGY_ARB
QDebug operator<<(QDebug d, const PIXELFORMATDESCRIPTOR &pd)
static QOpenGLContextData currentOpenGLContextData()
#define WGL_GREEN_BITS_ARB
static bool hasGLOverlay(const PIXELFORMATDESCRIPTOR &pd)
#define WGL_ALPHA_BITS_ARB
#define WGL_CONTEXT_MAJOR_VERSION_ARB
#define WGL_CONTEXT_PROFILE_MASK_ARB
#define WGL_NO_ACCELERATION_ARB
#define WGL_PIXEL_TYPE_ARB
#define WGL_DEPTH_BITS_ARB
#define ROBUSTNESS_EXTENSION
static bool isAcceptableFormat(const QWindowsOpenGLAdditionalFormat &additional, const PIXELFORMATDESCRIPTOR &pfd, bool ignoreGLSupport=false)
#define WGL_NUMBER_OVERLAYS_ARB
#define WGL_CONTEXT_DEBUG_BIT_ARB
#define WGL_DOUBLE_BUFFER_ARB
static HGLRC createDummyGLContext(HDC dc)
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB
static void initPixelFormatDescriptor(PIXELFORMATDESCRIPTOR *d)
static QOpenGLContextData createDummyWindowOpenGLContextData()
#define WGL_DRAW_TO_WINDOW_ARB
static HWND handleOf(QPlatformSurface *s)
#define WGL_TYPE_RGBA_ARB
#define LOSE_CONTEXT_ON_RESET_ARB
#define WGL_CONTEXT_FLAGS_ARB
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
static void describeFormats(HDC hdc)
#define SAMPLE_BUFFER_EXTENSION
bool testFlag(MaskType mask, FlagType flag)
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
#define WGL_FULL_ACCELERATION_ARB
#define WGL_SAMPLE_BUFFERS_ARB
static QWindowsWindow * glWindowOf(QPlatformSurface *s)
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT
#define WGL_ACCUM_BITS_ARB
#define GL_NUM_EXTENSIONS
static HWND createDummyGLWindow()
#define WGL_COLOR_BITS_ARB
#define WGL_SUPPORT_OPENGL_ARB
@ QWindowsGLDirectRendering
@ QWindowsGLRenderToPixmap
QSvgRenderer * renderer
[0]
QSurfaceFormat::FormatOptions options
majorVersion<<8 + minorVersion
QSurfaceFormat::OpenGLContextProfile profile
static QWindowsOpenGLContextFormat current()
void apply(QSurfaceFormat *format) const
bool init(bool softwareRendering)
int describePixelFormat(HDC dc, int pf, UINT size, PIXELFORMATDESCRIPTOR *pfd)
BOOL(WINAPI *wglDeleteContext)(HGLRC context)
GLenum(APIENTRY *glGetError)()
PROC(WINAPI *wglGetProcAddress)(LPCSTR name)
HGLRC(WINAPI *wglCreateContext)(HDC dc)
QFunctionPointer resolve(const char *name)
const GLubyte *APIENTRY * glGetString(GLenum name)
HDC(WINAPI *wglGetCurrentDC)()
bool moduleIsNotOpengl32() const
BOOL setPixelFormat(HDC dc, int pf, const PIXELFORMATDESCRIPTOR *pfd)