[GTK] [AC] Generalize WindowContextGL
authormrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Mar 2012 21:08:08 +0000 (21:08 +0000)
committermrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 2 Mar 2012 21:08:08 +0000 (21:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=78969

Reviewed by Gustavo Noronha Silva.

Source/WebCore:

No new tests. This should not change functionality.

* GNUmakefile.list.am: Added new files to source list.
* platform/graphics/cairo/GLContext.h: Added. An abstraction for all GL contexts.
* platform/graphics/glx/GLContextGLX.cpp: Added. This file is composed of very little
new code, as the logic for instantiating offscreen GL contexts is copied from
GraphicsContext3DPrivate. The code duplication will be removed in a followup patch.
(WebCore::GLContext::platformContext):
* platform/graphics/gtk/GLContextGtk.cpp: Added. This includes some helper factories
for creating and caching GL contexts for GTK+ widgets.

Source/WebKit/gtk:

Use GLContext instead of WindowContextGL. Remove a few unnecessary
namespace specifiers in the implementation of AcceleratedCompositingContext.

* WebCoreSupport/AcceleratedCompositingContext.h: Now we find the GLContext
of our widget, which is cached in WebCore. Remove m_initialized as it isn't needed.
(AcceleratedCompositingContext):
* WebCoreSupport/AcceleratedCompositingContextGL.cpp:
(WebKit::AcceleratedCompositingContext::AcceleratedCompositingContext): No longer initialize
m_initialized.
(WebKit::AcceleratedCompositingContext::glContext): Added.
(WebKit::AcceleratedCompositingContext::renderLayersToWindow): Use glContext() now.
(WebKit::AcceleratedCompositingContext::attachRootGraphicsLayer): Ditto.
(WebKit::AcceleratedCompositingContext::notifyAnimationStarted): Remove unnecessary namespace specifier.
(WebKit::AcceleratedCompositingContext::notifySyncRequired): Ditto.
(WebKit::AcceleratedCompositingContext::paintContents): Ditto.
(WebKit::AcceleratedCompositingContext::showDebugBorders): Ditto.
(WebKit::AcceleratedCompositingContext::showRepaintCounter): Ditto.

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

Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/platform/graphics/cairo/GLContext.h [new file with mode: 0644]
Source/WebCore/platform/graphics/glx/GLContextGLX.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/gtk/GLContextGtk.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/gtk/WindowGLContext.h [deleted file]
Source/WebCore/platform/graphics/gtk/WindowGLContextGLX.cpp [deleted file]
Source/WebKit/gtk/ChangeLog
Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContext.h
Source/WebKit/gtk/WebCoreSupport/AcceleratedCompositingContextGL.cpp

index e9194f8..a05d1bb 100644 (file)
@@ -1,3 +1,21 @@
+2012-02-18  Martin Robinson  <mrobinson@igalia.com>
+
+        [GTK] [AC] Generalize WindowContextGL
+        https://bugs.webkit.org/show_bug.cgi?id=78969
+
+        Reviewed by Gustavo Noronha Silva.
+
+        No new tests. This should not change functionality.
+
+        * GNUmakefile.list.am: Added new files to source list.
+        * platform/graphics/cairo/GLContext.h: Added. An abstraction for all GL contexts.
+        * platform/graphics/glx/GLContextGLX.cpp: Added. This file is composed of very little
+        new code, as the logic for instantiating offscreen GL contexts is copied from
+        GraphicsContext3DPrivate. The code duplication will be removed in a followup patch.
+        (WebCore::GLContext::platformContext):
+        * platform/graphics/gtk/GLContextGtk.cpp: Added. This includes some helper factories
+        for creating and caching GL contexts for GTK+ widgets.
+
 2012-03-02  W. James MacLean  <wjmaclean@chromium.org>
 
         [chromium] Remove TRACE_EVENT from CCQuadCuller::cullOccludedQuads.
index 5a86308..86ccc45 100644 (file)
@@ -5824,6 +5824,8 @@ endif  # END USE_TEXTURE_MAPPER_CAIRO
 
 if USE_TEXTURE_MAPPER_GL
 webcore_sources += \
+       Source/WebCore/platform/graphics/cairo/GLContext.h \
+       Source/WebCore/platform/graphics/glx/GLContextGLX.cpp \
        Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp \
        Source/WebCore/platform/graphics/texmap/TextureMapperGL.h \
        Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp \
@@ -5844,8 +5846,7 @@ webcore_sources += \
        Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h \
        Source/WebCore/platform/graphics/texmap/TextureMapperPlatformLayer.h
 webcoregtk_sources += \
-       Source/WebCore/platform/graphics/gtk/WindowGLContextGLX.cpp \
-       Source/WebCore/platform/graphics/gtk/WindowGLContext.h
+       Source/WebCore/platform/graphics/gtk/GLContextGtk.cpp
 endif  # END USE_TEXTURE_MAPPER_GL
 endif  # USE_ACCELERATED_COMPOSITING
 
diff --git a/Source/WebCore/platform/graphics/cairo/GLContext.h b/Source/WebCore/platform/graphics/cairo/GLContext.h
new file mode 100644 (file)
index 0000000..0a39cec
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301 USA
+ */
+
+#ifndef GLContext_h
+#define GLContext_h
+
+#include "GraphicsContext3D.h"
+#include "Widget.h"
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+#if defined(XP_UNIX)
+typedef struct __GLXcontextRec* GLXContext;
+typedef struct _XDisplay Display;
+typedef struct __GLXcontextRec *GLXContext;
+typedef unsigned long GLXPbuffer;
+typedef unsigned long GLXPixmap;
+typedef unsigned char GLubyte;
+typedef unsigned long Pixmap;
+typedef unsigned long XID;
+typedef void* ContextKeyType;
+#endif
+
+namespace WebCore {
+
+class GLContext {
+    WTF_MAKE_NONCOPYABLE(GLContext);
+public:
+    static GLContext* createSharingContext(GLContext* shareContext);
+    static GLContext* getContextForWidget(PlatformWidget);
+    static GLContext* getCurrent();
+    static void removeActiveContext(GLContext*);
+    static void removeActiveContextForWidget(PlatformWidget);
+
+    virtual ~GLContext();
+    bool makeContextCurrent();
+    void swapBuffers();
+    bool canRenderToDefaultFramebuffer();
+
+#if ENABLE(WEBGL)
+    PlatformGraphicsContext3D platformContext();
+#endif
+
+private:
+    static void addActiveContext(GLContext*);
+    static void cleanupActiveContextsAtExit();
+
+#if defined(XP_UNIX)
+    GLContext(GLXContext);
+    GLContext(GLXContext, Pixmap, GLXPixmap);
+    static GLContext* createContext(XID, GLXContext sharingContext = 0);
+    static GLContext* createWindowContext(XID window, GLXContext sharingContext);
+    static GLContext* createPbufferContext(GLXContext sharingContext);
+    static GLContext* createPixmapContext(GLXContext sharingContext);
+
+    GLXContext m_context;
+    Display* m_display;
+
+    XID m_window;
+    GLXPbuffer m_pbuffer;
+    Pixmap m_pixmap;
+    GLXPixmap m_glxPixmap;
+#endif
+};
+
+}
+
+#endif // GLContext_h
diff --git a/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp b/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp
new file mode 100644 (file)
index 0000000..cdced68
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2011, 2012 Igalia, S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "GLContext.h"
+
+#if ENABLE(WEBGL) || USE(TEXTURE_MAPPER_GL)
+#include "GraphicsContext3D.h"
+#include "OpenGLShims.h"
+#include <GL/glx.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+// We do not want to call glXMakeContextCurrent using different Display pointers,
+// because it might lead to crashes in some drivers (fglrx). We use a shared display
+// pointer here.
+static Display* gSharedDisplay = 0;
+static Display* sharedDisplay()
+{
+    if (!gSharedDisplay)
+        gSharedDisplay = XOpenDisplay(0);
+    return gSharedDisplay;
+}
+
+// Because of driver bugs, exiting the program when there are active pbuffers
+// can crash the X server (this has been observed with the official Nvidia drivers).
+// We need to ensure that we clean everything up on exit. There are several reasons
+// that GraphicsContext3Ds will still be alive at exit, including user error (memory
+// leaks) and the page cache. In any case, we don't want the X server to crash.
+typedef Vector<GLContext*> ActiveContextList;
+static ActiveContextList& activeContextList()
+{
+    DEFINE_STATIC_LOCAL(ActiveContextList, activeContexts, ());
+    return activeContexts;
+}
+
+void GLContext::addActiveContext(GLContext* context)
+{
+    static bool addedAtExitHandler = false;
+    if (!addedAtExitHandler) {
+        atexit(&GLContext::cleanupActiveContextsAtExit);
+        addedAtExitHandler = true;
+    }
+    activeContextList().append(context);
+}
+
+void GLContext::removeActiveContext(GLContext* context)
+{
+    ActiveContextList& contextList = activeContextList();
+    size_t i = contextList.find(context);
+    if (i != notFound)
+        contextList.remove(i);
+}
+
+void GLContext::cleanupActiveContextsAtExit()
+{
+    ActiveContextList& contextList = activeContextList();
+    for (size_t i = 0; i < contextList.size(); ++i)
+        delete contextList[i];
+
+    if (!gSharedDisplay)
+        return;
+    XCloseDisplay(gSharedDisplay);
+    gSharedDisplay = 0;
+}
+
+GLContext* GLContext::getCurrent()
+{
+    ActiveContextList& contextList = activeContextList();
+    GLXContext current = glXGetCurrentContext();
+    for (size_t i = 0; i < contextList.size(); ++i) {
+        if (current == contextList[i]->m_context)
+            return contextList[i];
+    }
+    return 0;
+}
+
+GLContext* GLContext::createSharingContext(GLContext* sharingContext)
+{
+    return createContext(0, sharingContext ? sharingContext->m_context : 0);
+}
+
+GLContext* GLContext::createWindowContext(XID window, GLXContext sharingContext)
+{
+    Display* display = sharedDisplay();
+    XWindowAttributes attributes;
+    if (!XGetWindowAttributes(display, window, &attributes))
+        return 0;
+
+    XVisualInfo visualInfo;
+    visualInfo.visualid = XVisualIDFromVisual(attributes.visual);
+
+    int numReturned = 0;
+    XVisualInfo* visualInfoList = XGetVisualInfo(display, VisualIDMask, &visualInfo, &numReturned);
+    GLXContext context = glXCreateContext(display, visualInfoList, sharingContext, True);
+    XFree(visualInfoList);
+
+    if (!context)
+        return 0;
+
+    // GLXPbuffer and XID are both the same types underneath, so we have to share
+    // a constructor here with the window path.
+    GLContext* contextWrapper = new GLContext(context);
+    contextWrapper->m_window = window;
+    return contextWrapper;
+}
+
+GLContext* GLContext::createPbufferContext(GLXContext sharingContext)
+{
+    int fbConfigAttributes[] = {
+        GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
+        GLX_RENDER_TYPE, GLX_RGBA_BIT,
+        GLX_RED_SIZE, 1,
+        GLX_GREEN_SIZE, 1,
+        GLX_BLUE_SIZE, 1,
+        GLX_ALPHA_SIZE, 1,
+        GLX_DOUBLEBUFFER, GL_FALSE,
+        0
+    };
+
+    int returnedElements;
+    Display* display = sharedDisplay();
+    GLXFBConfig* configs = glXChooseFBConfig(display, 0, fbConfigAttributes, &returnedElements);
+    if (!returnedElements) {
+        XFree(configs);
+        return 0;
+    }
+
+    // We will be rendering to a texture, so our pbuffer does not need to be large.
+    static const int pbufferAttributes[] = { GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, 0 };
+    GLXPbuffer pbuffer = glXCreatePbuffer(display, configs[0], pbufferAttributes);
+    if (!pbuffer) {
+        XFree(configs);
+        return 0;
+    }
+
+    GLXContext context = glXCreateNewContext(display, configs[0], GLX_RGBA_TYPE, sharingContext, GL_TRUE);
+    XFree(configs);
+    if (!context)
+        return 0;
+
+    // GLXPbuffer and XID are both the same types underneath, so we have to share
+    // a constructor here with the window path.
+    GLContext* contextWrapper = new GLContext(context);
+    contextWrapper->m_pbuffer = pbuffer;
+    return contextWrapper;
+}
+
+GLContext* GLContext::createPixmapContext(GLXContext sharingContext)
+{
+    static int visualAttributes[] = {
+        GLX_RGBA,
+        GLX_RED_SIZE, 1,
+        GLX_GREEN_SIZE, 1,
+        GLX_BLUE_SIZE, 1,
+        GLX_ALPHA_SIZE, 1,
+        0
+    };
+
+    Display* display = sharedDisplay();
+    XVisualInfo* visualInfo = glXChooseVisual(display, DefaultScreen(display), visualAttributes);
+    if (!visualInfo)
+        return 0;
+
+    GLXContext context = glXCreateContext(display, visualInfo, sharingContext, GL_TRUE);
+    if (!context) {
+        XFree(visualInfo);
+        return 0;
+    }
+
+    Pixmap pixmap = XCreatePixmap(display, DefaultRootWindow(display), 1, 1, visualInfo->depth);
+    if (!pixmap) {
+        XFree(visualInfo);
+        return 0;
+    }
+
+    GLXPixmap glxPixmap = glXCreateGLXPixmap(display, visualInfo, pixmap);
+    if (!glxPixmap) {
+        XFreePixmap(display, pixmap);
+        XFree(visualInfo);
+        return 0;
+    }
+
+    return new GLContext(context, pixmap, glxPixmap);
+}
+
+GLContext* GLContext::createContext(XID window, GLXContext sharingContext)
+{
+    if (!sharedDisplay())
+        return 0;
+
+    static bool initialized = false;
+    static bool success = true;
+    if (!initialized) {
+        success = initializeOpenGLShims();
+        initialized = true;
+    }
+    if (!success)
+        return 0;
+
+    GLContext* context = window ? createWindowContext(window, sharingContext) : 0;
+    if (!context)
+        context = createPbufferContext(sharingContext);
+    if (!context)
+        context = createPixmapContext(sharingContext);
+    if (!context)
+        return 0;
+
+    return context;
+}
+
+GLContext::GLContext(GLXContext context)
+    : m_context(context)
+    , m_window(0)
+    , m_pbuffer(0)
+    , m_pixmap(0)
+    , m_glxPixmap(0)
+{
+    addActiveContext(this);
+}
+
+GLContext::GLContext(GLXContext context, Pixmap pixmap, GLXPixmap glxPixmap)
+    : m_context(context)
+    , m_window(0)
+    , m_pbuffer(0)
+    , m_pixmap(pixmap)
+    , m_glxPixmap(glxPixmap)
+{
+    addActiveContext(this);
+}
+
+GLContext::~GLContext()
+{
+    if (m_context) {
+        // This may be necessary to prevent crashes with NVidia's closed source drivers. Originally
+        // from Mozilla's 3D canvas implementation at: http://bitbucket.org/ilmari/canvas3d/
+        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+        glXMakeCurrent(m_display, None, None);
+        glXDestroyContext(m_display, m_context);
+    }
+
+    if (m_pbuffer) {
+        glXDestroyPbuffer(sharedDisplay(), m_pbuffer);
+        m_pbuffer = 0;
+    }
+    if (m_glxPixmap) {
+        glXDestroyGLXPixmap(sharedDisplay(), m_glxPixmap);
+        m_glxPixmap = 0;
+    }
+    if (m_pixmap) {
+        XFreePixmap(sharedDisplay(), m_pixmap);
+        m_pixmap = 0;
+    }
+    removeActiveContext(this);
+}
+
+bool GLContext::canRenderToDefaultFramebuffer()
+{
+    return m_window;
+}
+
+bool GLContext::makeContextCurrent()
+{
+    ASSERT(m_context && (m_window || m_pbuffer || m_glxPixmap));
+    if (glXGetCurrentContext() == m_context)
+        return true;
+
+    if (m_window)
+        return glXMakeCurrent(sharedDisplay(), m_window, m_context);
+
+    if (m_pbuffer)
+        return glXMakeCurrent(sharedDisplay(), m_pbuffer, m_context);
+
+    return ::glXMakeCurrent(sharedDisplay(), m_glxPixmap, m_context);
+}
+
+void GLContext::swapBuffers()
+{
+    if (m_window)
+        glXSwapBuffers(sharedDisplay(), m_window);
+}
+
+#if ENABLE(WEBGL)
+PlatformGraphicsContext3D GLContext::platformContext()
+{
+    return m_context;
+}
+#endif
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL) || && USE(TEXTURE_MAPPER_GL)
diff --git a/Source/WebCore/platform/graphics/gtk/GLContextGtk.cpp b/Source/WebCore/platform/graphics/gtk/GLContextGtk.cpp
new file mode 100644 (file)
index 0000000..6b2461a
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 Igalia, S.L.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "GLContext.h"
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+namespace WebCore {
+
+typedef HashMap<GtkWidget*, OwnPtr<GLContext> > WindowContextMap;
+static WindowContextMap& windowContextsMap()
+{
+    DEFINE_STATIC_LOCAL(WindowContextMap, windowContexts, ());
+    return windowContexts;
+}
+
+static void shutdownGLContext(GtkWidget* widget, void*)
+{
+    WindowContextMap& windowContexts = windowContextsMap();
+    WindowContextMap::iterator i = windowContexts.find(widget);
+    if (i != windowContexts.end())
+        windowContexts.remove(i);
+}
+
+GLContext* GLContext::getContextForWidget(GtkWidget* widget)
+{
+    ASSERT(widget);
+
+    WindowContextMap& windowContexts = windowContextsMap();
+    WindowContextMap::iterator i = windowContextsMap().find(widget);
+    if (i != windowContexts.end())
+        return i->second.get();
+
+    // It's important that this context doesn't hang around after the window
+    // is unmapped, so we make sure to clean it up once that happens.
+    if (!g_signal_handler_find(widget, G_SIGNAL_MATCH_FUNC, 0, 0, 0, reinterpret_cast<void*>(shutdownGLContext), 0))
+        g_signal_connect(widget, "unmap", G_CALLBACK(shutdownGLContext), 0);
+
+    // If this GDK window doesn't have its own native window then, we don't want
+    // to use it for rendering, since we'll be drawing over some other widget's area.
+    GdkWindow* gdkWindow = gtk_widget_get_window(widget);
+    GLContext* context = gdkWindow && gdk_window_has_native(gdkWindow) ?  createContext(GDK_WINDOW_XID(gdkWindow)) : createContext(0);
+
+    if (!context)
+        return 0;
+
+    windowContexts.set(widget, adoptPtr(context));
+    return context;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/gtk/WindowGLContext.h b/Source/WebCore/platform/graphics/gtk/WindowGLContext.h
deleted file mode 100644 (file)
index 9623568..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012 Igalia S.L.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free
- *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301 USA
- */
-
-#ifndef WindowGLContext_h
-#define WindowGLContext_h
-
-#include <wtf/Noncopyable.h>
-#include <wtf/PassOwnPtr.h>
-
-#if defined(XP_UNIX)
-typedef struct __GLXcontextRec* GLXContext;
-typedef struct _XDisplay Display;
-#endif
-
-namespace WebCore {
-
-class WindowGLContext {
-    WTF_MAKE_NONCOPYABLE(WindowGLContext);
-public:
-    static PassOwnPtr<WindowGLContext> createContextWithGdkWindow(GdkWindow*);
-    virtual ~WindowGLContext();
-    void startDrawing();
-    void finishDrawing();
-
-private:
-    WindowGLContext(GdkWindow*);
-    GdkWindow* m_window;
-
-#if defined(XP_UNIX)
-    GLXContext m_context;
-    Display* m_display;
-    bool m_needToCloseDisplay;
-#endif
-};
-
-}
-
-#endif // WindowGLContext_h
diff --git a/Source/WebCore/platform/graphics/gtk/WindowGLContextGLX.cpp b/Source/WebCore/platform/graphics/gtk/WindowGLContextGLX.cpp
deleted file mode 100644 (file)
index c16a4f4..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 Igalia, S.L.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "config.h"
-#include "WindowGLContext.h"
-
-#include <GL/glx.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-#include <wtf/OwnPtr.h>
-
-namespace WebCore {
-
-PassOwnPtr<WindowGLContext> WindowGLContext::createContextWithGdkWindow(GdkWindow* window)
-{
-    OwnPtr<WindowGLContext> context = adoptPtr(new WindowGLContext(window));
-    if (!context->m_context)
-        return nullptr;
-    return context.release();
-}
-
-WindowGLContext::WindowGLContext(GdkWindow* window)
-    : m_window(window)
-    , m_context(0)
-    , m_display(0)
-    , m_needToCloseDisplay(0)
-{
-    GdkDisplay* gdkDisplay = gdk_window_get_display(m_window);
-    if (gdkDisplay)
-        m_display = GDK_DISPLAY_XDISPLAY(gdkDisplay);
-    else {
-        m_display = XOpenDisplay(0);
-        m_needToCloseDisplay = true;
-    }
-
-    XWindowAttributes attributes;
-    if (!XGetWindowAttributes(m_display, GDK_WINDOW_XID(m_window), &attributes))
-        return;
-
-    XVisualInfo visualInfo;
-    visualInfo.visualid = XVisualIDFromVisual(attributes.visual);
-
-    int numReturned = 0;
-    XVisualInfo* visualInfoList = XGetVisualInfo(m_display, VisualIDMask, &visualInfo, &numReturned);
-    m_context = glXCreateContext(m_display, visualInfoList, 0, True);
-    XFree(visualInfoList);
-}
-
-WindowGLContext::~WindowGLContext()
-{
-    if (!m_context)
-        return;
-    glXMakeCurrent(m_display, None, None);
-    glXDestroyContext(m_display, m_context);
-
-    if (m_needToCloseDisplay)
-        XCloseDisplay(m_display);
-}
-
-void WindowGLContext::startDrawing()
-{
-    glXMakeCurrent(m_display, GDK_WINDOW_XID(m_window), m_context);
-}
-
-void WindowGLContext::finishDrawing()
-{
-    glXSwapBuffers(m_display, GDK_WINDOW_XID(m_window));
-}
-
-} // namespace WebCore
index 7cb6da5..6fa9a9b 100644 (file)
@@ -1,3 +1,28 @@
+2012-02-18  Martin Robinson  <mrobinson@igalia.com>
+
+        [GTK] [AC] Generalize WindowContextGL
+        https://bugs.webkit.org/show_bug.cgi?id=78969
+
+        Reviewed by Gustavo Noronha Silva.
+
+        Use GLContext instead of WindowContextGL. Remove a few unnecessary
+        namespace specifiers in the implementation of AcceleratedCompositingContext.
+
+        * WebCoreSupport/AcceleratedCompositingContext.h: Now we find the GLContext
+        of our widget, which is cached in WebCore. Remove m_initialized as it isn't needed.
+        (AcceleratedCompositingContext):
+        * WebCoreSupport/AcceleratedCompositingContextGL.cpp:
+        (WebKit::AcceleratedCompositingContext::AcceleratedCompositingContext): No longer initialize
+        m_initialized.
+        (WebKit::AcceleratedCompositingContext::glContext): Added.
+        (WebKit::AcceleratedCompositingContext::renderLayersToWindow): Use glContext() now.
+        (WebKit::AcceleratedCompositingContext::attachRootGraphicsLayer): Ditto.
+        (WebKit::AcceleratedCompositingContext::notifyAnimationStarted): Remove unnecessary namespace specifier.
+        (WebKit::AcceleratedCompositingContext::notifySyncRequired): Ditto.
+        (WebKit::AcceleratedCompositingContext::paintContents): Ditto.
+        (WebKit::AcceleratedCompositingContext::showDebugBorders): Ditto.
+        (WebKit::AcceleratedCompositingContext::showRepaintCounter): Ditto.
+
 2012-03-02  Zan Dobersek  <zandobersek@gmail.com>
 
         [GTK] Smooth scrolling support
index cad4749..b2567eb 100644 (file)
@@ -28,8 +28,8 @@
 #include <wtf/PassOwnPtr.h>
 
 #if USE(TEXTURE_MAPPER_GL)
+#include "GLContext.h"
 #include "TextureMapperLayer.h"
-#include "WindowGLContext.h"
 #endif
 
 #if USE(ACCELERATED_COMPOSITING)
@@ -69,11 +69,8 @@ private:
 #if USE(CLUTTER)
     GtkWidget* m_rootLayerEmbedder;
 #elif USE(TEXTURE_MAPPER_GL)
-    void initializeIfNecessary();
-
-    bool m_initialized;
+    WebCore::GLContext* glContext();
     WebCore::TextureMapperLayer* m_rootTextureMapperLayer;
-    OwnPtr<WebCore::WindowGLContext> m_context;
     OwnPtr<WebCore::TextureMapper> m_textureMapper;
 #endif
 
index 8c4300f..6d33897 100644 (file)
@@ -42,7 +42,6 @@ namespace WebKit {
 AcceleratedCompositingContext::AcceleratedCompositingContext(WebKitWebView* webView)
     : m_webView(webView)
     , m_syncTimerCallbackId(0)
-    , m_initialized(false)
     , m_rootTextureMapperLayer(0)
 {
 }
@@ -53,38 +52,30 @@ AcceleratedCompositingContext::~AcceleratedCompositingContext()
         g_source_remove(m_syncTimerCallbackId);
 }
 
-void AcceleratedCompositingContext::initializeIfNecessary()
-{
-    if (m_initialized)
-        return;
-
-    m_initialized = true;
-
-    // The GTK+ docs say that we can fail to create a native window.
-    // FIXME: We should fall back to the ImageBuffer TextureMapper when it exists.
-    if (!m_webView->priv->hasNativeWindow)
-        return;
-
-    m_context = WebCore::WindowGLContext::createContextWithGdkWindow(gtk_widget_get_window(GTK_WIDGET(m_webView)));
-}
-
 bool AcceleratedCompositingContext::enabled()
 {
     return m_rootTextureMapperLayer && m_textureMapper;
 }
 
+GLContext* AcceleratedCompositingContext::glContext()
+{
+    GLContext* context = GLContext::getContextForWidget(GTK_WIDGET(m_webView));
+    if (!context->canRenderToDefaultFramebuffer())
+        return 0;
+    return context;
+}
 
 bool AcceleratedCompositingContext::renderLayersToWindow(const IntRect& clipRect)
 {
     if (!enabled())
         return false;
 
-    // We initialize the context lazily here so that we know that the GdkWindow realized.
-    initializeIfNecessary();
-    if (!m_context)
+    GLContext* context = glContext();
+    if (!context)
         return false;
 
-    m_context->startDrawing();
+    if (!context->makeContextCurrent())
+        return false;
 
     GtkAllocation allocation;
     gtk_widget_get_allocation(GTK_WIDGET(m_webView), &allocation);
@@ -94,7 +85,7 @@ bool AcceleratedCompositingContext::renderLayersToWindow(const IntRect& clipRect
     m_rootTextureMapperLayer->paint();
     m_textureMapper->endPainting();
 
-    m_context->finishDrawing();
+    context->swapBuffers();
     return true;
 }
 
@@ -114,14 +105,14 @@ void AcceleratedCompositingContext::attachRootGraphicsLayer(GraphicsLayer* graph
     m_rootGraphicsLayer->setNeedsDisplay();
     m_rootGraphicsLayer->setSize(core(m_webView)->mainFrame()->view()->frameRect().size());
 
-    // We initialize the context lazily here so that we know that the GdkWindow realized.
-    initializeIfNecessary();
-    if (!m_context)
+    GLContext* context = glContext();
+    if (!context)
         return;
 
     // The context needs to be active when creating the texture mapper. It's fine to
-    // avoid calling endDrawing here, because it will just initialize shaders.
-    m_context->startDrawing();
+    // avoid calling swapBuffers here, because it will just initialize shaders.
+    if (!context->makeContextCurrent())
+        return;
 
     GtkAllocation allocation;
     gtk_widget_get_allocation(GTK_WIDGET(m_webView), &allocation);
@@ -188,28 +179,28 @@ void AcceleratedCompositingContext::syncLayersTimeout()
         m_syncTimerCallbackId = g_timeout_add_full(GDK_PRIORITY_EVENTS, 1000.0 / 60.0, reinterpret_cast<GSourceFunc>(syncLayersTimeoutCallback), this, 0);
 }
 
-void AcceleratedCompositingContext::notifyAnimationStarted(const WebCore::GraphicsLayer*, double time)
+void AcceleratedCompositingContext::notifyAnimationStarted(const GraphicsLayer*, double time)
 {
 
 }
-void AcceleratedCompositingContext::notifySyncRequired(const WebCore::GraphicsLayer*)
+void AcceleratedCompositingContext::notifySyncRequired(const GraphicsLayer*)
 {
 
 }
 
-void AcceleratedCompositingContext::paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext& context, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& rectToPaint)
+void AcceleratedCompositingContext::paintContents(const GraphicsLayer*, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& rectToPaint)
 {
     cairo_t* cr = context.platformContext()->cr();
     copyRectFromCairoSurfaceToContext(m_webView->priv->backingStore->cairoSurface(), cr,
                                       IntSize(), rectToPaint);
 }
 
-bool AcceleratedCompositingContext::showDebugBorders(const WebCore::GraphicsLayer*) const
+bool AcceleratedCompositingContext::showDebugBorders(const GraphicsLayer*) const
 {
     return false;
 }
 
-bool AcceleratedCompositingContext::showRepaintCounter(const WebCore::GraphicsLayer*) const
+bool AcceleratedCompositingContext::showRepaintCounter(const GraphicsLayer*) const
 {
     return false;
 }