Title: [176016] trunk/Source
Revision
176016
Author
[email protected]
Date
2014-11-12 04:13:10 -0800 (Wed, 12 Nov 2014)

Log Message

[GTK] Move RedirectedXCompositeWindow from platform to WebKit2 layer
https://bugs.webkit.org/show_bug.cgi?id=138093

Reviewed by Martin Robinson.

Source/WebCore:

Remove RedirectedXCompositeWindow.

* PlatformGTK.cmake:

Source/WebKit2:

It's only used by WebKitWebViewBase. While moving the code the
following cleanups have been made:

  - Use NeverDestroyed instead of DEPRECATED_DEFINE_STATIC_LOCAL.
  - Use a helper class XDamageNotifier to handle the XDamage
    events filtering and notification.
  - Use std::function instead of pointer to function for the
    damage callback.
  - Pass the X display to the RedirectedXCompositeWindow constructor
    and keep it as a member to use it everywhere, instead of using
    the default display in some places and the widget display in others.
  - Pass the damage notify function as a contructor parameter of
    RedirectedXCompositeWindow instead of setting the callback
    right after creating the object.
  - Remove GLContextNeeded and all the dead code related to the
    CreateGLContext mode that is no longer used.
  - Rename cairoSurfaceForWidget() as surface().
  - windowId() has been renamed as windowID() and made const.
  - Use std::unique_ptr instead of PassOwnPtr.
  - Fix coding style issues.

* PlatformGTK.cmake:
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseConstructed):
(webkitWebViewRenderAcceleratedCompositingResults):
(webkitWebViewBaseCreateWebPage):
(redirectedWindowDamagedCallback): Deleted.
* UIProcess/gtk/RedirectedXCompositeWindow.cpp: Renamed from Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp.
(WebKit::XDamageNotifier::XDamageNotifier):
(WebKit::XDamageNotifier::add):
(WebKit::XDamageNotifier::remove):
(WebKit::XDamageNotifier::filterXDamageEvent):
(WebKit::XDamageNotifier::filterXEvent):
(WebKit::xDamageNotifier):
(WebKit::supportsXDamageAndXComposite):
(WebKit::RedirectedXCompositeWindow::create):
(WebKit::RedirectedXCompositeWindow::RedirectedXCompositeWindow):
(WebKit::RedirectedXCompositeWindow::~RedirectedXCompositeWindow):
(WebKit::RedirectedXCompositeWindow::resize):
(WebKit::RedirectedXCompositeWindow::cleanupPixmapAndPixmapSurface):
(WebKit::RedirectedXCompositeWindow::surface):
* UIProcess/gtk/RedirectedXCompositeWindow.h: Renamed from Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h.
(WebKit::RedirectedXCompositeWindow::windowID):

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (176015 => 176016)


--- trunk/Source/WebCore/ChangeLog	2014-11-12 11:25:16 UTC (rev 176015)
+++ trunk/Source/WebCore/ChangeLog	2014-11-12 12:13:10 UTC (rev 176016)
@@ -1,3 +1,14 @@
+2014-11-12  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Move RedirectedXCompositeWindow from platform to WebKit2 layer
+        https://bugs.webkit.org/show_bug.cgi?id=138093
+
+        Reviewed by Martin Robinson.
+
+        Remove RedirectedXCompositeWindow.
+
+        * PlatformGTK.cmake:
+
 2014-09-01  Philippe Normand  <[email protected]>
 
         [WK2] UserMediaClient support

Modified: trunk/Source/WebCore/PlatformGTK.cmake (176015 => 176016)


--- trunk/Source/WebCore/PlatformGTK.cmake	2014-11-12 11:25:16 UTC (rev 176015)
+++ trunk/Source/WebCore/PlatformGTK.cmake	2014-11-12 12:13:10 UTC (rev 176016)
@@ -233,7 +233,6 @@
     platform/gtk/PlatformMouseEventGtk.cpp
     platform/gtk/PlatformScreenGtk.cpp
     platform/gtk/PlatformWheelEventGtk.cpp
-    platform/gtk/RedirectedXCompositeWindow.cpp
     platform/gtk/ScrollbarThemeGtk.cpp
     platform/gtk/SoundGtk.cpp
     platform/gtk/WidgetGtk.cpp

Deleted: trunk/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp (176015 => 176016)


