Title: [122554] trunk
Revision
122554
Author
[email protected]
Date
2012-07-13 02:20:49 -0700 (Fri, 13 Jul 2012)

Log Message

[Qt][WK2] Implement GraphicsSurface for Linux/GLX.
https://bugs.webkit.org/show_bug.cgi?id=90881

Source/WebCore:

Add a GLX based GraphicsSurface implementation for Linux.
Native X windows are being used for exchanging textures
with the UIProcess.

Reviewed by Noam Rosenthal.

* Target.pri:
* WebCore.pri:
* platform/graphics/surfaces/GraphicsSurface.cpp:
(WebCore::GraphicsSurface::create):
    Move creating GraphicsSurface instance into
    platformCreate/platformImport functions to allow
    platform specific creation based on the provided flags.
(WebCore::GraphicsSurface::GraphicsSurface):
(WebCore::GraphicsSurface::~GraphicsSurface):
    Call platformDestroy when destroying a GraphicsSurface.
(WebCore):
* platform/graphics/surfaces/GraphicsSurface.h:
    Make platformCreate/platformImport functions static
    to be able to call these from the static create function.
    Add Destructor prototype and add GraphicsSurfacePrivate member.
(WebCore):
(GraphicsSurface):
* platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp:
(WebCore):
(WebCore::GraphicsSurface::platformCreate):
(WebCore::GraphicsSurface::platformImport):
    Insert creation of GraphicsSurface instance.
    This allows having a platform specific creation mechanism
    for GLX.
* platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp: Added.
(WebCore):
(OffScreenRootWindow):
(WebCore::OffScreenRootWindow::OffScreenRootWindow):
(WebCore::OffScreenRootWindow::get):
(WebCore::OffScreenRootWindow::~OffScreenRootWindow):
    Add an OffScreenRootWindow singelton that is being used
    as a parent for all native offscreen windows.
(GraphicsSurfacePrivate):
    This class is used to manage all the X related resources
    such as opening a display or creating XPixmaps etc.
(WebCore::GraphicsSurfacePrivate::GraphicsSurfacePrivate):
    Open a connection to the X server and create a
    QOpenGLContext that can be used to resolve GL functions.
(WebCore::GraphicsSurfacePrivate::~GraphicsSurfacePrivate):
    Properly cleanup and release all the X resources again.
(WebCore::GraphicsSurfacePrivate::createSurface):
    Create a surface that is placed off screen and can be
    used as a rendering target by the WebProcess.
(WebCore::GraphicsSurfacePrivate::createPixmap):
    Create a GLXPixmap from the XWindow that was previously
    redirected by the WebProcess. This GLXPixmap can then be
    bound to a texture and being painted on screen by the
    UIProcess.
(WebCore::GraphicsSurfacePrivate::makeCurrent):
(WebCore::GraphicsSurfacePrivate::swapBuffers):
(WebCore::GraphicsSurfacePrivate::display):
(WebCore::GraphicsSurfacePrivate::glxPixmap):
(WebCore::GraphicsSurfacePrivate::size):
(WebCore::GraphicsSurfacePrivate::glContext):
(WebCore::resolveGLMethods):
    Initialize all the function pointers for the GL functions used.
(WebCore::GraphicsSurface::platformExport):
(WebCore::GraphicsSurface::platformGetTextureID):
    Bind the GLXPixmap to a texture.
(WebCore::GraphicsSurface::platformCopyToGLTexture):
    Not beeing implemented for GLX.
(WebCore::GraphicsSurface::platformCopyFromFramebuffer):
    Blit origin fbo onto the GraphicsSurface's backing.
(WebCore::GraphicsSurface::platformCreate):
(WebCore::GraphicsSurface::platformImport):
(WebCore::GraphicsSurface::platformLock):
(WebCore::GraphicsSurface::platformUnlock):
(WebCore::GraphicsSurface::platformDestroy):

Source/WebKit2:

Add a GLX based GraphicsSurface implementation for Linux.

Reviewed by Noam Rosenthal.

* Shared/ShareableSurface.cpp:
(WebKit::ShareableSurface::create):
    Only create a GraphicsSurface from a ShareableSurface::Handle
    in case the Handle contains a valid GraphicsSurface token.
    Otherwise fall back to creating a ShareableBitmap.
* UIProcess/LayerTreeCoordinatorProxy.cpp:
(WebKit::createLayerTileUniqueKey):
    Create a unique key for a surface based on tileID and layerID.
