tdf#149068 reject OpenGL versions that don't support glGenVertexArrays

use a throwaway toplevel to figure that out, because if the current
window is used then gtk will always call glGenVertexArrays on it due
to the creation of a GLContext which is the problem we want to avoid.

Change-Id: I40ccc48b5ed2d9fd99d3c242244847c8448c3803
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134350
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
(cherry picked from commit da50382b366d6f3de778d8a52136cd812ef5b751)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134628
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index e29a1bfb..4008e98 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -1960,8 +1960,53 @@ private:
        glViewport(0, 0, width, height);
    }

    // Use a throw away toplevel to determine the OpenGL version because once
    // an GdkGLContext is created for a window then it seems that
    // glGenVertexArrays will always be called when the window gets rendered.
    static int GetOpenGLVersion()
    {
        int nMajorGLVersion(0);

        GtkWidget* pWindow;
#if !GTK_CHECK_VERSION(4,0,0)
        pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#else
        pWindow = gtk_window_new();
#endif

        gtk_widget_realize(pWindow);

        if (GdkSurface* pSurface = widget_get_surface(pWindow))
        {
            if (GdkGLContext* pContext = surface_create_gl_context(pSurface))
            {
                if (gdk_gl_context_realize(pContext, nullptr))
                {
                    gdk_gl_context_make_current(pContext);
                    gdk_gl_context_get_version(pContext, &nMajorGLVersion, nullptr);
                    gdk_gl_context_clear_current();
                }
                g_object_unref(pContext);
            }
        }

#if !GTK_CHECK_VERSION(4,0,0)
        gtk_widget_destroy(pWindow);
#else
        gtk_window_destroy(GTK_WINDOW(pWindow));
#endif
        return nMajorGLVersion;
    }

    virtual bool ImplInit() override
    {
        static int nOpenGLVersion = GetOpenGLVersion();
        if (nOpenGLVersion < 3)
        {
            SAL_WARN("vcl.gtk", "gtk GL requires glGenVertexArrays which is OpenGL 3, while system provides: " << nOpenGLVersion);
            return false;
        }

        const SystemEnvData* pEnvData = m_pChildWindow->GetSystemData();
        GtkWidget *pParent = static_cast<GtkWidget*>(pEnvData->pWidget);
        m_pGLArea = gtk_gl_area_new();