--- trunk/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp	2014-11-12 11:25:16 UTC (rev 176015)
+++ trunk/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp	2014-11-12 12:13:10 UTC (rev 176016)
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2012 Igalia S.L.
- * All rights reserved.
- *
- * 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 APPLE INC. ``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 APPLE INC. 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 "config.h"
-#include "RedirectedXCompositeWindow.h"
-
-#if USE(OPENGL) && PLATFORM(X11)
-
-#include <X11/extensions/Xcomposite.h>
-#include <X11/extensions/Xdamage.h>
-#include <cairo-xlib.h>
-#include <gdk/gdkx.h>
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <wtf/HashMap.h>
-
-namespace WebCore {
-
-typedef HashMap<Window, RedirectedXCompositeWindow*> WindowHashMap;
-static WindowHashMap& getWindowHashMap()
-{
-    DEPRECATED_DEFINE_STATIC_LOCAL(WindowHashMap, windowHashMap, ());
-    return windowHashMap;
-}
-
-static int gDamageEventBase;
-static GdkFilterReturn filterXDamageEvent(GdkXEvent* gdkXEvent, GdkEvent*, void*)
-{
-    XEvent* xEvent = static_cast<XEvent*>(gdkXEvent);
-    if (xEvent->type != gDamageEventBase + XDamageNotify)
-        return GDK_FILTER_CONTINUE;
-
-    XDamageNotifyEvent* damageEvent = reinterpret_cast<XDamageNotifyEvent*>(xEvent);
-    WindowHashMap& windowHashMap = getWindowHashMap();
-    WindowHashMap::iterator i = windowHashMap.find(damageEvent->drawable);
-    if (i == windowHashMap.end())
-        return GDK_FILTER_CONTINUE;
-
-    i->value->callDamageNotifyCallback();
-    XDamageSubtract(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), damageEvent->damage, None, None);
-    return GDK_FILTER_REMOVE;
-}
-
-static bool supportsXDamageAndXComposite()
-{
-    static bool initialized = false;
-    static bool hasExtensions = false;
-
-    if (initialized)
-        return hasExtensions;
-
-    initialized = true;
-
-    int errorBase;
-    Display* display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
-    if (!XDamageQueryExtension(display, &gDamageEventBase, &errorBase))
-        return false;
-
-    int eventBase;
-    if (!XCompositeQueryExtension(display, &eventBase, &errorBase))
-        return false;
-
-    // We need to support XComposite version 0.2.
-    int major, minor;
-    XCompositeQueryVersion(display, &major, &minor);
-    if (major < 0 || (!major && minor < 2))
-        return false;
-
-    hasExtensions = true;
-    return true;
-}
-
-PassOwnPtr<RedirectedXCompositeWindow> RedirectedXCompositeWindow::create(const IntSize& size, GLContextNeeded needsContext)
-{
-    return supportsXDamageAndXComposite() ? adoptPtr(new RedirectedXCompositeWindow(size, needsContext)) : nullptr;
-}
-
-RedirectedXCompositeWindow::RedirectedXCompositeWindow(const IntSize& size, GLContextNeeded needsContext)
-    : m_size(size)
-    , m_window(0)
-    , m_parentWindow(0)
-    , m_pixmap(0)
-    , m_needsContext(needsContext)
-    , m_surface(0)
-    , m_needsNewPixmapAfterResize(false)
-    , m_damage(0)
-    , m_damageNotifyCallback(0)
-    , m_damageNotifyData(0)
-{
-    Display* display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
-    Screen* screen = DefaultScreenOfDisplay(display);
-
-    // This is based on code from Chromium: src/content/common/gpu/image_transport_surface_linux.cc
-    XSetWindowAttributes windowAttributes;
-    windowAttributes.override_redirect = True;
-    m_parentWindow = XCreateWindow(display,
-        RootWindowOfScreen(screen),
-        WidthOfScreen(screen) + 1, 0, 1, 1,
-        0,
-        CopyFromParent,
-        InputOutput,
-        CopyFromParent,
-        CWOverrideRedirect,
-        &windowAttributes);
-    XMapWindow(display, m_parentWindow);
-
-    windowAttributes.event_mask = StructureNotifyMask;
-    windowAttributes.override_redirect = False;
-    m_window = XCreateWindow(display,
-                             m_parentWindow,
-                             0, 0, size.width(), size.height(),
-                             0,
-                             CopyFromParent,
-                             InputOutput,
-                             CopyFromParent,
-                             CWEventMask,
-                             &windowAttributes);
-    XMapWindow(display, m_window);
-
-    if (getWindowHashMap().isEmpty())
-        gdk_window_add_filter(0, reinterpret_cast<GdkFilterFunc>(filterXDamageEvent), 0);
-    getWindowHashMap().add(m_window, this);
-
-    while (1) {
-        XEvent event;
-        XWindowEvent(display, m_window, StructureNotifyMask, &event);
-        if (event.type == MapNotify && event.xmap.window == m_window)
-            break;
-    }
-    XSelectInput(display, m_window, NoEventMask);
-    XCompositeRedirectWindow(display, m_window, CompositeRedirectManual);
-    m_damage = XDamageCreate(display, m_window, XDamageReportNonEmpty);
-}
-
-RedirectedXCompositeWindow::~RedirectedXCompositeWindow()
-{
-    ASSERT(m_damage);
-    ASSERT(m_window);
-    ASSERT(m_parentWindow);
-
-    getWindowHashMap().remove(m_window);
-    if (getWindowHashMap().isEmpty())
-        gdk_window_remove_filter(0, reinterpret_cast<GdkFilterFunc>(filterXDamageEvent), 0);
-
-    Display* display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
-    XDamageDestroy(display, m_damage);
-    XDestroyWindow(display, m_window);
-    XDestroyWindow(display, m_parentWindow);
-    cleanupPixmapAndPixmapSurface();
-}
-
-void RedirectedXCompositeWindow::resize(const IntSize& size)
-{
-    Display* display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
-    XResizeWindow(display, m_window, size.width(), size.height());
-
-    XFlush(display);
-
-    if (m_needsContext == CreateGLContext) {
-        context()->waitNative();
-        // This swap is based on code in Chromium. It tries to work-around a bug in the Intel drivers
-        // where a swap is necessary to ensure the front and back buffers are properly resized.
-        if (context() == GLContext::getCurrent())
-            context()->swapBuffers();
-    }
-
-    m_size = size;
-    m_needsNewPixmapAfterResize = true;
-}
-
-GLContext* RedirectedXCompositeWindow::context()
-{
-    ASSERT(m_needsContext == CreateGLContext);
-
-    if (m_context)
-        return m_context.get();
-
-    ASSERT(m_window);
-    m_context = GLContext::createContextForWindow(m_window, GLContext::sharingContext());
-    return m_context.get();
-}
-
-void RedirectedXCompositeWindow::cleanupPixmapAndPixmapSurface()
-{
-    if (!m_pixmap)
-        return;
-
-    XFreePixmap(cairo_xlib_surface_get_display(m_surface.get()), m_pixmap);
-    m_pixmap = 0;
-    m_surface = nullptr;
-}
-
-cairo_surface_t* RedirectedXCompositeWindow::cairoSurfaceForWidget(GtkWidget* widget)
-{
-    if (!m_needsNewPixmapAfterResize && m_surface)
-        return m_surface.get();
-
-    m_needsNewPixmapAfterResize = false;
-
-    // It's important that the new pixmap be created with the same Display pointer as the target
-    // widget or else drawing speed can be 100x slower.
-    Display* newPixmapDisplay = GDK_DISPLAY_XDISPLAY(gtk_widget_get_display(widget));
-    Pixmap newPixmap = XCompositeNameWindowPixmap(newPixmapDisplay, m_window);
-    if (!newPixmap) {
-        cleanupPixmapAndPixmapSurface();
-        return 0;
-    }
-
-    XWindowAttributes windowAttributes;
-    if (!XGetWindowAttributes(newPixmapDisplay, m_window, &windowAttributes)) {
-        cleanupPixmapAndPixmapSurface();
-        XFreePixmap(newPixmapDisplay, newPixmap);
-        return 0;
-    }
-
-    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_xlib_surface_create(newPixmapDisplay, newPixmap,
-                                                                            windowAttributes.visual,
-                                                                            m_size.width(), m_size.height()));
-
-    // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
-    // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
-    // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
-    // pixmap to the new one to properly initialize it.
-    if (m_surface) {
-        RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
-        cairo_set_source_rgb(cr.get(), 1, 1, 1);
-        cairo_paint(cr.get());
-        cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
-        cairo_paint(cr.get());
-    }
-
-    cleanupPixmapAndPixmapSurface();
-    m_pixmap = newPixmap;
-    m_surface = newSurface;
-
-    return m_surface.get();
-}
-
-void RedirectedXCompositeWindow::callDamageNotifyCallback()
-{
-    if (m_damageNotifyCallback)
-        m_damageNotifyCallback(m_damageNotifyData);
-}
-
-} // namespace WebCore
-
-#endif // USE(OPENGL) && PLATFORM(X11)

