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),

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to