[GTK] Dramatic increase on memory usage since 2.14.x
authormagomez@igalia.com <magomez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Nov 2016 15:00:41 +0000 (15:00 +0000)
committermagomez@igalia.com <magomez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Nov 2016 15:00:41 +0000 (15:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=164049

Reviewed by Žan Doberšek.

Use OpenGL version 3.2 Core for rendering when available.
Update some operations that have changed when using 3.2 Core:
- Use glGetStringi to get the extensions list.
- Do not use GL_POINT_SPRITE.
- Always use a VAO when rendering.
- Use a GLSL 1.50 compatible shader.

No new tests needed.

* platform/graphics/GLContext.cpp:
(WebCore::GLContext::version):
Add a method to get OpenGL version we are using.
* platform/graphics/GLContext.h:
Ditto.
* platform/graphics/GraphicsContext3D.h:
Add an attribute to store the VAO used for rendering.
* platform/graphics/OpenGLShims.cpp:
(WebCore::initializeOpenGLShims):
Add glGetStringi to the list of functions.
* platform/graphics/OpenGLShims.h:
Ditto.
* platform/graphics/cairo/GraphicsContext3DCairo.cpp:
(WebCore::GraphicsContext3D::GraphicsContext3D):
Set appropriate output to the shader compiler and initalize the VAO if needed.
(WebCore::GraphicsContext3D::~GraphicsContext3D):
Delete the VAO if needed.
(WebCore::GraphicsContext3D::getExtensions):
Use glGetExtensionsi for OpenGL versions >= 3.2.
* platform/graphics/glx/GLContextGLX.cpp:
(WebCore::hasGLXARBCreateContextExtension):
Check whether the GLX_ARB_create_context extension is available.
(WebCore::GLContextGLX::createWindowContext):
Use glXCreateContextAttribsARB() if possible to request an OpenGL 3.2 context.
(WebCore::GLContextGLX::createPbufferContext):
Ditto.
* platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
(WebCore::Extensions3DOpenGLCommon::initializeAvailableExtensions):
Enable glGetStringi for GTK.
* platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
Do not use default getExtensions() method for GTK.
* platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp:
Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208997 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/GLContext.cpp
Source/WebCore/platform/graphics/GLContext.h
Source/WebCore/platform/graphics/GraphicsContext3D.h
Source/WebCore/platform/graphics/OpenGLShims.cpp
Source/WebCore/platform/graphics/OpenGLShims.h
Source/WebCore/platform/graphics/cairo/GraphicsContext3DCairo.cpp
Source/WebCore/platform/graphics/glx/GLContextGLX.cpp
Source/WebCore/platform/graphics/opengl/Extensions3DOpenGLCommon.cpp
Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp

index a436879..186783f 100644 (file)
@@ -1,3 +1,53 @@
+2016-11-28  Miguel Gomez  <magomez@igalia.com>
+
+        [GTK] Dramatic increase on memory usage since 2.14.x
+        https://bugs.webkit.org/show_bug.cgi?id=164049
+
+        Reviewed by Žan Doberšek.
+
+        Use OpenGL version 3.2 Core for rendering when available.
+        Update some operations that have changed when using 3.2 Core:
+        - Use glGetStringi to get the extensions list.
+        - Do not use GL_POINT_SPRITE.
+        - Always use a VAO when rendering.
+        - Use a GLSL 1.50 compatible shader.
+
+        No new tests needed.
+
+        * platform/graphics/GLContext.cpp:
+        (WebCore::GLContext::version):
+        Add a method to get OpenGL version we are using.
+        * platform/graphics/GLContext.h:
+        Ditto.
+        * platform/graphics/GraphicsContext3D.h:
+        Add an attribute to store the VAO used for rendering.
+        * platform/graphics/OpenGLShims.cpp:
+        (WebCore::initializeOpenGLShims):
+        Add glGetStringi to the list of functions.
+        * platform/graphics/OpenGLShims.h:
+        Ditto.
+        * platform/graphics/cairo/GraphicsContext3DCairo.cpp:
+        (WebCore::GraphicsContext3D::GraphicsContext3D):
+        Set appropriate output to the shader compiler and initalize the VAO if needed.
+        (WebCore::GraphicsContext3D::~GraphicsContext3D):
+        Delete the VAO if needed.
+        (WebCore::GraphicsContext3D::getExtensions):
+        Use glGetExtensionsi for OpenGL versions >= 3.2.
+        * platform/graphics/glx/GLContextGLX.cpp:
+        (WebCore::hasGLXARBCreateContextExtension):
+        Check whether the GLX_ARB_create_context extension is available.
+        (WebCore::GLContextGLX::createWindowContext):
+        Use glXCreateContextAttribsARB() if possible to request an OpenGL 3.2 context.
+        (WebCore::GLContextGLX::createPbufferContext):
+        Ditto.
+        * platform/graphics/opengl/Extensions3DOpenGLCommon.cpp:
+        (WebCore::Extensions3DOpenGLCommon::initializeAvailableExtensions):
+        Enable glGetStringi for GTK.
+        * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
+        Do not use default getExtensions() method for GTK.
+        * platform/graphics/opengl/GraphicsContext3DOpenGLES.cpp:
+        Ditto.
+
 2016-11-24  Sergio Villar Senin  <svillar@igalia.com>
 
         [css-grid] Move attributes from RenderGrid to the new Grid class
index c199781..52595b9 100644 (file)
@@ -160,6 +160,18 @@ bool GLContext::isExtensionSupported(const char* extensionList, const char* exte
     return false;
 }
 
+unsigned GLContext::version()
+{
+    if (!m_version) {
+        GC3Dint major = 0;
+        GC3Dint minor = 0;
+        ::glGetIntegerv(GL_MAJOR_VERSION, &major);
+        ::glGetIntegerv(GL_MINOR_VERSION, &minor);
+        m_version = major * 100 + minor * 10;
+    }
+    return m_version;
+}
+
 } // namespace WebCore
 
 #endif
