[Bf-blender-cvs] [71c832a7003] temp-drawcontext: Create an offscreen context with own hDC

Germano noreply at git.blender.org
Mon Feb 12 16:04:48 CET 2018


Commit: 71c832a700373a310418788d7c82b18eab4394bc
Author: Germano
Date:   Mon Feb 12 13:04:33 2018 -0200
Branches: temp-drawcontext
https://developer.blender.org/rB71c832a700373a310418788d7c82b18eab4394bc

Create an offscreen context with own hDC

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

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

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

diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp
index 8ca639363f4..cb79ffcf635 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.cpp
+++ b/intern/ghost/intern/GHOST_ContextWGL.cpp
@@ -69,6 +69,7 @@ GHOST_ContextWGL::GHOST_ContextWGL(
         int contextFlags,
         int contextResetNotificationStrategy)
     : GHOST_Context(stereoVisual, numOfAASamples),
+      m_dummyPbuffer(NULL),
       m_hWnd(hWnd),
       m_hDC(hDC),
       m_contextProfileMask(contextProfileMask),
@@ -85,7 +86,6 @@ GHOST_ContextWGL::GHOST_ContextWGL(
       m_dummyVersion(NULL)
 #endif
 {
-	assert(m_hDC);
 }
 
 
@@ -105,6 +105,12 @@ GHOST_ContextWGL::~GHOST_ContextWGL()
 
 			WIN32_CHK(::wglDeleteContext(m_hGLRC));
 		}
+		if (m_dummyPbuffer) {
+			if (m_hDC != NULL)
+				WIN32_CHK(::wglReleasePbufferDCARB(m_dummyPbuffer, m_hDC));
+
+			WIN32_CHK(::wglDestroyPbufferARB(m_dummyPbuffer));
+		}
 	}
 
 #ifndef NDEBUG
@@ -318,6 +324,8 @@ static HWND clone_window(HWND hWnd, LPVOID lpParam)
 void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD)
 {
 	HWND  dummyHWND  = NULL;
+	HPBUFFERARB dummyhBuffer = NULL;
+
 	HDC   dummyHDC   = NULL;
 	HGLRC dummyHGLRC = NULL;
 
@@ -334,23 +342,29 @@ void GHOST_ContextWGL::initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD)
 	prevHGLRC = ::wglGetCurrentContext();
 	WIN32_CHK(GetLastError() == NO_ERROR);
 
-	dummyHWND = clone_window(m_hWnd, NULL);
+	iPixelFormat = choose_pixel_format_legacy(m_hDC, preferredPFD);
 
-	if (dummyHWND == NULL)
+	if (iPixelFormat == 0)
 		goto finalize;
 
-	dummyHDC = GetDC(dummyHWND);
-
-	if (!WIN32_CHK(dummyHDC != NULL))
+	PIXELFORMATDESCRIPTOR chosenPFD;
+	if (!WIN32_CHK(::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD)))
 		goto finalize;
 
-	iPixelFormat = choose_pixel_format_legacy(dummyHDC, preferredPFD);
+	if (m_hWnd) {
+		dummyHWND = clone_window(m_hWnd, NULL);
 
-	if (iPixelFormat == 0)
-		goto finalize;
+		if (dummyHWND == NULL)
+			goto finalize;
 
-	PIXELFORMATDESCRIPTOR chosenPFD;
-	if (!WIN32_CHK(::DescribePixelFormat(dummyHDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD)))
+		dummyHDC = GetDC(dummyHWND);
+	}
+	else {
+		dummyhBuffer = wglCreatePbufferARB(m_hDC, iPixelFormat, 1, 1, 0);
+		dummyHDC = wglGetPbufferDCARB(dummyhBuffer);
+	}
+
+	if (!WIN32_CHK(dummyHDC != NULL))
 		goto finalize;
 
 	if (!WIN32_CHK(::SetPixelFormat(dummyHDC, iPixelFormat, &chosenPFD)))
@@ -393,6 +407,12 @@ finalize:
 
 		WIN32_CHK(::DestroyWindow(dummyHWND));
 	}
+	else if (dummyhBuffer != NULL) {
+		if (dummyHDC != NULL)
+			WIN32_CHK(::wglReleasePbufferDCARB(dummyhBuffer, dummyHDC));
+
+		WIN32_CHK(::wglDestroyPbufferARB(dummyhBuffer));
+	}
 }
 
 
@@ -754,7 +774,9 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
 	HDC prevHDC = ::wglGetCurrentDC();
 	WIN32_CHK(GetLastError() == NO_ERROR);
 
-	if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) {
+	const bool create_hDC = m_hDC == NULL;
+
+	if (!WGLEW_ARB_create_context || create_hDC || ::GetPixelFormat(m_hDC) == 0) {
 		const bool needAlpha = m_alphaBackground;
 
 #ifdef GHOST_OPENGL_STENCIL
@@ -771,20 +793,32 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
 		int iPixelFormat;
 		int lastPFD;
 
+		if (create_hDC) {
+			/* get a handle to a device context with graphics accelerator enabled */
+			m_hDC = wglGetCurrentDC();
+			if (m_hDC == NULL) {
+				m_hDC = GetDC(NULL);
+			}
+		}
+
 		PIXELFORMATDESCRIPTOR chosenPFD;
 
 		iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB);
 
 		if (iPixelFormat == 0) {
-			::wglMakeCurrent(prevHDC, prevHGLRC);
-			return GHOST_kFailure;
+			goto error;
+		}
+
+		if (create_hDC) {
+			/* create an off-screen pixel buffer (Pbuffer) */
+			m_dummyPbuffer = wglCreatePbufferARB(m_hDC, iPixelFormat, 1, 1, 0);
+			m_hDC = wglGetPbufferDCARB(m_dummyPbuffer);
 		}
 
 		lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD);
 
 		if (!WIN32_CHK(lastPFD != 0)) {
-			::wglMakeCurrent(prevHDC, prevHGLRC);
-			return GHOST_kFailure;
+			goto error;
 		}
 
 		if (needAlpha && chosenPFD.cAlphaBits == 0)
