[Libreoffice-commits] core.git: Branch 'libreoffice-5-2' - vcl/opengl

Tor Lillqvist tml at collabora.com
Tue May 31 16:36:54 UTC 2016


 vcl/opengl/win/gdiimpl.cxx |  109 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

New commits:
commit 776c124e8797431c8c4eaf6d0550959b05ce69ee
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon May 30 14:20:11 2016 +0300

    tdf#100159: On Windows, compile GL shaders in advance, disable GL on failure
    
    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: I3cc4a615f00a8a1adb584493861e4956c83cec32
    Reviewed-on: https://gerrit.libreoffice.org/25675
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    Tested-by: Tor Lillqvist <tml at collabora.com>

diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index cf45a46..8bc7943 100644
--- a/vcl/opengl/win/gdiimpl.cxx
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -8,6 +8,7 @@
  */
 
 #include "opengl/win/gdiimpl.hxx"
+#include <desktop/exithelper.h>
 #include <opengl/zone.hxx>
 #include <o3tl/lru_map.hxx>
 #include <win/wincomp.hxx>
@@ -349,6 +350,107 @@ bool InitMultisample(const PIXELFORMATDESCRIPTOR& pfd, int& rPixelFormat,
     return bArbMultisampleSupported;
 }
 
+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 WinOpenGLContext::ImplInit()
 {
     OpenGLZone aZone;
@@ -464,6 +566,13 @@ bool WinOpenGLContext::ImplInit()
         return false;
     }
 
+    if (!compiledShaderBinariesWork())
+    {
+        wglMakeCurrent(NULL, NULL);
+        wglDeleteContext(hTempRC);
+        return false;
+    }
+
     wglMakeCurrent(NULL, NULL);
     wglDeleteContext(hTempRC);
 


More information about the Libreoffice-commits mailing list