index 576ccad..2c0ea27 100644 (file)
@@ -47,6 +47,7 @@ public:
     static bool isExtensionSupported(const char* extensionList, const char* extension);
 
     PlatformDisplay& display() const { return m_display; }
+    unsigned version();
 
     virtual ~GLContext();
     virtual bool makeContextCurrent();
@@ -77,6 +78,7 @@ protected:
     GLContext(PlatformDisplay&);
 
     PlatformDisplay& m_display;
+    unsigned m_version { 0 };
 };
 
 } // namespace WebCore
index 83a11e8..cb2ea0c 100644 (file)
@@ -1436,6 +1436,11 @@ private:
     WebGLRenderingContextBase* m_webglContext;
 
     bool m_isForWebGL2 { false };
+
+#if USE(CAIRO)
+    Platform3DObject m_vao { 0 };
+#endif
+
 };
 
 } // namespace WebCore
index 536eb1b..d3cfd27 100644 (file)
@@ -162,6 +162,9 @@ bool initializeOpenGLShims()
     ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderInfoLog, success);
     ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderiv, success);
     ASSIGN_FUNCTION_TABLE_ENTRY(glGetShaderSource, success);
+    // glGetStringi is only available on OpenGL or GLES versions >= 3.0.
+    // Add it with _EXT so it doesn't cause an initialization failure on lower versions.
+    ASSIGN_FUNCTION_TABLE_ENTRY_EXT(glGetStringi);
     ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformfv, success);
     ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformiv, success);
     ASSIGN_FUNCTION_TABLE_ENTRY(glGetUniformLocation, success);