(WebKit::LayerTreeCoordinatorProxy::updateTileForLayer):
    Even when GraphicsSurface is enabled, not all ShareableSurfaces
    will necessarily be backed by a GraphicsSurface. In case of
    a ShareableSurface being backed by a ShareableBitmap instead,
    the GraphicsSurface token will always be null.
    So instead of using the GraphicsSurface token as a key for
    storing surfaces in a map, we create a unique key from
    layerID and tileID.
* UIProcess/LayerTreeCoordinatorProxy.h:
(LayerTreeCoordinatorProxy):

Tools:

Enable GraphicsSurface for Linux based platforms
whenever the Xcomposite extension is available.

Reviewed by Noam Rosenthal.

* qmake/config.tests/libXcomposite/libXcomposite.cpp: Added.
(main):
* qmake/config.tests/libXcomposite/libXcomposite.pro: Added.
  Add a configure test to detect Xcomposite extension and
  activate GraphicsSurface on linux in case the extension is available.
* qmake/configure.pri:
* qmake/mkspecs/features/features.prf:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (122553 => 122554)


--- trunk/Source/WebCore/ChangeLog	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebCore/ChangeLog	2012-07-13 09:20:49 UTC (rev 122554)
@@ -1,3 +1,83 @@
+2012-07-13  Zeno Albisser  <[email protected]>
+
+        [Qt][WK2] Implement GraphicsSurface for Linux/GLX.
+        https://bugs.webkit.org/show_bug.cgi?id=90881
+
+        Add a GLX based GraphicsSurface implementation for Linux.
+        Native X windows are being used for exchanging textures
+        with the UIProcess.
+
+        Reviewed by Noam Rosenthal.
+
+        * Target.pri:
+        * WebCore.pri:
+        * platform/graphics/surfaces/GraphicsSurface.cpp:
+        (WebCore::GraphicsSurface::create):
+            Move creating GraphicsSurface instance into
+            platformCreate/platformImport functions to allow
+            platform specific creation based on the provided flags.
+        (WebCore::GraphicsSurface::GraphicsSurface):
+        (WebCore::GraphicsSurface::~GraphicsSurface):
+            Call platformDestroy when destroying a GraphicsSurface.
+        (WebCore):
+        * platform/graphics/surfaces/GraphicsSurface.h:
+            Make platformCreate/platformImport functions static
+            to be able to call these from the static create function.
+            Add Destructor prototype and add GraphicsSurfacePrivate member.
+        (WebCore):
+        (GraphicsSurface):
+        * platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp:
+        (WebCore):
+        (WebCore::GraphicsSurface::platformCreate):
+        (WebCore::GraphicsSurface::platformImport):
+            Insert creation of GraphicsSurface instance.
+            This allows having a platform specific creation mechanism
+            for GLX.
+        * platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp: Added.
+        (WebCore):
+        (OffScreenRootWindow):
+        (WebCore::OffScreenRootWindow::OffScreenRootWindow):
+        (WebCore::OffScreenRootWindow::get):
+        (WebCore::OffScreenRootWindow::~OffScreenRootWindow):
+            Add an OffScreenRootWindow singelton that is being used
+            as a parent for all native offscreen windows.
+        (GraphicsSurfacePrivate):
+            This class is used to manage all the X related resources
+            such as opening a display or creating XPixmaps etc.
+        (WebCore::GraphicsSurfacePrivate::GraphicsSurfacePrivate):
+            Open a connection to the X server and create a
+            QOpenGLContext that can be used to resolve GL functions.
+        (WebCore::GraphicsSurfacePrivate::~GraphicsSurfacePrivate):
+            Properly cleanup and release all the X resources again.
+        (WebCore::GraphicsSurfacePrivate::createSurface):
+            Create a surface that is placed off screen and can be
+            used as a rendering target by the WebProcess.
+        (WebCore::GraphicsSurfacePrivate::createPixmap):
+            Create a GLXPixmap from the XWindow that was previously
+            redirected by the WebProcess. This GLXPixmap can then be
+            bound to a texture and being painted on screen by the
+            UIProcess.
+        (WebCore::GraphicsSurfacePrivate::makeCurrent):
+        (WebCore::GraphicsSurfacePrivate::swapBuffers):
+        (WebCore::GraphicsSurfacePrivate::display):
+        (WebCore::GraphicsSurfacePrivate::glxPixmap):
+        (WebCore::GraphicsSurfacePrivate::size):
+        (WebCore::GraphicsSurfacePrivate::glContext):
+        (WebCore::resolveGLMethods):
+            Initialize all the function pointers for the GL functions used.
+        (WebCore::GraphicsSurface::platformExport):
+        (WebCore::GraphicsSurface::platformGetTextureID):
+            Bind the GLXPixmap to a texture.
+        (WebCore::GraphicsSurface::platformCopyToGLTexture):
+            Not beeing implemented for GLX.
+        (WebCore::GraphicsSurface::platformCopyFromFramebuffer):
+            Blit origin fbo onto the GraphicsSurface's backing.
+        (WebCore::GraphicsSurface::platformCreate):
+        (WebCore::GraphicsSurface::platformImport):
+        (WebCore::GraphicsSurface::platformLock):
+        (WebCore::GraphicsSurface::platformUnlock):
+        (WebCore::GraphicsSurface::platformDestroy):
+
 2012-07-13  Dongwoo Im  <[email protected]>
 
         CodeGeneratorJS.pm : SetterExpression should use 'push' rather than 'unshift'

