Title: [205075] trunk/Source/WebKit2
Revision
205075
Author
[email protected]
Date
2016-08-27 02:18:54 -0700 (Sat, 27 Aug 2016)

Log Message

[GTK][Threaded Compositor] Several flaky tests
https://bugs.webkit.org/show_bug.cgi?id=161242

Reviewed by Michael Catanzaro.

We still have a lot of flaky tests since we switched to the threaded compositor. The UI process might
take the screenshot too early, before everything is actually painted. I can't reproduce the problem, so this is
actually a speculative fix or workaround. Our implementation of DrawingArea::dispatchAfterEnsuringDrawing() is
quite simple, we just dispatch the callback in the next run loop iteration, which doesn't really ensures any
drawing at all. So, we can wait for draw events before dispatching the given callback. Since we don't really
know if draw events were already processed before dispatchAfterEnsuringDrawing() is called, or if there will be
more than one damage event in a short time, this patch waits up to 1 second for draw events, and if a draw
happens it stops if there isn't another draw event in the next 100ms. This should ensure a drawing if it was
really needed.

* UIProcess/DrawingAreaProxyImpl.cpp:
(WebKit::DrawingAreaProxyImpl::DrawingMonitor::DrawingMonitor):
(WebKit::DrawingAreaProxyImpl::DrawingMonitor::~DrawingMonitor):
(WebKit::DrawingAreaProxyImpl::DrawingMonitor::webViewDrawCallback):
(WebKit::DrawingAreaProxyImpl::DrawingMonitor::start):
(WebKit::DrawingAreaProxyImpl::DrawingMonitor::stop):
(WebKit::DrawingAreaProxyImpl::DrawingMonitor::didDraw):
(WebKit::DrawingAreaProxyImpl::dispatchAfterEnsuringDrawing):
* UIProcess/DrawingAreaProxyImpl.h:

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (205074 => 205075)


--- trunk/Source/WebKit2/ChangeLog	2016-08-27 05:47:44 UTC (rev 205074)
+++ trunk/Source/WebKit2/ChangeLog	2016-08-27 09:18:54 UTC (rev 205075)
@@ -1,3 +1,30 @@
+2016-08-27  Carlos Garcia Campos  <[email protected]>
+
+        [GTK][Threaded Compositor] Several flaky tests
+        https://bugs.webkit.org/show_bug.cgi?id=161242
+
+        Reviewed by Michael Catanzaro.
+
+        We still have a lot of flaky tests since we switched to the threaded compositor. The UI process might
+        take the screenshot too early, before everything is actually painted. I can't reproduce the problem, so this is
+        actually a speculative fix or workaround. Our implementation of DrawingArea::dispatchAfterEnsuringDrawing() is
+        quite simple, we just dispatch the callback in the next run loop iteration, which doesn't really ensures any
+        drawing at all. So, we can wait for draw events before dispatching the given callback. Since we don't really
+        know if draw events were already processed before dispatchAfterEnsuringDrawing() is called, or if there will be
+        more than one damage event in a short time, this patch waits up to 1 second for draw events, and if a draw
+        happens it stops if there isn't another draw event in the next 100ms. This should ensure a drawing if it was
+        really needed.
+
+        * UIProcess/DrawingAreaProxyImpl.cpp:
+        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::DrawingMonitor):
+        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::~DrawingMonitor):
+        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::webViewDrawCallback):
+        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::start):
+        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::stop):
+        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::didDraw):
+        (WebKit::DrawingAreaProxyImpl::dispatchAfterEnsuringDrawing):
+        * UIProcess/DrawingAreaProxyImpl.h:
+
 2016-08-26  Sam Weinig  <[email protected]>
 
         Remove support for ENABLE_LEGACY_WEB_AUDIO

Modified: trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp (205074 => 205075)


--- trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp	2016-08-27 05:47:44 UTC (rev 205074)
+++ trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp	2016-08-27 09:18:54 UTC (rev 205075)
@@ -36,6 +36,10 @@
 #include "WebProcessProxy.h"
 #include <WebCore/Region.h>
 