index 90d28bc..a0b8e2a 100644 (file)
@@ -92,6 +92,7 @@ typedef void (GLAPIENTRY *glGetRenderbufferParameterivType) (GLenum, GLenum, GLi
 typedef void (GLAPIENTRY *glGetShaderInfoLogType) (GLuint, GLsizei, GLsizei*, char*);
 typedef void (GLAPIENTRY *glGetShaderivType) (GLuint, GLenum, GLint*);
 typedef void (GLAPIENTRY *glGetShaderSourceType) (GLuint, GLsizei, GLsizei*, char*);
+typedef const GLubyte* (GLAPIENTRY *glGetStringiType) (GLenum, GLuint);
 typedef GLint (GLAPIENTRY *glGetUniformLocationType) (GLuint, const char*);
 typedef void (GLAPIENTRY *glGetUniformfvType) (GLuint, GLint, GLfloat*);
 typedef void (GLAPIENTRY *glGetUniformivType) (GLuint, GLint, GLint*);
@@ -198,6 +199,7 @@ typedef struct _OpenGLFunctionTable {
     FUNCTION_TABLE_ENTRY(glGetShaderInfoLog);
     FUNCTION_TABLE_ENTRY(glGetShaderiv);
     FUNCTION_TABLE_ENTRY(glGetShaderSource);
+    FUNCTION_TABLE_ENTRY(glGetStringi);
     FUNCTION_TABLE_ENTRY(glGetUniformfv);
     FUNCTION_TABLE_ENTRY(glGetUniformiv);
     FUNCTION_TABLE_ENTRY(glGetUniformLocation);
@@ -325,6 +327,7 @@ typedef struct _OpenGLFunctionTable {
 #define glGetShaderInfoLog                     LOOKUP_GL_FUNCTION(glGetShaderInfoLog)
 #define glGetShaderiv                          LOOKUP_GL_FUNCTION(glGetShaderiv)
 #define glGetShaderSource                      LOOKUP_GL_FUNCTION(glGetShaderSource)
+#define glGetStringi                           LOOKUP_GL_FUNCTION(glGetStringi)
 #define glGetUniformfv                         LOOKUP_GL_FUNCTION(glGetUniformfv)
 #define glGetUniformiv                         LOOKUP_GL_FUNCTION(glGetUniformiv)
 #define glGetUniformLocation                   LOOKUP_GL_FUNCTION(glGetUniformLocation)
index c2e67d0..2e44b89 100644 (file)
@@ -79,7 +79,6 @@ RefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attribute
 GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attributes, HostWindow*, GraphicsContext3D::RenderStyle renderStyle)
     : m_currentWidth(0)
     , m_currentHeight(0)
-    , m_compiler(isGLES2Compliant() ? SH_ESSL_OUTPUT : SH_GLSL_COMPATIBILITY_OUTPUT)
     , m_attrs(attributes)
     , m_texture(0)
     , m_compositorTexture(0)
@@ -145,6 +144,34 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attributes, H
         }
     }
 
+#if !USE(OPENGL_ES_2)
+    ::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
+
+    if (GLContext::current()->version() >= 320) {
+        // From version 3.2 on we use the OpenGL Core profile, so request that ouput to the shader compiler.
+        // OpenGL version 3.2 uses GLSL version 1.50.
+        m_compiler = ANGLEWebKitBridge(SH_GLSL_150_CORE_OUTPUT);
+
+        // From version 3.2 on we use the OpenGL Core profile, and we need a VAO for rendering.
+        // A VAO could be created and bound by each component using GL rendering (TextureMapper, WebGL, etc). This is
+        // a simpler solution: the first GraphicsContext3D created on a GLContext will create and bind a VAO for that context.
+        GC3Dint currentVAO = 0;
+        getIntegerv(GraphicsContext3D::VERTEX_ARRAY_BINDING, &currentVAO);
+        if (!currentVAO) {
+            m_vao = createVertexArray();
+            bindVertexArray(m_vao);
+        }
+    } else {
+        // For lower versions request the compatibility output to the shader compiler.
+        m_compiler = ANGLEWebKitBridge(SH_GLSL_COMPATIBILITY_OUTPUT);
+
+        // GL_POINT_SPRITE is needed in lower versions.
+        ::glEnable(GL_POINT_SPRITE);
+    }
+#else
+    m_compiler = ANGLEWebKitBridge(SH_ESSL_OUTPUT);
+#endif
+
     // ANGLE initialization.
     ShBuiltInResources ANGLEResources;
     ShInitBuiltInResources(&ANGLEResources);