@@ -794,8 +828,7 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
 			fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n");
 
 		if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) {
-			::wglMakeCurrent(prevHDC, prevHGLRC);
-			return GHOST_kFailure;
+			goto error;
 		}
 	}
 
@@ -878,8 +911,7 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
 	}
 
 	if (!WIN32_CHK(m_hGLRC != NULL)) {
-		::wglMakeCurrent(prevHDC, prevHGLRC);
-		return GHOST_kFailure;
+		goto error;
 	}
 
 	if (s_sharedHGLRC == NULL)
@@ -888,13 +920,11 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
 	s_sharedCount++;
 
 	if (!s_singleContextMode && s_sharedHGLRC != m_hGLRC && !WIN32_CHK(::wglShareLists(s_sharedHGLRC, m_hGLRC))) {
-		::wglMakeCurrent(prevHDC, prevHGLRC);
-		return GHOST_kFailure;
+		goto error;
 	}
 
 	if (!WIN32_CHK(::wglMakeCurrent(m_hDC, m_hGLRC))) {
-		::wglMakeCurrent(prevHDC, prevHGLRC);
-		return GHOST_kFailure;
+		goto error;
 	}
 
 	initContextGLEW();
@@ -915,6 +945,16 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext()
 #endif
 
 	return GHOST_kSuccess;
+error:
+	if (m_dummyPbuffer) {
+		if (m_hDC != NULL)
+			WIN32_CHK(::wglReleasePbufferDCARB(m_dummyPbuffer, m_hDC));
+
+		WIN32_CHK(::wglDestroyPbufferARB(m_dummyPbuffer));
+	}
+	::wglMakeCurrent(prevHDC, prevHGLRC);
+	return GHOST_kFailure;
+
 }
 
 
diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h
index a07cc1b6301..2ab85b60a88 100644
--- a/intern/ghost/intern/GHOST_ContextWGL.h
+++ b/intern/ghost/intern/GHOST_ContextWGL.h
@@ -137,6 +137,10 @@ private:
 
 	void initContextWGLEW(PIXELFORMATDESCRIPTOR &preferredPFD);
 
+	/* offscreen buffer with size of 1x1 pixel,
+	 * kept here to release the device constext when closing the program. */
+	HPBUFFERARB m_dummyPbuffer;
+
 	HWND m_hWnd;
 	HDC  m_hDC;
 
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 0ec1f04b0be..056b5536ab0 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -312,28 +312,15 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow(
  */
 GHOST_IContext *GHOST_SystemWin32::createOffscreenContext()
 {
-	HDC hDC;
-
 	bool debug_context = false; /* TODO: inform as a parameter */
 
-	/* Get any hDC (it will only be used to keep the context current) */
-	std::vector<GHOST_IWindow *> ghost_windows = m_windowManager->getWindows();
-	if (!ghost_windows.empty()) {
-		GHOST_WindowWin32 * window = (GHOST_WindowWin32 *)ghost_windows[0];
-		hDC = GetDC(window->getHWND());
-//		debug_context = window->m_debug_context;
-	}
-	else {
-		hDC = GetDC(NULL); /* DC for the entire screen! */
-	}
-
 	GHOST_Context *context;
 
 #if defined(WITH_GL_PROFILE_CORE)
 	for (int minor = 5; minor >= 0; --minor) {
 			context = new GHOST_ContextWGL(
 			    false, true, 0,
-			    NULL, hDC,
+			    NULL, NULL,
 			    WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
 			    4, minor,
 			    (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
@@ -349,7 +336,7 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext()
 
 		context = new GHOST_ContextWGL(
 		    false, true, 0,
-		    NULL, hDC,
+		    NULL, NULL,
 		    WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
 		    3, 3,
 		    (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),
@@ -359,11 +346,14 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext()
 			return context;
 		}
 		else {
-			GHOST_PRINT(
+			MessageBox(
+			        NULL,
 			        "Blender requires a graphics driver with at least OpenGL 3.3 support.\n\n"
 			        "The program will now close.",
-			        "Blender - Unsupported Graphics Driver!");
+			        "Blender - Unsupported Graphics Driver!",
+			        MB_OK | MB_ICONERROR);
 			delete context;
+			exit();
 		}
 
 #elif defined(WITH_GL_PROFILE_COMPAT)
@@ -371,7 +361,7 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContext()
 		// 2.1 ignores the profile bit & is incompatible with core profile
 		context = new GHOST_ContextWGL(
 		        false, true, 0,
-		        NULL, hDC,
+		        NULL, NULL,
 		        0, // no profile bit
 		        2, 1,
 		        (debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0),



More information about the Bf-blender-cvs mailing list