Deleted: trunk/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h (176015 => 176016)


--- trunk/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h	2014-11-12 11:25:16 UTC (rev 176015)
+++ trunk/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h	2014-11-12 12:13:10 UTC (rev 176016)
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2012, Igalia S.L.
- * All rights reserved.
- *
- * 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 APPLE INC. ``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 APPLE INC. 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.
- */
-
-#ifndef  RedirectedXCompositeWindow_h
-#define  RedirectedXCompositeWindow_h
-
-#if USE(OPENGL) && PLATFORM(X11)
-
-#include "GLContext.h"
-#include "IntSize.h"
-#include "RefPtrCairo.h"
-
-typedef unsigned long Pixmap;
-typedef unsigned long Window;
-typedef unsigned long Damage;
-typedef void (*DamageNotifyCallback)(void*);
-
-namespace WebCore {
-
-class RedirectedXCompositeWindow {
-public:
-    enum GLContextNeeded { CreateGLContext, DoNotCreateGLContext };
-    static PassOwnPtr<RedirectedXCompositeWindow> create(const IntSize&, GLContextNeeded = CreateGLContext);
-    virtual ~RedirectedXCompositeWindow();
-    const IntSize& size() { return m_size; }
-
-    void resize(const IntSize& newSize);
-    GLContext* context();
-    cairo_surface_t* cairoSurfaceForWidget(GtkWidget*);
-    Window windowId() { return m_window; }
-    void callDamageNotifyCallback();
-
-    void setDamageNotifyCallback(DamageNotifyCallback callback, void* data)
-    {
-        m_damageNotifyCallback = callback;
-        m_damageNotifyData = data;
-    }
-
-private:
-    RedirectedXCompositeWindow(const IntSize&, GLContextNeeded);
-    void cleanupPixmapAndPixmapSurface();
-
-    IntSize m_size;
-    Window m_window;
-    Window m_parentWindow;
-    Pixmap m_pixmap;
-    GLContextNeeded m_needsContext;
-    OwnPtr<GLContext> m_context;
-    RefPtr<cairo_surface_t> m_surface;
-    bool m_needsNewPixmapAfterResize;
-
-    Damage m_damage;
-    DamageNotifyCallback m_damageNotifyCallback;
-    void* m_damageNotifyData;
-};
-
-} // namespace WebCore
-
-#endif // USE(OPENGL) && PLATFORM(X11)
-
-#endif // RedirectedXCompositeWindow_h