+#if PLATFORM(GTK)
+#include <gtk/gtk.h>
+#endif
+
 using namespace WebCore;
 
 namespace WebKit {
@@ -187,4 +191,70 @@
     backingStoreStateDidChange(DoNotRespondImmediately);
 }
 
+DrawingAreaProxyImpl::DrawingMonitor::DrawingMonitor(WebPageProxy& webPage)
+    : m_webPage(webPage)
+    , m_timer(RunLoop::main(), this, &DrawingMonitor::stop)
+{
+}
+
+DrawingAreaProxyImpl::DrawingMonitor::~DrawingMonitor()
+{
+    m_callback = nullptr;
+    stop();
+}
+
+int DrawingAreaProxyImpl::DrawingMonitor::webViewDrawCallback(DrawingAreaProxyImpl::DrawingMonitor* monitor)
+{
+    monitor->didDraw();
+    return FALSE;
+}
+
+void DrawingAreaProxyImpl::DrawingMonitor::start(std::function<void (CallbackBase::Error)> callback)
+{
+    m_startTime = monotonicallyIncreasingTimeMS();
+    m_callback = callback;
+#if PLATFORM(GTK)
+    g_signal_connect_swapped(m_webPage.viewWidget(), "draw", reinterpret_cast<GCallback>(webViewDrawCallback), this);
+    m_timer.startOneShot(1);
+#else
+    m_timer.startOneShot(0);
+#endif
+}
+
+void DrawingAreaProxyImpl::DrawingMonitor::stop()
+{
+    m_timer.stop();
+#if PLATFORM(GTK)
+    g_signal_handlers_disconnect_by_func(m_webPage.viewWidget(), reinterpret_cast<gpointer>(webViewDrawCallback), this);
+#endif
+    m_startTime = 0;
+    if (m_callback) {
+        m_callback(CallbackBase::Error::None);
+        m_callback = nullptr;
+    }
+}
+
+void DrawingAreaProxyImpl::DrawingMonitor::didDraw()
+{
+    // We wait up to 1 second for draw events. If there are several draw events queued quickly,
+    // we want to wait until all of them have been processed, so after receiving a draw, we wait
+    // up to 100ms for the next one or stop.
+    if (monotonicallyIncreasingTimeMS() - m_startTime > 1000)
+        stop();
+    else
+        m_timer.startOneShot(0.100);
+}
+
+void DrawingAreaProxyImpl::dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)> callbackFunction)
+{
+    if (!m_webPageProxy.isValid()) {
+        callbackFunction(CallbackBase::Error::OwnerWasInvalidated);
+        return;
+    }
+
+    if (!m_drawingMonitor)
+        m_drawingMonitor = std::make_unique<DrawingAreaProxyImpl::DrawingMonitor>(m_webPageProxy);
+    m_drawingMonitor->start(callbackFunction);
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h (205074 => 205075)


--- trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h	2016-08-27 05:47:44 UTC (rev 205074)
+++ trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h	2016-08-27 09:18:54 UTC (rev 205075)
@@ -60,9 +60,32 @@
     void discardBackingStoreSoon();
     void discardBackingStore();
 
+    void dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)>) override;
+
+    class DrawingMonitor {
+        WTF_MAKE_NONCOPYABLE(DrawingMonitor); WTF_MAKE_FAST_ALLOCATED;
+    public:
+        DrawingMonitor(WebPageProxy&);
+        ~DrawingMonitor();
+
+        void start(std::function<void (CallbackBase::Error)>);
+
+    private:
+        static int webViewDrawCallback(DrawingMonitor*);
+
+        void stop();
+        void didDraw();
+
+        WebPageProxy& m_webPage;
+        double m_startTime { 0 };
+        std::function<void (CallbackBase::Error)> m_callback;
+        RunLoop::Timer<DrawingMonitor> m_timer;
+    };
+
     bool m_isBackingStoreDiscardable { true };
     std::unique_ptr<BackingStore> m_backingStore;
     RunLoop::Timer<DrawingAreaProxyImpl> m_discardBackingStoreTimer;
+    std::unique_ptr<DrawingMonitor> m_drawingMonitor;
 };
 
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to