blob: 6d2c621bf7e37ad0cc84df5e28fadc7c4740b6c2 [file] [log] [blame]
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_TILE_MANAGER_H_
#define CC_TILE_MANAGER_H_
#include <list>
#include <queue>
#include <set>
#include <vector>
#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "cc/memory_history.h"
#include "cc/rendering_stats.h"
#include "cc/resource_pool.h"
#include "cc/tile_priority.h"
#include "cc/worker_pool.h"
namespace cc {
class RasterWorkerPool;
class ResourceProvider;
class Tile;
class TileVersion;
class CC_EXPORT TileManagerClient {
public:
virtual void ScheduleManageTiles() = 0;
virtual void DidUploadVisibleHighResolutionTile() = 0;
protected:
virtual ~TileManagerClient() {}
};
// Tile manager classifying tiles into a few basic
// bins:
enum TileManagerBin {
NOW_BIN = 0, // Needed ASAP.
SOON_BIN = 1, // Impl-side version of prepainting.
EVENTUALLY_BIN = 2, // Nice to have, if we've got memory and time.
NEVER_BIN = 3, // Dont bother.
NUM_BINS = 4
// Be sure to update TileManagerBinAsValue when adding new fields.
};
scoped_ptr<base::Value> TileManagerBinAsValue(
TileManagerBin bin);
enum TileManagerBinPriority {
HIGH_PRIORITY_BIN = 0,
LOW_PRIORITY_BIN = 1,
NUM_BIN_PRIORITIES = 2
};
scoped_ptr<base::Value> TileManagerBinPriorityAsValue(
TileManagerBinPriority bin);
enum TileRasterState {
IDLE_STATE = 0,
WAITING_FOR_RASTER_STATE = 1,
RASTER_STATE = 2,
UPLOAD_STATE = 3,
NUM_STATES = 4
};
scoped_ptr<base::Value> TileRasterStateAsValue(
TileRasterState bin);
// This is state that is specific to a tile that is
// managed by the TileManager.
class CC_EXPORT ManagedTileState {
public:
ManagedTileState();
~ManagedTileState();
scoped_ptr<base::Value> AsValue() const;
// Persisted state: valid all the time.
bool can_use_gpu_memory;
bool can_be_freed;
scoped_ptr<ResourcePool::Resource> resource;
bool resource_is_being_initialized;
bool contents_swizzled;
bool need_to_gather_pixel_refs;
std::list<skia::LazyPixelRef*> pending_pixel_refs;
TileRasterState raster_state;
// Ephemeral state, valid only during Manage.
TileManagerBin bin[NUM_BIN_PRIORITIES];
TileManagerBin tree_bin[NUM_TREES];
// The bin that the tile would have if the GPU memory manager had a maximally permissive policy,
// send to the GPU memory manager to determine policy.
TileManagerBin gpu_memmgr_stats_bin;
TileResolution resolution;
float time_to_needed_in_seconds;
float distance_to_visible_in_pixels;
};
// This class manages tiles, deciding which should get rasterized and which
// should no longer have any memory assigned to them. Tile objects are "owned"
// by layers; they automatically register with the manager when they are
// created, and unregister from the manager when they are deleted.
class CC_EXPORT TileManager : public WorkerPoolClient {
public:
TileManager(TileManagerClient* client,
ResourceProvider *resource_provider,
size_t num_raster_threads,
bool use_cheapess_estimator);
virtual ~TileManager();
const GlobalStateThatImpactsTilePriority& GlobalState() const {
return global_state_;
}
void SetGlobalState(const GlobalStateThatImpactsTilePriority& state);
void ManageTiles();
void CheckForCompletedTileUploads();
void AbortPendingTileUploads();
void DidCompleteFrame();
scoped_ptr<base::Value> BasicStateAsValue() const;
scoped_ptr<base::Value> AllTilesAsValue() const;
void GetMemoryStats(size_t* memoryRequiredBytes,
size_t* memoryNiceToHaveBytes,
size_t* memoryUsedBytes) const;
void SetRecordRenderingStats(bool record_rendering_stats);
void GetRenderingStats(RenderingStats* stats);
bool HasPendingWorkScheduled(WhichTree tree) const;
const MemoryHistory::Entry& memory_stats_from_last_assign() const {
return memory_stats_from_last_assign_;
}
// Overridden from WorkerPoolClient:
virtual void DidFinishDispatchingWorkerPoolCompletionCallbacks() OVERRIDE;
protected:
// Methods called by Tile
friend class Tile;
void RegisterTile(Tile* tile);
void UnregisterTile(Tile* tile);
void WillModifyTilePriority(
Tile* tile, WhichTree tree, const TilePriority& new_priority) {
// TODO(nduca): Do something smarter if reprioritization turns out to be
// costly.
ScheduleManageTiles();
}
private:
// Data that is passed to raster tasks.
struct RasterTaskMetadata {
bool use_cheapness_estimator;
bool is_tile_in_pending_tree_now_bin;
TileResolution tile_resolution;
int layer_id;
};
RasterTaskMetadata GetRasterTaskMetadata(const Tile& tile) const;
void SortTiles();
void AssignGpuMemoryToTiles();
void FreeResourcesForTile(Tile* tile);
void ScheduleManageTiles() {
if (manage_tiles_pending_)
return;
client_->ScheduleManageTiles();
manage_tiles_pending_ = true;
}
void DispatchMoreTasks();
void GatherPixelRefsForTile(Tile* tile);
void DispatchImageDecodeTasksForTile(Tile* tile);
void DispatchOneImageDecodeTask(
scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref);
void OnImageDecodeTaskCompleted(
scoped_refptr<Tile> tile,
uint32_t pixel_ref_id);
bool CanDispatchRasterTask(Tile* tile) const;
scoped_ptr<ResourcePool::Resource> PrepareTileForRaster(Tile* tile);
void DispatchOneRasterTask(scoped_refptr<Tile> tile);
void OnRasterTaskCompleted(
scoped_refptr<Tile> tile,
scoped_ptr<ResourcePool::Resource> resource,
int manage_tiles_call_count_when_dispatched);
void DidFinishTileInitialization(Tile* tile);
void DidTileRasterStateChange(Tile* tile, TileRasterState state);
void DidTileTreeBinChange(Tile* tile,
TileManagerBin new_tree_bin,
WhichTree tree);
scoped_ptr<Value> GetMemoryRequirementsAsValue() const;
static void RunRasterTask(uint8* buffer,
const gfx::Rect& rect,
float contents_scale,
const RasterTaskMetadata& metadata,
PicturePileImpl* picture_pile,
RenderingStats* stats);
static void RunImageDecodeTask(skia::LazyPixelRef* pixel_ref,
RenderingStats* stats);
static void RecordCheapnessPredictorResults(bool is_predicted_cheap,
bool is_actually_cheap);
TileManagerClient* client_;
scoped_ptr<ResourcePool> resource_pool_;
scoped_ptr<RasterWorkerPool> raster_worker_pool_;
bool manage_tiles_pending_;
int manage_tiles_call_count_;
GlobalStateThatImpactsTilePriority global_state_;
typedef std::vector<Tile*> TileVector;
typedef std::set<Tile*> TileSet;
TileSet all_tiles_;
TileVector live_or_allocated_tiles_;
TileVector tiles_that_need_to_be_rasterized_;
typedef std::list<Tile*> TileList;
// Tiles with image decoding tasks. These tiles need to be rasterized
// when all the image decoding tasks finish.
TileList tiles_with_image_decoding_tasks_;
typedef base::hash_map<uint32_t, skia::LazyPixelRef*> PixelRefMap;
PixelRefMap pending_decode_tasks_;
typedef std::queue<scoped_refptr<Tile> > TileQueue;
TileQueue tiles_with_pending_upload_;
size_t bytes_pending_upload_;
bool has_performed_uploads_since_last_flush_;
bool ever_exceeded_memory_budget_;
MemoryHistory::Entry memory_stats_from_last_assign_;
bool record_rendering_stats_;
RenderingStats rendering_stats_;
bool use_cheapness_estimator_;
bool did_schedule_cheap_tasks_;
bool allow_cheap_tasks_;
int raster_state_count_[NUM_STATES][NUM_TREES][NUM_BINS];
DISALLOW_COPY_AND_ASSIGN(TileManager);
};
} // namespace cc
#endif // CC_TILE_MANAGER_H_