Modified: trunk/Source/WebKit2/ChangeLog (176015 => 176016)


--- trunk/Source/WebKit2/ChangeLog	2014-11-12 11:25:16 UTC (rev 176015)
+++ trunk/Source/WebKit2/ChangeLog	2014-11-12 12:13:10 UTC (rev 176016)
@@ -1,3 +1,54 @@
+2014-11-12  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Move RedirectedXCompositeWindow from platform to WebKit2 layer
+        https://bugs.webkit.org/show_bug.cgi?id=138093
+
+        Reviewed by Martin Robinson.
+
+        It's only used by WebKitWebViewBase. While moving the code the
+        following cleanups have been made:
+
+          - Use NeverDestroyed instead of DEPRECATED_DEFINE_STATIC_LOCAL.
+          - Use a helper class XDamageNotifier to handle the XDamage
+            events filtering and notification.
+          - Use std::function instead of pointer to function for the
+            damage callback.
+          - Pass the X display to the RedirectedXCompositeWindow constructor
+            and keep it as a member to use it everywhere, instead of using
+            the default display in some places and the widget display in others.
+          - Pass the damage notify function as a contructor parameter of
+            RedirectedXCompositeWindow instead of setting the callback
+            right after creating the object.
+          - Remove GLContextNeeded and all the dead code related to the
+            CreateGLContext mode that is no longer used.
+          - Rename cairoSurfaceForWidget() as surface().
+          - windowId() has been renamed as windowID() and made const.
+          - Use std::unique_ptr instead of PassOwnPtr.
+          - Fix coding style issues.
+
+        * PlatformGTK.cmake:
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseConstructed):
+        (webkitWebViewRenderAcceleratedCompositingResults):
+        (webkitWebViewBaseCreateWebPage):
+        (redirectedWindowDamagedCallback): Deleted.
+        * UIProcess/gtk/RedirectedXCompositeWindow.cpp: Renamed from Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp.
+        (WebKit::XDamageNotifier::XDamageNotifier):
+        (WebKit::XDamageNotifier::add):
+        (WebKit::XDamageNotifier::remove):
+        (WebKit::XDamageNotifier::filterXDamageEvent):
+        (WebKit::XDamageNotifier::filterXEvent):
+        (WebKit::xDamageNotifier):
+        (WebKit::supportsXDamageAndXComposite):
+        (WebKit::RedirectedXCompositeWindow::create):
+        (WebKit::RedirectedXCompositeWindow::RedirectedXCompositeWindow):
+        (WebKit::RedirectedXCompositeWindow::~RedirectedXCompositeWindow):
+        (WebKit::RedirectedXCompositeWindow::resize):
+        (WebKit::RedirectedXCompositeWindow::cleanupPixmapAndPixmapSurface):
+        (WebKit::RedirectedXCompositeWindow::surface):
+        * UIProcess/gtk/RedirectedXCompositeWindow.h: Renamed from Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h.
+        (WebKit::RedirectedXCompositeWindow::windowID):
+
 2014-09-01  Philippe Normand  <[email protected]>
 
         [WK2] UserMediaClient support

