Commit: b43cdc91ce4188e2fc18ff6646781ff03fbfd693
Author: Dalai Felinto
Date:   Fri Jun 30 13:33:54 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBb43cdc91ce4188e2fc18ff6646781ff03fbfd693

Fix T51721: OpenGL Detection is broken on Windows

Now computers that support OpenGl3.3 (but not 4.5) can run Blender 2.8.

For any given HDC, you may only call SetPixelFormat *ONCE* any future
calls for the same HDC will fail. And computers that would support only
OpenGL 3.3 wouldn't have a change to get a valid OpenGL context because
the pixelformat was already set while trying to probe the supported
contexts.

We fix this by splitting the final context creation from the query of
supported OpenGL versions.

Patch by Ray Molenkamp (bzzt_ploink/LazyDodo) with code style fixes and
comments by me.

===================================================================

M       intern/ghost/intern/GHOST_ContextWGL.cpp
M       intern/ghost/intern/GHOST_ContextWGL.h
M       intern/ghost/intern/GHOST_WindowWin32.cpp

===================================================================

diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp 
b/intern/ghost/intern/GHOST_ContextWGL.cpp
index 8cf311b9e84..d2dd38878f7 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextWGL.cpp
@@ -914,29 +914,6 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
        reportContextString("Version",  m_dummyVersion,  version);
 #endif
 
-       if ((strcmp(vendor, "Microsoft Corporation") == 0 ||
-            strcmp(renderer, "GDI Generic") == 0) && version[0] == '1' && 
version[2] == '1')
-       {
-               MessageBox(m_hWnd, "Your system does not use 3D hardware 
acceleration.\n"
-                                  "Blender requires a graphics driver with 
OpenGL 3.3 support.\n\n"
-                                  "This may be caused by:\n"
-                                  "* A missing or faulty graphics driver 
installation.\n"
-                                  "  Blender needs a graphics card driver to 
work correctly.\n"
-                                  "* Accessing Blender through a remote 
connection.\n"
-                                  "* Using Blender through a virtual 
machine.\n\n"
-                                  "The program will now close.",
-                          "Blender - Can't detect 3D hardware accelerated 
Driver!",
-                          MB_OK | MB_ICONERROR);
-               exit(0);
-       }
-       else if (version[0] < '3' || (version[0] == '3' && version[2] < '3')) {
-               MessageBox(m_hWnd, "Blender requires a graphics driver with 
OpenGL 3.3 support.\n\n"
-                                  "The program will now close.",
-                          "Blender - Unsupported Graphics Driver!",
-                          MB_OK | MB_ICONERROR);
-               exit(0);
-       }
-
        return GHOST_kSuccess;
 }
 
@@ -950,3 +927,97 @@ GHOST_TSuccess GHOST_ContextWGL::releaseNativeHandles()
 
        return success;
 }