Modified: trunk/Source/WebCore/Target.pri (122553 => 122554)


--- trunk/Source/WebCore/Target.pri	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebCore/Target.pri	2012-07-13 09:20:49 UTC (rev 122554)
@@ -4179,6 +4179,9 @@
         SOURCES += platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp
         INCLUDEPATH += /System/Library/Frameworks/CoreFoundation.framework/Headers
     }
+    contains(DEFINES, HAVE_XCOMPOSITE=1)  {
+        SOURCES += platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp
+    }
 }
 
 # Make sure the derived sources are built

Modified: trunk/Source/WebCore/WebCore.pri (122553 => 122554)


--- trunk/Source/WebCore/WebCore.pri	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebCore/WebCore.pri	2012-07-13 09:20:49 UTC (rev 122554)
@@ -8,7 +8,7 @@
 SOURCE_DIR = $${ROOT_WEBKIT_DIR}/Source/WebCore
 
 QT *= network sql
-haveQt(5): QT *= gui-private
+haveQt(5): QT *= core-private gui-private
 
 WEBCORE_GENERATED_SOURCES_DIR = $${ROOT_BUILD_DIR}/Source/WebCore/$${GENERATED_SOURCES_DESTDIR}
 
@@ -204,6 +204,7 @@
 contains(DEFINES, WTF_USE_3D_GRAPHICS=1) {
     contains(QT_CONFIG, opengles2): LIBS += -lEGL
     mac: LIBS += -framework IOSurface -framework CoreFoundation
+    linux-*:contains(DEFINES, HAVE_XCOMPOSITE=1): LIBS += -lXcomposite
     # Only WebKit1 needs the opengl module, so it's optional for Qt5.
     haveQt(4)|contains(QT_CONFIG, opengl): QT *= opengl
 }

Modified: trunk/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp (122553 => 122554)


--- trunk/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.cpp	2012-07-13 09:20:49 UTC (rev 122554)
@@ -27,18 +27,12 @@
 
 PassRefPtr<GraphicsSurface> GraphicsSurface::create(const IntSize& size, Flags flags, uint32_t token)
 {
-    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
-    if (!surface->platformImport(token))
-        return PassRefPtr<GraphicsSurface>();
-    return surface;
+    return platformImport(size, flags, token);
 }
 
 PassRefPtr<GraphicsSurface> GraphicsSurface::create(const IntSize& size, GraphicsSurface::Flags flags)
 {
-    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
-    if (!surface->platformCreate(size, flags))
-        return PassRefPtr<GraphicsSurface>();
-    return surface;
+    return platformCreate(size, flags);
 }
 
 uint32_t GraphicsSurface::exportToken()
@@ -70,13 +64,19 @@
 }
 
 GraphicsSurface::GraphicsSurface(const IntSize& size, Flags flags)
-    : m_size(size)
-    , m_flags(flags)
+    : m_flags(flags)
+    , m_size(size)
     , m_platformSurface(0)
     , m_texture(0)
     , m_fbo(0)
+    , m_private(0)
 {
 }
 
+GraphicsSurface::~GraphicsSurface()
+{
+    platformDestroy();
 }
+
+}
 #endif

Modified: trunk/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h (122553 => 122554)


--- trunk/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebCore/platform/graphics/surfaces/GraphicsSurface.h	2012-07-13 09:20:49 UTC (rev 122554)
@@ -32,10 +32,14 @@
 #if OS(DARWIN)
 typedef struct __IOSurface* IOSurfaceRef;
 typedef IOSurfaceRef PlatformGraphicsSurface;
