Use OptionSet for layout milestones
[WebKit-https.git] / Source / WebKit / WebProcess / WebPage / mac / TiledCoreAnimationDrawingArea.mm
index d02ed72..e7627f4 100644 (file)
@@ -26,7 +26,7 @@
 #import "config.h"
 #import "TiledCoreAnimationDrawingArea.h"
 
-#if !PLATFORM(IOS)
+#if !PLATFORM(IOS_FAMILY)
 
 #import "ColorSpaceData.h"
 #import "DrawingAreaProxyMessages.h"
@@ -51,6 +51,7 @@
 #import <WebCore/RenderLayerBacking.h>
 #import <WebCore/RenderLayerCompositor.h>
 #import <WebCore/RenderView.h>
+#import <WebCore/RunLoopObserver.h>
 #import <WebCore/ScrollbarTheme.h>
 #import <WebCore/Settings.h>
 #import <WebCore/TiledBacking.h>
 + (void)synchronize;
 @end
 
-using namespace WebCore;
-
 namespace WebKit {
+using namespace WebCore;
 
 TiledCoreAnimationDrawingArea::TiledCoreAnimationDrawingArea(WebPage& webPage, const WebPageCreationParameters& parameters)
     : DrawingArea(DrawingAreaTypeTiledCoreAnimation, webPage)
     , m_layerTreeStateIsFrozen(false)
-    , m_layerFlushScheduler(this)
     , m_isPaintingSuspended(!(parameters.activityState & ActivityState::IsVisible))
     , m_transientZoomScale(1)
     , m_sendDidUpdateActivityStateTimer(RunLoop::main(), this, &TiledCoreAnimationDrawingArea::didUpdateActivityStateTimerFired)
-    , m_wantsDidUpdateActivityState(false)
     , m_viewOverlayRootLayer(nullptr)
 {
     m_webPage.corePage()->settings().setForceCompositingMode(true);
@@ -91,19 +89,23 @@ TiledCoreAnimationDrawingArea::TiledCoreAnimationDrawingArea(WebPage& webPage, c
     [m_hostingLayer setOpaque:YES];
     [m_hostingLayer setGeometryFlipped:YES];
 
+    m_layerFlushRunLoopObserver = std::make_unique<WebCore::RunLoopObserver>(static_cast<CFIndex>(RunLoopObserver::WellKnownRunLoopOrders::LayerFlush), [this]() {
+        this->layerFlushRunLoopCallback();
+    });
+
     updateLayerHostingContext();
     setColorSpace(parameters.colorSpace);
 
-    attachDrawingArea();
+    if (!parameters.shouldDelayAttachingDrawingArea)
+        attach();
 }
 
 TiledCoreAnimationDrawingArea::~TiledCoreAnimationDrawingArea()
 {
-    m_layerFlushScheduler.invalidate();
+    invalidateLayerFlushRunLoopObserver();
 }
 
-
-void TiledCoreAnimationDrawingArea::attachDrawingArea()
+void TiledCoreAnimationDrawingArea::attach()
 {
     LayerTreeContext layerTreeContext;
     layerTreeContext.contextID = m_layerHostingContext->contextID();
@@ -171,10 +173,11 @@ void TiledCoreAnimationDrawingArea::setLayerTreeStateIsFrozen(bool layerTreeStat
         return;
 
     m_layerTreeStateIsFrozen = layerTreeStateIsFrozen;
+
     if (m_layerTreeStateIsFrozen)
-        m_layerFlushScheduler.suspend();
+        invalidateLayerFlushRunLoopObserver();
     else
-        m_layerFlushScheduler.resume();
+        scheduleLayerFlushRunLoopObserver();
 }
 
 bool TiledCoreAnimationDrawingArea::layerTreeStateIsFrozen() const
@@ -184,7 +187,10 @@ bool TiledCoreAnimationDrawingArea::layerTreeStateIsFrozen() const
 
 void TiledCoreAnimationDrawingArea::scheduleCompositingLayerFlush()
 {
-    m_layerFlushScheduler.schedule();
+    if (m_layerTreeStateIsFrozen)
+        return;
+
+    scheduleLayerFlushRunLoopObserver();
 }
 
 void TiledCoreAnimationDrawingArea::scheduleCompositingLayerFlushImmediately()
@@ -375,7 +381,7 @@ void TiledCoreAnimationDrawingArea::dispatchAfterEnsuringUpdatedScrollPosition(W
     m_webPage.corePage()->scrollingCoordinator()->commitTreeStateIfNeeded();
 
     if (!m_layerTreeStateIsFrozen)
-        m_layerFlushScheduler.suspend();
+        invalidateLayerFlushRunLoopObserver();
 
     // It is possible for the drawing area to be destroyed before the bound block
     // is invoked, so grab a reference to the web page here so we can access the drawing area through it.
@@ -390,7 +396,7 @@ void TiledCoreAnimationDrawingArea::dispatchAfterEnsuringUpdatedScrollPosition(W
         function();
 
         if (!m_layerTreeStateIsFrozen)
-            m_layerFlushScheduler.resume();
+            scheduleLayerFlushRunLoopObserver();
 
         webPage->deref();
     });
@@ -405,7 +411,7 @@ void TiledCoreAnimationDrawingArea::sendPendingNewlyReachedLayoutMilestones()
         return;
 
     m_webPage.send(Messages::WebPageProxy::DidReachLayoutMilestone(m_pendingNewlyReachedLayoutMilestones));
-    m_pendingNewlyReachedLayoutMilestones = 0;
+    m_pendingNewlyReachedLayoutMilestones = { };
 }
 
 void TiledCoreAnimationDrawingArea::addTransactionCallbackID(CallbackID callbackID)
@@ -416,13 +422,15 @@ void TiledCoreAnimationDrawingArea::addTransactionCallbackID(CallbackID callback
 
 bool TiledCoreAnimationDrawingArea::flushLayers()
 {
-    ASSERT(!m_layerTreeStateIsFrozen);
+    if (layerTreeStateIsFrozen())
+        return false;
 
     @autoreleasepool {
         scaleViewToFitDocumentIfNeeded();
 
         m_webPage.layoutIfNeeded();
         m_webPage.flushPendingEditorStateUpdate();
+        m_webPage.willDisplayPage();
 
         updateIntrinsicContentSizeIfNeeded();
 
@@ -469,10 +477,10 @@ bool TiledCoreAnimationDrawingArea::flushLayers()
     }
 }
 
-void TiledCoreAnimationDrawingArea::activityStateDidChange(ActivityState::Flags changed, bool wantsDidUpdateActivityState, const Vector<CallbackID>& nextActivityStateChangeCallbackIDs)
+void TiledCoreAnimationDrawingArea::activityStateDidChange(OptionSet<WebCore::ActivityState::Flag> changed, ActivityStateChangeID activityStateChangeID, const Vector<CallbackID>& nextActivityStateChangeCallbackIDs)
 {
     m_nextActivityStateChangeCallbackIDs.appendVector(nextActivityStateChangeCallbackIDs);
-    m_wantsDidUpdateActivityState |= wantsDidUpdateActivityState;
+    m_activityStateChangeID = std::max(m_activityStateChangeID, activityStateChangeID);
 
     if (changed & ActivityState::IsVisible) {
         if (m_webPage.isVisible())
@@ -481,7 +489,7 @@ void TiledCoreAnimationDrawingArea::activityStateDidChange(ActivityState::Flags
             suspendPainting();
     }
 
-    if (m_wantsDidUpdateActivityState || !m_nextActivityStateChangeCallbackIDs.isEmpty())
+    if (m_activityStateChangeID != ActivityStateChangeAsynchronous || !m_nextActivityStateChangeCallbackIDs.isEmpty())
         m_sendDidUpdateActivityStateTimer.startOneShot(0_s);
 }
 
@@ -489,14 +497,14 @@ void TiledCoreAnimationDrawingArea::didUpdateActivityStateTimerFired()
 {
     [CATransaction flush];
 
-    if (m_wantsDidUpdateActivityState)
+    if (m_activityStateChangeID != ActivityStateChangeAsynchronous)
         m_webPage.send(Messages::WebPageProxy::DidUpdateActivityState());
 
     for (auto callbackID : m_nextActivityStateChangeCallbackIDs)
         m_webPage.send(Messages::WebPageProxy::VoidCallback(callbackID));
 
     m_nextActivityStateChangeCallbackIDs.clear();
-    m_wantsDidUpdateActivityState = false;
+    m_activityStateChangeID = ActivityStateChangeAsynchronous;
 }
 
 void TiledCoreAnimationDrawingArea::suspendPainting()
@@ -535,7 +543,7 @@ void TiledCoreAnimationDrawingArea::updateScrolledExposedRect()
 
     m_scrolledViewExposedRect = m_viewExposedRect;
 
-#if !PLATFORM(IOS)
+#if !PLATFORM(IOS_FAMILY)
     if (m_viewExposedRect) {
         ScrollOffset scrollOffset = frameView->scrollOffsetFromPosition(frameView->scrollPosition());
         m_scrolledViewExposedRect.value().moveBy(scrollOffset);
@@ -567,8 +575,7 @@ void TiledCoreAnimationDrawingArea::updateGeometry(const IntSize& viewSize, bool
         size = contentSize;
     }
 
-    if (!m_layerTreeStateIsFrozen)
-        flushLayers();
+    flushLayers();
 
     [CATransaction begin];
     [CATransaction setDisableActions:YES];
@@ -845,7 +852,7 @@ void TiledCoreAnimationDrawingArea::commitTransientZoom(double scale, FloatPoint
         RetainPtr<CABasicAnimation> shadowPositionAnimation = transientZoomSnapAnimationForKeyPath("position");
         [shadowPositionAnimation setToValue:[NSValue valueWithPoint:shadowLayerPositionForFrame(frameView, constrainedOrigin)]];
         RetainPtr<CABasicAnimation> shadowPathAnimation = transientZoomSnapAnimationForKeyPath("shadowPath");
-        [shadowPathAnimation setToValue:(id)shadowPath.get()];
+        [shadowPathAnimation setToValue:(__bridge id)shadowPath.get()];
 
         [shadowCALayer addAnimation:shadowBoundsAnimation.get() forKey:@"transientZoomCommitShadowBounds"];
         [shadowCALayer addAnimation:shadowPositionAnimation.get() forKey:@"transientZoomCommitShadowPosition"];
@@ -883,12 +890,28 @@ void TiledCoreAnimationDrawingArea::addFence(const MachSendRight& fencePort)
     m_layerHostingContext->setFencePort(fencePort.sendRight());
 }
 
-bool TiledCoreAnimationDrawingArea::dispatchDidReachLayoutMilestone(WebCore::LayoutMilestones layoutMilestones)
+bool TiledCoreAnimationDrawingArea::dispatchDidReachLayoutMilestone(OptionSet<WebCore::LayoutMilestone> layoutMilestones)
 {
-    m_pendingNewlyReachedLayoutMilestones |= layoutMilestones;
+    m_pendingNewlyReachedLayoutMilestones.add(layoutMilestones);
     return true;
 }
 
+void TiledCoreAnimationDrawingArea::layerFlushRunLoopCallback()
+{
+    if (flushLayers())
+        invalidateLayerFlushRunLoopObserver();
+}
+
+void TiledCoreAnimationDrawingArea::invalidateLayerFlushRunLoopObserver()
+{
+    m_layerFlushRunLoopObserver->invalidate();
+}
+
+void TiledCoreAnimationDrawingArea::scheduleLayerFlushRunLoopObserver()
+{
+    m_layerFlushRunLoopObserver->schedule(CFRunLoopGetCurrent());
+}
+
 } // namespace WebKit
 
-#endif // !PLATFORM(IOS)
+#endif // !PLATFORM(IOS_FAMILY)