Changeset 205075 in webkit


Ignore:
Timestamp:
Aug 27, 2016, 2:18:54 AM (9 years ago)
Author:
Carlos Garcia Campos
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:
Location:
trunk/Source/WebKit2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r205065 r205075  
     12016-08-27  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GTK][Threaded Compositor] Several flaky tests
     4        https://bugs.webkit.org/show_bug.cgi?id=161242
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        We still have a lot of flaky tests since we switched to the threaded compositor. The UI process might
     9        take the screenshot too early, before everything is actually painted. I can't reproduce the problem, so this is
     10        actually a speculative fix or workaround. Our implementation of DrawingArea::dispatchAfterEnsuringDrawing() is
     11        quite simple, we just dispatch the callback in the next run loop iteration, which doesn't really ensures any
     12        drawing at all. So, we can wait for draw events before dispatching the given callback. Since we don't really
     13        know if draw events were already processed before dispatchAfterEnsuringDrawing() is called, or if there will be
     14        more than one damage event in a short time, this patch waits up to 1 second for draw events, and if a draw
     15        happens it stops if there isn't another draw event in the next 100ms. This should ensure a drawing if it was
     16        really needed.
     17
     18        * UIProcess/DrawingAreaProxyImpl.cpp:
     19        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::DrawingMonitor):
     20        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::~DrawingMonitor):
     21        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::webViewDrawCallback):
     22        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::start):
     23        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::stop):
     24        (WebKit::DrawingAreaProxyImpl::DrawingMonitor::didDraw):
     25        (WebKit::DrawingAreaProxyImpl::dispatchAfterEnsuringDrawing):
     26        * UIProcess/DrawingAreaProxyImpl.h:
     27
    1282016-08-26  Sam Weinig  <sam@webkit.org>
    229
  • trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp

    r204249 r205075  
    3737#include <WebCore/Region.h>
    3838
     39#if PLATFORM(GTK)
     40#include <gtk/gtk.h>
     41#endif
     42
    3943using namespace WebCore;
    4044
     
    188192}
    189193
     194DrawingAreaProxyImpl::DrawingMonitor::DrawingMonitor(WebPageProxy& webPage)
     195    : m_webPage(webPage)
     196    , m_timer(RunLoop::main(), this, &DrawingMonitor::stop)
     197{
     198}
     199
     200DrawingAreaProxyImpl::DrawingMonitor::~DrawingMonitor()
     201{
     202    m_callback = nullptr;
     203    stop();
     204}
     205
     206int DrawingAreaProxyImpl::DrawingMonitor::webViewDrawCallback(DrawingAreaProxyImpl::DrawingMonitor* monitor)
     207{
     208    monitor->didDraw();
     209    return FALSE;
     210}
     211
     212void DrawingAreaProxyImpl::DrawingMonitor::start(std::function<void (CallbackBase::Error)> callback)
     213{
     214    m_startTime = monotonicallyIncreasingTimeMS();
     215    m_callback = callback;
     216#if PLATFORM(GTK)
     217    g_signal_connect_swapped(m_webPage.viewWidget(), "draw", reinterpret_cast<GCallback>(webViewDrawCallback), this);
     218    m_timer.startOneShot(1);
     219#else
     220    m_timer.startOneShot(0);
     221#endif
     222}
     223
     224void DrawingAreaProxyImpl::DrawingMonitor::stop()
     225{
     226    m_timer.stop();
     227#if PLATFORM(GTK)
     228    g_signal_handlers_disconnect_by_func(m_webPage.viewWidget(), reinterpret_cast<gpointer>(webViewDrawCallback), this);
     229#endif
     230    m_startTime = 0;
     231    if (m_callback) {
     232        m_callback(CallbackBase::Error::None);
     233        m_callback = nullptr;
     234    }
     235}
     236
     237void DrawingAreaProxyImpl::DrawingMonitor::didDraw()
     238{
     239    // We wait up to 1 second for draw events. If there are several draw events queued quickly,
     240    // we want to wait until all of them have been processed, so after receiving a draw, we wait
     241    // up to 100ms for the next one or stop.
     242    if (monotonicallyIncreasingTimeMS() - m_startTime > 1000)
     243        stop();
     244    else
     245        m_timer.startOneShot(0.100);
     246}
     247
     248void DrawingAreaProxyImpl::dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)> callbackFunction)
     249{
     250    if (!m_webPageProxy.isValid()) {
     251        callbackFunction(CallbackBase::Error::OwnerWasInvalidated);
     252        return;
     253    }
     254
     255    if (!m_drawingMonitor)
     256        m_drawingMonitor = std::make_unique<DrawingAreaProxyImpl::DrawingMonitor>(m_webPageProxy);
     257    m_drawingMonitor->start(callbackFunction);
     258}
     259
    190260} // namespace WebKit
  • trunk/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.h

    r204249 r205075  
    6161    void discardBackingStore();
    6262
     63    void dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)>) override;
     64
     65    class DrawingMonitor {
     66        WTF_MAKE_NONCOPYABLE(DrawingMonitor); WTF_MAKE_FAST_ALLOCATED;
     67    public:
     68        DrawingMonitor(WebPageProxy&);
     69        ~DrawingMonitor();
     70
     71        void start(std::function<void (CallbackBase::Error)>);
     72
     73    private:
     74        static int webViewDrawCallback(DrawingMonitor*);
     75
     76        void stop();
     77        void didDraw();
     78
     79        WebPageProxy& m_webPage;
     80        double m_startTime { 0 };
     81        std::function<void (CallbackBase::Error)> m_callback;
     82        RunLoop::Timer<DrawingMonitor> m_timer;
     83    };
     84
    6385    bool m_isBackingStoreDiscardable { true };
    6486    std::unique_ptr<BackingStore> m_backingStore;
    6587    RunLoop::Timer<DrawingAreaProxyImpl> m_discardBackingStoreTimer;
     88    std::unique_ptr<DrawingMonitor> m_drawingMonitor;
    6689};
    6790
Note: See TracChangeset for help on using the changeset viewer.