+
+/**
+ * For any given HDC you may call SetPixelFormat once
+ *
+ * So we better try to get the correct OpenGL version in a new window 
altogether, in case it fails.
+ * (see 
https://msdn.microsoft.com/en-us/library/windows/desktop/dd369049(v=vs.85).aspx)
+ */
+static bool TryOpenGLVersion(
+        HWND hwnd,
+        bool wantStereoVisual,
+        bool wantAlphaBackground,
+        GHOST_TUns16 wantNumOfAASamples,
+        int contextProfileMask,
+        bool debugContext,
+        int major, int minor)
+{
+       HWND dummyHWND = clone_window(hwnd, NULL);
+       if (dummyHWND == NULL) {
+               return false;
+       }
+
+       HDC dummyHDC = GetDC(dummyHWND);
+       if (dummyHDC == NULL) {
+               return false;
+       }
+
+       GHOST_ContextWGL * context = new GHOST_ContextWGL(
+               wantStereoVisual,
+               wantAlphaBackground,
+               wantNumOfAASamples,
+               dummyHWND,
+               dummyHDC,
+               contextProfileMask,
+               major, minor,
+               (debugContext ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+               GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+       bool result = context->initializeDrawingContext();
+       delete context;
+
+       ReleaseDC(dummyHWND, dummyHDC);
+       DestroyWindow(dummyHWND);
+
+       return result;
+}
+
+GHOST_TSuccess GHOST_ContextWGL::getMaximumSupportedOpenGLVersion(
+        HWND hwnd,
+        bool wantStereoVisual,
+        bool wantAlphaBackground,
+        GHOST_TUns16 wantNumOfAASamples,
+        int contextProfileMask,
+        bool debugContext,
+        GHOST_TUns8 *r_major_version,
+        GHOST_TUns8 *r_minor_version)
+{
+       /* - AMD and Intel give us exactly this version
+        * - NVIDIA gives at least this version <-- desired behavior
+        * So we ask for 4.5, 4.4 ... 3.3 in descending order to get the best 
version on the user's system. */
+       for (int minor = 5; minor >= 0; --minor) {
+               if (TryOpenGLVersion(
+                           hwnd,
+                           wantStereoVisual,
+                           wantAlphaBackground,
+                           wantNumOfAASamples,
+                           contextProfileMask,
+                           debugContext,
+                           4, minor))
+               {
+                       *r_major_version = 4;
+                       *r_minor_version = minor;
+                       return GHOST_kSuccess;
+               }
+       }
+
+       /* Fallback to OpenGL 3.3 */
+       if (TryOpenGLVersion(
+               hwnd,
+               wantStereoVisual,
+               wantAlphaBackground,
+               wantNumOfAASamples,
+               contextProfileMask,
+               debugContext,
+               3, 3))
+       {
+               *r_major_version = 3;
+               *r_minor_version = 3;
+               return GHOST_kSuccess;
+       }
+
+       *r_major_version = 0;
+       *r_minor_version = 0;
+       return GHOST_kFailure;
+}
diff --git a/intern/ghost/intern/GHOST_ContextWGL.h 
b/intern/ghost/intern/GHOST_ContextWGL.h
index a07cc1b6301..0d9986a0802 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.h
+++ b/intern/ghost/intern/GHOST_ContextWGL.h
@@ -105,6 +105,20 @@ public:
         */
        GHOST_TSuccess getSwapInterval(int &intervalOut);
 
+       /**
+       * Gets the maximum supported OpenGL context for the user hardware
+       * \return Whether major_version and minor_version resulted in a valid 
context.
+       */
+       static GHOST_TSuccess getMaximumSupportedOpenGLVersion(
+               HWND hwnd,
+               bool wantStereoVisual,
+               bool wantAlphaBackground,
+               GHOST_TUns16 wantNumOfAASamples,
+               int contextProfileMask,
+               bool debugContext,
+               GHOST_TUns8 *r_major_version,
+               GHOST_TUns8 *r_minor_version);
+
 private:
        int choose_pixel_format(
                bool stereoVisual,
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp 
b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 2a141f8770c..3afc3f9c1b9 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -611,54 +611,48 @@ GHOST_TSuccess GHOST_WindowWin32::invalidate()
 GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType 
type)
 {
        if (type == GHOST_kDrawingContextTypeOpenGL) {
-
-               // During development:
-               //   ask for 2.1 context, driver gives latest compatibility 
profile
-               //   (we check later to ensure it's >= 3.3 on Windows)
-               //
-               // Final Blender 2.8:
-               //   try 4.x core profile
-               //   try 3.3 core profile
-               //   no fallbacks
-
-               // TODO(merwin): query version of initial dummy context, 
request that + profile + debug
-
                GHOST_Context *context;
 
 #if defined(WITH_GL_PROFILE_CORE)
-               // our minimum requirement is 3.3 core profile
-               // when we request a specific GL version:
-               //   - AMD and Intel give us exactly this version
-               //   - NVIDIA gives at least this version <-- desired behavior
-               // so we ask for 4.5, 4.4 ... 3.3 in descending order to get 
the best version on the user's system
-               for (int minor = 5; minor >= 0; --minor) {
+               GHOST_TUns8 major, minor;
+
+               if (GHOST_ContextWGL::getMaximumSupportedOpenGLVersion(
+                   m_hWnd,
+                   m_wantStereoVisual,
+                   m_wantAlphaBackground,
+                   m_wantNumOfAASamples,
+                   WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+                   m_debug_context,
+                   &major, &minor))
+               {
                        context = new GHOST_ContextWGL(
-                               m_wantStereoVisual,
-                               m_wantAlphaBackground,
-                               m_wantNumOfAASamples,
-                               m_hWnd,
-                               m_hDC,
-                               WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
-                               4, minor,
-                               (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 
0),
-                               GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
-
-                       if (context->initializeDrawingContext())
+                           m_wantStereoVisual,
+                           m_wantAlphaBackground,
+                           m_wantNumOfAASamples,
+                           m_hWnd,
+                           m_hDC,
+                           WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+                           major, minor,
+                           (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
+                           GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
+
+                       if (context->initializeDrawingContext()) {
                                return context;
-                       else
+                       }
+                       else {
                                delete context;
+                       }
+               }
+               else {
+                       MessageBox(
+                               m_hWnd,
+                               "Blender requires a graphics driver with at 
least OpenGL 3.3 support.\n\n"
+                               "The program will now close.",
+                               "Blender - Unsupported Graphics Driver!",
+                               MB_OK | MB_ICONERROR);
+                       exit(0);
+                       return NULL;
                }
-
-               context = new GHOST_ContextWGL(
-                       m_wantStereoVisual,
-                       m_wantAlphaBackground,
-                       m_wantNumOfAASamples,
-                       m_hWnd,
-                       m_hDC,
-                       WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
-                       3, 3,
-                       (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
-                       GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY);
 
 #elif defined(WITH_GL_PROFILE_COMPAT)
                // ask for 2.1 context, driver gives any GL version >= 2.1 
(hopefully the latest compatibility profile)
@@ -677,10 +671,12 @@ GHOST_Context 
*GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty
 #  error // must specify either core or compat at build time
 #endif
 
-               if (context->initializeDrawingContext())
+               if (context->initializeDrawingContext()) {
                        return context;
-               else
+               }
+               else {
                        delete context;
+               }
        }
 
        return NULL;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to