vcl/opengl/win/gdiimpl.cxx | 53 ++++++++++++++++++++++++++++++------ vcl/source/opengl/OpenGLContext.cxx | 17 ++++++++++- 2 files changed, 61 insertions(+), 9 deletions(-)
New commits: commit 0b89ccb60f9bd270d762667e8b649faeef7496c5 Author: Tor Lillqvist <t...@collabora.com> Date: Fri Jun 3 09:25:13 2016 +0300 tdf#100193: Check earlier and harder whether OpenGL is good enough on Windows If we notice early enough that OpenGL is broken or not good enough, we can disable it and terminate with EXITHELPER_NORMAL_RESTART. Not beautiful, but works. The earlier added check whether shader compilation and loading of shader program binaries from a cached file works is now just one of the aspects that are checked. Change-Id: I9382576cc607f1916f6002f1fa78a62e23180fe3 (cherry picked from commit 210c39dd9a6ebaa964c03c20e4b442ea36941ae9) Reviewed-on: https://gerrit.libreoffice.org/25853 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Tor Lillqvist <t...@collabora.com> Tested-by: Tor Lillqvist <t...@collabora.com> diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx index 8bc7943..310eb14 100644 --- a/vcl/opengl/win/gdiimpl.cxx +++ b/vcl/opengl/win/gdiimpl.cxx @@ -353,6 +353,12 @@ bool InitMultisample(const PIXELFORMATDESCRIPTOR& pfd, int& rPixelFormat, namespace { +void disableOpenGLAndTerminateForRestart() +{ + OpenGLZone::hardDisable(); + TerminateProcess(GetCurrentProcess(), EXITHELPER_NORMAL_RESTART); +} + bool tryShaders(const OUString& rVertexShader, const OUString& rFragmentShader, const OUString& rGeometryShader = "", const OString& rPreamble = "") { GLint nId; @@ -440,12 +446,6 @@ bool compiledShaderBinariesWork() tryShaders("textureVertexShader", "convolutionFragmentShader") && tryShaders("textureVertexShader", "areaScaleFastFragmentShader")); - if (!bResult) - { - OpenGLZone::hardDisable(); - TerminateProcess(GetCurrentProcess(), EXITHELPER_NORMAL_RESTART); - } - return bResult; } @@ -453,6 +453,16 @@ bool compiledShaderBinariesWork() bool WinOpenGLContext::ImplInit() { + // Failures here typically means that OpenGL can't be used. Returning false is fairly pointless + // as the calling code doesn't even check, but oh well. If we notice that OpenGL is broken the + // first time being called, it is not too late to call + // disableOpenGLAndTerminateForRestart(). The first time this will be called is from displaying + // the splash screen, so if OpenGL is broken, it is "early enough" for us to be able to disable + // OpenGL and terminate bluntly with EXITHELPER_NORMAL_RESTART, thus causing the wrapper process + // to restart us, then without using OpenGL. + + static bool bFirstCall = true; + OpenGLZone aZone; VCL_GL_INFO("OpenGLContext::ImplInit----start"); @@ -504,6 +514,9 @@ bool WinOpenGLContext::ImplInit() if (WindowPix == 0) { SAL_WARN("vcl.opengl", "Invalid pixelformat"); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } @@ -511,6 +524,9 @@ bool WinOpenGLContext::ImplInit() { ImplWriteLastError(GetLastError(), "SetPixelFormat in OpenGLContext::ImplInit"); SAL_WARN("vcl.opengl", "SetPixelFormat failed"); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } @@ -519,6 +535,9 @@ bool WinOpenGLContext::ImplInit() { ImplWriteLastError(GetLastError(), "wglCreateContext in OpenGLContext::ImplInit"); SAL_WARN("vcl.opengl", "wglCreateContext failed"); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } @@ -526,13 +545,17 @@ bool WinOpenGLContext::ImplInit() { ImplWriteLastError(GetLastError(), "wglMakeCurrent in OpenGLContext::ImplInit"); SAL_WARN("vcl.opengl", "wglMakeCurrent failed"); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } if (!InitGLEW()) { - wglMakeCurrent(NULL, NULL); - wglDeleteContext(hTempRC); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } @@ -544,6 +567,9 @@ bool WinOpenGLContext::ImplInit() { wglMakeCurrent(NULL, NULL); wglDeleteContext(hTempRC); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } @@ -563,6 +589,9 @@ bool WinOpenGLContext::ImplInit() SAL_WARN("vcl.opengl", "wglCreateContextAttribsARB failed"); wglMakeCurrent(NULL, NULL); wglDeleteContext(hTempRC); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } @@ -570,6 +599,9 @@ bool WinOpenGLContext::ImplInit() { wglMakeCurrent(NULL, NULL); wglDeleteContext(hTempRC); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } @@ -580,6 +612,9 @@ bool WinOpenGLContext::ImplInit() { ImplWriteLastError(GetLastError(), "wglMakeCurrent (with shared context) in OpenGLContext::ImplInit"); SAL_WARN("vcl.opengl", "wglMakeCurrent failed"); + if (bFirstCall) + disableOpenGLAndTerminateForRestart(); + bFirstCall = false; return false; } @@ -596,6 +631,8 @@ bool WinOpenGLContext::ImplInit() registerAsCurrent(); + bFirstCall = false; + return true; } diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index ea90537..86a61e3 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -282,8 +282,23 @@ bool OpenGLContext::InitGLEW() bGlewInit = true; } - VCL_GL_INFO("OpenGLContext::ImplInit----end"); + VCL_GL_INFO("OpenGLContext::ImplInit----end, GL version: " << OpenGLHelper::getGLVersion()); mbInitialized = true; + + // I think we need at least GL 3.0 + if (!GLEW_VERSION_3_0) + { + SAL_WARN("vcl.opengl", "We don't have at least OpenGL 3.0"); + return false; + } + + // Check that some "optional" APIs that we use unconditionally are present + if (!glBindFramebuffer) + { + SAL_WARN("vcl.opengl", "We don't have glBindFramebuffer"); + return false; + } + return true; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits