// 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 #include #include #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" 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 TileManagerBinAsValue( TileManagerBin bin); enum TileManagerBinPriority { HIGH_PRIORITY_BIN = 0, LOW_PRIORITY_BIN = 1, NUM_BIN_PRIORITIES = 2 }; enum TileRasterState { IDLE_STATE = 0, WAITING_FOR_RASTER_STATE = 1, RASTER_STATE = 2, SET_PIXELS_STATE = 3, NUM_STATES = 4 }; // This is state that is specific to a tile that is // managed by the TileManager. class CC_EXPORT ManagedTileState { public: ManagedTileState(); ~ManagedTileState(); // Persisted state: valid all the time. bool can_use_gpu_memory; bool can_be_freed; scoped_ptr resource; bool resource_is_being_initialized; bool contents_swizzled; bool need_to_gather_pixel_refs; std::list 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; }; // 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: 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(); scoped_ptr AsValue() 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_; } 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: 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, skia::LazyPixelRef* pixel_ref); void OnImageDecodeTaskCompleted( scoped_refptr tile, uint32_t pixel_ref_id); bool CanDispatchRasterTask(Tile* tile); scoped_ptr PrepareTileForRaster(Tile* tile); void DispatchOneRasterTask(scoped_refptr tile); void PerformOneRaster(Tile* tile); void OnRasterCompleted( scoped_refptr tile, scoped_ptr resource, int manage_tiles_call_count_when_dispatched); void OnRasterTaskCompleted( scoped_refptr tile, scoped_ptr resource, int manage_tiles_call_count_when_dispatched); void DidFinishTileInitialization(Tile* tile); void DidTileRasterStateChange(Tile* tile, TileRasterState state); void DidTileBinChange(Tile* tile, TileManagerBin bin, WhichTree tree); scoped_ptr GetMemoryRequirementsAsValue() const; static void PerformRaster(uint8* buffer, const gfx::Rect& rect, float contents_scale, bool use_cheapness_estimator, 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 resource_pool_; scoped_ptr raster_worker_pool_; bool manage_tiles_pending_; int manage_tiles_call_count_; GlobalStateThatImpactsTilePriority global_state_; typedef std::vector TileVector; TileVector tiles_; TileVector tiles_that_need_to_be_rasterized_; typedef std::list 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 PixelRefMap; PixelRefMap pending_decode_tasks_; typedef std::queue > TileQueue; TileQueue tiles_with_pending_set_pixels_; size_t bytes_pending_set_pixels_; bool ever_exceeded_memory_budget_; MemoryHistory::Entry memory_stats_from_last_assign_; bool record_rendering_stats_; RenderingStats rendering_stats_; bool use_cheapness_estimator_; int raster_state_count_[NUM_STATES][NUM_TREES][NUM_BINS]; DISALLOW_COPY_AND_ASSIGN(TileManager); }; } // namespace cc #endif // CC_TILE_MANAGER_H_