Changeset 166654 in webkit


Ignore:
Timestamp:
Apr 2, 2014, 11:16:13 AM (11 years ago)
Author:
Antti Koivisto
Message:

Split tile grid out from TileController
https://bugs.webkit.org/show_bug.cgi?id=131102

Reviewed by Simon Fraser.

Source/WebCore:

Add a TileGrid class that encapsulates tiles, zoom level and the related metadata.
This will make it possible to have multiple grids per TileController later.

Source/WebKit2:

  • WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.cpp:

(WebKit::PlatformCALayerRemoteTiledBacking::PlatformCALayerRemoteTiledBacking):

  • WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.h:
Location:
trunk/Source
Files:
1 added
10 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r166653 r166654  
     12014-04-02  Antti Koivisto  <antti@apple.com>
     2
     3        Split tile grid out from TileController
     4        https://bugs.webkit.org/show_bug.cgi?id=131102
     5
     6        Reviewed by Simon Fraser.
     7
     8        Add a TileGrid class that encapsulates tiles, zoom level and the related metadata.
     9        This will make it possible to have multiple grids per TileController later.
     10
    1112014-03-31  Brent Fulgham  <bfulgham@apple.com>
    212
  • trunk/Source/WebCore/WebCore.exp.in

    r166582 r166654  
    431431__ZN7WebCore14SubframeLoader12allowPluginsENS_28ReasonForCallingAllowPluginsE
    432432__ZN7WebCore14TileController14setTilesOpaqueEb
     433__ZN7WebCore14TileController15containerLayersEv
    433434__ZN7WebCore14TileController15setNeedsDisplayEv
    434435__ZN7WebCore14TileController21setAcceleratesDrawingEb
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r166642 r166654  
    60726072                E4C1789A0EE6903800824D69 /* CSSSelectorList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C178950EE6903800824D69 /* CSSSelectorList.cpp */; };
    60736073                E4C1789B0EE6903800824D69 /* CSSSelectorList.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C178960EE6903800824D69 /* CSSSelectorList.h */; settings = {ATTRIBUTES = (Private, ); }; };
     6074                E4C274CA18E988EA00602C76 /* TileGrid.mm in Sources */ = {isa = PBXBuildFile; fileRef = E4C274C918E988EA00602C76 /* TileGrid.mm */; };
     6075                E4C274CC18E988F500602C76 /* TileGrid.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C274CB18E988F500602C76 /* TileGrid.h */; };
    60746076                E4C279580CF9741900E97B98 /* RenderMedia.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4C279560CF9741900E97B98 /* RenderMedia.cpp */; };
    60756077                E4C279590CF9741900E97B98 /* RenderMedia.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C279570CF9741900E97B98 /* RenderMedia.h */; };
     
    1347513477                E4C178950EE6903800824D69 /* CSSSelectorList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSSelectorList.cpp; sourceTree = "<group>"; };
    1347613478                E4C178960EE6903800824D69 /* CSSSelectorList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSSelectorList.h; sourceTree = "<group>"; };
     13479                E4C274C918E988EA00602C76 /* TileGrid.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TileGrid.mm; path = ca/mac/TileGrid.mm; sourceTree = "<group>"; };
     13480                E4C274CB18E988F500602C76 /* TileGrid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TileGrid.h; path = ca/mac/TileGrid.h; sourceTree = "<group>"; };
    1347713481                E4C279560CF9741900E97B98 /* RenderMedia.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMedia.cpp; sourceTree = "<group>"; };
    1347813482                E4C279570CF9741900E97B98 /* RenderMedia.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMedia.h; sourceTree = "<group>"; };
     
    1561015614                                1AA71609149BC4DB0016EC19 /* TileController.h */,
    1561115615                                1AA71608149BC4DA0016EC19 /* TileController.mm */,
     15616                                E4C274CB18E988F500602C76 /* TileGrid.h */,
     15617                                E4C274C918E988EA00602C76 /* TileGrid.mm */,
    1561215618                                0F580FA11496939100FB5BD8 /* WebTiledBackingLayer.h */,
    1561315619                                0F580FA21496939100FB5BD8 /* WebTiledBackingLayer.mm */,
     
    2445124457                                C585A68F11D4FB08004C3E4B /* JSIDBObjectStore.h in Headers */,
    2445224458                                C585A69111D4FB08004C3E4B /* JSIDBRequest.h in Headers */,
     24459                                E4C274CC18E988F500602C76 /* TileGrid.h in Headers */,
    2445324460                                B6566270120B1227006EA85C /* JSIDBTransaction.h in Headers */,
    2445424461                                269239961505E1AA009E57FC /* JSIDBVersionChangeEvent.h in Headers */,
     
    2822728234                                A86629D009DA2B48009633A5 /* JSUIEvent.cpp in Sources */,
    2822828235                                AAA4FAD3175D5CB300743873 /* JSUIRequestEvent.cpp in Sources */,
     28236                                E4C274CA18E988EA00602C76 /* TileGrid.mm in Sources */,
    2822928237                                15C77094100D3CA8005BA267 /* JSValidityState.cpp in Sources */,
    2823028238                                CDE83DB6183D352A0031EAA3 /* JSVideoPlaybackQuality.cpp in Sources */,
  • trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.h

    r166310 r166654  
    159159
    160160    RetainPtr<NSObject> m_delegate;
    161     OwnPtr<PlatformCALayerList> m_customSublayers;
     161    std::unique_ptr<PlatformCALayerList> m_customSublayers;
    162162    GraphicsLayer::CustomAppearance m_customAppearance;
    163163    GraphicsLayer::CustomBehavior m_customBehavior;
  • trunk/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm

    r166542 r166654  
    231231        TileController* tileController = [tiledBackingLayer createTileController:this];
    232232
    233         m_customSublayers = adoptPtr(new PlatformCALayerList(1));
    234         PlatformCALayer* tileCacheTileContainerLayer = tileController->tileContainerLayer();
    235         (*m_customSublayers)[0] = tileCacheTileContainerLayer;
     233        m_customSublayers = std::make_unique<PlatformCALayerList>(tileController->containerLayers());
    236234    }
    237235
  • trunk/Source/WebCore/platform/graphics/ca/mac/TileController.h

    r166516 r166654  
    11/*
    2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828
    2929#include "FloatRect.h"
    30 #include "IntPointHash.h"
    3130#include "IntRect.h"
    3231#include "PlatformCALayer.h"
     
    4544class IntPoint;
    4645class IntRect;
     46class TileGrid;
    4747
    4848typedef Vector<RetainPtr<PlatformLayer>> PlatformLayerList;
    4949
    50 class TileController : public TiledBacking, public PlatformCALayerClient {
     50class TileController final : public TiledBacking, public PlatformCALayerClient {
    5151    WTF_MAKE_NONCOPYABLE(TileController);
    5252
     
    6161
    6262    void setScale(float);
    63     float scale() const { return m_scale; }
     63    float scale() const;
    6464
    6565    bool acceleratesDrawing() const { return m_acceleratesDrawing; }
     
    6969    bool tilesAreOpaque() const { return m_tilesAreOpaque; }
    7070
    71     PlatformCALayer *tileContainerLayer() const { return m_tileContainerLayer.get(); }
     71    PlatformCALayer& rootLayer() { return *m_tileCacheLayer; }
    7272
    7373    void setTileDebugBorderWidth(float);
     
    8080
    8181#if PLATFORM(IOS)
    82     unsigned numberOfUnparentedTiles() const { return m_cohortList.size(); }
     82    unsigned numberOfUnparentedTiles() const;
    8383    void removeUnparentedTilesNow();
    8484#endif
    8585
    8686public:
    87     // Only public for inline methods in the implementation file.
    88     typedef IntPoint TileIndex;
    89     typedef unsigned TileCohort;
    90     static const TileCohort VisibleTileCohort = UINT_MAX;
     87    // Public for TileGrid
     88    bool isInWindow() const { return m_isInWindow; }
     89
     90    float deviceScaleFactor() const { return m_deviceScaleFactor; }
     91    FloatRect exposedRect() const { return m_exposedRect; }
     92
     93    Color tileDebugBorderColor() const { return m_tileDebugBorderColor; }
     94    float tileDebugBorderWidth() const { return m_tileDebugBorderWidth; }
     95
     96    virtual IntSize tileSize() const override { return m_tileSize; }
     97    virtual IntRect bounds() const override;
     98    virtual bool hasMargins() const override;
     99    virtual int topMarginHeight() const override;
     100    virtual int bottomMarginHeight() const override;
     101    virtual int leftMarginWidth() const override;
     102    virtual int rightMarginWidth() const override;
     103    virtual TileCoverage tileCoverage() const override { return m_tileCoverage; }
     104    virtual bool unparentsOffscreenTiles() const override { return m_unparentsOffscreenTiles; }
     105
     106    IntRect boundsWithoutMargin() const;
     107
     108    FloatRect computeTileCoverageRect(const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect) const;
     109
     110    IntRect boundsAtLastRevalidate() const { return m_boundsAtLastRevalidate; }
     111    IntRect boundsAtLastRevalidateWithoutMargin() const;
     112    FloatRect visibleRectAtLastRevalidate() const { return m_visibleRectAtLastRevalidate; }
     113    void didRevalidateTiles();
     114
     115    bool shouldAggressivelyRetainTiles() const;
     116    bool shouldTemporarilyRetainTileCohorts() const;
     117
    91118    typedef HashMap<PlatformCALayer*, int> RepaintCountMap;
    92 
    93     struct TileInfo {
    94         RefPtr<PlatformCALayer> layer;
    95         TileCohort cohort; // VisibleTileCohort is visible.
    96         bool hasStaleContent;
    97        
    98         TileInfo()
    99             : cohort(VisibleTileCohort)
    100             , hasStaleContent(false)
    101         { }
    102     };
     119    RepaintCountMap& repaintCountMap() { return m_tileRepaintCounts; }
     120
     121    void updateTileCoverageMap();
     122
     123    RefPtr<PlatformCALayer> createTileLayer(const IntRect&);
     124
     125    Vector<RefPtr<PlatformCALayer>> containerLayers();
    103126
    104127private:
    105128    TileController(PlatformCALayer*);
     129
     130    TileGrid& tileGrid() { return *m_tileGrid; }
     131    const TileGrid& tileGrid() const { return *m_tileGrid; }
    106132
    107133    // TiledBacking member functions.
     
    112138    virtual void setIsInWindow(bool) override;
    113139    virtual void setTileCoverage(TileCoverage) override;
    114     virtual TileCoverage tileCoverage() const override { return m_tileCoverage; }
    115140    virtual void revalidateTiles() override;
    116141    virtual void forceRepaint() override;
    117     virtual IntSize tileSize() const override { return m_tileSize; }
    118142    virtual IntRect tileGridExtent() const override;
    119143    virtual void setScrollingPerformanceLoggingEnabled(bool flag) override { m_scrollingPerformanceLoggingEnabled = flag; }
    120144    virtual bool scrollingPerformanceLoggingEnabled() const override { return m_scrollingPerformanceLoggingEnabled; }
    121145    virtual void setUnparentsOffscreenTiles(bool flag) override { m_unparentsOffscreenTiles = flag; }
    122     virtual bool unparentsOffscreenTiles() const override { return m_unparentsOffscreenTiles; }
    123146    virtual double retainedTileBackingStoreMemory() const override;
    124147    virtual IntRect tileCoverageRect() const override;
     
    126149    virtual void setScrollingModeIndication(ScrollingModeIndication) override;
    127150    virtual void setTileMargins(int marginTop, int marginBottom, int marginLeft, int marginRight) override;
    128     virtual bool hasMargins() const override;
    129     virtual int topMarginHeight() const override;
    130     virtual int bottomMarginHeight() const override;
    131     virtual int leftMarginWidth() const override;
    132     virtual int rightMarginWidth() const override;
    133151
    134152    // PlatformCALayerClient
     
    149167    virtual float platformCALayerDeviceScaleFactor() const override;
    150168
    151     virtual IntRect bounds() const override;
    152     IntRect boundsWithoutMargin() const;
    153     IntRect boundsAtLastRevalidateWithoutMargin() const;
    154 
    155     IntRect rectForTileIndex(const TileIndex&) const;
    156     void adjustRectAtTileIndexForMargin(const TileIndex&, IntRect&) const;
    157     void getTileIndexRangeForRect(const IntRect&, TileIndex& topLeft, TileIndex& bottomRight) const;
    158 
    159     FloatRect computeTileCoverageRect(const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect) const;
    160 
    161169    void scheduleTileRevalidation(double interval);
    162170    void tileRevalidationTimerFired(Timer<TileController>*);
    163171
    164     void scheduleCohortRemoval();
    165     void cohortRemovalTimerFired(Timer<TileController>*);
    166    
    167     typedef unsigned TileValidationPolicyFlags;
    168 
    169172    void setNeedsRevalidateTiles();
    170     void revalidateTiles(TileValidationPolicyFlags foregroundValidationPolicy, TileValidationPolicyFlags backgroundValidationPolicy);
    171     enum class CoverageType { PrimaryTiles, SecondaryTiles };
    172 
    173     // Returns the bounds of the covered tiles.
    174     IntRect ensureTilesForRect(const FloatRect&, CoverageType);
    175     void updateTileCoverageMap();
    176 
    177     void removeAllTiles();
    178     void removeAllSecondaryTiles();
    179     void removeTilesInCohort(TileCohort);
    180 
    181     TileCohort nextTileCohort() const;
    182     void startedNewCohort(TileCohort);
    183    
    184     TileCohort newestTileCohort() const;
    185     TileCohort oldestTileCohort() const;
    186 
    187     void setTileNeedsDisplayInRect(const TileIndex&, TileInfo&, const IntRect& repaintRectInTileCoords, const IntRect& coverageRectInTileCoords);
    188 
    189     RefPtr<PlatformCALayer> createTileLayer(const IntRect&);
    190173
    191174    void drawTileMapContents(CGContextRef, CGRect);
     
    193176    PlatformCALayerClient* owningGraphicsLayer() const { return m_tileCacheLayer->owner(); }
    194177
    195     FloatRect scaledExposedRect() const;
    196 
    197178    PlatformCALayer* m_tileCacheLayer;
    198     RefPtr<PlatformCALayer> m_tileContainerLayer;
    199179    RefPtr<PlatformCALayer> m_tiledScrollingIndicatorLayer; // Used for coverage visualization.
    200180    RefPtr<PlatformCALayer> m_visibleRectIndicatorLayer;
     181
     182    std::unique_ptr<TileGrid> m_tileGrid;
    201183
    202184    IntSize m_tileSize;
     
    205187    FloatRect m_exposedRect; // The exposed area of containing platform views.
    206188    IntRect m_boundsAtLastRevalidate;
    207    
    208     Vector<FloatRect> m_secondaryTileCoverageRects;
    209 
    210     typedef HashMap<TileIndex, TileInfo> TileMap;
    211     TileMap m_tiles;
     189
    212190    Timer<TileController> m_tileRevalidationTimer;
    213     Timer<TileController> m_cohortRemovalTimer;
    214191
    215192    RepaintCountMap m_tileRepaintCounts;
    216193
    217     struct TileCohortInfo {
    218         TileCohort cohort;
    219         double creationTime; // in monotonicallyIncreasingTime().
    220         TileCohortInfo(TileCohort inCohort, double inTime)
    221             : cohort(inCohort)
    222             , creationTime(inTime)
    223         { }
    224     };
    225     typedef Deque<TileCohortInfo> TileCohortList;
    226     TileCohortList m_cohortList;
    227    
    228     IntRect m_primaryTileCoverageRect; // In tile coords.
    229 
    230     float m_scale;
    231194    float m_deviceScaleFactor;
    232195
  • trunk/Source/WebCore/platform/graphics/ca/mac/TileController.mm

    r166542 r166654  
    3131#import "PlatformCALayer.h"
    3232#import "Region.h"
     33#import "TileGrid.h"
    3334#if !PLATFORM(IOS)
    3435#import "LayerPool.h"
     
    5657TileController::TileController(PlatformCALayer* rootPlatformLayer)
    5758    : m_tileCacheLayer(rootPlatformLayer)
     59    , m_tileGrid(std::make_unique<TileGrid>(*this))
    5860    , m_tileSize(defaultTileWidth, defaultTileHeight)
    5961    , m_exposedRect(FloatRect::infiniteRect())
    6062    , m_tileRevalidationTimer(this, &TileController::tileRevalidationTimerFired)
    61     , m_cohortRemovalTimer(this, &TileController::cohortRemovalTimerFired)
    62     , m_scale(1)
    6363    , m_deviceScaleFactor(1)
    6464    , m_tileCoverage(CoverageForVisibleArea)
     
    7676    , m_indicatorMode(AsyncScrollingIndication)
    7777{
    78     m_tileContainerLayer = m_tileCacheLayer->createCompatibleLayer(PlatformCALayer::LayerTypeLayer, nullptr);
    79 #ifndef NDEBUG
    80     m_tileContainerLayer->setName("TileController Container Layer");
    81 #endif
    8278}
    8379
     
    9086#endif
    9187
    92     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    93         it->value.layer->setOwner(nullptr);
    94 
    9588    if (m_tiledScrollingIndicatorLayer)
    9689        m_tiledScrollingIndicatorLayer->setOwner(nullptr);
     
    10598void TileController::setNeedsDisplay()
    10699{
    107     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    108         TileInfo& tileInfo = it->value;
    109         IntRect tileRect = rectForTileIndex(it->key);
    110 
    111         if (tileRect.intersects(m_primaryTileCoverageRect) && tileInfo.layer->superlayer())
    112             tileInfo.layer->setNeedsDisplay();
    113         else
    114             tileInfo.hasStaleContent = true;
    115     }
     100    tileGrid().setNeedsDisplay();
    116101}
    117102
    118103void TileController::setNeedsDisplayInRect(const IntRect& rect)
    119104{
    120     if (m_tiles.isEmpty())
    121         return;
    122 
    123     FloatRect scaledRect(rect);
    124     scaledRect.scale(m_scale);
    125     IntRect repaintRectInTileCoords(enclosingIntRect(scaledRect));
    126 
    127     // For small invalidations, lookup the covered tiles.
    128     if (repaintRectInTileCoords.height() < 2 * m_tileSize.height() && repaintRectInTileCoords.width() < 2 * m_tileSize.width()) {
    129         TileIndex topLeft;
    130         TileIndex bottomRight;
    131         getTileIndexRangeForRect(repaintRectInTileCoords, topLeft, bottomRight);
    132 
    133         for (int y = topLeft.y(); y <= bottomRight.y(); ++y) {
    134             for (int x = topLeft.x(); x <= bottomRight.x(); ++x) {
    135                 TileIndex tileIndex(x, y);
    136                
    137                 TileMap::iterator it = m_tiles.find(tileIndex);
    138                 if (it != m_tiles.end())
    139                     setTileNeedsDisplayInRect(tileIndex, it->value, repaintRectInTileCoords, m_primaryTileCoverageRect);
    140             }
    141         }
    142         return;
    143     }
    144 
    145     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    146         setTileNeedsDisplayInRect(it->key, it->value, repaintRectInTileCoords, m_primaryTileCoverageRect);
    147 }
    148 
    149 void TileController::setTileNeedsDisplayInRect(const TileIndex& tileIndex, TileInfo& tileInfo, const IntRect& repaintRectInTileCoords, const IntRect& coverageRectInTileCoords)
    150 {
    151     PlatformCALayer* tileLayer = tileInfo.layer.get();
    152 
    153     IntRect tileRect = rectForTileIndex(tileIndex);
    154     FloatRect tileRepaintRect = tileRect;
    155     tileRepaintRect.intersect(repaintRectInTileCoords);
    156     if (tileRepaintRect.isEmpty())
    157         return;
    158 
    159     tileRepaintRect.moveBy(-tileRect.location());
    160    
    161     // We could test for intersection with the visible rect. This would reduce painting yet more,
    162     // but may make scrolling stale tiles into view more frequent.
    163     if (tileRect.intersects(coverageRectInTileCoords) && tileLayer->superlayer()) {
    164         tileLayer->setNeedsDisplay(&tileRepaintRect);
    165 
    166         if (owningGraphicsLayer()->platformCALayerShowRepaintCounter(0)) {
    167             FloatRect indicatorRect(0, 0, 52, 27);
    168             tileLayer->setNeedsDisplay(&indicatorRect);
    169         }
    170     } else
    171         tileInfo.hasStaleContent = true;
     105    tileGrid().setNeedsDisplayInRect(rect);
    172106}
    173107
     
    180114
    181115    if (platformCALayer == m_tiledScrollingIndicatorLayer.get()) {
    182         drawTileMapContents(context.platformContext(), m_tiledScrollingIndicatorLayer->bounds());
     116        tileGrid().drawTileMapContents(context.platformContext(), m_tiledScrollingIndicatorLayer->bounds());
    183117        return;
    184118    }
     
    189123        FloatPoint3D layerOrigin = platformCALayer->position();
    190124        context.translate(-layerOrigin.x(), -layerOrigin.y());
    191         context.scale(FloatSize(m_scale, m_scale));
     125        context.scale(FloatSize(tileGrid().scale(), tileGrid().scale()));
    192126
    193127        RepaintRectList dirtyRects = collectRectsToPaint(context.platformContext(), platformCALayer);
     
    223157}
    224158
     159float TileController::scale() const
     160{
     161    return tileGrid().scale();
     162}
     163
    225164void TileController::setScale(float scale)
    226165{
    227166    ASSERT(owningGraphicsLayer()->isCommittingChanges());
    228167
    229     float deviceScaleFactor = owningGraphicsLayer()->platformCALayerDeviceScaleFactor();
     168    float deviceScaleFactor = platformCALayerDeviceScaleFactor();
    230169
    231170    // The scale we get is the product of the page scale factor and device scale factor.
     
    233172    scale /= deviceScaleFactor;
    234173
    235     if (m_scale == scale && m_deviceScaleFactor == deviceScaleFactor && !m_hasTilesWithTemporaryScaleFactor)
     174    if (tileGrid().scale() == scale && m_deviceScaleFactor == deviceScaleFactor && !m_hasTilesWithTemporaryScaleFactor)
    236175        return;
    237176
    238177    m_hasTilesWithTemporaryScaleFactor = false;
    239178    m_deviceScaleFactor = deviceScaleFactor;
    240     m_scale = scale;
    241 
    242     TransformationMatrix transform;
    243     transform.scale(1 / m_scale);
    244     m_tileContainerLayer->setTransform(transform);
    245 
    246     // FIXME: we may revalidateTiles twice in this commit.
    247     revalidateTiles(PruneSecondaryTiles, PruneSecondaryTiles);
    248 
    249     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    250         it->value.layer->setContentsScale(deviceScaleFactor);
     179
     180    tileGrid().setScale(scale);
    251181}
    252182
     
    255185    if (m_acceleratesDrawing == acceleratesDrawing)
    256186        return;
    257 
    258187    m_acceleratesDrawing = acceleratesDrawing;
    259188
    260     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    261         const TileInfo& tileInfo = it->value;
    262         tileInfo.layer->setAcceleratesDrawing(m_acceleratesDrawing);
    263     }
     189    tileGrid().updateTilerLayerProperties();
    264190}
    265191
     
    268194    if (opaque == m_tilesAreOpaque)
    269195        return;
    270 
    271196    m_tilesAreOpaque = opaque;
    272197
    273     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    274         const TileInfo& tileInfo = it->value;
    275         tileInfo.layer->setOpaque(opaque);
    276     }
     198    tileGrid().updateTilerLayerProperties();
    277199}
    278200
     
    289211bool TileController::tilesWouldChangeForVisibleRect(const FloatRect& newVisibleRect) const
    290212{
    291     FloatRect visibleRect = newVisibleRect;
    292     visibleRect.intersect(scaledExposedRect());
    293 
    294     if (visibleRect.isEmpty() || bounds().isEmpty())
     213    if (bounds().isEmpty())
    295214        return false;
    296        
    297     FloatRect currentTileCoverageRect = computeTileCoverageRect(m_visibleRect, newVisibleRect);
    298     FloatRect scaledRect(currentTileCoverageRect);
    299     scaledRect.scale(m_scale);
    300     IntRect currentCoverageRectInTileCoords(enclosingIntRect(scaledRect));
    301 
    302     TileIndex topLeft;
    303     TileIndex bottomRight;
    304     getTileIndexRangeForRect(currentCoverageRectInTileCoords, topLeft, bottomRight);
    305 
    306     IntRect coverageRect = rectForTileIndex(topLeft);
    307     coverageRect.unite(rectForTileIndex(bottomRight));
    308     return coverageRect != m_primaryTileCoverageRect;
     215    return tileGrid().tilesWouldChangeForVisibleRect(newVisibleRect, m_visibleRect);
    309216}
    310217
     
    318225}
    319226
    320 FloatRect TileController::scaledExposedRect() const
    321 {
    322     FloatRect scaledExposedRect = m_exposedRect;
    323     scaledExposedRect.scale(1 / m_scale);
    324     return scaledExposedRect;
    325 }
    326 
    327227void TileController::prepopulateRect(const FloatRect& rect)
    328228{
    329     FloatRect scaledRect(rect);
    330     scaledRect.scale(m_scale);
    331     IntRect rectInTileCoords(enclosingIntRect(scaledRect));
    332 
    333     if (m_primaryTileCoverageRect.contains(rectInTileCoords))
    334         return;
    335    
    336     m_secondaryTileCoverageRects.append(rect);
    337     setNeedsRevalidateTiles();
     229    if (tileGrid().prepopulateRect(rect))
     230        setNeedsRevalidateTiles();
    338231}
    339232
     
    365258{
    366259    ASSERT(owningGraphicsLayer()->isCommittingChanges());
    367     revalidateTiles(0, 0);
     260    tileGrid().revalidateTiles(0);
     261    m_visibleRectAtLastRevalidate = m_visibleRect;
    368262}
    369263
     
    377271    if (m_tileDebugBorderWidth == borderWidth)
    378272        return;
    379 
    380273    m_tileDebugBorderWidth = borderWidth;
    381     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    382         const TileInfo& tileInfo = it->value;
    383         tileInfo.layer->setBorderWidth(m_tileDebugBorderWidth);
    384     }
     274
     275    tileGrid().updateTilerLayerProperties();
    385276}
    386277
     
    389280    if (m_tileDebugBorderColor == borderColor)
    390281        return;
    391 
    392282    m_tileDebugBorderColor = borderColor;
    393     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    394         it->value.layer->setBorderColor(borderColor);
     283
     284    tileGrid().updateTilerLayerProperties();
    395285}
    396286
     
    416306}
    417307
    418 void TileController::adjustRectAtTileIndexForMargin(const TileIndex& tileIndex, IntRect& rect) const
    419 {
    420     if (!hasMargins())
    421         return;
    422 
    423     // This is a tile in the top margin.
    424     if (m_marginTop && tileIndex.y() < 0) {
    425         rect.setY(tileIndex.y() * topMarginHeight());
    426         rect.setHeight(topMarginHeight());
    427     }
    428 
    429     // This is a tile in the left margin.
    430     if (m_marginLeft && tileIndex.x() < 0) {
    431         rect.setX(tileIndex.x() * leftMarginWidth());
    432         rect.setWidth(leftMarginWidth());
    433     }
    434 
    435     TileIndex contentTopLeft;
    436     TileIndex contentBottomRight;
    437     getTileIndexRangeForRect(boundsWithoutMargin(), contentTopLeft, contentBottomRight);
    438 
    439     // This is a tile in the bottom margin.
    440     if (m_marginBottom && tileIndex.y() > contentBottomRight.y())
    441         rect.setHeight(bottomMarginHeight());
    442 
    443     // This is a tile in the right margin.
    444     if (m_marginRight && tileIndex.x() > contentBottomRight.x())
    445         rect.setWidth(rightMarginWidth());
    446 }
    447 
    448 IntRect TileController::rectForTileIndex(const TileIndex& tileIndex) const
    449 {
    450     IntRect rect(tileIndex.x() * m_tileSize.width(), tileIndex.y() * m_tileSize.height(), m_tileSize.width(), m_tileSize.height());
    451     IntRect scaledBounds(bounds());
    452     scaledBounds.scale(m_scale);
    453 
    454     rect.intersect(scaledBounds);
    455 
    456     // These rect computations assume m_tileSize is the correct size to use. However, a tile in the margin area
    457     // might be a different size depending on the size of the margins. So adjustRectAtTileIndexForMargin() will
    458     // fix the rect we've computed to match the margin sizes if this tile is in the margins.
    459     adjustRectAtTileIndexForMargin(tileIndex, rect);
    460 
    461     return rect;
    462 }
    463 
    464 void TileController::getTileIndexRangeForRect(const IntRect& rect, TileIndex& topLeft, TileIndex& bottomRight) const
    465 {
    466     IntRect clampedRect = bounds();
    467     clampedRect.scale(m_scale);
    468     clampedRect.intersect(rect);
    469 
    470     if (clampedRect.x() >= 0)
    471         topLeft.setX(clampedRect.x() / m_tileSize.width());
    472     else
    473         topLeft.setX(floorf((float)clampedRect.x() / leftMarginWidth()));
    474 
    475     if (clampedRect.y() >= 0)
    476         topLeft.setY(clampedRect.y() / m_tileSize.height());
    477     else
    478         topLeft.setY(floorf((float)clampedRect.y() / topMarginHeight()));
    479 
    480     int bottomXRatio = ceil((float)clampedRect.maxX() / m_tileSize.width());
    481     bottomRight.setX(std::max(bottomXRatio - 1, 0));
    482 
    483     int bottomYRatio = ceil((float)clampedRect.maxY() / m_tileSize.height());
    484     bottomRight.setY(std::max(bottomYRatio - 1, 0));
    485 }
    486 
    487 FloatRect TileController::computeTileCoverageRect(const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect) const
    488 {
    489     FloatRect visibleRect = currentVisibleRect;
    490     visibleRect.intersect(scaledExposedRect());
    491 
     308FloatRect TileController::computeTileCoverageRect(const FloatRect& previousVisibleRect, const FloatRect& visibleRect) const
     309{
    492310    // If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
    493311    if (!m_isInWindow)
     
    537355}
    538356
     357bool TileController::shouldAggressivelyRetainTiles() const
     358{
     359    return owningGraphicsLayer()->platformCALayerShouldAggressivelyRetainTiles(m_tileCacheLayer);
     360}
     361
     362bool TileController::shouldTemporarilyRetainTileCohorts() const
     363{
     364    return owningGraphicsLayer()->platformCALayerShouldTemporarilyRetainTileCohorts(m_tileCacheLayer);
     365}
     366
    539367void TileController::tileRevalidationTimerFired(Timer<TileController>*)
    540368{
     
    544372    }
    545373
    546     TileValidationPolicyFlags foregroundValidationPolicy = owningGraphicsLayer()->platformCALayerShouldAggressivelyRetainTiles(m_tileCacheLayer) ? 0 : PruneSecondaryTiles;
    547     TileValidationPolicyFlags backgroundValidationPolicy = foregroundValidationPolicy | UnparentAllTiles;
    548 
    549     revalidateTiles(foregroundValidationPolicy, backgroundValidationPolicy);
     374    TileGrid::TileValidationPolicyFlags validationPolicy = (shouldAggressivelyRetainTiles() ? 0 : PruneSecondaryTiles) | UnparentAllTiles;
     375
     376    tileGrid().revalidateTiles(validationPolicy);
     377}
     378
     379void TileController::didRevalidateTiles()
     380{
     381    m_visibleRectAtLastRevalidate = visibleRect();
     382    m_boundsAtLastRevalidate = bounds();
     383
     384    updateTileCoverageMap();
    550385}
    551386
    552387unsigned TileController::blankPixelCount() const
    553388{
    554     PlatformLayerList tiles(m_tiles.size());
    555 
    556     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    557         if (PlatformLayer *layer = it->value.layer->platformLayer())
    558             tiles.append(layer);
    559     }
    560 
    561     return blankPixelCountForTiles(tiles, m_visibleRect, IntPoint(0,0));
     389    return tileGrid().blankPixelCount();
    562390}
    563391
     
    582410}
    583411
    584 static inline void queueTileForRemoval(const TileController::TileIndex& tileIndex, const TileController::TileInfo& tileInfo, Vector<TileController::TileIndex>& tilesToRemove, TileController::RepaintCountMap& repaintCounts)
    585 {
    586     tileInfo.layer->removeFromSuperlayer();
    587     repaintCounts.remove(tileInfo.layer.get());
    588     tilesToRemove.append(tileIndex);
    589 }
    590 
    591 void TileController::removeAllTiles()
    592 {
    593     Vector<TileIndex> tilesToRemove;
    594 
    595     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    596         queueTileForRemoval(it->key, it->value, tilesToRemove, m_tileRepaintCounts);
    597 
    598     for (size_t i = 0; i < tilesToRemove.size(); ++i) {
    599         TileInfo tileInfo = m_tiles.take(tilesToRemove[i]);
    600 #if !PLATFORM(IOS)
    601         LayerPool::sharedPool()->addLayer(tileInfo.layer);
    602 #endif
    603     }
    604 }
    605 
    606 void TileController::removeAllSecondaryTiles()
    607 {
    608     Vector<TileIndex> tilesToRemove;
    609 
    610     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    611         const TileInfo& tileInfo = it->value;
    612         if (tileInfo.cohort == VisibleTileCohort)
    613             continue;
    614 
    615         queueTileForRemoval(it->key, it->value, tilesToRemove, m_tileRepaintCounts);
    616     }
    617 
    618     for (size_t i = 0; i < tilesToRemove.size(); ++i) {
    619         TileInfo tileInfo = m_tiles.take(tilesToRemove[i]);
    620 #if !PLATFORM(IOS)
    621         LayerPool::sharedPool()->addLayer(tileInfo.layer);
    622 #endif
    623     }
    624 }
    625 
    626 void TileController::removeTilesInCohort(TileCohort cohort)
    627 {
    628     ASSERT(cohort != VisibleTileCohort);
    629     Vector<TileIndex> tilesToRemove;
    630 
    631     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    632         const TileInfo& tileInfo = it->value;
    633         if (tileInfo.cohort != cohort)
    634             continue;
    635 
    636         queueTileForRemoval(it->key, it->value, tilesToRemove, m_tileRepaintCounts);
    637     }
    638 
    639     for (size_t i = 0; i < tilesToRemove.size(); ++i) {
    640         TileInfo tileInfo = m_tiles.take(tilesToRemove[i]);
    641 #if !PLATFORM(IOS)
    642         LayerPool::sharedPool()->addLayer(tileInfo.layer);
    643 #endif
    644     }
    645 }
    646 
    647412void TileController::setNeedsRevalidateTiles()
    648413{
     
    650415}
    651416
    652 void TileController::revalidateTiles(TileValidationPolicyFlags foregroundValidationPolicy, TileValidationPolicyFlags backgroundValidationPolicy)
    653 {
    654     FloatRect visibleRect = m_visibleRect;
    655     IntRect bounds = this->bounds();
    656 
    657     visibleRect.intersect(scaledExposedRect());
    658 
    659     if (visibleRect.isEmpty() || bounds.isEmpty())
    660         return;
    661    
    662     TileValidationPolicyFlags validationPolicy = m_isInWindow ? foregroundValidationPolicy : backgroundValidationPolicy;
    663    
    664     FloatRect tileCoverageRect = computeTileCoverageRect(m_visibleRectAtLastRevalidate, m_visibleRect);
    665     FloatRect scaledRect(tileCoverageRect);
    666     scaledRect.scale(m_scale);
    667     IntRect coverageRectInTileCoords(enclosingIntRect(scaledRect));
    668 
    669     TileCohort currCohort = nextTileCohort();
    670     unsigned tilesInCohort = 0;
    671 
    672     // Move tiles newly outside the coverage rect into the cohort map.
    673     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    674         TileInfo& tileInfo = it->value;
    675         TileIndex tileIndex = it->key;
    676 
    677         PlatformCALayer* tileLayer = tileInfo.layer.get();
    678         IntRect tileRect = rectForTileIndex(tileIndex);
    679         if (tileRect.intersects(coverageRectInTileCoords)) {
    680             tileInfo.cohort = VisibleTileCohort;
    681             if (tileInfo.hasStaleContent) {
    682                 // FIXME: store a dirty region per layer?
    683                 tileLayer->setNeedsDisplay();
    684                 tileInfo.hasStaleContent = false;
    685             }
    686         } else {
    687             // Add to the currentCohort if not already in one.
    688             if (tileInfo.cohort == VisibleTileCohort) {
    689                 tileInfo.cohort = currCohort;
    690                 ++tilesInCohort;
    691 
    692                 if (m_unparentsOffscreenTiles)
    693                     tileLayer->removeFromSuperlayer();
    694             }
    695         }
    696     }
    697 
    698     if (tilesInCohort)
    699         startedNewCohort(currCohort);
    700 
    701     if (!owningGraphicsLayer()->platformCALayerShouldAggressivelyRetainTiles(m_tileCacheLayer)) {
    702         if (owningGraphicsLayer()->platformCALayerShouldTemporarilyRetainTileCohorts(m_tileCacheLayer))
    703             scheduleCohortRemoval();
    704         else if (tilesInCohort)
    705             removeTilesInCohort(currCohort);
    706     }
    707 
    708     // Ensure primary tile coverage tiles.
    709     m_primaryTileCoverageRect = ensureTilesForRect(tileCoverageRect, CoverageType::PrimaryTiles);
    710 
    711     if (validationPolicy & PruneSecondaryTiles) {
    712         removeAllSecondaryTiles();
    713         m_cohortList.clear();
    714     } else {
    715         for (size_t i = 0; i < m_secondaryTileCoverageRects.size(); ++i)
    716             ensureTilesForRect(m_secondaryTileCoverageRects[i], CoverageType::SecondaryTiles);
    717         m_secondaryTileCoverageRects.clear();
    718     }
    719 
    720     if (m_unparentsOffscreenTiles && (validationPolicy & UnparentAllTiles)) {
    721         for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    722             it->value.layer->removeFromSuperlayer();
    723     }
    724 
    725     if (m_boundsAtLastRevalidate != bounds) {
    726         // If there are margin tiles and the bounds have grown taller or wider, then the tiles that used to
    727         // be bottom or right margin tiles need to be invalidated.
    728         if (hasMargins()) {
    729             if (bounds.width() > m_boundsAtLastRevalidate.width() || bounds.height() > m_boundsAtLastRevalidate.height()) {
    730                 IntRect boundsWithoutMargin = this->boundsWithoutMargin();
    731                 IntRect oldBoundsWithoutMargin = boundsAtLastRevalidateWithoutMargin();
    732 
    733                 if (bounds.height() > m_boundsAtLastRevalidate.height()) {
    734                     IntRect formerBottomMarginRect = IntRect(oldBoundsWithoutMargin.x(), oldBoundsWithoutMargin.height(),
    735                         oldBoundsWithoutMargin.width(), boundsWithoutMargin.height() - oldBoundsWithoutMargin.height());
    736                     setNeedsDisplayInRect(formerBottomMarginRect);
    737                 }
    738 
    739                 if (bounds.width() > m_boundsAtLastRevalidate.width()) {
    740                     IntRect formerRightMarginRect = IntRect(oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.y(),
    741                         boundsWithoutMargin.width() - oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.height());
    742                     setNeedsDisplayInRect(formerRightMarginRect);
    743                 }
    744             }
    745         }
    746 
    747         FloatRect scaledBounds(bounds);
    748         scaledBounds.scale(m_scale);
    749         IntRect boundsInTileCoords(enclosingIntRect(scaledBounds));
    750 
    751         TileIndex topLeftForBounds;
    752         TileIndex bottomRightForBounds;
    753         getTileIndexRangeForRect(boundsInTileCoords, topLeftForBounds, bottomRightForBounds);
    754 
    755         Vector<TileIndex> tilesToRemove;
    756         for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    757             const TileIndex& index = it->key;
    758             if (index.y() < topLeftForBounds.y()
    759                 || index.y() > bottomRightForBounds.y()
    760                 || index.x() < topLeftForBounds.x()
    761                 || index.x() > bottomRightForBounds.x())
    762                 queueTileForRemoval(index, it->value, tilesToRemove, m_tileRepaintCounts);
    763         }
    764 
    765         for (size_t i = 0, size = tilesToRemove.size(); i < size; ++i) {
    766             TileInfo tileInfo = m_tiles.take(tilesToRemove[i]);
    767 #if !PLATFORM(IOS)
    768             LayerPool::sharedPool()->addLayer(tileInfo.layer);
    769 #endif
    770         }
    771     }
    772 
    773     if (m_tiledScrollingIndicatorLayer)
    774         updateTileCoverageMap();
    775 
    776     m_visibleRectAtLastRevalidate = visibleRect;
    777     m_boundsAtLastRevalidate = bounds;
    778 }
    779 
    780 TileController::TileCohort TileController::nextTileCohort() const
    781 {
    782     if (!m_cohortList.isEmpty())
    783         return m_cohortList.last().cohort + 1;
    784 
    785     return 1;
    786 }
    787 
    788 void TileController::startedNewCohort(TileCohort cohort)
    789 {
    790     m_cohortList.append(TileCohortInfo(cohort, monotonicallyIncreasingTime()));
    791 #if PLATFORM(IOS)
    792     if (!m_isInWindow)
    793         tileControllerMemoryHandler().tileControllerGainedUnparentedTiles(this);
    794 #endif
    795 }
    796 
    797 TileController::TileCohort TileController::newestTileCohort() const
    798 {
    799     return m_cohortList.isEmpty() ? 0 : m_cohortList.last().cohort;
    800 }
    801 
    802 TileController::TileCohort TileController::oldestTileCohort() const
    803 {
    804     return m_cohortList.isEmpty() ? 0 : m_cohortList.first().cohort;
    805 }
    806 
    807 void TileController::scheduleCohortRemoval()
    808 {
    809     const double cohortRemovalTimerSeconds = 1;
    810 
    811     // Start the timer, or reschedule the timer from now if it's already active.
    812     if (!m_cohortRemovalTimer.isActive())
    813         m_cohortRemovalTimer.startRepeating(cohortRemovalTimerSeconds);
    814 }
    815 
    816 void TileController::cohortRemovalTimerFired(Timer<TileController>*)
    817 {
    818     if (m_cohortList.isEmpty()) {
    819         m_cohortRemovalTimer.stop();
    820         return;
    821     }
    822 
    823     double cohortLifeTimeSeconds = 2;
    824     double timeThreshold = monotonicallyIncreasingTime() - cohortLifeTimeSeconds;
    825 
    826     while (!m_cohortList.isEmpty() && m_cohortList.first().creationTime < timeThreshold) {
    827         TileCohortInfo firstCohort = m_cohortList.takeFirst();
    828         removeTilesInCohort(firstCohort.cohort);
    829     }
    830 
    831     if (m_tiledScrollingIndicatorLayer)
    832         updateTileCoverageMap();
    833 }
    834 
    835 IntRect TileController::ensureTilesForRect(const FloatRect& rect, CoverageType newTileType)
    836 {
    837     if (m_unparentsOffscreenTiles && !m_isInWindow)
    838         return IntRect();
    839 
    840     FloatRect scaledRect(rect);
    841     scaledRect.scale(m_scale);
    842     IntRect rectInTileCoords(enclosingIntRect(scaledRect));
    843 
    844     TileIndex topLeft;
    845     TileIndex bottomRight;
    846     getTileIndexRangeForRect(rectInTileCoords, topLeft, bottomRight);
    847 
    848     TileCohort currCohort = nextTileCohort();
    849     unsigned tilesInCohort = 0;
    850 
    851     IntRect coverageRect;
    852 
    853     for (int y = topLeft.y(); y <= bottomRight.y(); ++y) {
    854         for (int x = topLeft.x(); x <= bottomRight.x(); ++x) {
    855             TileIndex tileIndex(x, y);
    856 
    857             IntRect tileRect = rectForTileIndex(tileIndex);
    858             TileInfo& tileInfo = m_tiles.add(tileIndex, TileInfo()).iterator->value;
    859 
    860             coverageRect.unite(tileRect);
    861 
    862             bool shouldChangeTileLayerFrame = false;
    863 
    864             if (!tileInfo.layer)
    865                 tileInfo.layer = createTileLayer(tileRect);
    866             else {
    867                 // We already have a layer for this tile. Ensure that its size is correct.
    868                 FloatSize tileLayerSize(tileInfo.layer->bounds().size());
    869                 shouldChangeTileLayerFrame = tileLayerSize != FloatSize(tileRect.size());
    870 
    871                 if (shouldChangeTileLayerFrame) {
    872                     tileInfo.layer->setBounds(FloatRect(FloatPoint(), tileRect.size()));
    873                     tileInfo.layer->setPosition(tileRect.location());
    874                     tileInfo.layer->setNeedsDisplay();
    875                 }
    876             }
    877 
    878             if (newTileType == CoverageType::SecondaryTiles && !tileRect.intersects(m_primaryTileCoverageRect)) {
    879                 tileInfo.cohort = currCohort;
    880                 ++tilesInCohort;
    881             }
    882 
    883             bool shouldParentTileLayer = (!m_unparentsOffscreenTiles || m_isInWindow) && !tileInfo.layer->superlayer();
    884 
    885             if (shouldParentTileLayer)
    886                 m_tileContainerLayer->appendSublayer(tileInfo.layer.get());
    887         }
    888     }
    889    
    890     if (tilesInCohort)
    891         startedNewCohort(currCohort);
    892 
    893     return coverageRect;
    894 }
    895 
    896417void TileController::updateTileCoverageMap()
    897418{
     419    if (!m_tiledScrollingIndicatorLayer)
     420        return;
    898421    FloatRect containerBounds = bounds();
    899422    FloatRect visibleRect = this->visibleRect();
    900423
    901     visibleRect.intersect(scaledExposedRect());
     424    visibleRect.intersect(tileGrid().scaledExposedRect());
    902425    visibleRect.contract(4, 4); // Layer is positioned 2px from top and left edges.
    903426
     
    909432    }
    910433   
    911     float indicatorScale = scale * m_scale;
     434    float indicatorScale = scale * tileGrid().scale();
    912435    FloatRect mapBounds = containerBounds;
    913436    mapBounds.scale(indicatorScale, indicatorScale);
     
    944467IntRect TileController::tileGridExtent() const
    945468{
    946     TileIndex topLeft;
    947     TileIndex bottomRight;
    948     getTileIndexRangeForRect(m_primaryTileCoverageRect, topLeft, bottomRight);
    949 
    950     // Return index of top, left tile and the number of tiles across and down.
    951     return IntRect(topLeft.x(), topLeft.y(), bottomRight.x() - topLeft.x() + 1, bottomRight.y() - topLeft.y() + 1);
     469    return tileGrid().extent();
    952470}
    953471
    954472double TileController::retainedTileBackingStoreMemory() const
    955473{
    956     double totalBytes = 0;
    957    
    958     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    959         const TileInfo& tileInfo = it->value;
    960         if (tileInfo.layer->superlayer()) {
    961             FloatRect bounds = tileInfo.layer->bounds();
    962             double contentsScale = tileInfo.layer->contentsScale();
    963             totalBytes += 4 * bounds.width() * contentsScale * bounds.height() * contentsScale;
    964         }
    965     }
    966 
    967     return totalBytes;
     474    return tileGrid().retainedTileBackingStoreMemory();
    968475}
    969476
     
    971478IntRect TileController::tileCoverageRect() const
    972479{
    973     IntRect coverageRectInLayerCoords(m_primaryTileCoverageRect);
    974     coverageRectInLayerCoords.scale(1 / m_scale);
    975     return coverageRectInLayerCoords;
     480    return tileGrid().tileCoverageRect();
    976481}
    977482
     
    1006511    m_indicatorMode = scrollingMode;
    1007512
    1008     if (m_tiledScrollingIndicatorLayer)
    1009         updateTileCoverageMap();
     513    updateTileCoverageMap();
    1010514}
    1011515
     
    1093597}
    1094598
    1095 void TileController::drawTileMapContents(CGContextRef context, CGRect layerBounds)
    1096 {
    1097     CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 1);
    1098     CGContextFillRect(context, layerBounds);
    1099 
    1100     CGFloat scaleFactor = layerBounds.size.width / bounds().width();
    1101 
    1102     CGFloat contextScale = scaleFactor / scale();
    1103     CGContextScaleCTM(context, contextScale, contextScale);
    1104    
    1105     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    1106         const TileInfo& tileInfo = it->value;
    1107         PlatformCALayer* tileLayer = tileInfo.layer.get();
    1108 
    1109         CGFloat red = 1;
    1110         CGFloat green = 1;
    1111         CGFloat blue = 1;
    1112         if (tileInfo.hasStaleContent) {
    1113             red = 0.25;
    1114             green = 0.125;
    1115             blue = 0;
    1116         }
    1117 
    1118         TileCohort newestCohort = newestTileCohort();
    1119         TileCohort oldestCohort = oldestTileCohort();
    1120 
    1121         if (!owningGraphicsLayer()->platformCALayerShouldAggressivelyRetainTiles(m_tileCacheLayer) && tileInfo.cohort != VisibleTileCohort && newestCohort > oldestCohort) {
    1122             float cohortProportion = static_cast<float>((newestCohort - tileInfo.cohort)) / (newestCohort - oldestCohort);
    1123             CGContextSetRGBFillColor(context, red, green, blue, 1 - cohortProportion);
    1124         } else
    1125             CGContextSetRGBFillColor(context, red, green, blue, 1);
    1126 
    1127         if (tileLayer->superlayer()) {
    1128             CGContextSetLineWidth(context, 0.5 / contextScale);
    1129             CGContextSetRGBStrokeColor(context, 0, 0, 0, 1);
    1130         } else {
    1131             CGContextSetLineWidth(context, 1 / contextScale);
    1132             CGContextSetRGBStrokeColor(context, 0.2, 0.1, 0.9, 1);
    1133         }
    1134 
    1135         CGRect frame = CGRectMake(tileLayer->position().x(), tileLayer->position().y(), tileLayer->bounds().size().width(), tileLayer->bounds().size().height());
    1136         CGContextFillRect(context, frame);
    1137         CGContextStrokeRect(context, frame);
    1138     }
     599Vector<RefPtr<PlatformCALayer>> TileController::containerLayers()
     600{
     601    Vector<RefPtr<PlatformCALayer>> layerList(1);
     602    layerList[0] = &tileGrid().containerLayer();
     603    return layerList;
    1139604}
    1140605   
    1141606#if PLATFORM(IOS)
     607unsigned TileController::numberOfUnparentedTiles() const
     608{
     609    return tileGrid().numberOfUnparentedTiles();
     610}
     611
    1142612void TileController::removeUnparentedTilesNow()
    1143613{
    1144     while (!m_cohortList.isEmpty()) {
    1145         TileCohortInfo firstCohort = m_cohortList.takeFirst();
    1146         removeTilesInCohort(firstCohort.cohort);
    1147     }
    1148 
    1149     if (m_tiledScrollingIndicatorLayer)
    1150         updateTileCoverageMap();
     614    tileGrid().removeUnparentedTilesNow();
     615
     616    updateTileCoverageMap();
    1151617}
    1152618#endif
  • trunk/Source/WebCore/platform/graphics/ca/mac/TileGrid.mm

    r166575 r166654  
    11/*
    2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011-2014 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2525
    2626#import "config.h"
     27#import "TileGrid.h"
     28
     29#import "LayerPool.h"
     30#import "PlatformCALayer.h"
    2731#import "TileController.h"
    28 
    29 #import "GraphicsContext.h"
    30 #import "IntRect.h"
    31 #import "PlatformCALayer.h"
    32 #import "Region.h"
    33 #if !PLATFORM(IOS)
    34 #import "LayerPool.h"
    35 #endif
    36 #import "WebLayer.h"
    3732#import <wtf/MainThread.h>
    38 #import <utility>
    3933
    4034#if PLATFORM(IOS)
     
    4943};
    5044
    51 PassOwnPtr<TileController> TileController::create(PlatformCALayer* rootPlatformLayer)
    52 {
    53     return adoptPtr(new TileController(rootPlatformLayer));
    54 }
    55 
    56 TileController::TileController(PlatformCALayer* rootPlatformLayer)
    57     : m_tileCacheLayer(rootPlatformLayer)
    58     , m_tileSize(defaultTileWidth, defaultTileHeight)
    59     , m_exposedRect(FloatRect::infiniteRect())
    60     , m_tileRevalidationTimer(this, &TileController::tileRevalidationTimerFired)
    61     , m_cohortRemovalTimer(this, &TileController::cohortRemovalTimerFired)
    62     , m_scale(1)
    63     , m_deviceScaleFactor(1)
    64     , m_tileCoverage(CoverageForVisibleArea)
    65     , m_marginTop(0)
    66     , m_marginBottom(0)
    67     , m_marginLeft(0)
    68     , m_marginRight(0)
    69     , m_isInWindow(false)
    70     , m_scrollingPerformanceLoggingEnabled(false)
    71     , m_unparentsOffscreenTiles(false)
    72     , m_acceleratesDrawing(false)
    73     , m_tilesAreOpaque(false)
    74     , m_hasTilesWithTemporaryScaleFactor(false)
    75     , m_tileDebugBorderWidth(0)
    76     , m_indicatorMode(AsyncScrollingIndication)
    77 {
    78     m_tileContainerLayer = m_tileCacheLayer->createCompatibleLayer(PlatformCALayer::LayerTypeLayer, nullptr);
     45TileGrid::TileGrid(TileController& controller)
     46    : m_controller(controller)
     47    , m_containerLayer(*controller.rootLayer().createCompatibleLayer(PlatformCALayer::LayerTypeLayer, nullptr))
     48    , m_cohortRemovalTimer(this, &TileGrid::cohortRemovalTimerFired)
     49{
    7950#ifndef NDEBUG
    80     m_tileContainerLayer->setName("TileController Container Layer");
     51    m_containerLayer.get().setName("TileGrid Container Layer");
    8152#endif
    8253}
    8354
    84 TileController::~TileController()
     55TileGrid::~TileGrid()
    8556{
    8657    ASSERT(isMainThread());
    8758
    88 #if PLATFORM(IOS)
    89     tileControllerMemoryHandler().removeTileController(this);
    90 #endif
    91 
    92     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    93         it->value.layer->setOwner(nullptr);
    94 
    95     if (m_tiledScrollingIndicatorLayer)
    96         m_tiledScrollingIndicatorLayer->setOwner(nullptr);
    97 }
    98 
    99 void TileController::tileCacheLayerBoundsChanged()
    100 {
    101     ASSERT(owningGraphicsLayer()->isCommittingChanges());
    102     setNeedsRevalidateTiles();
    103 }
    104 
    105 void TileController::setNeedsDisplay()
    106 {
    107     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    108         TileInfo& tileInfo = it->value;
    109         IntRect tileRect = rectForTileIndex(it->key);
     59    for (auto& tile : m_tiles.values())
     60        tile.layer->setOwner(nullptr);
     61}
     62
     63void TileGrid::setScale(float scale)
     64{
     65    m_scale = scale;
     66
     67    TransformationMatrix transform;
     68    transform.scale(1 / m_scale);
     69    m_containerLayer->setTransform(transform);
     70
     71    // FIXME: we may revalidateTiles twice in this commit.
     72    revalidateTiles(PruneSecondaryTiles);
     73
     74    for (auto& tile : m_tiles.values())
     75        tile.layer->setContentsScale(m_controller.deviceScaleFactor());
     76}
     77
     78void TileGrid::setNeedsDisplay()
     79{
     80    for (auto& entry : m_tiles) {
     81        TileInfo& tileInfo = entry.value;
     82        IntRect tileRect = rectForTileIndex(entry.key);
    11083
    11184        if (tileRect.intersects(m_primaryTileCoverageRect) && tileInfo.layer->superlayer())
     
    11689}
    11790
    118 void TileController::setNeedsDisplayInRect(const IntRect& rect)
     91void TileGrid::setNeedsDisplayInRect(const IntRect& rect)
    11992{
    12093    if (m_tiles.isEmpty())
     
    12598    IntRect repaintRectInTileCoords(enclosingIntRect(scaledRect));
    12699
     100    IntSize tileSize = m_controller.tileSize();
     101
    127102    // For small invalidations, lookup the covered tiles.
    128     if (repaintRectInTileCoords.height() < 2 * m_tileSize.height() && repaintRectInTileCoords.width() < 2 * m_tileSize.width()) {
     103    if (repaintRectInTileCoords.height() < 2 * tileSize.height() && repaintRectInTileCoords.width() < 2 * tileSize.width()) {
    129104        TileIndex topLeft;
    130105        TileIndex bottomRight;
     
    147122}
    148123
    149 void TileController::setTileNeedsDisplayInRect(const TileIndex& tileIndex, TileInfo& tileInfo, const IntRect& repaintRectInTileCoords, const IntRect& coverageRectInTileCoords)
     124void TileGrid::setTileNeedsDisplayInRect(const TileIndex& tileIndex, TileInfo& tileInfo, const IntRect& repaintRectInTileCoords, const IntRect& coverageRectInTileCoords)
    150125{
    151126    PlatformCALayer* tileLayer = tileInfo.layer.get();
     
    164139        tileLayer->setNeedsDisplay(&tileRepaintRect);
    165140
    166         if (owningGraphicsLayer()->platformCALayerShowRepaintCounter(0)) {
     141        if (m_controller.rootLayer().owner()->platformCALayerShowRepaintCounter(0)) {
    167142            FloatRect indicatorRect(0, 0, 52, 27);
    168143            tileLayer->setNeedsDisplay(&indicatorRect);
     
    172147}
    173148
    174 void TileController::platformCALayerPaintContents(PlatformCALayer* platformCALayer, GraphicsContext& context, const FloatRect&)
    175 {
    176 #if PLATFORM(IOS)
    177     if (pthread_main_np())
    178         WebThreadLock();
    179 #endif
    180 
    181     if (platformCALayer == m_tiledScrollingIndicatorLayer.get()) {
    182         drawTileMapContents(context.platformContext(), m_tiledScrollingIndicatorLayer->bounds());
    183         return;
    184     }
    185 
    186     {
    187         GraphicsContextStateSaver stateSaver(context);
    188 
    189         FloatPoint3D layerOrigin = platformCALayer->position();
    190         context.translate(-layerOrigin.x(), -layerOrigin.y());
    191         context.scale(FloatSize(m_scale, m_scale));
    192 
    193         RepaintRectList dirtyRects = collectRectsToPaint(context.platformContext(), platformCALayer);
    194         drawLayerContents(context.platformContext(), m_tileCacheLayer, dirtyRects);
    195     }
    196 
    197     int repaintCount = platformCALayerIncrementRepaintCount(platformCALayer);
    198     if (owningGraphicsLayer()->platformCALayerShowRepaintCounter(0))
    199         drawRepaintIndicator(context.platformContext(), platformCALayer, repaintCount, cachedCGColor(m_tileDebugBorderColor, ColorSpaceDeviceRGB));
    200 
    201     if (scrollingPerformanceLoggingEnabled()) {
    202         FloatRect visiblePart(platformCALayer->position().x(), platformCALayer->position().y(), platformCALayer->bounds().size().width(), platformCALayer->bounds().size().height());
    203         visiblePart.intersect(visibleRect());
    204 
    205         if (repaintCount == 1 && !visiblePart.isEmpty())
    206             WTFLogAlways("SCROLLING: Filled visible fresh tile. Time: %f Unfilled Pixels: %u\n", WTF::monotonicallyIncreasingTime(), blankPixelCount());
    207     }
    208 }
    209 
    210 float TileController::platformCALayerDeviceScaleFactor() const
    211 {
    212     return owningGraphicsLayer()->platformCALayerDeviceScaleFactor();
    213 }
    214 
    215 bool TileController::platformCALayerShowDebugBorders() const
    216 {
    217     return owningGraphicsLayer()->platformCALayerShowDebugBorders();
    218 }
    219 
    220 bool TileController::platformCALayerShowRepaintCounter(PlatformCALayer*) const
    221 {
    222     return owningGraphicsLayer()->platformCALayerShowRepaintCounter(0);
    223 }
    224 
    225 void TileController::setScale(float scale)
    226 {
    227     ASSERT(owningGraphicsLayer()->isCommittingChanges());
    228 
    229     float deviceScaleFactor = owningGraphicsLayer()->platformCALayerDeviceScaleFactor();
    230 
    231     // The scale we get is the product of the page scale factor and device scale factor.
    232     // Divide by the device scale factor so we'll get the page scale factor.
    233     scale /= deviceScaleFactor;
    234 
    235     if (m_scale == scale && m_deviceScaleFactor == deviceScaleFactor && !m_hasTilesWithTemporaryScaleFactor)
    236         return;
    237 
    238     m_hasTilesWithTemporaryScaleFactor = false;
    239     m_deviceScaleFactor = deviceScaleFactor;
    240     m_scale = scale;
    241 
    242     TransformationMatrix transform;
    243     transform.scale(1 / m_scale);
    244     m_tileContainerLayer->setTransform(transform);
    245 
    246     // FIXME: we may revalidateTiles twice in this commit.
    247     revalidateTiles(PruneSecondaryTiles, PruneSecondaryTiles);
    248 
    249     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    250         it->value.layer->setContentsScale(deviceScaleFactor);
    251 }
    252 
    253 void TileController::setAcceleratesDrawing(bool acceleratesDrawing)
    254 {
    255     if (m_acceleratesDrawing == acceleratesDrawing)
    256         return;
    257 
    258     m_acceleratesDrawing = acceleratesDrawing;
     149void TileGrid::updateTilerLayerProperties()
     150{
     151    bool acceleratesDrawing = m_controller.acceleratesDrawing();
     152    bool opaque = m_controller.tilesAreOpaque();
     153    Color tileDebugBorderColor = m_controller.tileDebugBorderColor();
     154    float tileDebugBorderWidth = m_controller.tileDebugBorderWidth();
    259155
    260156    for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    261157        const TileInfo& tileInfo = it->value;
    262         tileInfo.layer->setAcceleratesDrawing(m_acceleratesDrawing);
    263     }
    264 }
    265 
    266 void TileController::setTilesOpaque(bool opaque)
    267 {
    268     if (opaque == m_tilesAreOpaque)
    269         return;
    270 
    271     m_tilesAreOpaque = opaque;
    272 
    273     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    274         const TileInfo& tileInfo = it->value;
     158        tileInfo.layer->setAcceleratesDrawing(acceleratesDrawing);
    275159        tileInfo.layer->setOpaque(opaque);
    276     }
    277 }
    278 
    279 void TileController::setVisibleRect(const FloatRect& visibleRect)
    280 {
    281     ASSERT(owningGraphicsLayer()->isCommittingChanges());
    282     if (m_visibleRect == visibleRect)
    283         return;
    284 
    285     m_visibleRect = visibleRect;
    286     setNeedsRevalidateTiles();
    287 }
    288 
    289 bool TileController::tilesWouldChangeForVisibleRect(const FloatRect& newVisibleRect) const
     160        tileInfo.layer->setBorderColor(tileDebugBorderColor);
     161        tileInfo.layer->setBorderWidth(tileDebugBorderWidth);
     162    }
     163}
     164
     165bool TileGrid::tilesWouldChangeForVisibleRect(const FloatRect& newVisibleRect, const FloatRect& oldVisibleRect) const
    290166{
    291167    FloatRect visibleRect = newVisibleRect;
    292168    visibleRect.intersect(scaledExposedRect());
    293169
    294     if (visibleRect.isEmpty() || bounds().isEmpty())
     170    if (visibleRect.isEmpty())
    295171        return false;
    296172       
    297     FloatRect currentTileCoverageRect = computeTileCoverageRect(m_visibleRect, newVisibleRect);
     173    FloatRect currentTileCoverageRect = m_controller.computeTileCoverageRect(oldVisibleRect, newVisibleRect);
    298174    FloatRect scaledRect(currentTileCoverageRect);
    299175    scaledRect.scale(m_scale);
     
    309185}
    310186
    311 void TileController::setExposedRect(const FloatRect& exposedRect)
    312 {
    313     if (m_exposedRect == exposedRect)
    314         return;
    315 
    316     m_exposedRect = exposedRect;
    317     setNeedsRevalidateTiles();
    318 }
    319 
    320 FloatRect TileController::scaledExposedRect() const
    321 {
    322     FloatRect scaledExposedRect = m_exposedRect;
     187FloatRect TileGrid::scaledExposedRect() const
     188{
     189    FloatRect scaledExposedRect = m_controller.exposedRect();
    323190    scaledExposedRect.scale(1 / m_scale);
    324191    return scaledExposedRect;
    325192}
    326193
    327 void TileController::prepopulateRect(const FloatRect& rect)
     194bool TileGrid::prepopulateRect(const FloatRect& rect)
    328195{
    329196    FloatRect scaledRect(rect);
     
    332199
    333200    if (m_primaryTileCoverageRect.contains(rectInTileCoords))
    334         return;
     201        return false;
    335202   
    336203    m_secondaryTileCoverageRects.append(rect);
    337     setNeedsRevalidateTiles();
    338 }
    339 
    340 void TileController::setIsInWindow(bool isInWindow)
    341 {
    342     if (m_isInWindow == isInWindow)
     204    return true;
     205}
     206
     207void TileGrid::adjustRectAtTileIndexForMargin(const TileIndex& tileIndex, IntRect& rect) const
     208{
     209    if (!m_controller.hasMargins())
    343210        return;
    344211
    345     m_isInWindow = isInWindow;
    346 
    347     if (m_isInWindow)
    348         setNeedsRevalidateTiles();
    349     else {
    350         const double tileRevalidationTimeout = 4;
    351         scheduleTileRevalidation(tileRevalidationTimeout);
    352     }
    353 }
    354 
    355 void TileController::setTileCoverage(TileCoverage coverage)
    356 {
    357     if (coverage == m_tileCoverage)
    358         return;
    359 
    360     m_tileCoverage = coverage;
    361     setNeedsRevalidateTiles();
    362 }
    363 
    364 void TileController::revalidateTiles()
    365 {
    366     ASSERT(owningGraphicsLayer()->isCommittingChanges());
    367     revalidateTiles(0, 0);
    368 }
    369 
    370 void TileController::forceRepaint()
    371 {
    372     setNeedsDisplay();
    373 }
    374 
    375 void TileController::setTileDebugBorderWidth(float borderWidth)
    376 {
    377     if (m_tileDebugBorderWidth == borderWidth)
    378         return;
    379 
    380     m_tileDebugBorderWidth = borderWidth;
    381     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    382         const TileInfo& tileInfo = it->value;
    383         tileInfo.layer->setBorderWidth(m_tileDebugBorderWidth);
    384     }
    385 }
    386 
    387 void TileController::setTileDebugBorderColor(Color borderColor)
    388 {
    389     if (m_tileDebugBorderColor == borderColor)
    390         return;
    391 
    392     m_tileDebugBorderColor = borderColor;
    393     for (TileMap::const_iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    394         it->value.layer->setBorderColor(borderColor);
    395 }
    396 
    397 IntRect TileController::bounds() const
    398 {
    399     IntPoint boundsOriginIncludingMargin(-leftMarginWidth(), -topMarginHeight());
    400     IntSize boundsSizeIncludingMargin = expandedIntSize(m_tileCacheLayer->bounds().size());
    401     boundsSizeIncludingMargin.expand(leftMarginWidth() + rightMarginWidth(), topMarginHeight() + bottomMarginHeight());
    402 
    403     return IntRect(boundsOriginIncludingMargin, boundsSizeIncludingMargin);
    404 }
    405 
    406 IntRect TileController::boundsWithoutMargin() const
    407 {
    408     return IntRect(IntPoint(), expandedIntSize(m_tileCacheLayer->bounds().size()));
    409 }
    410 
    411 IntRect TileController::boundsAtLastRevalidateWithoutMargin() const
    412 {
    413     IntRect boundsWithoutMargin = IntRect(IntPoint(), m_boundsAtLastRevalidate.size());
    414     boundsWithoutMargin.contract(IntSize(leftMarginWidth() + rightMarginWidth(), topMarginHeight() + bottomMarginHeight()));
    415     return boundsWithoutMargin;
    416 }
    417 
    418 void TileController::adjustRectAtTileIndexForMargin(const TileIndex& tileIndex, IntRect& rect) const
    419 {
    420     if (!hasMargins())
    421         return;
    422 
    423212    // This is a tile in the top margin.
    424     if (m_marginTop && tileIndex.y() < 0) {
    425         rect.setY(tileIndex.y() * topMarginHeight());
    426         rect.setHeight(topMarginHeight());
     213    if (m_controller.topMarginHeight() && tileIndex.y() < 0) {
     214        rect.setY(tileIndex.y() * m_controller.topMarginHeight());
     215        rect.setHeight(m_controller.topMarginHeight());
    427216    }
    428217
    429218    // This is a tile in the left margin.
    430     if (m_marginLeft && tileIndex.x() < 0) {
    431         rect.setX(tileIndex.x() * leftMarginWidth());
    432         rect.setWidth(leftMarginWidth());
     219    if (m_controller.leftMarginWidth() && tileIndex.x() < 0) {
     220        rect.setX(tileIndex.x() * m_controller.leftMarginWidth());
     221        rect.setWidth(m_controller.leftMarginWidth());
    433222    }
    434223
    435224    TileIndex contentTopLeft;
    436225    TileIndex contentBottomRight;
    437     getTileIndexRangeForRect(boundsWithoutMargin(), contentTopLeft, contentBottomRight);
     226    getTileIndexRangeForRect(m_controller.boundsWithoutMargin(), contentTopLeft, contentBottomRight);
    438227
    439228    // This is a tile in the bottom margin.
    440     if (m_marginBottom && tileIndex.y() > contentBottomRight.y())
    441         rect.setHeight(bottomMarginHeight());
     229    if (m_controller.bottomMarginHeight() && tileIndex.y() > contentBottomRight.y())
     230        rect.setHeight(m_controller.bottomMarginHeight());
    442231
    443232    // This is a tile in the right margin.
    444     if (m_marginRight && tileIndex.x() > contentBottomRight.x())
    445         rect.setWidth(rightMarginWidth());
    446 }
    447 
    448 IntRect TileController::rectForTileIndex(const TileIndex& tileIndex) const
    449 {
    450     IntRect rect(tileIndex.x() * m_tileSize.width(), tileIndex.y() * m_tileSize.height(), m_tileSize.width(), m_tileSize.height());
    451     IntRect scaledBounds(bounds());
     233    if (m_controller.rightMarginWidth()  && tileIndex.x() > contentBottomRight.x())
     234        rect.setWidth(m_controller.rightMarginWidth());
     235}
     236
     237IntRect TileGrid::rectForTileIndex(const TileIndex& tileIndex) const
     238{
     239    IntSize tileSize = m_controller.tileSize();
     240    IntRect rect(tileIndex.x() * tileSize.width(), tileIndex.y() * tileSize.height(), tileSize.width(), tileSize.height());
     241    IntRect scaledBounds(m_controller.bounds());
    452242    scaledBounds.scale(m_scale);
    453243
     
    462252}
    463253
    464 void TileController::getTileIndexRangeForRect(const IntRect& rect, TileIndex& topLeft, TileIndex& bottomRight) const
    465 {
    466     IntRect clampedRect = bounds();
     254void TileGrid::getTileIndexRangeForRect(const IntRect& rect, TileIndex& topLeft, TileIndex& bottomRight) const
     255{
     256    IntRect clampedRect = m_controller.bounds();
    467257    clampedRect.scale(m_scale);
    468258    clampedRect.intersect(rect);
    469259
     260    auto tileSize = m_controller.tileSize();
    470261    if (clampedRect.x() >= 0)
    471         topLeft.setX(clampedRect.x() / m_tileSize.width());
     262        topLeft.setX(clampedRect.x() / tileSize.width());
    472263    else
    473         topLeft.setX(floorf((float)clampedRect.x() / leftMarginWidth()));
     264        topLeft.setX(floorf((float)clampedRect.x() / m_controller.leftMarginWidth()));
    474265
    475266    if (clampedRect.y() >= 0)
    476         topLeft.setY(clampedRect.y() / m_tileSize.height());
     267        topLeft.setY(clampedRect.y() / tileSize.height());
    477268    else
    478         topLeft.setY(floorf((float)clampedRect.y() / topMarginHeight()));
    479 
    480     int bottomXRatio = ceil((float)clampedRect.maxX() / m_tileSize.width());
     269        topLeft.setY(floorf((float)clampedRect.y() / m_controller.topMarginHeight()));
     270
     271    int bottomXRatio = ceil((float)clampedRect.maxX() / tileSize.width());
    481272    bottomRight.setX(std::max(bottomXRatio - 1, 0));
    482273
    483     int bottomYRatio = ceil((float)clampedRect.maxY() / m_tileSize.height());
     274    int bottomYRatio = ceil((float)clampedRect.maxY() / tileSize.height());
    484275    bottomRight.setY(std::max(bottomYRatio - 1, 0));
    485276}
    486277
    487 FloatRect TileController::computeTileCoverageRect(const FloatRect& previousVisibleRect, const FloatRect& currentVisibleRect) const
    488 {
    489     FloatRect visibleRect = currentVisibleRect;
    490     visibleRect.intersect(scaledExposedRect());
    491 
    492     // If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
    493     if (!m_isInWindow)
    494         return visibleRect;
    495 
    496     // FIXME: look at how far the document can scroll in each dimension.
    497     float coverageHorizontalSize = visibleRect.width();
    498     float coverageVerticalSize = visibleRect.height();
    499 
    500 #if PLATFORM(IOS)
    501     UNUSED_PARAM(previousVisibleRect);
    502     return visibleRect;
    503 #else
    504     bool largeVisibleRectChange = !previousVisibleRect.isEmpty() && !visibleRect.intersects(previousVisibleRect);
    505 
    506     // Inflate the coverage rect so that it covers 2x of the visible width and 3x of the visible height.
    507     // These values were chosen because it's more common to have tall pages and to scroll vertically,
    508     // so we keep more tiles above and below the current area.
    509 
    510     if (m_tileCoverage & CoverageForHorizontalScrolling && !largeVisibleRectChange)
    511         coverageHorizontalSize *= 2;
    512 
    513     if (m_tileCoverage & CoverageForVerticalScrolling && !largeVisibleRectChange)
    514         coverageVerticalSize *= 3;
    515 #endif
    516     coverageVerticalSize += topMarginHeight() + bottomMarginHeight();
    517     coverageHorizontalSize += leftMarginWidth() + rightMarginWidth();
    518 
    519     FloatRect coverageBounds = bounds();
    520     float coverageLeft = visibleRect.x() - (coverageHorizontalSize - visibleRect.width()) / 2;
    521     coverageLeft = std::min(coverageLeft, coverageBounds.maxX() - coverageHorizontalSize);
    522     coverageLeft = std::max(coverageLeft, coverageBounds.x());
    523 
    524     float coverageTop = visibleRect.y() - (coverageVerticalSize - visibleRect.height()) / 2;
    525     coverageTop = std::min(coverageTop, coverageBounds.maxY() - coverageVerticalSize);
    526     coverageTop = std::max(coverageTop, coverageBounds.y());
    527 
    528     return FloatRect(coverageLeft, coverageTop, coverageHorizontalSize, coverageVerticalSize);
    529 }
    530 
    531 void TileController::scheduleTileRevalidation(double interval)
    532 {
    533     if (m_tileRevalidationTimer.isActive() && m_tileRevalidationTimer.nextFireInterval() < interval)
    534         return;
    535 
    536     m_tileRevalidationTimer.startOneShot(interval);
    537 }
    538 
    539 void TileController::tileRevalidationTimerFired(Timer<TileController>*)
    540 {
    541     if (m_isInWindow) {
    542         setNeedsRevalidateTiles();
    543         return;
    544     }
    545 
    546     TileValidationPolicyFlags foregroundValidationPolicy = owningGraphicsLayer()->platformCALayerShouldAggressivelyRetainTiles(m_tileCacheLayer) ? 0 : PruneSecondaryTiles;
    547     TileValidationPolicyFlags backgroundValidationPolicy = foregroundValidationPolicy | UnparentAllTiles;
    548 
    549     revalidateTiles(foregroundValidationPolicy, backgroundValidationPolicy);
    550 }
    551 
    552 unsigned TileController::blankPixelCount() const
     278unsigned TileGrid::blankPixelCount() const
    553279{
    554280    PlatformLayerList tiles(m_tiles.size());
     
    559285    }
    560286
    561     return blankPixelCountForTiles(tiles, m_visibleRect, IntPoint(0,0));
    562 }
    563 
    564 unsigned TileController::blankPixelCountForTiles(const PlatformLayerList& tiles, const FloatRect& visibleRect, const IntPoint& tileTranslation)
    565 {
    566     Region paintedVisibleTiles;
    567 
    568     for (PlatformLayerList::const_iterator it = tiles.begin(), end = tiles.end(); it != end; ++it) {
    569         const PlatformLayer* tileLayer = it->get();
    570 
    571         FloatRect visiblePart(CGRectOffset([tileLayer frame], tileTranslation.x(), tileTranslation.y()));
    572         visiblePart.intersect(visibleRect);
    573 
    574         if (!visiblePart.isEmpty())
    575             paintedVisibleTiles.unite(enclosingIntRect(visiblePart));
    576     }
    577 
    578     Region uncoveredRegion(enclosingIntRect(visibleRect));
    579     uncoveredRegion.subtract(paintedVisibleTiles);
    580 
    581     return uncoveredRegion.totalArea();
    582 }
    583 
    584 static inline void queueTileForRemoval(const TileController::TileIndex& tileIndex, const TileController::TileInfo& tileInfo, Vector<TileController::TileIndex>& tilesToRemove, TileController::RepaintCountMap& repaintCounts)
     287    return TileController::blankPixelCountForTiles(tiles, m_controller.visibleRect(), IntPoint(0,0));
     288}
     289
     290static inline void queueTileForRemoval(const TileGrid::TileIndex& tileIndex, const TileGrid::TileInfo& tileInfo, Vector<TileGrid::TileIndex>& tilesToRemove, TileController::RepaintCountMap& repaintCounts)
    585291{
    586292    tileInfo.layer->removeFromSuperlayer();
     
    589295}
    590296
    591 void TileController::removeAllTiles()
     297void TileGrid::removeAllSecondaryTiles()
    592298{
    593299    Vector<TileIndex> tilesToRemove;
    594300
    595     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    596         queueTileForRemoval(it->key, it->value, tilesToRemove, m_tileRepaintCounts);
     301    for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
     302        const TileInfo& tileInfo = it->value;
     303        if (tileInfo.cohort == VisibleTileCohort)
     304            continue;
     305
     306        queueTileForRemoval(it->key, it->value, tilesToRemove, m_controller.repaintCountMap());
     307    }
    597308
    598309    for (size_t i = 0; i < tilesToRemove.size(); ++i) {
     
    604315}
    605316
    606 void TileController::removeAllSecondaryTiles()
    607 {
     317void TileGrid::removeTilesInCohort(TileCohort cohort)
     318{
     319    ASSERT(cohort != VisibleTileCohort);
    608320    Vector<TileIndex> tilesToRemove;
    609321
    610322    for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    611323        const TileInfo& tileInfo = it->value;
    612         if (tileInfo.cohort == VisibleTileCohort)
     324        if (tileInfo.cohort != cohort)
    613325            continue;
    614326
    615         queueTileForRemoval(it->key, it->value, tilesToRemove, m_tileRepaintCounts);
     327        queueTileForRemoval(it->key, it->value, tilesToRemove, m_controller.repaintCountMap());
    616328    }
    617329
     
    624336}
    625337
    626 void TileController::removeTilesInCohort(TileCohort cohort)
    627 {
    628     ASSERT(cohort != VisibleTileCohort);
    629     Vector<TileIndex> tilesToRemove;
    630 
    631     for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it) {
    632         const TileInfo& tileInfo = it->value;
    633         if (tileInfo.cohort != cohort)
    634             continue;
    635 
    636         queueTileForRemoval(it->key, it->value, tilesToRemove, m_tileRepaintCounts);
    637     }
    638 
    639     for (size_t i = 0; i < tilesToRemove.size(); ++i) {
    640         TileInfo tileInfo = m_tiles.take(tilesToRemove[i]);
    641 #if !PLATFORM(IOS)
    642         LayerPool::sharedPool()->addLayer(tileInfo.layer);
    643 #endif
    644     }
    645 }
    646 
    647 void TileController::setNeedsRevalidateTiles()
    648 {
    649     owningGraphicsLayer()->platformCALayerSetNeedsToRevalidateTiles();
    650 }
    651 
    652 void TileController::revalidateTiles(TileValidationPolicyFlags foregroundValidationPolicy, TileValidationPolicyFlags backgroundValidationPolicy)
    653 {
    654     FloatRect visibleRect = m_visibleRect;
    655     IntRect bounds = this->bounds();
     338void TileGrid::revalidateTiles(TileValidationPolicyFlags validationPolicy)
     339{
     340    FloatRect visibleRect = m_controller.visibleRect();
     341    IntRect bounds = m_controller.bounds();
    656342
    657343    visibleRect.intersect(scaledExposedRect());
     
    659345    if (visibleRect.isEmpty() || bounds.isEmpty())
    660346        return;
    661    
    662     TileValidationPolicyFlags validationPolicy = m_isInWindow ? foregroundValidationPolicy : backgroundValidationPolicy;
    663    
    664     FloatRect tileCoverageRect = computeTileCoverageRect(m_visibleRectAtLastRevalidate, m_visibleRect);
     347
     348    FloatRect tileCoverageRect = m_controller.computeTileCoverageRect(m_controller.visibleRectAtLastRevalidate(), visibleRect);
    665349    FloatRect scaledRect(tileCoverageRect);
    666350    scaledRect.scale(m_scale);
     
    690374                ++tilesInCohort;
    691375
    692                 if (m_unparentsOffscreenTiles)
     376                if (m_controller.unparentsOffscreenTiles())
    693377                    tileLayer->removeFromSuperlayer();
    694378            }
     
    699383        startedNewCohort(currCohort);
    700384
    701     if (!owningGraphicsLayer()->platformCALayerShouldAggressivelyRetainTiles(m_tileCacheLayer)) {
    702         if (owningGraphicsLayer()->platformCALayerShouldTemporarilyRetainTileCohorts(m_tileCacheLayer))
     385    if (!m_controller.shouldAggressivelyRetainTiles()) {
     386        if (m_controller.shouldTemporarilyRetainTileCohorts())
    703387            scheduleCohortRemoval();
    704388        else if (tilesInCohort)
     
    718402    }
    719403
    720     if (m_unparentsOffscreenTiles && (validationPolicy & UnparentAllTiles)) {
     404    if (m_controller.unparentsOffscreenTiles() && (validationPolicy & UnparentAllTiles)) {
    721405        for (TileMap::iterator it = m_tiles.begin(), end = m_tiles.end(); it != end; ++it)
    722406            it->value.layer->removeFromSuperlayer();
    723407    }
    724408
    725     if (m_boundsAtLastRevalidate != bounds) {
     409    auto boundsAtLastRevalidate = m_controller.boundsAtLastRevalidate();
     410    if (boundsAtLastRevalidate != bounds) {
    726411        // If there are margin tiles and the bounds have grown taller or wider, then the tiles that used to
    727412        // be bottom or right margin tiles need to be invalidated.
    728         if (hasMargins()) {
    729             if (bounds.width() > m_boundsAtLastRevalidate.width() || bounds.height() > m_boundsAtLastRevalidate.height()) {
    730                 IntRect boundsWithoutMargin = this->boundsWithoutMargin();
    731                 IntRect oldBoundsWithoutMargin = boundsAtLastRevalidateWithoutMargin();
    732 
    733                 if (bounds.height() > m_boundsAtLastRevalidate.height()) {
     413        if (m_controller.hasMargins()) {
     414            if (bounds.width() > boundsAtLastRevalidate.width() || bounds.height() > boundsAtLastRevalidate.height()) {
     415                IntRect boundsWithoutMargin = m_controller.boundsWithoutMargin();
     416                IntRect oldBoundsWithoutMargin = m_controller.boundsAtLastRevalidateWithoutMargin();
     417
     418                if (bounds.height() > boundsAtLastRevalidate.height()) {
    734419                    IntRect formerBottomMarginRect = IntRect(oldBoundsWithoutMargin.x(), oldBoundsWithoutMargin.height(),
    735420                        oldBoundsWithoutMargin.width(), boundsWithoutMargin.height() - oldBoundsWithoutMargin.height());
     
    737422                }
    738423
    739                 if (bounds.width() > m_boundsAtLastRevalidate.width()) {
     424                if (bounds.width() > boundsAtLastRevalidate.width()) {
    740425                    IntRect formerRightMarginRect = IntRect(oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.y(),
    741426                        boundsWithoutMargin.width() - oldBoundsWithoutMargin.width(), oldBoundsWithoutMargin.height());
     
    760445                || index.x() < topLeftForBounds.x()
    761446                || index.x() > bottomRightForBounds.x())
    762                 queueTileForRemoval(index, it->value, tilesToRemove, m_tileRepaintCounts);
     447                queueTileForRemoval(index, it->value, tilesToRemove, m_controller.repaintCountMap());
    763448        }
    764449
     
    771456    }
    772457
    773     if (m_tiledScrollingIndicatorLayer)
    774         updateTileCoverageMap();
    775 
    776     m_visibleRectAtLastRevalidate = visibleRect;
    777     m_boundsAtLastRevalidate = bounds;
    778 }
    779 
    780 TileController::TileCohort TileController::nextTileCohort() const
     458    m_controller.didRevalidateTiles();
     459}
     460
     461TileGrid::TileCohort TileGrid::nextTileCohort() const
    781462{
    782463    if (!m_cohortList.isEmpty())
     
    786467}
    787468
    788 void TileController::startedNewCohort(TileCohort cohort)
     469void TileGrid::startedNewCohort(TileCohort cohort)
    789470{
    790471    m_cohortList.append(TileCohortInfo(cohort, monotonicallyIncreasingTime()));
    791472#if PLATFORM(IOS)
    792     if (!m_isInWindow)
    793         tileControllerMemoryHandler().tileControllerGainedUnparentedTiles(this);
     473    if (!m_controller.isInWindow())
     474        tileControllerMemoryHandler().tileControllerGainedUnparentedTiles(&m_controller);
    794475#endif
    795476}
    796477
    797 TileController::TileCohort TileController::newestTileCohort() const
     478TileGrid::TileCohort TileGrid::newestTileCohort() const
    798479{
    799480    return m_cohortList.isEmpty() ? 0 : m_cohortList.last().cohort;
    800481}
    801482
    802 TileController::TileCohort TileController::oldestTileCohort() const
     483TileGrid::TileCohort TileGrid::oldestTileCohort() const
    803484{
    804485    return m_cohortList.isEmpty() ? 0 : m_cohortList.first().cohort;
    805486}
    806487
    807 void TileController::scheduleCohortRemoval()
     488void TileGrid::scheduleCohortRemoval()
    808489{
    809490    const double cohortRemovalTimerSeconds = 1;
     
    814495}
    815496
    816 void TileController::cohortRemovalTimerFired(Timer<TileController>*)
     497void TileGrid::cohortRemovalTimerFired(Timer<TileGrid>*)
    817498{
    818499    if (m_cohortList.isEmpty()) {
     
    829510    }
    830511
    831     if (m_tiledScrollingIndicatorLayer)
    832         updateTileCoverageMap();
    833 }
    834 
    835 IntRect TileController::ensureTilesForRect(const FloatRect& rect, CoverageType newTileType)
    836 {
    837     if (m_unparentsOffscreenTiles && !m_isInWindow)
     512    m_controller.updateTileCoverageMap();
     513}
     514
     515IntRect TileGrid::ensureTilesForRect(const FloatRect& rect, CoverageType newTileType)
     516{
     517    if (m_controller.unparentsOffscreenTiles() && !m_controller.isInWindow())
    838518        return IntRect();
    839519
     
    863543
    864544            if (!tileInfo.layer)
    865                 tileInfo.layer = createTileLayer(tileRect);
     545                tileInfo.layer = m_controller.createTileLayer(tileRect);
    866546            else {
    867547                // We already have a layer for this tile. Ensure that its size is correct.
     
    881561            }
    882562
    883             bool shouldParentTileLayer = (!m_unparentsOffscreenTiles || m_isInWindow) && !tileInfo.layer->superlayer();
     563            bool shouldParentTileLayer = (!m_controller.unparentsOffscreenTiles() || m_controller.isInWindow()) && !tileInfo.layer->superlayer();
    884564
    885565            if (shouldParentTileLayer)
    886                 m_tileContainerLayer->appendSublayer(tileInfo.layer.get());
     566                m_containerLayer.get().appendSublayer(tileInfo.layer.get());
    887567        }
    888568    }
     
    894574}
    895575
    896 void TileController::updateTileCoverageMap()
    897 {
    898     FloatRect containerBounds = bounds();
    899     FloatRect visibleRect = this->visibleRect();
    900 
    901     visibleRect.intersect(scaledExposedRect());
    902     visibleRect.contract(4, 4); // Layer is positioned 2px from top and left edges.
    903 
    904     float widthScale = 1;
    905     float scale = 1;
    906     if (!containerBounds.isEmpty()) {
    907         widthScale = std::min<float>(visibleRect.width() / containerBounds.width(), 0.1);
    908         scale = std::min(widthScale, visibleRect.height() / containerBounds.height());
    909     }
    910    
    911     float indicatorScale = scale * m_scale;
    912     FloatRect mapBounds = containerBounds;
    913     mapBounds.scale(indicatorScale, indicatorScale);
    914 
    915     if (!m_exposedRect.isInfinite())
    916         m_tiledScrollingIndicatorLayer->setPosition(m_exposedRect.location() + FloatPoint(2, 2));
    917     else
    918         m_tiledScrollingIndicatorLayer->setPosition(FloatPoint(2, 2));
    919 
    920     m_tiledScrollingIndicatorLayer->setBounds(mapBounds);
    921     m_tiledScrollingIndicatorLayer->setNeedsDisplay();
    922 
    923     visibleRect.scale(indicatorScale, indicatorScale);
    924     visibleRect.expand(2, 2);
    925     m_visibleRectIndicatorLayer->setPosition(visibleRect.location());
    926     m_visibleRectIndicatorLayer->setBounds(FloatRect(FloatPoint(), visibleRect.size()));
    927 
    928     Color visibleRectIndicatorColor;
    929     switch (m_indicatorMode) {
    930     case SynchronousScrollingBecauseOfStyleIndication:
    931         visibleRectIndicatorColor = Color(255, 0, 0);
    932         break;
    933     case SynchronousScrollingBecauseOfEventHandlersIndication:
    934         visibleRectIndicatorColor = Color(255, 255, 0);
    935         break;
    936     case AsyncScrollingIndication:
    937         visibleRectIndicatorColor = Color(0, 200, 0);
    938         break;
    939     }
    940 
    941     m_visibleRectIndicatorLayer->setBorderColor(visibleRectIndicatorColor);
    942 }
    943 
    944 IntRect TileController::tileGridExtent() const
     576IntRect TileGrid::extent() const
    945577{
    946578    TileIndex topLeft;
     
    952584}
    953585
    954 double TileController::retainedTileBackingStoreMemory() const
     586double TileGrid::retainedTileBackingStoreMemory() const
    955587{
    956588    double totalBytes = 0;
     
    969601
    970602// Return the rect in layer coords, not tile coords.
    971 IntRect TileController::tileCoverageRect() const
     603IntRect TileGrid::tileCoverageRect() const
    972604{
    973605    IntRect coverageRectInLayerCoords(m_primaryTileCoverageRect);
     
    976608}
    977609
    978 PlatformCALayer* TileController::tiledScrollingIndicatorLayer()
    979 {
    980     if (!m_tiledScrollingIndicatorLayer) {
    981         m_tiledScrollingIndicatorLayer = m_tileCacheLayer->createCompatibleLayer(PlatformCALayer::LayerTypeSimpleLayer, this);
    982         m_tiledScrollingIndicatorLayer->setOpacity(0.75);
    983         m_tiledScrollingIndicatorLayer->setAnchorPoint(FloatPoint3D());
    984         m_tiledScrollingIndicatorLayer->setBorderColor(Color::black);
    985         m_tiledScrollingIndicatorLayer->setBorderWidth(1);
    986         m_tiledScrollingIndicatorLayer->setPosition(FloatPoint(2, 2));
    987 
    988         m_visibleRectIndicatorLayer = m_tileCacheLayer->createCompatibleLayer(PlatformCALayer::LayerTypeLayer, nullptr);
    989         m_visibleRectIndicatorLayer->setBorderWidth(2);
    990         m_visibleRectIndicatorLayer->setAnchorPoint(FloatPoint3D());
    991         m_visibleRectIndicatorLayer->setBorderColor(Color(255, 0, 0));
    992 
    993         m_tiledScrollingIndicatorLayer->appendSublayer(m_visibleRectIndicatorLayer.get());
    994 
    995         updateTileCoverageMap();
    996     }
    997 
    998     return m_tiledScrollingIndicatorLayer.get();
    999 }
    1000 
    1001 void TileController::setScrollingModeIndication(ScrollingModeIndication scrollingMode)
    1002 {
    1003     if (scrollingMode == m_indicatorMode)
    1004         return;
    1005 
    1006     m_indicatorMode = scrollingMode;
    1007 
    1008     if (m_tiledScrollingIndicatorLayer)
    1009         updateTileCoverageMap();
    1010 }
    1011 
    1012 void TileController::setTileMargins(int marginTop, int marginBottom, int marginLeft, int marginRight)
    1013 {
    1014     m_marginTop = marginTop;
    1015     m_marginBottom = marginBottom;
    1016     m_marginLeft = marginLeft;
    1017     m_marginRight = marginRight;
    1018 
    1019     setNeedsRevalidateTiles();
    1020 }
    1021 
    1022 bool TileController::hasMargins() const
    1023 {
    1024     return m_marginTop || m_marginBottom || m_marginLeft || m_marginRight;
    1025 }
    1026 
    1027 int TileController::topMarginHeight() const
    1028 {
    1029     return m_marginTop;
    1030 }
    1031 
    1032 int TileController::bottomMarginHeight() const
    1033 {
    1034     return m_marginBottom;
    1035 }
    1036 
    1037 int TileController::leftMarginWidth() const
    1038 {
    1039     return m_marginLeft;
    1040 }
    1041 
    1042 int TileController::rightMarginWidth() const
    1043 {
    1044     return m_marginRight;
    1045 }
    1046 
    1047 RefPtr<PlatformCALayer> TileController::createTileLayer(const IntRect& tileRect)
    1048 {
    1049 #if PLATFORM(IOS)
    1050     RefPtr<PlatformCALayer> layer;
    1051 #else
    1052     RefPtr<PlatformCALayer> layer = LayerPool::sharedPool()->takeLayerWithSize(tileRect.size());
    1053 #endif
    1054 
    1055     if (layer) {
    1056         m_tileRepaintCounts.remove(layer.get());
    1057         layer->setOwner(this);
    1058     } else
    1059         layer = m_tileCacheLayer->createCompatibleLayer(PlatformCALayer::LayerTypeTiledBackingTileLayer, this);
    1060 
    1061     layer->setAnchorPoint(FloatPoint3D());
    1062     layer->setBounds(FloatRect(FloatPoint(), tileRect.size()));
    1063     layer->setPosition(tileRect.location());
    1064     layer->setBorderColor(m_tileDebugBorderColor);
    1065     layer->setBorderWidth(m_tileDebugBorderWidth);
    1066     layer->setEdgeAntialiasingMask(0);
    1067     layer->setOpaque(m_tilesAreOpaque);
    1068 #ifndef NDEBUG
    1069     layer->setName("Tile");
    1070 #endif
    1071 
    1072     float temporaryScaleFactor = owningGraphicsLayer()->platformCALayerContentsScaleMultiplierForNewTiles(m_tileCacheLayer);
    1073     m_hasTilesWithTemporaryScaleFactor |= temporaryScaleFactor != 1;
    1074 
    1075     layer->setContentsScale(m_deviceScaleFactor * temporaryScaleFactor);
    1076     layer->setAcceleratesDrawing(m_acceleratesDrawing);
    1077 
    1078     layer->setNeedsDisplay();
    1079 
    1080     return layer;
    1081 }
    1082 
    1083 int TileController::platformCALayerIncrementRepaintCount(PlatformCALayer* platformCALayer)
    1084 {
    1085     int repaintCount = 0;
    1086 
    1087     if (m_tileRepaintCounts.contains(platformCALayer))
    1088         repaintCount = m_tileRepaintCounts.get(platformCALayer);
    1089 
    1090     m_tileRepaintCounts.set(platformCALayer, ++repaintCount);
    1091 
    1092     return repaintCount;
    1093 }
    1094 
    1095 void TileController::drawTileMapContents(CGContextRef context, CGRect layerBounds)
     610void TileGrid::drawTileMapContents(CGContextRef context, CGRect layerBounds)
    1096611{
    1097612    CGContextSetRGBFillColor(context, 0.3, 0.3, 0.3, 1);
    1098613    CGContextFillRect(context, layerBounds);
    1099614
    1100     CGFloat scaleFactor = layerBounds.size.width / bounds().width();
    1101 
    1102     CGFloat contextScale = scaleFactor / scale();
     615    CGFloat scaleFactor = layerBounds.size.width / m_controller.bounds().width();
     616
     617    CGFloat contextScale = scaleFactor / m_scale;
    1103618    CGContextScaleCTM(context, contextScale, contextScale);
    1104619   
     
    1119634        TileCohort oldestCohort = oldestTileCohort();
    1120635
    1121         if (!owningGraphicsLayer()->platformCALayerShouldAggressivelyRetainTiles(m_tileCacheLayer) && tileInfo.cohort != VisibleTileCohort && newestCohort > oldestCohort) {
     636        if (!m_controller.shouldAggressivelyRetainTiles() && tileInfo.cohort != VisibleTileCohort && newestCohort > oldestCohort) {
    1122637            float cohortProportion = static_cast<float>((newestCohort - tileInfo.cohort)) / (newestCohort - oldestCohort);
    1123638            CGContextSetRGBFillColor(context, red, green, blue, 1 - cohortProportion);
     
    1138653    }
    1139654}
    1140    
     655
    1141656#if PLATFORM(IOS)
    1142 void TileController::removeUnparentedTilesNow()
     657void TileGrid::removeUnparentedTilesNow()
    1143658{
    1144659    while (!m_cohortList.isEmpty()) {
     
    1146661        removeTilesInCohort(firstCohort.cohort);
    1147662    }
    1148 
    1149     if (m_tiledScrollingIndicatorLayer)
    1150         updateTileCoverageMap();
    1151663}
    1152664#endif
  • trunk/Source/WebKit2/ChangeLog

    r166651 r166654  
     12014-04-02  Antti Koivisto  <antti@apple.com>
     2
     3        Split tile grid out from TileController
     4        https://bugs.webkit.org/show_bug.cgi?id=131102
     5
     6        Reviewed by Simon Fraser.
     7
     8        * WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.cpp:
     9        (WebKit::PlatformCALayerRemoteTiledBacking::PlatformCALayerRemoteTiledBacking):
     10        * WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.h:
     11
    1122014-04-02  Anders Carlsson  <andersca@apple.com>
    213
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.cpp

    r166542 r166654  
    4141{
    4242    m_tileController = TileController::create(this);
    43 
    44     m_customSublayers = adoptPtr(new PlatformCALayerList(1));
    45     PlatformCALayer* tileCacheTileContainerLayer = m_tileController->tileContainerLayer();
    46     (*m_customSublayers)[0] = tileCacheTileContainerLayer;
     43    m_customSublayers = std::make_unique<PlatformCALayerList>(m_tileController->containerLayers());
    4744}
    4845
  • trunk/Source/WebKit2/WebProcess/WebPage/mac/PlatformCALayerRemoteTiledBacking.h

    r165676 r166654  
    5555
    5656    OwnPtr<WebCore::TileController> m_tileController;
    57     OwnPtr<WebCore::PlatformCALayerList> m_customSublayers;
     57    std::unique_ptr<WebCore::PlatformCALayerList> m_customSublayers;
    5858};
    5959
Note: See TracChangeset for help on using the changeset viewer.