@@ -166,11 +193,6 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attributes, H
 
     m_compiler.setResources(ANGLEResources);
 
-#if !USE(OPENGL_ES_2)
-    ::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
-    ::glEnable(GL_POINT_SPRITE);
-#endif
-
     ::glClearColor(0, 0, 0, 0);
 }
 
@@ -198,6 +220,9 @@ GraphicsContext3D::~GraphicsContext3D()
 #if USE(COORDINATED_GRAPHICS_THREADED)
     ::glDeleteTextures(1, &m_intermediateTexture);
 #endif
+
+    if (m_vao)
+        deleteVertexArray(m_vao);
 }
 
 GraphicsContext3D::ImageExtractor::~ImageExtractor()
@@ -344,6 +369,22 @@ PlatformLayer* GraphicsContext3D::platformLayer() const
     return m_private.get();
 }
 
+#if PLATFORM(GTK)
+Extensions3D& GraphicsContext3D::getExtensions()
+{
+    if (!m_extensions) {
+#if USE(OPENGL_ES_2)
+        // glGetStringi is not available on GLES2.
+        m_extensions = std::make_unique<Extensions3DOpenGLES>(this,  false);
+#else
+        // From OpenGL 3.2 on we use the Core profile, and there we must use glGetStringi.
+        m_extensions = std::make_unique<Extensions3DOpenGL>(this, GLContext::current()->version() >= 320);
+#endif
+    }
+    return *m_extensions;
+}
+#endif
+
 } // namespace WebCore
 
 #endif // ENABLE(GRAPHICS_CONTEXT_3D)