Modified: trunk/Source/WebKit2/PlatformGTK.cmake (176015 => 176016)


--- trunk/Source/WebKit2/PlatformGTK.cmake	2014-11-12 11:25:16 UTC (rev 176015)
+++ trunk/Source/WebKit2/PlatformGTK.cmake	2014-11-12 12:13:10 UTC (rev 176016)
@@ -253,6 +253,7 @@
     UIProcess/gtk/ExperimentalFeatures.cpp
     UIProcess/gtk/GestureController.cpp
     UIProcess/gtk/InputMethodFilter.cpp
+    UIProcess/gtk/RedirectedXCompositeWindow.cpp
     UIProcess/gtk/TextCheckerGtk.cpp
     UIProcess/gtk/WebContextGtk.cpp
     UIProcess/gtk/WebContextMenuProxyGtk.cpp

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp (176015 => 176016)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp	2014-11-12 11:25:16 UTC (rev 176015)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp	2014-11-12 12:13:10 UTC (rev 176016)
@@ -34,6 +34,7 @@
 #include "NativeWebMouseEvent.h"
 #include "NativeWebWheelEvent.h"
 #include "PageClientImpl.h"
+#include "RedirectedXCompositeWindow.h"
 #include "ViewState.h"
 #include "WebContext.h"
 #include "WebEventFactory.h"
@@ -70,10 +71,6 @@
 #include "WebFullScreenManagerProxy.h"
 #endif
 
-#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
-#include <WebCore/RedirectedXCompositeWindow.h>
-#endif
-
 // gtk_widget_get_scale_factor() appeared in GTK 3.10, but we also need
 // to make sure we have cairo new enough to support cairo_surface_set_device_scale
 #define HAVE_GTK_SCALE_FACTOR HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE && GTK_CHECK_VERSION(3, 10, 0)
@@ -84,10 +81,6 @@
 typedef HashMap<GtkWidget*, IntRect> WebKitWebViewChildrenMap;
 typedef HashMap<uint32_t, GUniquePtr<GdkEvent>> TouchEventsMap;
 
