diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp')
-rw-r--r-- | Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp | 259 |
1 files changed, 80 insertions, 179 deletions
diff --git a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp index e8c45a709..1445354d7 100644 --- a/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp +++ b/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp @@ -36,28 +36,22 @@ #include "WebProcessProxy.h" #include <WebCore/Region.h> +#if PLATFORM(GTK) +#include <gtk/gtk.h> +#endif + using namespace WebCore; namespace WebKit { -DrawingAreaProxyImpl::DrawingAreaProxyImpl(WebPageProxy* webPageProxy) - : DrawingAreaProxy(DrawingAreaTypeImpl, webPageProxy) - , m_currentBackingStoreStateID(0) - , m_nextBackingStoreStateID(0) - , m_isWaitingForDidUpdateBackingStoreState(false) - , m_hasReceivedFirstUpdate(false) - , m_isBackingStoreDiscardable(true) +DrawingAreaProxyImpl::DrawingAreaProxyImpl(WebPageProxy& webPageProxy) + : AcceleratedDrawingAreaProxy(webPageProxy) , m_discardBackingStoreTimer(RunLoop::current(), this, &DrawingAreaProxyImpl::discardBackingStore) { } DrawingAreaProxyImpl::~DrawingAreaProxyImpl() { -#if USE(ACCELERATED_COMPOSITING) - // Make sure to exit accelerated compositing mode. - if (isInAcceleratedCompositingMode()) - exitAcceleratedCompositingMode(); -#endif } void DrawingAreaProxyImpl::paint(BackingStore::PlatformGraphicsContext context, const IntRect& rect, Region& unpaintedRegion) @@ -75,8 +69,8 @@ void DrawingAreaProxyImpl::paint(BackingStore::PlatformGraphicsContext context, // If we haven't yet received our first bits from the WebProcess then don't paint anything. if (!m_hasReceivedFirstUpdate) - return; - + return; + if (m_isWaitingForDidUpdateBackingStoreState) { // Wait for a DidUpdateBackingStoreState message that contains the new bits before we paint // what's currently in the backing store. @@ -103,16 +97,6 @@ void DrawingAreaProxyImpl::paint(BackingStore::PlatformGraphicsContext context, discardBackingStoreSoon(); } -void DrawingAreaProxyImpl::sizeDidChange() -{ - backingStoreStateDidChange(RespondImmediately); -} - -void DrawingAreaProxyImpl::deviceScaleFactorDidChange() -{ - backingStoreStateDidChange(RespondImmediately); -} - void DrawingAreaProxyImpl::setBackingStoreIsDiscardable(bool isBackingStoreDiscardable) { if (m_isBackingStoreDiscardable == isBackingStoreDiscardable) @@ -125,11 +109,6 @@ void DrawingAreaProxyImpl::setBackingStoreIsDiscardable(bool isBackingStoreDisca m_discardBackingStoreTimer.stop(); } -void DrawingAreaProxyImpl::waitForBackingStoreUpdateOnNextPaint() -{ - m_hasReceivedFirstUpdate = true; -} - void DrawingAreaProxyImpl::update(uint64_t backingStoreStateID, const UpdateInfo& updateInfo) { ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); @@ -139,47 +118,16 @@ void DrawingAreaProxyImpl::update(uint64_t backingStoreStateID, const UpdateInfo // FIXME: Handle the case where the view is hidden. incorporateUpdate(updateInfo); - m_webPageProxy->process().send(Messages::DrawingArea::DidUpdate(), m_webPageProxy->pageID()); + m_webPageProxy.process().send(Messages::DrawingArea::DidUpdate(), m_webPageProxy.pageID()); } void DrawingAreaProxyImpl::didUpdateBackingStoreState(uint64_t backingStoreStateID, const UpdateInfo& updateInfo, const LayerTreeContext& layerTreeContext) { - ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_nextBackingStoreStateID); - ASSERT_ARG(backingStoreStateID, backingStoreStateID > m_currentBackingStoreStateID); - m_currentBackingStoreStateID = backingStoreStateID; - - m_isWaitingForDidUpdateBackingStoreState = false; - - // Stop the responsiveness timer that was started in sendUpdateBackingStoreState. - m_webPageProxy->process().responsivenessTimer()->stop(); - -#if USE(ACCELERATED_COMPOSITING) - if (layerTreeContext != m_layerTreeContext) { - if (!m_layerTreeContext.isEmpty()) { - exitAcceleratedCompositingMode(); - ASSERT(m_layerTreeContext.isEmpty()); - } - - if (!layerTreeContext.isEmpty()) { - enterAcceleratedCompositingMode(layerTreeContext); - ASSERT(layerTreeContext == m_layerTreeContext); - } - } -#endif - - if (m_nextBackingStoreStateID != m_currentBackingStoreStateID) - sendUpdateBackingStoreState(RespondImmediately); - else - m_hasReceivedFirstUpdate = true; - -#if USE(ACCELERATED_COMPOSITING) + AcceleratedDrawingAreaProxy::didUpdateBackingStoreState(backingStoreStateID, updateInfo, layerTreeContext); if (isInAcceleratedCompositingMode()) { ASSERT(!m_backingStore); return; } -#else - UNUSED_PARAM(layerTreeContext); -#endif // If we have a backing store the right size, reuse it. if (m_backingStore && (m_backingStore->size() != updateInfo.viewSize || m_backingStore->deviceScaleFactor() != updateInfo.deviceScaleFactor)) @@ -187,45 +135,17 @@ void DrawingAreaProxyImpl::didUpdateBackingStoreState(uint64_t backingStoreState incorporateUpdate(updateInfo); } -void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext& layerTreeContext) -{ - ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); - if (backingStoreStateID < m_currentBackingStoreStateID) - return; - -#if USE(ACCELERATED_COMPOSITING) - enterAcceleratedCompositingMode(layerTreeContext); -#else - UNUSED_PARAM(layerTreeContext); -#endif -} - void DrawingAreaProxyImpl::exitAcceleratedCompositingMode(uint64_t backingStoreStateID, const UpdateInfo& updateInfo) { ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); if (backingStoreStateID < m_currentBackingStoreStateID) return; -#if USE(ACCELERATED_COMPOSITING) - exitAcceleratedCompositingMode(); -#endif + AcceleratedDrawingAreaProxy::exitAcceleratedCompositingMode(); incorporateUpdate(updateInfo); } -void DrawingAreaProxyImpl::updateAcceleratedCompositingMode(uint64_t backingStoreStateID, const LayerTreeContext& layerTreeContext) -{ - ASSERT_ARG(backingStoreStateID, backingStoreStateID <= m_currentBackingStoreStateID); - if (backingStoreStateID < m_currentBackingStoreStateID) - return; - -#if USE(ACCELERATED_COMPOSITING) - updateAcceleratedCompositingMode(layerTreeContext); -#else - UNUSED_PARAM(layerTreeContext); -#endif -} - void DrawingAreaProxyImpl::incorporateUpdate(const UpdateInfo& updateInfo) { ASSERT(!isInAcceleratedCompositingMode()); @@ -238,124 +158,105 @@ void DrawingAreaProxyImpl::incorporateUpdate(const UpdateInfo& updateInfo) m_backingStore->incorporateUpdate(updateInfo); - bool shouldScroll = !updateInfo.scrollRect.isEmpty(); - - if (shouldScroll) - m_webPageProxy->scrollView(updateInfo.scrollRect, updateInfo.scrollOffset); - - if (shouldScroll && !m_webPageProxy->canScrollView()) - m_webPageProxy->setViewNeedsDisplay(IntRect(IntPoint(), m_webPageProxy->viewSize())); - else { - for (size_t i = 0; i < updateInfo.updateRects.size(); ++i) - m_webPageProxy->setViewNeedsDisplay(updateInfo.updateRects[i]); - } - - if (shouldScroll) - m_webPageProxy->displayView(); + Region damageRegion; + if (updateInfo.scrollRect.isEmpty()) { + for (const auto& rect : updateInfo.updateRects) + damageRegion.unite(rect); + } else + damageRegion = IntRect(IntPoint(), m_webPageProxy.viewSize()); + m_webPageProxy.setViewNeedsDisplay(damageRegion); } -void DrawingAreaProxyImpl::backingStoreStateDidChange(RespondImmediatelyOrNot respondImmediatelyOrNot) +void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) { - ++m_nextBackingStoreStateID; - sendUpdateBackingStoreState(respondImmediatelyOrNot); + m_backingStore = nullptr; + AcceleratedDrawingAreaProxy::enterAcceleratedCompositingMode(layerTreeContext); } -void DrawingAreaProxyImpl::sendUpdateBackingStoreState(RespondImmediatelyOrNot respondImmediatelyOrNot) +void DrawingAreaProxyImpl::discardBackingStoreSoon() { - ASSERT(m_currentBackingStoreStateID < m_nextBackingStoreStateID); - - if (!m_webPageProxy->isValid()) - return; - - if (m_isWaitingForDidUpdateBackingStoreState) + if (!m_backingStore || !m_isBackingStoreDiscardable || m_discardBackingStoreTimer.isActive()) return; - if (m_webPageProxy->viewSize().isEmpty() && !m_webPageProxy->useFixedLayout()) - return; - - m_isWaitingForDidUpdateBackingStoreState = respondImmediatelyOrNot == RespondImmediately; - - m_webPageProxy->process().send(Messages::DrawingArea::UpdateBackingStoreState(m_nextBackingStoreStateID, respondImmediatelyOrNot == RespondImmediately, m_webPageProxy->deviceScaleFactor(), m_size, m_scrollOffset), m_webPageProxy->pageID()); - m_scrollOffset = IntSize(); - - if (m_isWaitingForDidUpdateBackingStoreState) { - // Start the responsiveness timer. We will stop it when we hear back from the WebProcess - // in didUpdateBackingStoreState. - m_webPageProxy->process().responsivenessTimer()->start(); - } + // We'll wait this many seconds after the last paint before throwing away our backing store to save memory. + // FIXME: It would be smarter to make this delay based on how expensive painting is. See <http://webkit.org/b/55733>. + static const double discardBackingStoreDelay = 2; -#if USE(ACCELERATED_COMPOSITING) - if (m_isWaitingForDidUpdateBackingStoreState && !m_layerTreeContext.isEmpty()) { - // Wait for the DidUpdateBackingStoreState message. Normally we do this in DrawingAreaProxyImpl::paint, but that - // function is never called when in accelerated compositing mode. - waitForAndDispatchDidUpdateBackingStoreState(); - } -#endif + m_discardBackingStoreTimer.startOneShot(discardBackingStoreDelay); } -void DrawingAreaProxyImpl::waitForAndDispatchDidUpdateBackingStoreState() +void DrawingAreaProxyImpl::discardBackingStore() { - ASSERT(m_isWaitingForDidUpdateBackingStoreState); - - if (!m_webPageProxy->isValid()) - return; - if (m_webPageProxy->process().isLaunching()) + if (!m_backingStore) return; - -#if USE(ACCELERATED_COMPOSITING) - // FIXME: waitForAndDispatchImmediately will always return the oldest DidUpdateBackingStoreState message that - // hasn't yet been processed. But it might be better to skip ahead to some other DidUpdateBackingStoreState - // message, if multiple DidUpdateBackingStoreState messages are waiting to be processed. For instance, we could - // choose the most recent one, or the one that is closest to our current size. - - // The timeout we use when waiting for a DidUpdateBackingStoreState message when we're asked to paint is 500 milliseconds. - m_webPageProxy->process().connection()->waitForAndDispatchImmediately<Messages::DrawingAreaProxy::DidUpdateBackingStoreState>(m_webPageProxy->pageID(), std::chrono::milliseconds(500)); -#endif + m_backingStore = nullptr; + backingStoreStateDidChange(DoNotRespondImmediately); } -#if USE(ACCELERATED_COMPOSITING) -void DrawingAreaProxyImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +DrawingAreaProxyImpl::DrawingMonitor::DrawingMonitor(WebPageProxy& webPage) + : m_webPage(webPage) + , m_timer(RunLoop::main(), this, &DrawingMonitor::stop) { - ASSERT(!isInAcceleratedCompositingMode()); - - m_backingStore = nullptr; - m_layerTreeContext = layerTreeContext; - m_webPageProxy->enterAcceleratedCompositingMode(layerTreeContext); } -void DrawingAreaProxyImpl::exitAcceleratedCompositingMode() +DrawingAreaProxyImpl::DrawingMonitor::~DrawingMonitor() { - ASSERT(isInAcceleratedCompositingMode()); - - m_layerTreeContext = LayerTreeContext(); - m_webPageProxy->exitAcceleratedCompositingMode(); + m_callback = nullptr; + stop(); } -void DrawingAreaProxyImpl::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext) +int DrawingAreaProxyImpl::DrawingMonitor::webViewDrawCallback(DrawingAreaProxyImpl::DrawingMonitor* monitor) { - ASSERT(isInAcceleratedCompositingMode()); - - m_layerTreeContext = layerTreeContext; - m_webPageProxy->updateAcceleratedCompositingMode(layerTreeContext); + monitor->didDraw(); + return FALSE; } -#endif -void DrawingAreaProxyImpl::discardBackingStoreSoon() +void DrawingAreaProxyImpl::DrawingMonitor::start(std::function<void (CallbackBase::Error)> callback) { - if (!m_isBackingStoreDiscardable || m_discardBackingStoreTimer.isActive()) - return; + 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 +} - // We'll wait this many seconds after the last paint before throwing away our backing store to save memory. - // FIXME: It would be smarter to make this delay based on how expensive painting is. See <http://webkit.org/b/55733>. - static const double discardBackingStoreDelay = 2; +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; + } +} - m_discardBackingStoreTimer.startOneShot(discardBackingStoreDelay); +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::discardBackingStore() +void DrawingAreaProxyImpl::dispatchAfterEnsuringDrawing(std::function<void(CallbackBase::Error)> callbackFunction) { - m_backingStore = nullptr; - backingStoreStateDidChange(DoNotRespondImmediately); + 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 |