From 0bf615fc2464a06b3e40fc5936873b67ec6dd684 Mon Sep 17 00:00:00 2001 From: Germano Date: Sat, 10 Feb 2018 00:32:13 -0200 Subject: GHOST: Optimize and simplify the creation of a GHOST_Context on Windows Instead of cloning the window to create dummyHWNDs and dummyHDCs to avoid calling the SetPixelFormat more than once in the same window, use the original window and HDC and do not call the SetPixelFormat again. In addition to avoiding a lot of unnecessary calls, it simplifies the code and makes it match the others OS --- intern/ghost/intern/GHOST_ContextWGL.cpp | 175 +++++++----------------------- intern/ghost/intern/GHOST_ContextWGL.h | 14 --- intern/ghost/intern/GHOST_WindowWin32.cpp | 39 ++++--- 3 files changed, 63 insertions(+), 165 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp index d2dd38878f7..e6498f1ffa8 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.cpp +++ b/intern/ghost/intern/GHOST_ContextWGL.cpp @@ -745,60 +745,57 @@ static void reportContextString(const char *name, const char *dummy, const char GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() { - const bool needAlpha = m_alphaBackground; + SetLastError(NO_ERROR); + + HGLRC prevHGLRC = ::wglGetCurrentContext(); + WIN32_CHK(GetLastError() == NO_ERROR); + + HDC prevHDC = ::wglGetCurrentDC(); + WIN32_CHK(GetLastError() == NO_ERROR); + + if (!WGLEW_ARB_create_context || ::GetPixelFormat(m_hDC) == 0) { + const bool needAlpha = m_alphaBackground; #ifdef GHOST_OPENGL_STENCIL - const bool needStencil = true; + const bool needStencil = true; #else - const bool needStencil = false; + const bool needStencil = false; #endif #ifdef GHOST_OPENGL_SRGB - const bool sRGB = true; + const bool sRGB = true; #else - const bool sRGB = false; + const bool sRGB = false; #endif + int iPixelFormat; + int lastPFD; - HGLRC prevHGLRC; - HDC prevHDC; - - int iPixelFormat; - int lastPFD; - - PIXELFORMATDESCRIPTOR chosenPFD; + PIXELFORMATDESCRIPTOR chosenPFD; + iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB); - SetLastError(NO_ERROR); - - prevHGLRC = ::wglGetCurrentContext(); - WIN32_CHK(GetLastError() == NO_ERROR); - - prevHDC = ::wglGetCurrentDC(); - WIN32_CHK(GetLastError() == NO_ERROR); - - iPixelFormat = choose_pixel_format(m_stereoVisual, m_numOfAASamples, needAlpha, needStencil, sRGB); - - if (iPixelFormat == 0) { - ::wglMakeCurrent(prevHDC, prevHGLRC); - return GHOST_kFailure; - } + if (iPixelFormat == 0) { + ::wglMakeCurrent(prevHDC, prevHGLRC); + return GHOST_kFailure; + } - lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); + lastPFD = ::DescribePixelFormat(m_hDC, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &chosenPFD); - if (!WIN32_CHK(lastPFD != 0)) { - ::wglMakeCurrent(prevHDC, prevHGLRC); - return GHOST_kFailure; - } + if (!WIN32_CHK(lastPFD != 0)) { + ::wglMakeCurrent(prevHDC, prevHGLRC); + return GHOST_kFailure; + } - if (needAlpha && chosenPFD.cAlphaBits == 0) - fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); + if (needAlpha && chosenPFD.cAlphaBits == 0) + fprintf(stderr, "Warning! Unable to find a pixel format with an alpha channel.\n"); - if (needStencil && chosenPFD.cStencilBits == 0) - fprintf(stderr, "Warning! Unable to find a pixel format with a stencil buffer.\n"); + if (needStencil && chosenPFD.cStencilBits == 0) + 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; + if (!WIN32_CHK(::SetPixelFormat(m_hDC, iPixelFormat, &chosenPFD))) { + ::wglMakeCurrent(prevHDC, prevHGLRC); + return GHOST_kFailure; + } } if (WGLEW_ARB_create_context) { @@ -909,9 +906,11 @@ GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() const char *version = reinterpret_cast(glGetString(GL_VERSION)); #ifndef NDEBUG - reportContextString("Vendor", m_dummyVendor, vendor); - reportContextString("Renderer", m_dummyRenderer, renderer); - reportContextString("Version", m_dummyVersion, version); + if (m_dummyVendor != NULL) { + reportContextString("Vendor", m_dummyVendor, vendor); + reportContextString("Renderer", m_dummyRenderer, renderer); + reportContextString("Version", m_dummyVersion, version); + } #endif return GHOST_kSuccess; @@ -927,97 +926,3 @@ 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 0d9986a0802..a07cc1b6301 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.h +++ b/intern/ghost/intern/GHOST_ContextWGL.h @@ -105,20 +105,6 @@ 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 ee0d7ef460c..3c9c7c415bb 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -622,17 +622,10 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty GHOST_Context *context; #if defined(WITH_GL_PROFILE_CORE) - 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)) - { + /* - 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) { context = new GHOST_ContextWGL( m_wantStereoVisual, m_wantAlphaBackground, @@ -640,7 +633,7 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty m_hWnd, m_hDC, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - major, minor, + 4, minor, (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); @@ -651,6 +644,20 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty delete context; } } + 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); + + if (context->initializeDrawingContext()) { + return context; + } else { MessageBox( m_hWnd, @@ -658,8 +665,8 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty "The program will now close.", "Blender - Unsupported Graphics Driver!", MB_OK | MB_ICONERROR); + delete context; exit(0); - return NULL; } #elif defined(WITH_GL_PROFILE_COMPAT) @@ -675,9 +682,6 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty 2, 1, (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); -#else -# error // must specify either core or compat at build time -#endif if (context->initializeDrawingContext()) { return context; @@ -685,6 +689,9 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty else { delete context; } +#else +# error // must specify either core or compat at build time +#endif } return NULL; -- cgit v1.2.3