summaryrefslogtreecommitdiff
path: root/Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp')
-rw-r--r--Source/WebKit2/UIProcess/DrawingAreaProxyImpl.cpp259
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