index 9c2ed3d..0d3a970 100644 (file)
@@ -35,8 +35,12 @@ namespace WebCore {
 #if !defined(PFNGLXSWAPINTERVALSGIPROC)
 typedef int (*PFNGLXSWAPINTERVALSGIPROC) (int);
 #endif
+#if !defined(PFNGLXCREATECONTEXTATTRIBSARBPROC)
+typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+#endif
 
 static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI;
+static PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB;
 
 static bool hasSGISwapControlExtension(Display* display)
 {
@@ -52,6 +56,20 @@ static bool hasSGISwapControlExtension(Display* display)
     return !!glXSwapIntervalSGI;
 }
 
+static bool hasGLXARBCreateContextExtension(Display* display)
+{
+    static bool initialized = false;
+    if (initialized)
+        return !!glXCreateContextAttribsARB;
+
+    initialized = true;
+    if (!GLContext::isExtensionSupported(glXQueryExtensionsString(display, 0), "GLX_ARB_create_context"))
+        return false;
+
+    glXCreateContextAttribsARB = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(glXGetProcAddress(reinterpret_cast<const unsigned char*>("glXCreateContextAttribsARB")));
+    return !!glXCreateContextAttribsARB;
+}
+
 std::unique_ptr<GLContextGLX> GLContextGLX::createWindowContext(GLNativeWindowType window, PlatformDisplay& platformDisplay, GLXContext sharingContext)
 {
     Display* display = downcast<PlatformDisplayX11>(platformDisplay).native();
@@ -62,10 +80,38 @@ std::unique_ptr<GLContextGLX> GLContextGLX::createWindowContext(GLNativeWindowTy
     XVisualInfo visualInfo;
     visualInfo.visualid = XVisualIDFromVisual(attributes.visual);
 
-    int numReturned = 0;
-    XUniquePtr<XVisualInfo> visualInfoList(XGetVisualInfo(display, VisualIDMask, &visualInfo, &numReturned));
+    int numConfigs = 0;
+    GLXFBConfig config = nullptr;
+    XUniquePtr<GLXFBConfig> configs(glXGetFBConfigs(display, DefaultScreen(display), &numConfigs));
+    for (int i = 0; i < numConfigs; i++) {
+        XUniquePtr<XVisualInfo> glxVisualInfo(glXGetVisualFromFBConfig(display, configs.get()[i]));
+        if (!glxVisualInfo)
+            continue;
+
+        if (glxVisualInfo.get()->visualid == visualInfo.visualid) {
+            config = configs.get()[i];
+            break;
+        }
+    }
+    ASSERT(config);
+
+    XUniqueGLXContext context;
+    if (hasGLXARBCreateContextExtension(display)) {
+        // Request OpenGL version 3.2 and core profile, which guarantees that the i965 driver doesn't use the software renderer.
+        static const int contextAttributes[] = {
+            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+            GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+            0
+        };
+        context.reset(glXCreateContextAttribsARB(display, config, sharingContext, GL_TRUE, contextAttributes));
+    }
+
+    if (!context) {
+        // Fallback to legacy OpenGL version.
+        XUniquePtr<XVisualInfo> visualInfoList(glXGetVisualFromFBConfig(display, config));
+        context.reset(glXCreateContext(display, visualInfoList.get(), sharingContext, True));
+    }
 
-    XUniqueGLXContext context(glXCreateContext(display, visualInfoList.get(), sharingContext, True));
     if (!context)
         return nullptr;
 
@@ -97,7 +143,23 @@ std::unique_ptr<GLContextGLX> GLContextGLX::createPbufferContext(PlatformDisplay
     if (!pbuffer)
         return nullptr;
 
-    XUniqueGLXContext context(glXCreateNewContext(display, configs.get()[0], GLX_RGBA_TYPE, sharingContext, GL_TRUE));
+    XUniqueGLXContext context;
+
+    if (hasGLXARBCreateContextExtension(display)) {
+        // Request OpenGL version 3.2 and core profile, which guarantees that the i965 driver doesn't use the software renderer.
+        static const int contextAttributes[] = {
+            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+            GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+            0
+        };
+        context.reset(glXCreateContextAttribsARB(display, configs.get()[0], sharingContext, GL_TRUE, contextAttributes));
+    }
+
+    if (!context) {
+        // Fallback to legacy OpenGL version.
+        context.reset(glXCreateNewContext(display, configs.get()[0], GLX_RGBA_TYPE, sharingContext, GL_TRUE));
+    }
+
     if (!context)
         return nullptr;
 
index a29ee2d..492b593 100644 (file)
@@ -209,7 +209,7 @@ String Extensions3DOpenGLCommon::getTranslatedShaderSourceANGLE(Platform3DObject
 
 void Extensions3DOpenGLCommon::initializeAvailableExtensions()
 {
-#if PLATFORM(MAC)
+#if PLATFORM(MAC) || PLATFORM(GTK)
     if (m_useIndexedGetString) {
         GLint numExtensions = 0;
         ::glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
index ae8bca7..31c287c 100644 (file)
@@ -407,12 +407,14 @@ void GraphicsContext3D::clearDepth(GC3Dclampf depth)
 #endif
 }
 
+#if !PLATFORM(GTK)
 Extensions3D& GraphicsContext3D::getExtensions()
 {
     if (!m_extensions)
         m_extensions = std::make_unique<Extensions3DOpenGL>(this, isGLES2Compliant());
     return *m_extensions;
 }
+#endif
 
 void GraphicsContext3D::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, void* data)
 {
index 552763c..fefd38f 100644 (file)
@@ -238,12 +238,14 @@ void GraphicsContext3D::clearDepth(GC3Dclampf depth)
     ::glClearDepthf(depth);
 }
 
+#if !PLATFORM(GTK)
 Extensions3D& GraphicsContext3D::getExtensions()
 {
     if (!m_extensions)
         m_extensions = std::make_unique<Extensions3DOpenGLES>(this, isGLES2Compliant());
     return *m_extensions;
 }
+#endif
 
 }