Changeset 266634 in webkit
- Timestamp:
- Sep 4, 2020 1:17:21 PM (4 years ago)
- Location:
- trunk/Source
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/PAL/ChangeLog
r266133 r266634 1 2020-09-04 Sihui Liu <sihui_liu@apple.com> 2 3 Webpages flash when switching between windows 4 https://bugs.webkit.org/show_bug.cgi?id=216012 5 6 Reviewed by Tim Horton. 7 8 * pal/spi/cocoa/QuartzCoreSPI.h: 9 1 10 2020-08-25 Alex Christensen <achristensen@webkit.org> 2 11 -
trunk/Source/WebCore/PAL/pal/spi/cocoa/QuartzCoreSPI.h
r261153 r266634 144 144 + (CATransactionPhase)currentPhase; 145 145 + (void)synchronize; 146 + (uint32_t)currentState; 146 147 @end 147 148 -
trunk/Source/WebKit/ChangeLog
r266613 r266634 1 2020-09-04 Sihui Liu <sihui_liu@apple.com> 2 3 Webpages flash when switching between windows 4 https://bugs.webkit.org/show_bug.cgi?id=216012 5 6 Reviewed by Tim Horton. 7 8 Based on patches from Tim Horton. To avoid flash, we need to make sure view to be selected updates its content 9 before UI process commits its transaction. We did this by making UI process block until receiving a reply 10 DidUpdateActivityState from web process. However, web process did not make sure the reply would be sent after 11 normal rendering update and corresponding transasction commit. Instead, it flushed transactions in progress and 12 replied. To fix this, now we make web process reply in transaction commit handler after rendering update, if 13 there is an active transaction. 14 15 In the switching case, view to be unselected will detach from root layer in its web process, which makes its 16 content empty. This change is independent from the UI process commit, so we want this to happen after UI process 17 commits (which submits the view hierachy change). Otherwise, empty content(white flash) on the unselected view 18 will be displayed. To fix this, we let UI process send the activity state change message in transaction commit 19 handler, if there is an active transaction. 20 21 * UIProcess/Cocoa/WebPageProxyCocoa.mm: 22 (WebKit::WebPageProxy::scheduleActivityStateUpdate): 23 * UIProcess/WebPageProxy.cpp: 24 (WebKit::WebPageProxy::setSuppressVisibilityUpdates): 25 (WebKit::WebPageProxy::activityStateDidChange): 26 (WebKit::WebPageProxy::dispatchActivityStateChange): 27 * UIProcess/WebPageProxy.h: 28 * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h: 29 * WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm: 30 (WebKit::TiledCoreAnimationDrawingArea::TiledCoreAnimationDrawingArea): 31 (WebKit::TiledCoreAnimationDrawingArea::updateRendering): 32 (WebKit::TiledCoreAnimationDrawingArea::handleActivityStateChangeCallbacks): 33 (WebKit::TiledCoreAnimationDrawingArea::handleActivityStateChangeCallbacksIfNeeded): 34 (WebKit::TiledCoreAnimationDrawingArea::activityStateDidChange): 35 (WebKit::TiledCoreAnimationDrawingArea::didUpdateActivityStateTimerFired): Deleted. 36 1 37 2020-09-04 Per Arne Vollan <pvollan@apple.com> 2 38 -
trunk/Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm
r266412 r266634 46 46 #import <WebCore/LocalCurrentGraphicsContext.h> 47 47 #import <WebCore/NotImplemented.h> 48 #import <WebCore/RunLoopObserver.h> 48 49 #import <WebCore/SearchPopupMenuCocoa.h> 49 50 #import <WebCore/TextAlternativeWithRange.h> 50 51 #import <WebCore/ValidationBubble.h> 51 52 #import <pal/spi/cocoa/NEFilterSourceSPI.h> 53 #import <pal/spi/cocoa/QuartzCoreSPI.h> 52 54 #import <wtf/BlockPtr.h> 53 55 #import <wtf/SoftLinking.h> … … 488 490 #endif // HAVE(QUICKLOOK_THUMBNAILING) 489 491 492 void WebPageProxy::scheduleActivityStateUpdate() 493 { 494 bool hasScheduledObserver = m_activityStateChangeDispatcher->isScheduled(); 495 bool hasActiveCATransaction = [CATransaction currentState]; 496 497 if (hasScheduledObserver && hasActiveCATransaction) { 498 ASSERT(m_hasScheduledActivityStateUpdate); 499 m_hasScheduledActivityStateUpdate = false; 500 m_activityStateChangeDispatcher->invalidate(); 501 } 502 503 if (m_hasScheduledActivityStateUpdate) 504 return; 505 m_hasScheduledActivityStateUpdate = true; 506 507 // If there is an active transaction, we need to dispatch the update after the transaction is committed, 508 // to avoid flash caused by web process setting root layer too early. 509 // If there is no active transaction, likely there is no root layer change or change is committed, 510 // then schedule dispatch on runloop observer to collect changes in the same runloop cycle before dispatching. 511 if (hasActiveCATransaction) { 512 [CATransaction addCommitHandler:[weakThis = makeWeakPtr(*this)] { 513 auto protectedThis = makeRefPtr(weakThis.get()); 514 if (!protectedThis) 515 return; 516 517 protectedThis->dispatchActivityStateChange(); 518 } forPhase:kCATransactionPhasePostCommit]; 519 return; 520 } 521 522 m_activityStateChangeDispatcher->schedule(); 523 } 524 490 525 } // namespace WebKit 491 526 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r266412 r266634 1857 1857 if (!m_suppressVisibilityUpdates) { 1858 1858 #if PLATFORM(COCOA) 1859 m_activityStateChangeDispatcher->schedule();1859 scheduleActivityStateUpdate(); 1860 1860 #else 1861 1861 dispatchActivityStateChange(); … … 1909 1909 return; 1910 1910 } 1911 m_activityStateChangeDispatcher->schedule();1911 scheduleActivityStateUpdate(); 1912 1912 #else 1913 1913 UNUSED_PARAM(dispatchMode); … … 1938 1938 { 1939 1939 #if PLATFORM(COCOA) 1940 m_activityStateChangeDispatcher->invalidate(); 1940 if (m_activityStateChangeDispatcher->isScheduled()) 1941 m_activityStateChangeDispatcher->invalidate(); 1942 m_hasScheduledActivityStateUpdate = false; 1941 1943 #endif 1942 1944 -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r266576 r266634 899 899 bool scrollPerformanceDataCollectionEnabled() const { return m_scrollPerformanceDataCollectionEnabled; } 900 900 RemoteLayerTreeScrollingPerformanceData* scrollingPerformanceData() { return m_scrollingPerformanceData.get(); } 901 902 void scheduleActivityStateUpdate(); 901 903 #endif // PLATFORM(COCOA) 902 904 … … 2721 2723 std::unique_ptr<RemoteLayerTreeScrollingPerformanceData> m_scrollingPerformanceData; 2722 2724 bool m_scrollPerformanceDataCollectionEnabled { false }; 2725 2726 bool m_hasScheduledActivityStateUpdate { false }; 2723 2727 #endif 2724 2728 UserObservablePageCounter::Token m_pageIsUserObservableCount; -
trunk/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.h
r266412 r266634 85 85 86 86 void activityStateDidChange(OptionSet<WebCore::ActivityState::Flag> changed, ActivityStateChangeID, const Vector<CallbackID>&) override; 87 void didUpdateActivityStateTimerFired();88 87 89 88 void attachViewOverlayGraphicsLayer(WebCore::GraphicsLayer*) override; … … 109 108 void sendEnterAcceleratedCompositingModeIfNeeded() override; 110 109 void sendDidFirstLayerFlushIfNeeded(); 110 void handleActivityStateChangeCallbacksIfNeeded(); 111 void handleActivityStateChangeCallbacks(); 111 112 112 113 void adjustTransientZoom(double scale, WebCore::FloatPoint origin) override; … … 152 153 WebCore::FloatPoint m_transientZoomOrigin; 153 154 154 RunLoop::Timer<TiledCoreAnimationDrawingArea> m_sendDidUpdateActivityStateTimer;155 155 Vector<CallbackID> m_nextActivityStateChangeCallbackIDs; 156 156 ActivityStateChangeID m_activityStateChangeID { ActivityStateChangeAsynchronous }; … … 170 170 bool m_needsSendEnterAcceleratedCompositingMode { true }; 171 171 bool m_needsSendDidFirstLayerFlush { true }; 172 bool m_shouldHandleActivityStateChangeCallbacks { false }; 172 173 }; 173 174 -
trunk/Source/WebKit/WebProcess/WebPage/mac/TiledCoreAnimationDrawingArea.mm
r266412 r266634 74 74 TiledCoreAnimationDrawingArea::TiledCoreAnimationDrawingArea(WebPage& webPage, const WebPageCreationParameters& parameters) 75 75 : DrawingArea(DrawingAreaTypeTiledCoreAnimation, parameters.drawingAreaIdentifier, webPage) 76 , m_sendDidUpdateActivityStateTimer(RunLoop::main(), this, &TiledCoreAnimationDrawingArea::didUpdateActivityStateTimerFired)77 76 , m_isPaintingSuspended(!(parameters.activityState & ActivityState::IsVisible)) 78 77 { … … 493 492 494 493 sendDidFirstLayerFlushIfNeeded(); 494 handleActivityStateChangeCallbacksIfNeeded(); 495 495 invalidateRenderingUpdateRunLoopObserver(); 496 496 } 497 } 498 499 void TiledCoreAnimationDrawingArea::handleActivityStateChangeCallbacks() 500 { 501 if (!m_shouldHandleActivityStateChangeCallbacks) 502 return; 503 m_shouldHandleActivityStateChangeCallbacks = false; 504 505 if (m_activityStateChangeID != ActivityStateChangeAsynchronous) 506 m_webPage.send(Messages::WebPageProxy::DidUpdateActivityState()); 507 508 for (auto& callbackID : m_nextActivityStateChangeCallbackIDs) 509 m_webPage.send(Messages::WebPageProxy::VoidCallback(callbackID)); 510 m_nextActivityStateChangeCallbackIDs.clear(); 511 512 m_activityStateChangeID = ActivityStateChangeAsynchronous; 513 } 514 515 void TiledCoreAnimationDrawingArea::handleActivityStateChangeCallbacksIfNeeded() 516 { 517 if (!m_shouldHandleActivityStateChangeCallbacks) 518 return; 519 520 // If there is no active transaction, likely there is no layer change or change is committed, 521 // perform the callbacks immediately, which may unblock UI process. 522 if (![CATransaction currentState]) { 523 handleActivityStateChangeCallbacks(); 524 return; 525 } 526 527 [CATransaction addCommitHandler:[weakThis = makeWeakPtr(*this)] { 528 if (!weakThis) 529 return; 530 531 auto protectedPage = makeRef(weakThis->m_webPage); 532 auto* drawingArea = static_cast<TiledCoreAnimationDrawingArea*>(protectedPage->drawingArea()); 533 ASSERT(weakThis.get() == drawingArea); 534 if (drawingArea != weakThis.get()) 535 return; 536 537 drawingArea->handleActivityStateChangeCallbacks(); 538 } forPhase:kCATransactionPhasePostCommit]; 497 539 } 498 540 … … 510 552 511 553 if (m_activityStateChangeID != ActivityStateChangeAsynchronous || !m_nextActivityStateChangeCallbackIDs.isEmpty()) 512 m_sendDidUpdateActivityStateTimer.startOneShot(0_s); 513 } 514 515 void TiledCoreAnimationDrawingArea::didUpdateActivityStateTimerFired() 516 { 517 [CATransaction flush]; 518 519 if (m_activityStateChangeID != ActivityStateChangeAsynchronous) 520 m_webPage.send(Messages::WebPageProxy::DidUpdateActivityState()); 521 522 for (const auto& callbackID : m_nextActivityStateChangeCallbackIDs) 523 m_webPage.send(Messages::WebPageProxy::VoidCallback(callbackID)); 524 525 m_nextActivityStateChangeCallbackIDs.clear(); 526 m_activityStateChangeID = ActivityStateChangeAsynchronous; 554 m_shouldHandleActivityStateChangeCallbacks = true; 555 556 scheduleRenderingUpdate(); 527 557 } 528 558
Note: See TracChangeset
for help on using the changeset viewer.