[Bf-blender-cvs] [b43cdc91ce4] blender2.8: Fix T51721: OpenGL Detection is broken on Windows

Dalai Felinto noreply at git.blender.org
Fri Jun 30 15:53:37 CEST 2017


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;




More information about the Bf-blender-cvs mailing list