+#else
+typedef uint32_t PlatformGraphicsSurface;
 #endif
 
 namespace WebCore {
 
+struct GraphicsSurfacePrivate;
+
 class GraphicsSurface : public RefCounted<GraphicsSurface> {
 public:
     enum Flag {
@@ -69,10 +73,11 @@
     uint32_t getTextureID();
     PassOwnPtr<GraphicsContext> beginPaint(const IntRect&, LockOptions);
     PassRefPtr<Image> createReadOnlyImage(const IntRect&);
+    ~GraphicsSurface();
 
 protected:
-    bool platformCreate(const IntSize&, Flags);
-    bool platformImport(uint32_t);
+    static PassRefPtr<GraphicsSurface> platformCreate(const IntSize&, Flags);
+    static PassRefPtr<GraphicsSurface> platformImport(const IntSize&, Flags, uint32_t);
     uint32_t platformExport();
     void platformDestroy();
 
@@ -100,6 +105,7 @@
     PlatformGraphicsSurface m_platformSurface;
     uint32_t m_texture;
     uint32_t m_fbo;
+    GraphicsSurfacePrivate* m_private;
 };
 
 }

Modified: trunk/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp (122553 => 122554)


--- trunk/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebCore/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp	2012-07-13 09:20:49 UTC (rev 122554)
@@ -30,6 +30,8 @@
 
 namespace WebCore {
 
+struct GraphicsSurfacePrivate { };
+
 uint32_t GraphicsSurface::platformExport()
 {
     return IOSurfaceGetID(m_platformSurface);
@@ -118,7 +120,7 @@
     glFlush();
 }
 
-bool GraphicsSurface::platformCreate(const IntSize& size, Flags flags)
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags)
 {
     unsigned pixelFormat = 'BGRA';
     unsigned bytesPerElement = 4;
@@ -154,14 +156,20 @@
     for (unsigned i = 0; i < 7; i++)
         CFRelease(values[i]);
 
-    m_platformSurface = IOSurfaceCreate(dict);
-    return !!m_platformSurface;
+    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
+    surface->m_platformSurface = IOSurfaceCreate(dict);
+    if (!surface->m_platformSurface)
+        return PassRefPtr<GraphicsSurface>();
+    return surface;
 }
 
-bool GraphicsSurface::platformImport(uint32_t token)
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, uint32_t token)
 {
-    m_platformSurface = IOSurfaceLookup(token);
-    return !!m_platformSurface;
+    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
+    surface->m_platformSurface = IOSurfaceLookup(token);
+    if (!surface->m_platformSurface)
+        return PassRefPtr<GraphicsSurface>();
+    return surface;
 }
 
 static int ioSurfaceLockOptions(int lockOptions)

Added: trunk/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp (0 => 122554)


