#ifndef TileGrid_h
#define TileGrid_h
#include "IntPointHash.h"
#include "IntRect.h"
#include "PlatformCALayerClient.h"
#include "Timer.h"
#include <wtf/Deque.h>
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
#include <wtf/Ref.h>
#if USE(CG)
typedef struct CGContext *CGContextRef;
#endif
namespace WebCore {
class GraphicsContext;
class PlatformCALayer;
class TileController;
class TileGrid : public PlatformCALayerClient {
WTF_MAKE_NONCOPYABLE(TileGrid); WTF_MAKE_FAST_ALLOCATED;
public:
TileGrid(TileController&);
~TileGrid();
PlatformCALayer& containerLayer() { return m_containerLayer; }
void setIsZoomedOutTileGrid(bool);
void setScale(float);
float scale() const { return m_scale; }
void setNeedsDisplay();
void setNeedsDisplayInRect(const IntRect&);
void dropTilesInRect(const IntRect&);
void updateTileLayerProperties();
bool prepopulateRect(const FloatRect&);
enum TileValidationPolicyFlags {
PruneSecondaryTiles = 1 << 0,
UnparentAllTiles = 1 << 1
};
typedef unsigned TileValidationPolicy;
void revalidateTiles(TileValidationPolicy);
bool tilesWouldChangeForCoverageRect(const FloatRect&) const;
IntRect tileCoverageRect() const;
IntRect extent() const;
double retainedTileBackingStoreMemory() const;
unsigned blankPixelCount() const;
void drawTileMapContents(CGContextRef, CGRect layerBounds) const;
#if PLATFORM(IOS)
unsigned numberOfUnparentedTiles() const { return m_cohortList.size(); }
void removeUnparentedTilesNow();
#endif
typedef IntPoint TileIndex;
typedef unsigned TileCohort;
static const TileCohort VisibleTileCohort = UINT_MAX;
struct TileInfo {
RefPtr<PlatformCALayer> layer;
TileCohort cohort; bool hasStaleContent;
TileInfo()
: cohort(VisibleTileCohort)
, hasStaleContent(false)
{ }
};
private:
void setTileNeedsDisplayInRect(const TileIndex&, TileInfo&, const IntRect& repaintRectInTileCoords, const IntRect& coverageRectInTileCoords);
IntRect rectForTileIndex(const TileIndex&) const;
void getTileIndexRangeForRect(const IntRect&, TileIndex& topLeft, TileIndex& bottomRight) const;
enum class CoverageType { PrimaryTiles, SecondaryTiles };
IntRect ensureTilesForRect(const FloatRect&, CoverageType);
struct TileCohortInfo {
TileCohort cohort;
double creationTime; TileCohortInfo(TileCohort inCohort, double inTime)
: cohort(inCohort)
, creationTime(inTime)
{ }
double timeUntilExpiration();
};
void removeAllSecondaryTiles();
void removeTilesInCohort(TileCohort);
void scheduleCohortRemoval();
void cohortRemovalTimerFired();
TileCohort nextTileCohort() const;
void startedNewCohort(TileCohort);
TileCohort newestTileCohort() const;
TileCohort oldestTileCohort() const;
void removeTiles(Vector<TileGrid::TileIndex>& toRemove);
virtual void platformCALayerPaintContents(PlatformCALayer*, GraphicsContext&, const FloatRect&) override;
virtual bool platformCALayerShowDebugBorders() const override;
virtual bool platformCALayerShowRepaintCounter(PlatformCALayer*) const override;
virtual int platformCALayerIncrementRepaintCount(PlatformCALayer*) override;
virtual bool platformCALayerContentsOpaque() const override;
virtual bool platformCALayerDrawsContent() const override { return true; }
virtual float platformCALayerDeviceScaleFactor() const override;
TileController& m_controller;
Ref<PlatformCALayer> m_containerLayer;
typedef HashMap<TileIndex, TileInfo> TileMap;
TileMap m_tiles;
IntRect m_primaryTileCoverageRect;
Vector<FloatRect> m_secondaryTileCoverageRects;
float m_scale;
typedef Deque<TileCohortInfo> TileCohortList;
TileCohortList m_cohortList;
Timer m_cohortRemovalTimer;
typedef HashMap<PlatformCALayer*, int> RepaintCountMap;
RepaintCountMap m_tileRepaintCounts;
};
}
#endif