summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp')
-rw-r--r--Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp235
1 files changed, 235 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp
new file mode 100644
index 0000000..74aa4b2
--- /dev/null
+++ b/Source/WebKit2/WebProcess/WebPage/TiledDrawingArea.cpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if ENABLE(TILED_BACKING_STORE)
+
+#include "TiledDrawingArea.h"
+
+#include "DrawingAreaMessageKinds.h"
+#include "DrawingAreaProxyMessageKinds.h"
+#include "MessageID.h"
+#include "UpdateChunk.h"
+#include "WebCore/Frame.h"
+#include "WebCore/FrameView.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebFrame.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+TiledDrawingArea::TiledDrawingArea(DrawingAreaInfo::Identifier identifier, WebPage* webPage)
+ : DrawingArea(DrawingAreaInfo::Tiled, identifier, webPage)
+ , m_isWaitingForUpdate(false)
+ , m_shouldPaint(true)
+ , m_displayTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::display)
+ , m_tileUpdateTimer(WebProcess::shared().runLoop(), this, &TiledDrawingArea::tileUpdateTimerFired)
+{
+}
+
+TiledDrawingArea::~TiledDrawingArea()
+{
+}
+
+void TiledDrawingArea::scroll(const IntRect& scrollRect, const IntSize& scrollDelta)
+{
+ // FIXME: Do something much smarter.
+ setNeedsDisplay(scrollRect);
+}
+
+void TiledDrawingArea::setNeedsDisplay(const IntRect& rect)
+{
+ // FIXME: Collect a set of rects/region instead of just the union of all rects.
+ m_dirtyRect.unite(rect);
+ scheduleDisplay();
+}
+
+void TiledDrawingArea::display()
+{
+ if (!m_shouldPaint)
+ return;
+
+ if (m_dirtyRect.isEmpty())
+ return;
+
+ m_webPage->layoutIfNeeded();
+
+ IntRect dirtyRect = m_dirtyRect;
+ m_dirtyRect = IntRect();
+
+ WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::Invalidate, m_webPage->pageID(), CoreIPC::In(dirtyRect));
+
+ m_displayTimer.stop();
+}
+
+void TiledDrawingArea::scheduleDisplay()
+{
+ if (!m_shouldPaint)
+ return;
+
+ if (m_displayTimer.isActive())
+ return;
+
+ m_displayTimer.startOneShot(0);
+}
+
+void TiledDrawingArea::setSize(const IntSize& viewSize)
+{
+ ASSERT(m_shouldPaint);
+ ASSERT_ARG(viewSize, !viewSize.isEmpty());
+
+ m_webPage->setSize(viewSize);
+
+ scheduleDisplay();
+
+ WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::DidSetSize, m_webPage->pageID(), CoreIPC::In(viewSize));
+}
+
+void TiledDrawingArea::suspendPainting()
+{
+ ASSERT(m_shouldPaint);
+
+ m_shouldPaint = false;
+ m_displayTimer.stop();
+}
+
+void TiledDrawingArea::resumePainting()
+{
+ ASSERT(!m_shouldPaint);
+
+ m_shouldPaint = true;
+
+ // Display if needed.
+ display();
+}
+
+void TiledDrawingArea::didUpdate()
+{
+ // Display if needed.
+ display();
+}
+
+void TiledDrawingArea::updateTile(int tileID, const IntRect& dirtyRect, float scale)
+{
+ m_webPage->layoutIfNeeded();
+
+ UpdateChunk updateChunk(dirtyRect);
+ paintIntoUpdateChunk(&updateChunk, scale);
+
+ unsigned pendingUpdateCount = m_pendingUpdates.size();
+ WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::TileUpdated, m_webPage->pageID(), CoreIPC::In(tileID, updateChunk, scale, pendingUpdateCount));
+}
+
+void TiledDrawingArea::tileUpdateTimerFired()
+{
+ ASSERT(!m_pendingUpdates.isEmpty());
+
+ UpdateMap::iterator it = m_pendingUpdates.begin();
+ TileUpdate update = it->second;
+ m_pendingUpdates.remove(it);
+
+ updateTile(update.tileID, update.dirtyRect, update.scale);
+
+ if (m_pendingUpdates.isEmpty())
+ WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In());
+ else
+ m_tileUpdateTimer.startOneShot(0.001);
+}
+
+void TiledDrawingArea::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
+{
+ switch (messageID.get<DrawingAreaLegacyMessage::Kind>()) {
+ case DrawingAreaLegacyMessage::SetSize: {
+ IntSize size;
+ if (!arguments->decode(CoreIPC::Out(size)))
+ return;
+
+ setSize(size);
+ break;
+ }
+ case DrawingAreaLegacyMessage::SuspendPainting:
+ suspendPainting();
+ break;
+ case DrawingAreaLegacyMessage::ResumePainting:
+ resumePainting();
+ break;
+ case DrawingAreaLegacyMessage::CancelTileUpdate: {
+ int tileID;
+ if (!arguments->decode(CoreIPC::Out(tileID)))
+ return;
+ UpdateMap::iterator it = m_pendingUpdates.find(tileID);
+ if (it != m_pendingUpdates.end()) {
+ m_pendingUpdates.remove(it);
+ if (m_pendingUpdates.isEmpty()) {
+ WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::AllTileUpdatesProcessed, m_webPage->pageID(), CoreIPC::In());
+ m_tileUpdateTimer.stop();
+ }
+ }
+ break;
+ }
+ case DrawingAreaLegacyMessage::RequestTileUpdate: {
+ TileUpdate update;
+ if (!arguments->decode(CoreIPC::Out(update.tileID, update.dirtyRect, update.scale)))
+ return;
+ UpdateMap::iterator it = m_pendingUpdates.find(update.tileID);
+ if (it != m_pendingUpdates.end())
+ it->second.dirtyRect.unite(update.dirtyRect);
+ else {
+ m_pendingUpdates.add(update.tileID, update);
+ if (!m_tileUpdateTimer.isActive())
+ m_tileUpdateTimer.startOneShot(0);
+ }
+ break;
+ }
+ case DrawingAreaLegacyMessage::TakeSnapshot: {
+ IntSize targetSize;
+ IntRect contentsRect;
+
+ if (!arguments->decode(CoreIPC::Out(targetSize, contentsRect)))
+ return;
+
+ m_webPage->layoutIfNeeded();
+
+ contentsRect.intersect(IntRect(IntPoint::zero(), m_webPage->mainFrame()->coreFrame()->view()->contentsSize()));
+
+ float targetScale = float(targetSize.width()) / contentsRect.width();
+
+ UpdateChunk updateChunk(IntRect(IntPoint(contentsRect.x() * targetScale, contentsRect.y() * targetScale), targetSize));
+ paintIntoUpdateChunk(&updateChunk, targetScale);
+
+ WebProcess::shared().connection()->send(DrawingAreaProxyLegacyMessage::SnapshotTaken, m_webPage->pageID(), CoreIPC::In(updateChunk));
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+} // namespace WebKit
+
+#endif // TILED_BACKING_STORE