summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2016-06-03 09:25:13 +0300
committerTor Lillqvist <tml@collabora.com>2016-06-03 10:29:57 +0300
commit210c39dd9a6ebaa964c03c20e4b442ea36941ae9 (patch)
tree365ef9454867d4572925abaee3e5a4e7f6759b01
parentc6d553b5fac93d97cb0d316586db34f4d5a8def1 (diff)
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
-rw-r--r--vcl/opengl/win/gdiimpl.cxx53
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx17
2 files changed, 61 insertions, 9 deletions
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index 8bc79438ed3e..310eb14b6552 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 72cb1d61e6f8..4d3549509a57 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;
}