165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2011 Apple Inc. All rights reserved.
365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Redistribution and use in source and binary forms, with or without
565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modification, are permitted provided that the following conditions
665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * are met:
765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1. Redistributions of source code must retain the above copyright
865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer.
965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    documentation and/or other materials provided with the distribution.
1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */
2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "config.h"
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "DrawingAreaImpl.h"
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "DrawingAreaProxyMessages.h"
302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "LayerTreeContext.h"
3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "ShareableBitmap.h"
3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "UpdateInfo.h"
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebPage.h"
34ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "WebPageCreationParameters.h"
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WebProcess.h"
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/GraphicsContext.h>
3781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <WebCore/Page.h>
3881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include <WebCore/Settings.h>
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#if !PLATFORM(MAC) && !PLATFORM(WIN)
4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error "This drawing area is not ready for use by other ports yet."
4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif
4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochusing namespace WebCore;
452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochusing namespace std;
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace WebKit {
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen MurdochPassOwnPtr<DrawingAreaImpl> DrawingAreaImpl::create(WebPage* webPage, const WebPageCreationParameters& parameters)
502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
5181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    return adoptPtr(new DrawingAreaImpl(webPage, parameters));
5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochDrawingAreaImpl::~DrawingAreaImpl()
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_layerTreeHost)
572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_layerTreeHost->invalidate();
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
60ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen MurdochDrawingAreaImpl::DrawingAreaImpl(WebPage* webPage, const WebPageCreationParameters& parameters)
6181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    : DrawingArea(DrawingAreaTypeImpl, webPage)
6281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_backingStoreStateID(0)
6381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_inUpdateBackingStoreState(false)
6481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_shouldSendDidUpdateBackingStoreState(false)
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    , m_isWaitingForDidUpdate(false)
66ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    , m_isPaintingSuspended(!parameters.isVisible)
6781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    , m_alwaysUseCompositing(false)
682bde8e466a4451c7319e3a072d118917957d6554Steve Block    , m_lastDisplayTime(0)
692bde8e466a4451c7319e3a072d118917957d6554Steve Block    , m_displayTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::displayTimerFired)
702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_exitCompositingTimer(WebProcess::shared().runLoop(), this, &DrawingAreaImpl::exitAcceleratedCompositingMode)
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
7281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (webPage->corePage()->settings()->acceleratedDrawingEnabled())
7381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_alwaysUseCompositing = true;
7481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_alwaysUseCompositing)
7681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        enterAcceleratedCompositingMode(0);
7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid DrawingAreaImpl::setNeedsDisplay(const IntRect& rect)
8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    IntRect dirtyRect = rect;
822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    dirtyRect.intersect(m_webPage->bounds());
832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (dirtyRect.isEmpty())
8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_layerTreeHost) {
882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ASSERT(m_dirtyRegion.isEmpty());
892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_layerTreeHost->setNonCompositedContentsNeedDisplay(dirtyRect);
912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
942bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_webPage->mainFrameHasCustomRepresentation())
952bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
962bde8e466a4451c7319e3a072d118917957d6554Steve Block
972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_dirtyRegion.unite(dirtyRect);
9865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    scheduleDisplay();
9965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
10065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
101ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid DrawingAreaImpl::scroll(const IntRect& scrollRect, const IntSize& scrollOffset)
10265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
1032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_layerTreeHost) {
1042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ASSERT(m_scrollRect.isEmpty());
1052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ASSERT(m_scrollOffset.isEmpty());
1062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ASSERT(m_dirtyRegion.isEmpty());
1072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_layerTreeHost->scrollNonCompositedContents(scrollRect, scrollOffset);
1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_webPage->mainFrameHasCustomRepresentation())
1132bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block
11565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!m_scrollRect.isEmpty() && scrollRect != m_scrollRect) {
11665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        unsigned scrollArea = scrollRect.width() * scrollRect.height();
11765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        unsigned currentScrollArea = m_scrollRect.width() * m_scrollRect.height();
11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        if (currentScrollArea >= scrollArea) {
12065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // The rect being scrolled is at least as large as the rect we'd like to scroll.
12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            // Go ahead and just invalidate the scroll rect.
12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            setNeedsDisplay(scrollRect);
12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch            return;
12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        }
12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Just repaint the entire current scroll rect, we'll scroll the new rect instead.
12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        setNeedsDisplay(m_scrollRect);
12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_scrollRect = IntRect();
129ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        m_scrollOffset = IntSize();
13065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
13165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Get the part of the dirty region that is in the scroll rect.
13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    Region dirtyRegionInScrollRect = intersect(scrollRect, m_dirtyRegion);
13465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!dirtyRegionInScrollRect.isEmpty()) {
13565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // There are parts of the dirty region that are inside the scroll rect.
13665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // We need to subtract them from the region, move them and re-add them.
13765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_dirtyRegion.subtract(scrollRect);
13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
13965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // Move the dirty parts.
140ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        Region movedDirtyRegionInScrollRect = intersect(translate(dirtyRegionInScrollRect, scrollOffset), scrollRect);
14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        // And add them back.
14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        m_dirtyRegion.unite(movedDirtyRegionInScrollRect);
14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Compute the scroll repaint region.
147ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    Region scrollRepaintRegion = subtract(scrollRect, translate(scrollRect, scrollOffset));
14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_dirtyRegion.unite(scrollRepaintRegion);
15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_scrollRect = scrollRect;
152ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    m_scrollOffset += scrollOffset;
15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid DrawingAreaImpl::forceRepaint()
1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
15781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    setNeedsDisplay(m_webPage->bounds());
15881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
15981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_webPage->layoutIfNeeded();
16081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
16181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_layerTreeHost) {
16281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_layerTreeHost->forceRepaint();
1632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!m_layerTreeHost->participatesInDisplay())
1642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
16581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
16681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
1672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_isWaitingForDidUpdate = false;
1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    display();
1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid DrawingAreaImpl::didInstallPageOverlay()
1722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_layerTreeHost)
1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_layerTreeHost->didInstallPageOverlay();
1752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid DrawingAreaImpl::didUninstallPageOverlay()
1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_layerTreeHost)
1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_layerTreeHost->didUninstallPageOverlay();
1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    setNeedsDisplay(m_webPage->bounds());
1832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid DrawingAreaImpl::setPageOverlayNeedsDisplay(const IntRect& rect)
1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_layerTreeHost) {
1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        m_layerTreeHost->setPageOverlayNeedsDisplay(rect);
1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
1902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    setNeedsDisplay(rect);
1932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
1942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid DrawingAreaImpl::setLayerHostNeedsDisplay()
1962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(m_layerTreeHost);
1982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(m_layerTreeHost->participatesInDisplay());
1992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    scheduleDisplay();
2002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
2012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
20281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid DrawingAreaImpl::layerHostDidFlushLayers()
20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
20481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(m_layerTreeHost);
20565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
20681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_layerTreeHost->forceRepaint();
20781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
20881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_shouldSendDidUpdateBackingStoreState) {
20981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        sendDidUpdateBackingStoreState();
21081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
21181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
21281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_layerTreeHost || m_layerTreeHost->participatesInDisplay()) {
2142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // When the layer tree host participates in display, we never tell the UI process about
2152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // accelerated compositing. From the UI process's point of view, we're still just sending
2162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // it a series of bitmaps in Update messages.
21781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
2182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
21981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2202bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(ACCELERATED_COMPOSITING)
22181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_webPage->send(Messages::DrawingAreaProxy::EnterAcceleratedCompositingMode(m_backingStoreStateID, m_layerTreeHost->layerTreeContext()));
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
22365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
22465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2252fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid DrawingAreaImpl::setRootCompositingLayer(GraphicsLayer* graphicsLayer)
22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
2272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (graphicsLayer) {
2282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (!m_layerTreeHost) {
2292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // We're actually entering accelerated compositing mode.
2302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            enterAcceleratedCompositingMode(graphicsLayer);
2312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
2322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            m_exitCompositingTimer.stop();
2332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            // We're already in accelerated compositing mode, but the root compositing layer changed.
2342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
2352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
2362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    } else {
2372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (m_layerTreeHost) {
23881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_layerTreeHost->setRootCompositingLayer(0);
23981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            if (!m_alwaysUseCompositing) {
24081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // We'll exit accelerated compositing mode on a timer, to avoid re-entering
24181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // compositing code via display() and layout.
24281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // If we're leaving compositing mode because of a setSize, it is safe to
24381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                // exit accelerated compositing mode right away.
24481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                if (m_inUpdateBackingStoreState)
24581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    exitAcceleratedCompositingMode();
24681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                else
24781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    exitAcceleratedCompositingModeSoon();
24881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            }
2492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
2502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid DrawingAreaImpl::scheduleCompositingLayerSync()
25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
2552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!m_layerTreeHost)
2562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
2572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_layerTreeHost->scheduleLayerFlush();
25865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
25965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid DrawingAreaImpl::syncCompositingLayers()
26165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
26265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
26365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid DrawingAreaImpl::didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*)
26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
26765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
26881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid DrawingAreaImpl::updateBackingStoreState(uint64_t stateID, bool respondImmediately, const WebCore::IntSize& size, const WebCore::IntSize& scrollOffset)
26965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
27081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(!m_inUpdateBackingStoreState);
27181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_inUpdateBackingStoreState = true;
27281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
27381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT_ARG(stateID, stateID >= m_backingStoreStateID);
27481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (stateID != m_backingStoreStateID) {
27581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_backingStoreStateID = stateID;
27681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_shouldSendDidUpdateBackingStoreState = true;
27781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
27881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_webPage->setSize(size);
27981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_webPage->layoutIfNeeded();
28081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_webPage->scrollMainFrameIfNotAtMaxScrollPosition(scrollOffset);
28181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
28281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (m_layerTreeHost)
28381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_layerTreeHost->sizeDidChange(size);
28481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        else
28581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_dirtyRegion = m_webPage->bounds();
28681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    } else {
28781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        ASSERT(size == m_webPage->size());
28881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (!m_shouldSendDidUpdateBackingStoreState) {
28981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // We've already sent a DidUpdateBackingStoreState message for this state. We have nothing more to do.
29081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_inUpdateBackingStoreState = false;
29181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            return;
29281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
29381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
2942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
29581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // The UI process has updated to a new backing store state. Any Update messages we sent before
29681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // this point will be ignored. We wait to set this to false until after updating the page's
29781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // size so that any displays triggered by the relayout will be ignored. If we're supposed to
29881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // respond to the UpdateBackingStoreState message immediately, we'll do a display anyway in
29981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // sendDidUpdateBackingStoreState; otherwise we shouldn't do one right now.
30065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_isWaitingForDidUpdate = false;
30165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
30281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (respondImmediately)
30381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        sendDidUpdateBackingStoreState();
30481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
30581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_inUpdateBackingStoreState = false;
30681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
30781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
30881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid DrawingAreaImpl::sendDidUpdateBackingStoreState()
30981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
31081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(!m_isWaitingForDidUpdate);
31181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(m_shouldSendDidUpdateBackingStoreState);
31281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
31381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_shouldSendDidUpdateBackingStoreState = false;
31465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
315ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    UpdateInfo updateInfo;
316ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
3172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_isPaintingSuspended && (!m_layerTreeHost || m_layerTreeHost->participatesInDisplay()))
31881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        display(updateInfo);
3192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3202bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(ACCELERATED_COMPOSITING)
3212bde8e466a4451c7319e3a072d118917957d6554Steve Block    LayerTreeContext layerTreeContext;
3222bde8e466a4451c7319e3a072d118917957d6554Steve Block
3232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_isPaintingSuspended || (m_layerTreeHost && !m_layerTreeHost->participatesInDisplay())) {
324ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        updateInfo.viewSize = m_webPage->size();
3252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
32681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        if (m_layerTreeHost) {
32781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            layerTreeContext = m_layerTreeHost->layerTreeContext();
32865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
32981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // We don't want the layer tree host to notify after the next scheduled
33081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // layer flush because that might end up sending an EnterAcceleratedCompositingMode
33181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // message back to the UI process, but the updated layer tree context
33281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            // will be sent back in the DidUpdateBackingStoreState message.
33381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(false);
3342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            m_layerTreeHost->forceRepaint();
33581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        }
33681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
3372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
33881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_webPage->send(Messages::DrawingAreaProxy::DidUpdateBackingStoreState(m_backingStoreStateID, updateInfo, layerTreeContext));
3392bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
34065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
34165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
34265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid DrawingAreaImpl::didUpdate()
34365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
3442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // We might get didUpdate messages from the UI process even after we've
3452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // entered accelerated compositing mode. Ignore them.
3462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_layerTreeHost && !m_layerTreeHost->participatesInDisplay())
3472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
3482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
34965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_isWaitingForDidUpdate = false;
35065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3512bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Display if needed. We call displayTimerFired here since it will throttle updates to 60fps.
3522bde8e466a4451c7319e3a072d118917957d6554Steve Block    displayTimerFired();
35365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
35465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
355ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid DrawingAreaImpl::suspendPainting()
356ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
357ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    ASSERT(!m_isPaintingSuspended);
358ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
3592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_layerTreeHost)
3602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_layerTreeHost->pauseRendering();
3612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
362ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    m_isPaintingSuspended = true;
363ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    m_displayTimer.stop();
364ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
365ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
366ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid DrawingAreaImpl::resumePainting()
367ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{
3682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_isPaintingSuspended) {
3692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // FIXME: We can get a call to resumePainting when painting is not suspended.
3702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // This happens when sending a synchronous message to create a new page. See <rdar://problem/8976531>.
3712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return;
3722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
3732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
3742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_layerTreeHost)
3752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_layerTreeHost->resumeRendering();
3762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
377ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    m_isPaintingSuspended = false;
378ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
3792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // FIXME: We shouldn't always repaint everything here.
3802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    setNeedsDisplay(m_webPage->bounds());
3812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
3822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3832fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid DrawingAreaImpl::enterAcceleratedCompositingMode(GraphicsLayer* graphicsLayer)
3842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
3852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_exitCompositingTimer.stop();
3862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(!m_layerTreeHost);
3882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_layerTreeHost = LayerTreeHost::create(m_webPage);
39081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (!m_inUpdateBackingStoreState)
39181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        m_layerTreeHost->setShouldNotifyAfterNextScheduledLayerFlush(true);
39281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
3932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_layerTreeHost->setRootCompositingLayer(graphicsLayer);
3942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    // Non-composited content will now be handled exclusively by the layer tree host.
3962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_dirtyRegion = Region();
3972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_scrollRect = IntRect();
3982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_scrollOffset = IntSize();
3992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
4002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_layerTreeHost->participatesInDisplay()) {
4012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_displayTimer.stop();
4022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_isWaitingForDidUpdate = false;
4032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
4042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
4052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4062fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid DrawingAreaImpl::exitAcceleratedCompositingMode()
4072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
40881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_alwaysUseCompositing)
40981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
41081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
4112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_exitCompositingTimer.stop();
4122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(m_layerTreeHost);
4142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    bool wasParticipatingInDisplay = m_layerTreeHost->participatesInDisplay();
4162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
4172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_layerTreeHost->invalidate();
4182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_layerTreeHost = nullptr;
41981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_dirtyRegion = m_webPage->bounds();
42081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
42181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_inUpdateBackingStoreState)
42281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
4232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
42481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_shouldSendDidUpdateBackingStoreState) {
42581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        sendDidUpdateBackingStoreState();
4262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
42781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
4282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    UpdateInfo updateInfo;
4302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_isPaintingSuspended)
4312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        updateInfo.viewSize = m_webPage->size();
43281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
4332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        display(updateInfo);
4342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4352bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(ACCELERATED_COMPOSITING)
4362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (wasParticipatingInDisplay) {
4372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // When the layer tree host participates in display, we never tell the UI process about
4382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // accelerated compositing. From the UI process's point of view, we're still just sending
4392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // it a series of bitmaps in Update messages.
4402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
4412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    } else {
4422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // Send along a complete update of the page so we can paint the contents right after we exit the
4432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        // accelerated compositing mode, eliminiating flicker.
4442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_webPage->send(Messages::DrawingAreaProxy::ExitAcceleratedCompositingMode(m_backingStoreStateID, updateInfo));
4452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
4462bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
4472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
4482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4492fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid DrawingAreaImpl::exitAcceleratedCompositingModeSoon()
4502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
4512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_exitCompositingTimer.isActive())
4522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
4532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
4542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_exitCompositingTimer.startOneShot(0);
455ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch}
456ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
45765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid DrawingAreaImpl::scheduleDisplay()
45865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
4592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(!m_layerTreeHost || m_layerTreeHost->participatesInDisplay());
4602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
46165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (m_isWaitingForDidUpdate)
46265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
46365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
464ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    if (m_isPaintingSuspended)
465ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        return;
466ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
4672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_layerTreeHost) {
4682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!m_layerTreeHost->needsDisplay())
4692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
4702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    } else if (m_dirtyRegion.isEmpty())
4712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
47265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
47365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (m_displayTimer.isActive())
47465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
47565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
47665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_displayTimer.startOneShot(0);
47765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
47865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4792bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid DrawingAreaImpl::displayTimerFired()
4802bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4812bde8e466a4451c7319e3a072d118917957d6554Steve Block    static const double minimumFrameInterval = 1.0 / 60.0;
4822bde8e466a4451c7319e3a072d118917957d6554Steve Block
4832bde8e466a4451c7319e3a072d118917957d6554Steve Block    double timeSinceLastDisplay = currentTime() - m_lastDisplayTime;
4842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    double timeUntilLayerTreeHostNeedsDisplay = m_layerTreeHost && m_layerTreeHost->participatesInDisplay() ? m_layerTreeHost->timeUntilNextDisplay() : 0;
4852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    double timeUntilNextDisplay = max(minimumFrameInterval - timeSinceLastDisplay, timeUntilLayerTreeHostNeedsDisplay);
4862bde8e466a4451c7319e3a072d118917957d6554Steve Block
4872bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (timeUntilNextDisplay > 0) {
4882bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_displayTimer.startOneShot(timeUntilNextDisplay);
4892bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
4902bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4912bde8e466a4451c7319e3a072d118917957d6554Steve Block
4922bde8e466a4451c7319e3a072d118917957d6554Steve Block    display();
4932bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4942bde8e466a4451c7319e3a072d118917957d6554Steve Block
49565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid DrawingAreaImpl::display()
49665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
4972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(!m_layerTreeHost || m_layerTreeHost->participatesInDisplay());
498ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    ASSERT(!m_isWaitingForDidUpdate);
49981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ASSERT(!m_inUpdateBackingStoreState);
500ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
501ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    if (m_isPaintingSuspended)
502ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        return;
503ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
5042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_layerTreeHost) {
5052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!m_layerTreeHost->needsDisplay())
5062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
5072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    } else if (m_dirtyRegion.isEmpty())
50865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
50965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
51081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (m_shouldSendDidUpdateBackingStoreState) {
51181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        sendDidUpdateBackingStoreState();
51281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
51381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    }
51481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
51565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    UpdateInfo updateInfo;
51665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    display(updateInfo);
51765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_layerTreeHost && !m_layerTreeHost->participatesInDisplay()) {
5192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // The call to update caused layout which turned on accelerated compositing.
5202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        // Don't send an Update message in this case.
5212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
5222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
5232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
52481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_webPage->send(Messages::DrawingAreaProxy::Update(m_backingStoreStateID, updateInfo));
52565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_isWaitingForDidUpdate = true;
52665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
52765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
52865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic bool shouldPaintBoundsRect(const IntRect& bounds, const Vector<IntRect>& rects)
52965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
53065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    const size_t rectThreshold = 10;
53165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    const float wastedSpaceThreshold = 0.75f;
53265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
53365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (rects.size() <= 1 || rects.size() > rectThreshold)
53465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return true;
53565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
53665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Attempt to guess whether or not we should use the region bounds rect or the individual rects.
53765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // We do this by computing the percentage of "wasted space" in the bounds.  If that wasted space
53865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // is too large, then we will do individual rect painting instead.
53965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    unsigned boundsArea = bounds.width() * bounds.height();
54065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    unsigned rectsArea = 0;
54165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    for (size_t i = 0; i < rects.size(); ++i)
54265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        rectsArea += rects[i].width() * rects[i].height();
54365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
54465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    float wastedSpace = 1 - (rectsArea / boundsArea);
54565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
54665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return wastedSpace <= wastedSpaceThreshold;
54765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
54865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
54965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid DrawingAreaImpl::display(UpdateInfo& updateInfo)
55065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
551ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    ASSERT(!m_isPaintingSuspended);
5522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(!m_layerTreeHost || m_layerTreeHost->participatesInDisplay());
5532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ASSERT(!m_webPage->size().isEmpty());
554ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch
55565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // FIXME: It would be better if we could avoid painting altogether when there is a custom representation.
5562bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_webPage->mainFrameHasCustomRepresentation()) {
5572bde8e466a4451c7319e3a072d118917957d6554Steve Block        // ASSUMPTION: the custom representation will be painting the dirty region for us.
5582bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_dirtyRegion = Region();
55965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return;
5602bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
56165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
56281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_webPage->layoutIfNeeded();
56381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // The layout may have put the page into accelerated compositing mode. If the LayerTreeHost is
5652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // in charge of displaying, we have nothing more to do.
5662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_layerTreeHost && !m_layerTreeHost->participatesInDisplay())
56781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
56881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    updateInfo.viewSize = m_webPage->size();
5702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
5712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_layerTreeHost)
5722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_layerTreeHost->display(updateInfo);
5732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    else {
5742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        IntRect bounds = m_dirtyRegion.bounds();
5752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ASSERT(m_webPage->bounds().contains(bounds));
57681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(bounds.size(), ShareableBitmap::SupportsAlpha);
5782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (!bitmap->createHandle(updateInfo.bitmapHandle))
5792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            return;
58081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
5812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        Vector<IntRect> rects = m_dirtyRegion.rects();
58265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (shouldPaintBoundsRect(bounds, rects)) {
5842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            rects.clear();
5852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            rects.append(bounds);
5862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
58765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        updateInfo.scrollRect = m_scrollRect;
5892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        updateInfo.scrollOffset = m_scrollOffset;
59065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_dirtyRegion = Region();
5922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_scrollRect = IntRect();
5932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_scrollOffset = IntSize();
59465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
5962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
5972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        updateInfo.updateRectBounds = bounds;
59865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        graphicsContext->translate(-bounds.x(), -bounds.y());
60065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        for (size_t i = 0; i < rects.size(); ++i) {
6022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            m_webPage->drawRect(*graphicsContext, rects[i]);
6032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            if (m_webPage->hasPageOverlay())
6042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                m_webPage->drawPageOverlay(*graphicsContext, rects[i]);
6052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            updateInfo.updateRects.append(rects[i]);
6062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
60765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
6082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
60965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Layout can trigger more calls to setNeedsDisplay and we don't want to process them
61065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // until the UI process has painted the update, so we stop the timer here.
61165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_displayTimer.stop();
6122bde8e466a4451c7319e3a072d118917957d6554Steve Block
6132bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_lastDisplayTime = currentTime();
61465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
61565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
61665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
61765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace WebKit
618