-#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
-void redirectedWindowDamagedCallback(void* data);
-#endif
-
 struct _WebKitWebViewBasePrivate {
     WebKitWebViewChildrenMap children;
     std::unique_ptr<PageClientImpl> pageClient;
@@ -132,7 +125,7 @@
 #endif
 
 #if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
-    OwnPtr<RedirectedXCompositeWindow> redirectedWindow;
+    std::unique_ptr<RedirectedXCompositeWindow> redirectedWindow;
 #endif
 
 #if ENABLE(DRAG_SUPPORT)
@@ -437,11 +430,8 @@
 
 #if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
     GdkDisplay* display = gdk_display_manager_get_default_display(gdk_display_manager_get());
-    if (GDK_IS_X11_DISPLAY(display)) {
-        priv->redirectedWindow = RedirectedXCompositeWindow::create(IntSize(1, 1), RedirectedXCompositeWindow::DoNotCreateGLContext);
-        if (priv->redirectedWindow)
-            priv->redirectedWindow->setDamageNotifyCallback(redirectedWindowDamagedCallback, object);
-    }
+    if (GDK_IS_X11_DISPLAY(display))
+        priv->redirectedWindow = RedirectedXCompositeWindow::create(GDK_DISPLAY_XDISPLAY(display), IntSize(1, 1), [viewWidget] { gtk_widget_queue_draw(viewWidget); });
 #endif
 
     priv->authenticationDialog = 0;
@@ -460,10 +450,12 @@
     if (!priv->redirectedWindow)
         return false;
 
-    cairo_rectangle(cr, clipRect->x, clipRect->y, clipRect->width, clipRect->height);
-    cairo_surface_t* surface = priv->redirectedWindow->cairoSurfaceForWidget(GTK_WIDGET(webViewBase));
-    cairo_set_source_surface(cr, surface, 0, 0);
-    cairo_fill(cr);
+    if (cairo_surface_t* surface = priv->redirectedWindow->surface()) {
+        cairo_rectangle(cr, clipRect->x, clipRect->y, clipRect->width, clipRect->height);
+        cairo_set_source_surface(cr, surface, 0, 0);
+        cairo_fill(cr);
+    }
+
     return true;
 #else
     return false;
@@ -1065,7 +1057,7 @@
 
 #if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
     if (priv->redirectedWindow)
-        priv->pageProxy->setAcceleratedCompositingWindowId(priv->redirectedWindow->windowId());
+        priv->pageProxy->setAcceleratedCompositingWindowId(priv->redirectedWindow->windowID());
 #endif
 
 #if HAVE(GTK_SCALE_FACTOR)
@@ -1182,13 +1174,6 @@
     return webkitWebViewBase->priv->contextMenuEvent.release();
 }
 
