[Threaded Compositor] Flickering and rendering artifacts when resizing the web view
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Jun 2016 07:48:54 +0000 (07:48 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Jun 2016 07:48:54 +0000 (07:48 +0000)
https://bugs.webkit.org/show_bug.cgi?id=154070

Reviewed by Žan Doberšek.

Resizing the web view is expected to be a sync operation, the UI process creates a new backing store state ID,
sends UpdateBackingStoreState message with the flag RespondImmediately to the web process and waits up to 500ms
for the reply (DidUpdateBackingStoreState message). When using the threaded compositor, we schedule a task in
the compositing thread to update the viewport size, and return immediately, so that we reply to the UI process
before the compositing thread has actually updated its size. There's a moment in which sizes are out of sync
causing the flickering and rendering artifacts, the UI process continues rendering at the new size, while the
web process is still rendering at the previous size. We can prevent this from happening just by making the
resize task synchronous in the threaded compositor.

* Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp:
(WebKit::CompositingRunLoop::performTaskSync): Add sync version of performTask().
* Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h:
* Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
(WebKit::ThreadedCompositor::didChangeViewportSize): Use performTaskSync().

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

Source/WebKit2/ChangeLog
Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp
Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h
Source/WebKit2/Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp

index f0c7f98..6f88d95 100644 (file)
@@ -1,5 +1,27 @@
 2016-06-14  Carlos Garcia Campos  <cgarcia@igalia.com>
 
+        [Threaded Compositor] Flickering and rendering artifacts when resizing the web view
+        https://bugs.webkit.org/show_bug.cgi?id=154070
+
+        Reviewed by Žan Doberšek.
+
+        Resizing the web view is expected to be a sync operation, the UI process creates a new backing store state ID,
+        sends UpdateBackingStoreState message with the flag RespondImmediately to the web process and waits up to 500ms
+        for the reply (DidUpdateBackingStoreState message). When using the threaded compositor, we schedule a task in
+        the compositing thread to update the viewport size, and return immediately, so that we reply to the UI process
+        before the compositing thread has actually updated its size. There's a moment in which sizes are out of sync
+        causing the flickering and rendering artifacts, the UI process continues rendering at the new size, while the
+        web process is still rendering at the previous size. We can prevent this from happening just by making the
+        resize task synchronous in the threaded compositor.
+
+        * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.cpp:
+        (WebKit::CompositingRunLoop::performTaskSync): Add sync version of performTask().
+        * Shared/CoordinatedGraphics/threadedcompositor/CompositingRunLoop.h:
+        * Shared/CoordinatedGraphics/threadedcompositor/ThreadedCompositor.cpp:
+        (WebKit::ThreadedCompositor::didChangeViewportSize): Use performTaskSync().
+
+2016-06-14  Carlos Garcia Campos  <cgarcia@igalia.com>
+
         Unreviewed. Fix Soup downloads after r201943.
 
         This is a follow up of r201943. The DownloadClient used in DownloadSoup was not updated to the new API of the
index f059010..f4ace10 100644 (file)
@@ -37,7 +37,6 @@ CompositingRunLoop::CompositingRunLoop(std::function<void ()>&& updateFunction)
     : m_runLoop(RunLoop::current())
     , m_updateTimer(m_runLoop, this, &CompositingRunLoop::updateTimerFired)
     , m_updateFunction(WTFMove(updateFunction))
-    , m_lastUpdateTime(0)
 {
 }
 
@@ -47,6 +46,18 @@ void CompositingRunLoop::performTask(std::function<void ()>&& function)
     m_runLoop.dispatch(WTFMove(function));
 }
 
+void CompositingRunLoop::performTaskSync(std::function<void ()>&& function)
+{
+    ASSERT(isMainThread());
+    LockHolder locker(m_dispatchSyncConditionMutex);
+    m_runLoop.dispatch([this, function = WTFMove(function)] {
+        LockHolder locker(m_dispatchSyncConditionMutex);
+        function();
+        m_dispatchSyncCondition.notifyOne();
+    });
+    m_dispatchSyncCondition.wait(m_dispatchSyncConditionMutex);
+}
+
 void CompositingRunLoop::setUpdateTimer(UpdateTiming timing)
 {
     if (m_updateTimer.isActive())
index 3860a28..fc0f95c 100644 (file)
@@ -47,6 +47,7 @@ public:
     CompositingRunLoop(std::function<void ()>&&);
 
     void performTask(std::function<void ()>&&);
+    void performTaskSync(std::function<void ()>&&);
 
     void setUpdateTimer(UpdateTiming timing = Immediate);
     void stopUpdateTimer();
@@ -59,8 +60,10 @@ private:
     RunLoop& m_runLoop;
     RunLoop::Timer<CompositingRunLoop> m_updateTimer;
     std::function<void ()> m_updateFunction;
+    Lock m_dispatchSyncConditionMutex;
+    Condition m_dispatchSyncCondition;
 
-    double m_lastUpdateTime;
+    double m_lastUpdateTime { 0 };
 };
 
 } // namespace WebKit
index e70491f..1c68e67 100644 (file)
@@ -82,7 +82,7 @@ void ThreadedCompositor::setDeviceScaleFactor(float scale)
 void ThreadedCompositor::didChangeViewportSize(const IntSize& size)
 {
     RefPtr<ThreadedCompositor> protector(this);
-    m_compositingRunLoop->performTask([protector, size] {
+    m_compositingRunLoop->performTaskSync([protector, size] {
         protector->viewportController()->didChangeViewportSize(size);
     });
 }