diff options
author | Tor Lillqvist <tml@collabora.com> | 2016-05-25 15:23:22 +0300 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2016-05-31 20:45:03 +0000 |
commit | 0f2d826394fcbb3f9cfbcc818d46dc15f32b5028 (patch) | |
tree | ba18fe9a29c1aeaad7f70bacd4e1d36c07e939fd /vcl/source/opengl/OpenGLContext.cxx | |
parent | a97f9c5790b4751098b0c3f78a387fbff36582a6 (diff) |
tdf#100159: On Windows, compile GL shaders in advance, disable GL on failure
This is a combination of multiple commits in master, adapted for this
branch as necessary:
Don't claim to be reading a file before trying to open it
Avoid redundancy: The same information was logged in readProgramBinary()
Use VCL_GL_INFO here
Failing to open a cached shader binary is a no reason for a
SAL_WARN. It is normal that they don't exist when first trying, that
is the very nature of a 'cache'.
Move exithelper.h to include. We will want to use EXITHELPER_NORMAL_RESTART
in vcl, too.
If the shader compilation or loading of an already compiled shader
fails, disable OpenGL in the registry and exit with the
EXITHELPER_NORMAL_RESTART status. The wrapper process will thus
run soffice.bin once more, and this time OpenGL will not be used.
Change-Id: I54d92f150975d3fa72d93f3f679b16c90ee38f02
Reviewed-on: https://gerrit.libreoffice.org/25708
Reviewed-by: Jan Holesovsky <kendy@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
Diffstat (limited to 'vcl/source/opengl/OpenGLContext.cxx')
-rw-r--r-- | vcl/source/opengl/OpenGLContext.cxx | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index 03d0a5d05811..1ce8ce8e5fca 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -9,6 +9,7 @@ #include <config_opengl.h> +#include <desktop/exithelper.h> #include <vcl/opengl/OpenGLContext.hxx> #include <vcl/opengl/OpenGLHelper.hxx> #include <vcl/opengl/OpenGLWrapper.hxx> @@ -839,6 +840,107 @@ bool OpenGLContext::ImplInit() #elif defined( _WIN32 ) +namespace +{ + +bool tryShaders(const OUString& rVertexShader, const OUString& rFragmentShader, const OUString& rGeometryShader = "", const OString& rPreamble = "") +{ + GLint nId; + + // Somewhat mysteriously, the OpenGLHelper::LoadShaders() API saves a compiled binary of the + // shader only if you give it the digest of the shaders. We have API to calculate the digest + // only of the combination of vertex and fragment (but not geometry) shader. So if we have a + // geometry shader, we should not save the binary. + if (rGeometryShader.isEmpty()) + { + nId = OpenGLHelper::LoadShaders(rVertexShader, rFragmentShader, rPreamble, OpenGLHelper::GetDigest( rVertexShader, rFragmentShader, rPreamble)); + } + else + { + assert(rPreamble.isEmpty()); + nId = OpenGLHelper::LoadShaders(rVertexShader, rFragmentShader, rGeometryShader); + } + if (!nId) + return false; + glDeleteProgram(nId); + return glGetError() == GL_NO_ERROR; +} + +bool compiledShaderBinariesWork() +{ + static bool bBeenHere = false; + static bool bResult; + + if (bBeenHere) + return bResult; + + bBeenHere = true; + + bResult = + ( +#if 0 // Only look at shaders used by vcl for now + // canvas + tryShaders("dummyVertexShader", "linearMultiColorGradientFragmentShader") && + tryShaders("dummyVertexShader", "linearTwoColorGradientFragmentShader") && + tryShaders("dummyVertexShader", "radialMultiColorGradientFragmentShader") && + tryShaders("dummyVertexShader", "radialTwoColorGradientFragmentShader") && + tryShaders("dummyVertexShader", "rectangularMultiColorGradientFragmentShader") && + tryShaders("dummyVertexShader", "rectangularTwoColorGradientFragmentShader") && + // chart2 + (GLEW_VERSION_3_3 ? + (tryShaders("shape3DVertexShader", "shape3DFragmentShader") && + tryShaders("shape3DVertexShaderBatchScroll", "shape3DFragmentShaderBatchScroll") && + tryShaders("shape3DVertexShaderBatch", "shape3DFragmentShaderBatch") && + tryShaders("textVertexShaderBatch", "textFragmentShaderBatch")) : + (tryShaders("shape3DVertexShaderV300", "shape3DFragmentShaderV300"))) && + tryShaders("textVertexShader", "textFragmentShader") && + tryShaders("screenTextVertexShader", "screenTextFragmentShader") && + tryShaders("commonVertexShader", "commonFragmentShader") && + tryShaders("pickingVertexShader", "pickingFragmentShader") && + tryShaders("backgroundVertexShader", "backgroundFragmentShader") && + tryShaders("symbolVertexShader", "symbolFragmentShader") && + tryShaders("symbolVertexShader", "symbolFragmentShader") && + // slideshow + tryShaders("reflectionVertexShader", "reflectionFragmentShader") && + tryShaders("basicVertexShader", "basicFragmentShader") && + tryShaders("vortexVertexShader", "vortexFragmentShader", "vortexGeometryShader") && + tryShaders("basicVertexShader", "rippleFragmentShader") && + tryShaders("glitterVertexShader", "glitterFragmentShader") && + tryShaders("honeycombVertexShader", "honeycombFragmentShader", "honeycombGeometryShader") && +#endif + // vcl + tryShaders("combinedVertexShader", "combinedFragmentShader") && + tryShaders("dumbVertexShader", "invert50FragmentShader") && + tryShaders("combinedTextureVertexShader", "combinedTextureFragmentShader") && + tryShaders("textureVertexShader", "areaScaleFragmentShader") && + tryShaders("transformedTextureVertexShader", "maskedTextureFragmentShader") && + tryShaders("transformedTextureVertexShader", "areaScaleFastFragmentShader") && + tryShaders("transformedTextureVertexShader", "areaScaleFastFragmentShader", "", "#define MASKED") && + tryShaders("transformedTextureVertexShader", "areaScaleFragmentShader") && + tryShaders("transformedTextureVertexShader", "areaScaleFragmentShader", "", "#define MASKED") && + tryShaders("transformedTextureVertexShader", "textureFragmentShader") && + tryShaders("combinedTextureVertexShader", "combinedTextureFragmentShader") && + tryShaders("combinedTextureVertexShader", "combinedTextureFragmentShader", "", "// flush shader\n") && + tryShaders("textureVertexShader", "linearGradientFragmentShader") && + tryShaders("textureVertexShader", "radialGradientFragmentShader") && + tryShaders("textureVertexShader", "areaHashCRC64TFragmentShader") && + tryShaders("textureVertexShader", "replaceColorFragmentShader") && + tryShaders("textureVertexShader", "greyscaleFragmentShader") && + tryShaders("textureVertexShader", "textureFragmentShader") && + tryShaders("textureVertexShader", "convolutionFragmentShader") && + tryShaders("textureVertexShader", "areaScaleFastFragmentShader")); + + if (!bResult) + { + OpenGLZone::hardDisable(); + TerminateProcess(GetCurrentProcess(), EXITHELPER_NORMAL_RESTART); + } + + return bResult; +} + +} // unnamed namespace + bool OpenGLContext::init(HDC hDC, HWND hWnd) { if (mbInitialized) @@ -964,6 +1066,13 @@ bool OpenGLContext::ImplInit() return false; } + if (!compiledShaderBinariesWork()) + { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hTempRC); + return false; + } + wglMakeCurrent(NULL, NULL); wglDeleteContext(hTempRC); |