--- trunk/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/surfaces/qt/GraphicsSurfaceGLX.cpp	2012-07-13 09:20:49 UTC (rev 122554)
@@ -0,0 +1,330 @@
+/*
+ Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB.  If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "GraphicsSurface.h"
+
+#if USE(GRAPHICS_SURFACE)
+
+// Qt headers must be included before glx headers.
+#include <QCoreApplication>
+#include <QOpenGLContext>
+#include <QVector>
+#include <QWindow>
+#include <qpa/qplatformwindow.h>
+#include <GL/glext.h>
+#include <GL/glx.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xrender.h>
+
+namespace WebCore {
+
+static long X11OverrideRedirect = 1L << 9;
+
+static PFNGLXBINDTEXIMAGEEXTPROC pGlXBindTexImageEXT = 0;
+static PFNGLXRELEASETEXIMAGEEXTPROC pGlXReleaseTexImageEXT = 0;
+static PFNGLBINDFRAMEBUFFERPROC pGlBindFramebuffer = 0;
+static PFNGLBLITFRAMEBUFFERPROC pGlBlitFramebuffer = 0;
+
+class OffScreenRootWindow {
+public:
+    OffScreenRootWindow()
+    {
+        ++refCount;
+    }
+
+    QWindow* get(Display* dpy)
+    {
+        if (!window) {
+            window = new QWindow;
+            window->setGeometry(QRect(-1, -1, 1, 1));
+            window->create();
+            XSetWindowAttributes attributes;
+            attributes.override_redirect = true;
+            XChangeWindowAttributes(dpy, window->handle()->winId(), X11OverrideRedirect, &attributes);
+            window->show();
+        }
+        return window;
+    }
+
+    ~OffScreenRootWindow()
+    {
+        if (!--refCount) {
+            delete window;
+            window = 0;
+        }
+    }
+
+private:
+    static int refCount;
+    static QWindow* window;
+};
+
+int OffScreenRootWindow::refCount = 0;
+QWindow* OffScreenRootWindow::window = 0;
+
+static const int glxSpec[] = {
+    // The specification is a set key value pairs stored in a simple array.
+    GLX_LEVEL,                          0,
+    GLX_DRAWABLE_TYPE,                  GLX_PIXMAP_BIT | GLX_WINDOW_BIT,
+    GLX_BIND_TO_TEXTURE_TARGETS_EXT,    GLX_TEXTURE_2D_BIT_EXT,
+    GLX_BIND_TO_TEXTURE_RGB_EXT,        TRUE,
+    0
+};
+
+static const int glxAttributes[] = {
+    GLX_TEXTURE_FORMAT_EXT,
+    GLX_TEXTURE_FORMAT_RGB_EXT,
+    GLX_TEXTURE_TARGET_EXT,
+    GLX_TEXTURE_2D_EXT,
+    0
+};
+
+struct GraphicsSurfacePrivate {
+    GraphicsSurfacePrivate()
+        : m_display(0)
+        , m_xPixmap(0)
+        , m_glxPixmap(0)
+        , m_glContext(adoptPtr(new QOpenGLContext))
+        , m_textureIsYInverted(false)
+        , m_hasAlpha(false)
+    {
+        m_display = XOpenDisplay(0);
+        m_glContext->create();
+    }
+
+    ~GraphicsSurfacePrivate()
+    {
+        if (m_glxPixmap)
+            glXDestroyPixmap(m_display, m_glxPixmap);
+        m_glxPixmap = 0;
+
+        if (m_xPixmap)
+            XFreePixmap(m_display, m_xPixmap);
+        m_xPixmap = 0;
+
+        if (m_display)
+            XCloseDisplay(m_display);
+        m_display = 0;
+    }
+
+    uint32_t createSurface(const IntSize& size)
+    {
+        m_surface = adoptPtr(new QWindow(m_offScreenWindow.get(m_display)));
+        m_surface->setSurfaceType(QSurface::OpenGLSurface);
+        m_surface->setGeometry(0, 0, size.width(), size.height());
+        m_surface->create();
+        XCompositeRedirectWindow(m_display, m_surface->handle()->winId(), CompositeRedirectManual);
+
+        // Make sure the XRender Extension is available.
+        int eventBasep, errorBasep;
+        if (!XRenderQueryExtension(m_display, &eventBasep, &errorBasep))
+            return 0;
+
+        m_surface->show();
+
+        return m_surface->handle()->winId();
+    }
+
+    void createPixmap(uint32_t winId)
+    {
+        XWindowAttributes attr;
+        XGetWindowAttributes(m_display, winId, &attr);
+
+        XRenderPictFormat* format = XRenderFindVisualFormat(m_display, attr.visual);
+        m_hasAlpha = (format->type == PictTypeDirect && format->direct.alphaMask);
+        m_size = IntSize(attr.width, attr.height);
+
+        int numberOfConfigs;
+        GLXFBConfig* configs = glXChooseFBConfig(m_display, XDefaultScreen(m_display), glxSpec, &numberOfConfigs);
+
+        m_xPixmap = XCompositeNameWindowPixmap(m_display, winId);
+        m_glxPixmap = glXCreatePixmap(m_display, *configs, m_xPixmap, glxAttributes);
+
+        uint inverted = 0;
+        glXQueryDrawable(m_display, m_glxPixmap, GLX_Y_INVERTED_EXT, &inverted);
+        m_textureIsYInverted = !!inverted;
+
+        XFree(configs);
+    }
+
+    void makeCurrent()
+    {
+        QOpenGLContext* glContext = QOpenGLContext::currentContext();
+        if (m_surface && glContext)
+            glContext->makeCurrent(m_surface.get());
+    }
+
+    void swapBuffers()
+    {
+        if (!m_surface->isVisible())
+            return;
+
+        // Creating and exposing the surface is asynchronous. Therefore we have to wait here
+        // before swapping the buffers. This should only be the case for the very first frame.
+        while (!m_surface->isExposed())
+            QCoreApplication::processEvents();
+
+        QOpenGLContext* glContext = QOpenGLContext::currentContext();
+        if (m_surface && glContext)
+            glContext->swapBuffers(m_surface.get());
+    }
+
+
+    Display* display() const { return m_display; }
+
+    GLXPixmap glxPixmap() const { return m_glxPixmap; }
+
+    IntSize size() const { return m_size; }
+
+    QOpenGLContext* glContext() { return m_glContext.get(); }
+
+private:
+    OffScreenRootWindow m_offScreenWindow;
+    IntSize m_size;
+    Display* m_display;
+    Pixmap m_xPixmap;
+    GLXPixmap m_glxPixmap;
+    OwnPtr<QWindow> m_surface;
+    OwnPtr<QOpenGLContext> m_glContext;
+    bool m_textureIsYInverted;
+    bool m_hasAlpha;
+};
+
+static bool resolveGLMethods(GraphicsSurfacePrivate* p)
+{
+    static bool resolved = false;
+    if (resolved)
+        return true;
+
+    QOpenGLContext* glContext = p->glContext();
+    pGlXBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glContext->getProcAddress("glXBindTexImageEXT"));
+    pGlXReleaseTexImageEXT = reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(glContext->getProcAddress("glXReleaseTexImageEXT"));
+    pGlBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(glContext->getProcAddress("glBindFramebuffer"));
+    pGlBlitFramebuffer = reinterpret_cast<PFNGLBLITFRAMEBUFFERPROC>(glContext->getProcAddress("glBlitFramebuffer"));
+
+    resolved = pGlBlitFramebuffer && pGlBindFramebuffer && pGlXBindTexImageEXT && pGlXReleaseTexImageEXT;
+
+    return resolved;
+}
+
+uint32_t GraphicsSurface::platformExport()
+{
+    return m_platformSurface;
+}
+
+uint32_t GraphicsSurface::platformGetTextureID()
+{
+    if (!m_texture)
+        glGenTextures(1, &m_texture);
+
+    glBindTexture(GL_TEXTURE_2D, m_texture);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    pGlXBindTexImageEXT(m_private->display(), m_private->glxPixmap(), GLX_FRONT_EXT, 0);
+
+    return m_texture;
+}
+
+void GraphicsSurface::platformCopyToGLTexture(uint32_t target, uint32_t id, const IntRect& targetRect, const IntPoint& offset)
+{
+    // This is not supported by GLX/Xcomposite.
+}
+
+void GraphicsSurface::platformCopyFromFramebuffer(uint32_t originFbo, const IntRect& sourceRect)
+{
+    m_private->makeCurrent();
+    int width = m_size.width();
+    int height = m_size.height();
+
+    glPushAttrib(GL_ALL_ATTRIB_BITS);
+    GLint oldFBO;
+    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO);
+    pGlBindFramebuffer(GL_READ_FRAMEBUFFER, originFbo);
+    pGlBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_private->glContext()->defaultFramebufferObject());
+    pGlBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
+    pGlBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
+    glPopAttrib();
+
+    m_private->swapBuffers();
+}
+
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags)
+{
+    // X11 does not support CopyToTexture, so we do not create a GraphicsSurface if this is requested.
+    if (flags & SupportsCopyToTexture)
+        return PassRefPtr<GraphicsSurface>();
+
+    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
+
+    surface->m_private = new GraphicsSurfacePrivate();
+    if (!resolveGLMethods(surface->m_private))
+        return PassRefPtr<GraphicsSurface>();
+
+    surface->m_platformSurface = surface->m_private->createSurface(size);
+
+    return surface;
+}
+
+PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, uint32_t token)
+{
+    // X11 does not support CopyToTexture, so we do not create a GraphicsSurface if this is requested.
+    if (flags & SupportsCopyToTexture)
+        return PassRefPtr<GraphicsSurface>();
+
+    RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
+
+    surface->m_private = new GraphicsSurfacePrivate();
+    if (!resolveGLMethods(surface->m_private))
+        return PassRefPtr<GraphicsSurface>();
+
+    surface->m_platformSurface = token;
+
+    surface->m_private->createPixmap(surface->m_platformSurface);
+    surface->m_size = surface->m_private->size();
+
+    return surface;
+}
+
+char* GraphicsSurface::platformLock(const IntRect& rect, int* outputStride, LockOptions lockOptions)
+{
+    // GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism.
+    return 0;
+}
+
+void GraphicsSurface::platformUnlock()
+{
+    // GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism.
+}
+
+void GraphicsSurface::platformDestroy()
+{
+    if (m_texture) {
+        pGlXReleaseTexImageEXT(m_private->display(), m_private->glxPixmap(), GLX_FRONT_EXT);
+        glDeleteTextures(1, &m_texture);
+    }
+
+    delete m_private;
+    m_private = 0;
+}
+
+}
+#endif

Modified: trunk/Source/WebKit2/ChangeLog (122553 => 122554)


--- trunk/Source/WebKit2/ChangeLog	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebKit2/ChangeLog	2012-07-13 09:20:49 UTC (rev 122554)
@@ -1,3 +1,31 @@
+2012-07-13  Zeno Albisser  <[email protected]>
+
+        [Qt][WK2] Implement GraphicsSurface for Linux/GLX.
+        https://bugs.webkit.org/show_bug.cgi?id=90881
+
+        Add a GLX based GraphicsSurface implementation for Linux.
+
+        Reviewed by Noam Rosenthal.
+
+        * Shared/ShareableSurface.cpp:
+        (WebKit::ShareableSurface::create):
+            Only create a GraphicsSurface from a ShareableSurface::Handle
+            in case the Handle contains a valid GraphicsSurface token.
+            Otherwise fall back to creating a ShareableBitmap.
+        * UIProcess/LayerTreeCoordinatorProxy.cpp:
+        (WebKit::createLayerTileUniqueKey):
+            Create a unique key for a surface based on tileID and layerID.
+        (WebKit::LayerTreeCoordinatorProxy::updateTileForLayer):
+            Even when GraphicsSurface is enabled, not all ShareableSurfaces
+            will necessarily be backed by a GraphicsSurface. In case of
+            a ShareableSurface being backed by a ShareableBitmap instead,
+            the GraphicsSurface token will always be null.
+            So instead of using the GraphicsSurface token as a key for
+            storing surfaces in a map, we create a unique key from
+            layerID and tileID.
+        * UIProcess/LayerTreeCoordinatorProxy.h:
+        (LayerTreeCoordinatorProxy):
+
 2012-07-12  Carlos Garcia Campos  <[email protected]>
 
         [GTK] Add API to get HTTPS status to WebKit2 GTK+

Modified: trunk/Source/WebKit2/Shared/ShareableSurface.cpp (122553 => 122554)


--- trunk/Source/WebKit2/Shared/ShareableSurface.cpp	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebKit2/Shared/ShareableSurface.cpp	2012-07-13 09:20:49 UTC (rev 122554)
@@ -149,9 +149,11 @@
 PassRefPtr<ShareableSurface> ShareableSurface::create(const Handle& handle)
 {
 #if USE(GRAPHICS_SURFACE)
+    if (handle.graphicsSurfaceToken()) {
         RefPtr<GraphicsSurface> surface = GraphicsSurface::create(handle.m_size, handle.m_flags, handle.m_graphicsSurfaceToken);
         if (surface)
             return adoptRef(new ShareableSurface(handle.m_size, handle.m_flags, PassRefPtr<GraphicsSurface>(surface)));
+    }
 #endif
 
     RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle.m_bitmapHandle);

Modified: trunk/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.cpp (122553 => 122554)


--- trunk/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.cpp	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.cpp	2012-07-13 09:20:49 UTC (rev 122554)
@@ -61,15 +61,24 @@
     updateTileForLayer(layerID, tileID, targetRect, updateInfo);
 }
 
+static inline uint64_t createLayerTileUniqueKey(int layerID, int tileID)
+{
+    uint64_t key = layerID;
+    key <<= 32;
+    key |= tileID;
+    return key;
+}
+
 void LayerTreeCoordinatorProxy::updateTileForLayer(int layerID, int tileID, const IntRect& targetRect, const WebKit::SurfaceUpdateInfo& updateInfo)
 {
     RefPtr<ShareableSurface> surface;
 #if USE(GRAPHICS_SURFACE)
-    uint32_t token = updateInfo.surfaceHandle.graphicsSurfaceToken();
-    HashMap<uint32_t, RefPtr<ShareableSurface> >::iterator it = m_surfaces.find(token);
+    uint64_t key = createLayerTileUniqueKey(layerID, tileID);
+
+    HashMap<uint64_t, RefPtr<ShareableSurface> >::iterator it = m_surfaces.find(key);
     if (it == m_surfaces.end()) {
         surface = ShareableSurface::create(updateInfo.surfaceHandle);
-        m_surfaces.add(token, surface);
+        m_surfaces.add(key, surface);
     } else
         surface = it->second;
 #else

Modified: trunk/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.h (122553 => 122554)


--- trunk/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.h	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Source/WebKit2/UIProcess/LayerTreeCoordinatorProxy.h	2012-07-13 09:20:49 UTC (rev 122554)
@@ -79,7 +79,7 @@
     DrawingAreaProxy* m_drawingAreaProxy;
     RefPtr<WebLayerTreeRenderer> m_renderer;
 #if USE(GRAPHICS_SURFACE)
-    HashMap<uint32_t, RefPtr<ShareableSurface> > m_surfaces;
+    HashMap<uint64_t, RefPtr<ShareableSurface> > m_surfaces;
 #endif
 };
 

Modified: trunk/Tools/ChangeLog (122553 => 122554)


--- trunk/Tools/ChangeLog	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Tools/ChangeLog	2012-07-13 09:20:49 UTC (rev 122554)
@@ -1,3 +1,21 @@
+2012-07-13  Zeno Albisser  <[email protected]>
+
+        [Qt][WK2] Implement GraphicsSurface for Linux/GLX.
+        https://bugs.webkit.org/show_bug.cgi?id=90881
+
+        Enable GraphicsSurface for Linux based platforms
+        whenever the Xcomposite extension is available.
+
+        Reviewed by Noam Rosenthal.
+
+        * qmake/config.tests/libXcomposite/libXcomposite.cpp: Added.
+        (main):
+        * qmake/config.tests/libXcomposite/libXcomposite.pro: Added.
+          Add a configure test to detect Xcomposite extension and
+          activate GraphicsSurface on linux in case the extension is available.
+        * qmake/configure.pri:
+        * qmake/mkspecs/features/features.prf:
+
 2012-07-13  David Grogan  <[email protected]>
 
         nrwt: don't choke when printing invalid utf-8 to stderr

Added: trunk/Tools/qmake/config.tests/libXcomposite/libXcomposite.cpp (0 => 122554)


--- trunk/Tools/qmake/config.tests/libXcomposite/libXcomposite.cpp	                        (rev 0)
+++ trunk/Tools/qmake/config.tests/libXcomposite/libXcomposite.cpp	2012-07-13 09:20:49 UTC (rev 122554)
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <X11/extensions/Xcomposite.h>
+
+int main(int, char**)
+{
+    Display* display = XOpenDisplay(0);
+    int majorVersion;
+    int minorVersion;
+    (void)XCompositeQueryVersion(display, &majorVersion, &minorVersion);
+    XCloseDisplay(display);
+    return 0;
+}

Added: trunk/Tools/qmake/config.tests/libXcomposite/libXcomposite.pro (0 => 122554)


--- trunk/Tools/qmake/config.tests/libXcomposite/libXcomposite.pro	                        (rev 0)
+++ trunk/Tools/qmake/config.tests/libXcomposite/libXcomposite.pro	2012-07-13 09:20:49 UTC (rev 122554)
@@ -0,0 +1,3 @@
+SOURCES = libXcomposite.cpp
+OBJECTS_DIR = obj
+LIBS += -lXcomposite -lX11

Modified: trunk/Tools/qmake/configure.pri (122553 => 122554)


--- trunk/Tools/qmake/configure.pri	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Tools/qmake/configure.pri	2012-07-13 09:20:49 UTC (rev 122554)
@@ -15,6 +15,7 @@
         libpng \
         libjpeg \
         libwebp \
+        libXcomposite \
         libxml2 \
         libxslt \
         libzlib

Modified: trunk/Tools/qmake/mkspecs/features/features.prf (122553 => 122554)


--- trunk/Tools/qmake/mkspecs/features/features.prf	2012-07-13 09:05:21 UTC (rev 122553)
+++ trunk/Tools/qmake/mkspecs/features/features.prf	2012-07-13 09:20:49 UTC (rev 122554)
@@ -170,8 +170,16 @@
     # is called QmlEngine and it is safe for us to use QQuick1 again.
 }
 
+# Xcomposite Support
+haveQt(5):linux-*:config_libXcomposite: DEFINES += HAVE_XCOMPOSITE=1
+
+# Support for Graphics Surface
 !contains(DEFINES, WTF_USE_GRAPHICS_SURFACE=.) {
-    haveQt(5):mac: DEFINES += WTF_USE_GRAPHICS_SURFACE=1
+    haveQt(5) {
+        mac: DEFINES += WTF_USE_GRAPHICS_SURFACE=1
+        # On linux we require libXcomposite to enable graphics surface.
+        linux-*:contains(DEFINES, HAVE_XCOMPOSITE=1): DEFINES += WTF_USE_GRAPHICS_SURFACE=1
+    }
 }
 
 # -------------- Fill in static defaults --------------
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to