-#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
-void redirectedWindowDamagedCallback(void* data)
-{
-    gtk_widget_queue_draw(GTK_WIDGET(data));
-}
-#endif
-
 void webkitWebViewBaseSetFocus(WebKitWebViewBase* webViewBase, bool focused)
 {
     WebKitWebViewBasePrivate* priv = webViewBase->priv;

Copied: trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp (from rev 176015, trunk/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.cpp) (0 => 176016)


--- trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.cpp	2014-11-12 12:13:10 UTC (rev 176016)
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2012,2014 Igalia S.L.
+ * All rights reserved.
+ *
+ * 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 APPLE INC. ``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 APPLE INC. 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 "config.h"
+#include "RedirectedXCompositeWindow.h"
+
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
+
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xdamage.h>
+#include <cairo-xlib.h>
+#include <gdk/gdkx.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
+
+using namespace WebCore;
+
+namespace WebKit {
+
+class XDamageNotifier {
+    WTF_MAKE_NONCOPYABLE(XDamageNotifier);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static int s_damageEventBase;
+
+    XDamageNotifier()
+    {
+    }
+
+    void add(Window window, std::function<void()> notifyFunction)
+    {
+        if (m_notifyFunctions.isEmpty())
+            gdk_window_add_filter(nullptr, reinterpret_cast<GdkFilterFunc>(&filterXDamageEvent), this);
+        m_notifyFunctions.add(window, WTF::move(notifyFunction));
+    }
+
+    void remove(Window window)
+    {
+        m_notifyFunctions.remove(window);
+        if (m_notifyFunctions.isEmpty())
+            gdk_window_remove_filter(nullptr, reinterpret_cast<GdkFilterFunc>(&filterXDamageEvent), this);
+    }
+
+private:
+    static GdkFilterReturn filterXDamageEvent(GdkXEvent* event, GdkEvent*, XDamageNotifier* notifier)
+    {
+        return notifier->filterXEvent(static_cast<XEvent*>(event));
+    }
+
+    GdkFilterReturn filterXEvent(XEvent* event) const
+    {
+        if (event->type != s_damageEventBase + XDamageNotify)
+            return GDK_FILTER_CONTINUE;
+
+        XDamageNotifyEvent* damageEvent = reinterpret_cast<XDamageNotifyEvent*>(event);
+        if (const auto& notifyFunction = m_notifyFunctions.get(damageEvent->drawable)) {
+            notifyFunction();
+            XDamageSubtract(event->xany.display, damageEvent->damage, None, None);
+            return GDK_FILTER_REMOVE;
+        }
+
+        return GDK_FILTER_CONTINUE;
+    }
+
+    HashMap<Window, std::function<void()>> m_notifyFunctions;
+};
+
+int XDamageNotifier::s_damageEventBase = 0;
+
+static XDamageNotifier& xDamageNotifier()
+{
+    static NeverDestroyed<XDamageNotifier> notifier;
+    return notifier;
+}
+
+static bool supportsXDamageAndXComposite(Display* display)
+{
+    static bool initialized = false;
+    static bool hasExtensions = false;
+
+    if (initialized)
+        return hasExtensions;
+
+    initialized = true;
+
+    int errorBase;
+    if (!XDamageQueryExtension(display, &XDamageNotifier::s_damageEventBase, &errorBase))
+        return false;
+
+    int eventBase;
+    if (!XCompositeQueryExtension(display, &eventBase, &errorBase))
+        return false;
+
+    // We need to support XComposite version 0.2.
+    int major, minor;
+    XCompositeQueryVersion(display, &major, &minor);
+    if (major < 0 || (!major && minor < 2))
+        return false;
+
+    hasExtensions = true;
+    return true;
+}
+
+std::unique_ptr<RedirectedXCompositeWindow> RedirectedXCompositeWindow::create(Display* display, const IntSize& size, std::function<void()> damageNotify)
+{
+    return supportsXDamageAndXComposite(display) ? std::unique_ptr<RedirectedXCompositeWindow>(new RedirectedXCompositeWindow(display, size, damageNotify)) : nullptr;
+}
+
+RedirectedXCompositeWindow::RedirectedXCompositeWindow(Display* display, const IntSize& size, std::function<void()> damageNotify)
+    : m_display(display)
+    , m_size(size)
+    , m_window(0)
+    , m_parentWindow(0)
+    , m_pixmap(0)
+    , m_damage(0)
+    , m_needsNewPixmapAfterResize(false)
+{
+    Screen* screen = DefaultScreenOfDisplay(display);
+
+    // This is based on code from Chromium: src/content/common/gpu/image_transport_surface_linux.cc
+    XSetWindowAttributes windowAttributes;
+    windowAttributes.override_redirect = True;
+    m_parentWindow = XCreateWindow(display,
+        RootWindowOfScreen(screen),
+        WidthOfScreen(screen) + 1, 0, 1, 1,
+        0,
+        CopyFromParent,
+        InputOutput,
+        CopyFromParent,
+        CWOverrideRedirect,
+        &windowAttributes);
+    XMapWindow(display, m_parentWindow);
+
+    windowAttributes.event_mask = StructureNotifyMask;
+    windowAttributes.override_redirect = False;
+    m_window = XCreateWindow(display,
+        m_parentWindow,
+        0, 0, size.width(), size.height(),
+        0,
+        CopyFromParent,
+        InputOutput,
+        CopyFromParent,
+        CWEventMask,
+        &windowAttributes);
+    XMapWindow(display, m_window);
+
+    xDamageNotifier().add(m_window, WTF::move(damageNotify));
+
+    while (1) {
+        XEvent event;
+        XWindowEvent(display, m_window, StructureNotifyMask, &event);
+        if (event.type == MapNotify && event.xmap.window == m_window)
+            break;
+    }
+    XSelectInput(display, m_window, NoEventMask);
+    XCompositeRedirectWindow(display, m_window, CompositeRedirectManual);
+    m_damage = XDamageCreate(display, m_window, XDamageReportNonEmpty);
+}
+
+RedirectedXCompositeWindow::~RedirectedXCompositeWindow()
+{
+    ASSERT(m_display);
+    ASSERT(m_damage);
+    ASSERT(m_window);
+    ASSERT(m_parentWindow);
+
+    xDamageNotifier().remove(m_window);
+
+    XDamageDestroy(m_display, m_damage);
+    XDestroyWindow(m_display, m_window);
+    XDestroyWindow(m_display, m_parentWindow);
+    cleanupPixmapAndPixmapSurface();
+}
+
+void RedirectedXCompositeWindow::resize(const IntSize& size)
+{
+    XResizeWindow(m_display, m_window, size.width(), size.height());
+    XFlush(m_display);
+
+    m_size = size;
+    m_needsNewPixmapAfterResize = true;
+}
+
+void RedirectedXCompositeWindow::cleanupPixmapAndPixmapSurface()
+{
+    if (!m_pixmap)
+        return;
+
+    XFreePixmap(m_display, m_pixmap);
+    m_pixmap = 0;
+    m_surface = nullptr;
+}
+
+cairo_surface_t* RedirectedXCompositeWindow::surface()
+{
+    if (!m_needsNewPixmapAfterResize && m_surface)
+        return m_surface.get();
+
+    m_needsNewPixmapAfterResize = false;
+
+    Pixmap newPixmap = XCompositeNameWindowPixmap(m_display, m_window);
+    if (!newPixmap) {
+        cleanupPixmapAndPixmapSurface();
+        return nullptr;
+    }
+
+    XWindowAttributes windowAttributes;
+    if (!XGetWindowAttributes(m_display, m_window, &windowAttributes)) {
+        cleanupPixmapAndPixmapSurface();
+        XFreePixmap(m_display, newPixmap);
+        return nullptr;
+    }
+
+    RefPtr<cairo_surface_t> newSurface = adoptRef(cairo_xlib_surface_create(m_display, newPixmap, windowAttributes.visual, m_size.width(), m_size.height()));
+
+    // Nvidia drivers seem to prepare their redirected window pixmap asynchronously, so for a few fractions
+    // of a second after each resize, while doing continuous resizing (which constantly destroys and creates
+    // pixmap window-backings), the pixmap memory is uninitialized. To work around this issue, paint the old
+    // pixmap to the new one to properly initialize it.
+    if (m_surface) {
+        RefPtr<cairo_t> cr = adoptRef(cairo_create(newSurface.get()));
+        cairo_set_source_rgb(cr.get(), 1, 1, 1);
+        cairo_paint(cr.get());
+        cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
+        cairo_paint(cr.get());
+    }
+
+    cleanupPixmapAndPixmapSurface();
+    m_pixmap = newPixmap;
+    m_surface = newSurface;
+    return m_surface.get();
+}
+
+} // namespace WebCore
+
+#endif // USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)

Copied: trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.h (from rev 176015, trunk/Source/WebCore/platform/gtk/RedirectedXCompositeWindow.h) (0 => 176016)


--- trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.h	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/gtk/RedirectedXCompositeWindow.h	2014-11-12 12:13:10 UTC (rev 176016)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ * All rights reserved.
+ *
+ * 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 APPLE INC. ``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 APPLE INC. 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.
+ */
+
+#ifndef  RedirectedXCompositeWindow_h
+#define  RedirectedXCompositeWindow_h
+
+#if USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
+
+#include <WebCore/IntSize.h>
+#include <WebCore/RefPtrCairo.h>
+
+typedef struct _XDisplay Display;
+typedef unsigned long Damage;
+typedef unsigned long Pixmap;
+typedef unsigned long Window;
+
+namespace WebKit {
+
+class RedirectedXCompositeWindow {
+public:
+    static std::unique_ptr<RedirectedXCompositeWindow> create(Display*, const WebCore::IntSize&, std::function<void()> damageNotify);
+    ~RedirectedXCompositeWindow();
+
+    Window windowID() const { return m_window; }
+    void resize(const WebCore::IntSize&);
+    cairo_surface_t* surface();
+
+private:
+    RedirectedXCompositeWindow(Display*, const WebCore::IntSize&, std::function<void()> damageNotify);
+    void cleanupPixmapAndPixmapSurface();
+
+    Display* m_display;
+    WebCore::IntSize m_size;
+    Window m_window;
+    Window m_parentWindow;
+    Pixmap m_pixmap;
+    Damage m_damage;
+    RefPtr<cairo_surface_t> m_surface;
+    bool m_needsNewPixmapAfterResize;
+};
+
+} // namespace WebKit
+
+#endif // USE(TEXTURE_MAPPER_GL) && PLATFORM(X11)
+
+#endif // RedirectedXCompositeWindow_h
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to