[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