diff options
author | aelias@chromium.org <aelias@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-03 02:41:07 +0000 |
---|---|---|
committer | aelias@chromium.org <aelias@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-03 02:41:07 +0000 |
commit | 3f2ff115793c21854acf80b50532a6b03dd172a0 (patch) | |
tree | 90b8fb95da57adfe7e8d1855af231a0074118206 | |
parent | d600df7d219890dd9a101922b25d3bff9f4195c3 (diff) | |
download | chromium_src-3f2ff115793c21854acf80b50532a6b03dd172a0.zip chromium_src-3f2ff115793c21854acf80b50532a6b03dd172a0.tar.gz chromium_src-3f2ff115793c21854acf80b50532a6b03dd172a0.tar.bz2 |
Add memory policy limit by number of resources.
Currently, MemoryPolicy only limits by number of bytes allocated. For
resources like Android gralloc buffers which also have a process or
system-wide limit, we also need to limit by count of the resource. This
patch implements this and sets a limit of 100 from the AndroidWebView
OutputSurface.
As additional cleanup, I also moved the ignore-0-memory-policy logic to
OutputSurface as it doesn't seem appropriate in CC.
New test parametrization for TileManagerTests.
NOTRY=true
BUG=266619
Review URL: https://chromiumcodereview.appspot.com/20843007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215464 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/output/managed_memory_policy.cc | 14 | ||||
-rw-r--r-- | cc/output/managed_memory_policy.h | 5 | ||||
-rw-r--r-- | cc/output/output_surface.cc | 17 | ||||
-rw-r--r-- | cc/output/output_surface_client.h | 5 | ||||
-rw-r--r-- | cc/output/output_surface_unittest.cc | 5 | ||||
-rw-r--r-- | cc/resources/resource_pool.cc | 13 | ||||
-rw-r--r-- | cc/resources/resource_pool.h | 8 | ||||
-rw-r--r-- | cc/resources/tile_manager.cc | 27 | ||||
-rw-r--r-- | cc/resources/tile_manager_unittest.cc | 56 | ||||
-rw-r--r-- | cc/resources/tile_priority.cc | 3 | ||||
-rw-r--r-- | cc/resources/tile_priority.h | 2 | ||||
-rw-r--r-- | cc/test/fake_output_surface_client.cc | 9 | ||||
-rw-r--r-- | cc/test/fake_output_surface_client.h | 5 | ||||
-rw-r--r-- | cc/test/pixel_test.cc | 4 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 108 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.h | 14 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 35 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc | 5 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 9 | ||||
-rw-r--r-- | content/browser/android/in_process/synchronous_compositor_output_surface.cc | 11 |
20 files changed, 212 insertions, 143 deletions
diff --git a/cc/output/managed_memory_policy.cc b/cc/output/managed_memory_policy.cc index f21fbd6..7e83766 100644 --- a/cc/output/managed_memory_policy.cc +++ b/cc/output/managed_memory_policy.cc @@ -9,28 +9,34 @@ namespace cc { +const size_t ManagedMemoryPolicy::kDefaultNumResourcesLimit = 10 * 1000 * 1000; + ManagedMemoryPolicy::ManagedMemoryPolicy(size_t bytes_limit_when_visible) : bytes_limit_when_visible(bytes_limit_when_visible), priority_cutoff_when_visible(CUTOFF_ALLOW_EVERYTHING), bytes_limit_when_not_visible(0), - priority_cutoff_when_not_visible(CUTOFF_ALLOW_NOTHING) {} + priority_cutoff_when_not_visible(CUTOFF_ALLOW_NOTHING), + num_resources_limit(kDefaultNumResourcesLimit) {} ManagedMemoryPolicy::ManagedMemoryPolicy( size_t bytes_limit_when_visible, PriorityCutoff priority_cutoff_when_visible, size_t bytes_limit_when_not_visible, - PriorityCutoff priority_cutoff_when_not_visible) + PriorityCutoff priority_cutoff_when_not_visible, + size_t num_resources_limit) : bytes_limit_when_visible(bytes_limit_when_visible), priority_cutoff_when_visible(priority_cutoff_when_visible), bytes_limit_when_not_visible(bytes_limit_when_not_visible), - priority_cutoff_when_not_visible(priority_cutoff_when_not_visible) {} + priority_cutoff_when_not_visible(priority_cutoff_when_not_visible), + num_resources_limit(num_resources_limit) {} bool ManagedMemoryPolicy::operator==(const ManagedMemoryPolicy& other) const { return bytes_limit_when_visible == other.bytes_limit_when_visible && priority_cutoff_when_visible == other.priority_cutoff_when_visible && bytes_limit_when_not_visible == other.bytes_limit_when_not_visible && priority_cutoff_when_not_visible == - other.priority_cutoff_when_not_visible; + other.priority_cutoff_when_not_visible && + num_resources_limit == other.num_resources_limit; } bool ManagedMemoryPolicy::operator!=(const ManagedMemoryPolicy& other) const { diff --git a/cc/output/managed_memory_policy.h b/cc/output/managed_memory_policy.h index 2790e8b..5a607a7 100644 --- a/cc/output/managed_memory_policy.h +++ b/cc/output/managed_memory_policy.h @@ -18,12 +18,14 @@ struct CC_EXPORT ManagedMemoryPolicy { CUTOFF_ALLOW_NICE_TO_HAVE, CUTOFF_ALLOW_EVERYTHING, }; + static const size_t kDefaultNumResourcesLimit; explicit ManagedMemoryPolicy(size_t bytes_limit_when_visible); ManagedMemoryPolicy(size_t bytes_limit_when_visible, PriorityCutoff priority_cutoff_when_visible, size_t bytes_limit_when_not_visible, - PriorityCutoff priority_cutoff_when_not_visible); + PriorityCutoff priority_cutoff_when_not_visible, + size_t num_resources_limit); bool operator==(const ManagedMemoryPolicy&) const; bool operator!=(const ManagedMemoryPolicy&) const; @@ -31,6 +33,7 @@ struct CC_EXPORT ManagedMemoryPolicy { PriorityCutoff priority_cutoff_when_visible; size_t bytes_limit_when_not_visible; PriorityCutoff priority_cutoff_when_not_visible; + size_t num_resources_limit; static int PriorityCutoffToValue(PriorityCutoff priority_cutoff); static TileMemoryLimitPolicy PriorityCutoffToTileMemoryLimitPolicy( diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index ce2e477..be990cc 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -78,8 +78,10 @@ class OutputSurfaceCallbacks allocation.bytesLimitWhenVisible, ConvertPriorityCutoff(allocation.priorityCutoffWhenVisible), allocation.bytesLimitWhenNotVisible, - ConvertPriorityCutoff(allocation.priorityCutoffWhenNotVisible)); - client_->SetMemoryPolicy(policy, !allocation.suggestHaveBackbuffer); + ConvertPriorityCutoff(allocation.priorityCutoffWhenNotVisible), + ManagedMemoryPolicy::kDefaultNumResourcesLimit); + bool discard_backbuffer = !allocation.suggestHaveBackbuffer; + client_->SetMemoryPolicy(policy, discard_backbuffer); } private: @@ -442,11 +444,16 @@ void OutputSurface::PostSwapBuffersComplete() { } void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy, - bool discard_backbuffer_when_not_visible) { + bool discard_backbuffer) { TRACE_EVENT2("cc", "OutputSurface::SetMemoryPolicy", "bytes_limit_when_visible", policy.bytes_limit_when_visible, - "discard_backbuffer", discard_backbuffer_when_not_visible); - client_->SetMemoryPolicy(policy, discard_backbuffer_when_not_visible); + "discard_backbuffer", discard_backbuffer); + // Just ignore the memory manager when it says to set the limit to zero + // bytes. This will happen when the memory manager thinks that the renderer + // is not visible (which the renderer knows better). + if (policy.bytes_limit_when_visible) + client_->SetMemoryPolicy(policy); + client_->SetDiscardBackBufferWhenNotVisible(discard_backbuffer); } } // namespace cc diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h index b4e2820..4d17622 100644 --- a/cc/output/output_surface_client.h +++ b/cc/output/output_surface_client.h @@ -37,15 +37,14 @@ class CC_EXPORT OutputSurfaceClient { virtual void SetExternalStencilTest(bool enabled) = 0; virtual void SetExternalDrawConstraints(const gfx::Transform& transform, gfx::Rect viewport) = 0; - virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy, - bool discard_backbuffer_when_not_visible) = 0; + virtual void SetDiscardBackBufferWhenNotVisible(bool discard) = 0; + virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) = 0; // If set, |callback| will be called subsequent to each new tree activation, // regardless of the compositor visibility or damage. |callback| must remain // valid for the lifetime of the OutputSurfaceClient or until unregisted -- // use SetTreeActivationCallback(base::Closure()) to unregister it. virtual void SetTreeActivationCallback(const base::Closure& callback) = 0; - protected: virtual ~OutputSurfaceClient() {} }; diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc index b0b34ba..276828c 100644 --- a/cc/output/output_surface_unittest.cc +++ b/cc/output/output_surface_unittest.cc @@ -360,6 +360,11 @@ TEST(OutputSurfaceTest, MemoryAllocation) { client.memory_policy().priority_cutoff_when_visible); EXPECT_EQ(ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE, client.memory_policy().priority_cutoff_when_not_visible); + + // 0 bytes limit should be ignored. + allocation.bytesLimitWhenVisible = 0; + context->SetMemoryAllocation(allocation); + EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible); } } // namespace diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc index 7bf482c..5835db5 100644 --- a/cc/resources/resource_pool.cc +++ b/cc/resources/resource_pool.cc @@ -32,11 +32,12 @@ ResourcePool::ResourcePool(ResourceProvider* resource_provider) max_memory_usage_bytes_(0), max_unused_memory_usage_bytes_(0), memory_usage_bytes_(0), - unused_memory_usage_bytes_(0) { + unused_memory_usage_bytes_(0), + num_resources_limit_(0) { } ResourcePool::~ResourcePool() { - SetMaxMemoryUsageBytes(0, 0); + SetMemoryUsageLimits(0, 0, 0); } scoped_ptr<ResourcePool::Resource> ResourcePool::AcquireResource( @@ -85,11 +86,13 @@ void ResourcePool::ReleaseResource( resources_.push_back(resource.release()); } -void ResourcePool::SetMaxMemoryUsageBytes( +void ResourcePool::SetMemoryUsageLimits( size_t max_memory_usage_bytes, - size_t max_unused_memory_usage_bytes) { + size_t max_unused_memory_usage_bytes, + size_t num_resources_limit) { max_memory_usage_bytes_ = max_memory_usage_bytes; max_unused_memory_usage_bytes_ = max_unused_memory_usage_bytes; + num_resources_limit_ = num_resources_limit; while (!resources_.empty()) { if (!MemoryUsageTooHigh()) @@ -106,6 +109,8 @@ void ResourcePool::SetMaxMemoryUsageBytes( } bool ResourcePool::MemoryUsageTooHigh() { + if (resources_.size() > num_resources_limit_) + return true; if (memory_usage_bytes_ > max_memory_usage_bytes_) return true; if (unused_memory_usage_bytes_ > max_unused_memory_usage_bytes_) diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h index 44936e9..2304a50 100644 --- a/cc/resources/resource_pool.h +++ b/cc/resources/resource_pool.h @@ -40,13 +40,14 @@ class CC_EXPORT ResourcePool { GLenum format); void ReleaseResource(scoped_ptr<ResourcePool::Resource>); - void SetMaxMemoryUsageBytes( - size_t max_memory_usage_bytes, - size_t max_unused_memory_usage_bytes); + void SetMemoryUsageLimits(size_t max_memory_usage_bytes, + size_t max_unused_memory_usage_bytes, + size_t num_resources_limit); size_t acquired_memory_usage_bytes() const { return memory_usage_bytes_ - unused_memory_usage_bytes_; } + size_t NumResources() const { return resources_.size(); } protected: explicit ResourcePool(ResourceProvider* resource_provider); @@ -59,6 +60,7 @@ class CC_EXPORT ResourcePool { size_t max_unused_memory_usage_bytes_; size_t memory_usage_bytes_; size_t unused_memory_usage_bytes_; + size_t num_resources_limit_; typedef std::list<Resource*> ResourceList; ResourceList resources_; diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc index b014aed1..0c4103e 100644 --- a/cc/resources/tile_manager.cc +++ b/cc/resources/tile_manager.cc @@ -161,9 +161,10 @@ TileManager::~TileManager() { void TileManager::SetGlobalState( const GlobalStateThatImpactsTilePriority& global_state) { global_state_ = global_state; - resource_pool_->SetMaxMemoryUsageBytes( + resource_pool_->SetMemoryUsageLimits( global_state_.memory_limit_in_bytes, - global_state_.unused_memory_limit_in_bytes); + global_state_.unused_memory_limit_in_bytes, + global_state_.num_resources_limit); } void TileManager::RegisterTile(Tile* tile) { @@ -474,14 +475,17 @@ void TileManager::AssignGpuMemoryToTiles( // Now give memory out to the tiles until we're out, and build // the needs-to-be-rasterized queue. size_t bytes_releasable = 0; + size_t resources_releasable = 0; for (TileRefVector::const_iterator it = sorted_tiles.begin(); it != sorted_tiles.end(); ++it) { const Tile* tile = it->get(); const ManagedTileState& mts = tile->managed_state(); for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { - if (mts.tile_versions[mode].resource_) + if (mts.tile_versions[mode].resource_) { bytes_releasable += tile->bytes_consumed_if_allocated(); + resources_releasable++; + } } } @@ -494,12 +498,17 @@ void TileManager::AssignGpuMemoryToTiles( static_cast<int64>(bytes_releasable) + static_cast<int64>(global_state_.memory_limit_in_bytes) - static_cast<int64>(resource_pool_->acquired_memory_usage_bytes()); + int resources_available = resources_releasable + + global_state_.num_resources_limit - + resource_pool_->NumResources(); size_t bytes_allocatable = std::max(static_cast<int64>(0), bytes_available); + size_t resources_allocatable = std::max(0, resources_available); size_t bytes_that_exceeded_memory_budget = 0; size_t bytes_left = bytes_allocatable; + size_t resources_left = resources_allocatable; bool oomed = false; for (TileRefVector::const_iterator it = sorted_tiles.begin(); it != sorted_tiles.end(); @@ -523,11 +532,14 @@ void TileManager::AssignGpuMemoryToTiles( } size_t tile_bytes = 0; + size_t tile_resources = 0; // It costs to maintain a resource. for (int mode = 0; mode < NUM_RASTER_MODES; ++mode) { - if (mts.tile_versions[mode].resource_) + if (mts.tile_versions[mode].resource_) { tile_bytes += tile->bytes_consumed_if_allocated(); + tile_resources++; + } } // Allow lower priority tiles with initialized resources to keep @@ -536,12 +548,14 @@ void TileManager::AssignGpuMemoryToTiles( if (tiles_that_need_to_be_rasterized->size() < kMaxRasterTasks) { // If we don't have the required version, and it's not in flight // then we'll have to pay to create a new task. - if (!tile_version.resource_ && tile_version.raster_task_.is_null()) + if (!tile_version.resource_ && tile_version.raster_task_.is_null()) { tile_bytes += tile->bytes_consumed_if_allocated(); + tile_resources++; + } } // Tile is OOM. - if (tile_bytes > bytes_left) { + if (tile_bytes > bytes_left || tile_resources > resources_left) { FreeResourcesForTile(tile); // This tile was already on screen and now its resources have been @@ -554,6 +568,7 @@ void TileManager::AssignGpuMemoryToTiles( bytes_that_exceeded_memory_budget += tile_bytes; } else { bytes_left -= tile_bytes; + resources_left -= tile_resources; if (tile_version.resource_) continue; diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc index 12f46a3..f55f1e4 100644 --- a/cc/resources/tile_manager_unittest.cc +++ b/cc/resources/tile_manager_unittest.cc @@ -59,11 +59,11 @@ class TilePriorityRequiredForActivation : public TilePriority { } }; -class TileManagerTest : public testing::Test { +class TileManagerTest : public testing::TestWithParam<bool> { public: typedef std::vector<scoped_refptr<Tile> > TileVector; - void Initialize(int max_memory_tiles, + void Initialize(int max_tiles, TileMemoryLimitPolicy memory_limit_policy, TreePriority tree_priority) { output_surface_ = FakeOutputSurface::Create3d(); @@ -72,11 +72,20 @@ class TileManagerTest : public testing::Test { new FakeTileManager(&tile_manager_client_, resource_provider_.get())); memory_limit_policy_ = memory_limit_policy; - max_memory_tiles_ = max_memory_tiles; + max_memory_tiles_ = max_tiles; GlobalStateThatImpactsTilePriority state; gfx::Size tile_size = settings_.default_tile_size; - state.memory_limit_in_bytes = - max_memory_tiles * 4 * tile_size.width() * tile_size.height(); + + // The parametrization specifies whether the max tile limit should + // be applied to RAM or to tile limit. + if (GetParam()) { + state.memory_limit_in_bytes = + max_tiles * 4 * tile_size.width() * tile_size.height(); + state.num_resources_limit = 100; + } else { + state.memory_limit_in_bytes = 100 * 1000 * 1000; + state.num_resources_limit = max_tiles; + } state.memory_limit_policy = memory_limit_policy; state.tree_priority = tree_priority; @@ -90,6 +99,7 @@ class TileManagerTest : public testing::Test { state.memory_limit_in_bytes = max_memory_tiles_ * 4 * tile_size.width() * tile_size.height(); state.memory_limit_policy = memory_limit_policy_; + state.num_resources_limit = 100; state.tree_priority = tree_priority; tile_manager_->SetGlobalState(state); } @@ -160,7 +170,7 @@ class TileManagerTest : public testing::Test { int max_memory_tiles_; }; -TEST_F(TileManagerTest, EnoughMemoryAllowAnything) { +TEST_P(TileManagerTest, EnoughMemoryAllowAnything) { // A few tiles of each type of priority, with enough memory for all tiles. Initialize(10, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); @@ -180,7 +190,7 @@ TEST_F(TileManagerTest, EnoughMemoryAllowAnything) { EXPECT_EQ(0, AssignedMemoryCount(never_bin)); } -TEST_F(TileManagerTest, EnoughMemoryAllowPrepaintOnly) { +TEST_P(TileManagerTest, EnoughMemoryAllowPrepaintOnly) { // A few tiles of each type of priority, with enough memory for all tiles, // with the exception of never bin. @@ -201,7 +211,7 @@ TEST_F(TileManagerTest, EnoughMemoryAllowPrepaintOnly) { EXPECT_EQ(0, AssignedMemoryCount(never_bin)); } -TEST_F(TileManagerTest, EnoughMemoryAllowAbsoluteMinimum) { +TEST_P(TileManagerTest, EnoughMemoryAllowAbsoluteMinimum) { // A few tiles of each type of priority, with enough memory for all tiles, // with the exception of never and soon bins. @@ -222,7 +232,7 @@ TEST_F(TileManagerTest, EnoughMemoryAllowAbsoluteMinimum) { EXPECT_EQ(0, AssignedMemoryCount(never_bin)); } -TEST_F(TileManagerTest, EnoughMemoryAllowNothing) { +TEST_P(TileManagerTest, EnoughMemoryAllowNothing) { // A few tiles of each type of priority, with enough memory for all tiles, // but allow nothing should not assign any memory. @@ -243,7 +253,7 @@ TEST_F(TileManagerTest, EnoughMemoryAllowNothing) { EXPECT_EQ(0, AssignedMemoryCount(never_bin)); } -TEST_F(TileManagerTest, PartialOOMMemoryToPending) { +TEST_P(TileManagerTest, PartialOOMMemoryToPending) { // 5 tiles on active tree eventually bin, 5 tiles on pending tree that are // required for activation, but only enough memory for 8 tiles. The result // is all pending tree tiles get memory, and 3 of the active tree tiles @@ -267,7 +277,7 @@ TEST_F(TileManagerTest, PartialOOMMemoryToPending) { EXPECT_EQ(5, AssignedMemoryCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, PartialOOMMemoryToActive) { +TEST_P(TileManagerTest, PartialOOMMemoryToActive) { // 5 tiles on active tree eventually bin, 5 tiles on pending tree now bin, // but only enough memory for 8 tiles. The result is all active tree tiles // get memory, and 3 of the pending tree tiles get memory. @@ -284,7 +294,7 @@ TEST_F(TileManagerTest, PartialOOMMemoryToActive) { EXPECT_EQ(3, AssignedMemoryCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, TotalOOMMemoryToPending) { +TEST_P(TileManagerTest, TotalOOMMemoryToPending) { // 5 tiles on active tree eventually bin, 5 tiles on pending tree that are // required for activation, but only enough memory for 4 tiles. The result // is 4 pending tree tiles get memory, and none of the active tree tiles @@ -308,7 +318,7 @@ TEST_F(TileManagerTest, TotalOOMMemoryToPending) { EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, TotalOOMActiveSoonMemoryToPending) { +TEST_P(TileManagerTest, TotalOOMActiveSoonMemoryToPending) { // 5 tiles on active tree soon bin, 5 tiles on pending tree that are // required for activation, but only enough memory for 4 tiles. The result // is 4 pending tree tiles get memory, and none of the active tree tiles @@ -332,7 +342,7 @@ TEST_F(TileManagerTest, TotalOOMActiveSoonMemoryToPending) { EXPECT_EQ(4, AssignedMemoryCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, TotalOOMMemoryToActive) { +TEST_P(TileManagerTest, TotalOOMMemoryToActive) { // 5 tiles on active tree eventually bin, 5 tiles on pending tree now bin, // but only enough memory for 4 tiles. The result is 5 active tree tiles // get memory, and none of the pending tree tiles get memory. @@ -349,7 +359,9 @@ TEST_F(TileManagerTest, TotalOOMMemoryToActive) { EXPECT_EQ(0, AssignedMemoryCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, RasterAsLCD) { + + +TEST_P(TileManagerTest, RasterAsLCD) { Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); TileVector active_tree_tiles = CreateTiles(5, TilePriorityForNowBin(), TilePriority()); @@ -362,7 +374,7 @@ TEST_F(TileManagerTest, RasterAsLCD) { EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, RasterAsNoLCD) { +TEST_P(TileManagerTest, RasterAsNoLCD) { Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); TileVector active_tree_tiles = CreateTiles(5, TilePriorityForNowBin(), TilePriority()); @@ -386,7 +398,7 @@ TEST_F(TileManagerTest, RasterAsNoLCD) { EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, ReRasterAsNoLCD) { +TEST_P(TileManagerTest, ReRasterAsNoLCD) { Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); TileVector active_tree_tiles = CreateTiles(5, TilePriorityForNowBin(), TilePriority()); @@ -415,7 +427,7 @@ TEST_F(TileManagerTest, ReRasterAsNoLCD) { EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, NoTextDontReRasterAsNoLCD) { +TEST_P(TileManagerTest, NoTextDontReRasterAsNoLCD) { Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); TileVector active_tree_tiles = CreateTiles(5, TilePriorityForNowBin(), TilePriority()); @@ -452,7 +464,7 @@ TEST_F(TileManagerTest, NoTextDontReRasterAsNoLCD) { EXPECT_EQ(5, TilesWithLCDCount(pending_tree_tiles)); } -TEST_F(TileManagerTest, TextReRasterAsNoLCD) { +TEST_P(TileManagerTest, TextReRasterAsNoLCD) { Initialize(20, ALLOW_ANYTHING, SMOOTHNESS_TAKES_PRIORITY); TileVector active_tree_tiles = CreateTiles(5, TilePriorityForNowBin(), TilePriority()); @@ -494,5 +506,11 @@ TEST_F(TileManagerTest, TextReRasterAsNoLCD) { EXPECT_EQ(0, TilesWithLCDCount(pending_tree_tiles)); } +// If true, the max tile limit should be applied as bytes; if false, +// as num_resources_limit. +INSTANTIATE_TEST_CASE_P(TileManagerTests, + TileManagerTest, + ::testing::Values(true, false)); + } // namespace } // namespace cc diff --git a/cc/resources/tile_priority.cc b/cc/resources/tile_priority.cc index 1f7a6f6..970ea1d 100644 --- a/cc/resources/tile_priority.cc +++ b/cc/resources/tile_priority.cc @@ -188,6 +188,9 @@ scoped_ptr<base::Value> GlobalStateThatImpactsTilePriority::AsValue() const { state->Set("memory_limit_policy", TileMemoryLimitPolicyAsValue(memory_limit_policy).release()); state->SetInteger("memory_limit_in_bytes", memory_limit_in_bytes); + state->SetInteger("unused_memory_limit_in_bytes", + unused_memory_limit_in_bytes); + state->SetInteger("num_resources_limit", num_resources_limit); state->Set("tree_priority", TreePriorityAsValue(tree_priority).release()); return state.PassAs<base::Value>(); } diff --git a/cc/resources/tile_priority.h b/cc/resources/tile_priority.h index 88323ba..5c92d2f 100644 --- a/cc/resources/tile_priority.h +++ b/cc/resources/tile_priority.h @@ -160,12 +160,14 @@ class GlobalStateThatImpactsTilePriority { : memory_limit_policy(ALLOW_NOTHING), memory_limit_in_bytes(0), unused_memory_limit_in_bytes(0), + num_resources_limit(0), tree_priority(SAME_PRIORITY_FOR_BOTH_TREES) {} TileMemoryLimitPolicy memory_limit_policy; size_t memory_limit_in_bytes; size_t unused_memory_limit_in_bytes; + size_t num_resources_limit; TreePriority tree_priority; diff --git a/cc/test/fake_output_surface_client.cc b/cc/test/fake_output_surface_client.cc index 7b371ca..2ce6cf0 100644 --- a/cc/test/fake_output_surface_client.cc +++ b/cc/test/fake_output_surface_client.cc @@ -21,10 +21,13 @@ void FakeOutputSurfaceClient::DidLoseOutputSurface() { } void FakeOutputSurfaceClient::SetMemoryPolicy( - const ManagedMemoryPolicy& policy, - bool discard_backbuffer_when_not_visible) { + const ManagedMemoryPolicy& policy) { memory_policy_ = policy; - discard_backbuffer_when_not_visible_ = discard_backbuffer_when_not_visible; } +void FakeOutputSurfaceClient::SetDiscardBackBufferWhenNotVisible(bool discard) { + discard_backbuffer_when_not_visible_ = discard; +} + + } // namespace cc diff --git a/cc/test/fake_output_surface_client.h b/cc/test/fake_output_surface_client.h index c8169d2..5a824e7 100644 --- a/cc/test/fake_output_surface_client.h +++ b/cc/test/fake_output_surface_client.h @@ -30,9 +30,8 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient { virtual void SetExternalDrawConstraints(const gfx::Transform& transform, gfx::Rect viewport) OVERRIDE {} virtual void SetExternalStencilTest(bool enable) OVERRIDE {} - virtual void SetMemoryPolicy( - const ManagedMemoryPolicy& policy, - bool discard_backbuffer_when_not_visible) OVERRIDE; + virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE; + virtual void SetDiscardBackBufferWhenNotVisible(bool discard) OVERRIDE; virtual void SetTreeActivationCallback(const base::Closure&) OVERRIDE {} int begin_frame_count() { diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index 5ec7a5c..266af36 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc @@ -71,8 +71,8 @@ class PixelTest::PixelTestRendererClient virtual void SetExternalStencilTest(bool enable) OVERRIDE { stencil_enabled_ = enable; } - virtual void SetMemoryPolicy( - const ManagedMemoryPolicy& policy, bool discard) OVERRIDE {} + virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE {} + virtual void SetDiscardBackBufferWhenNotVisible(bool discard) OVERRIDE {} virtual void SetTreeActivationCallback(const base::Closure&) OVERRIDE {} private: diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index f5661a8..c61e6be 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -178,11 +178,12 @@ LayerTreeHostImpl::LayerTreeHostImpl( root_layer_scroll_offset_delegate_(NULL), settings_(settings), visible_(true), - managed_memory_policy_( + cached_managed_memory_policy_( PrioritizedResourceManager::DefaultMemoryAllocationLimit(), ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, 0, - ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING), + ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING, + ManagedMemoryPolicy::kDefaultNumResourcesLimit), pinch_gesture_active_(false), fps_counter_(FrameRateCounter::Create(proxy_->HasImplThread())), paint_time_counter_(PaintTimeCounter::Create()), @@ -1043,6 +1044,7 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy( visible_ ? policy.priority_cutoff_when_visible : policy.priority_cutoff_when_not_visible); + new_state.num_resources_limit = policy.num_resources_limit; tile_manager_->SetGlobalState(new_state); manage_tiles_needed_ = true; } @@ -1070,17 +1072,13 @@ bool LayerTreeHostImpl::ShouldClearRootRenderPass() const { return settings_.should_clear_root_render_pass; } -void LayerTreeHostImpl::SetMemoryPolicy( - const ManagedMemoryPolicy& policy, - bool discard_backbuffer_when_not_visible) { - if (policy.bytes_limit_when_visible) { - // Just ignore the memory manager when it says to set the limit to zero - // bytes. This will happen when the memory manager thinks that the renderer - // is not visible (which the renderer knows better). - SetManagedMemoryPolicy(policy); - } - renderer_->SetDiscardBackBufferWhenNotVisible( - discard_backbuffer_when_not_visible); +void LayerTreeHostImpl::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { + SetManagedMemoryPolicy(policy, zero_budget_); +} + +void LayerTreeHostImpl::SetDiscardBackBufferWhenNotVisible(bool discard) { + DCHECK(renderer_); + renderer_->SetDiscardBackBufferWhenNotVisible(discard); } void LayerTreeHostImpl::SetTreeActivationCallback( @@ -1091,37 +1089,40 @@ void LayerTreeHostImpl::SetTreeActivationCallback( } void LayerTreeHostImpl::SetManagedMemoryPolicy( - const ManagedMemoryPolicy& policy) { - if (managed_memory_policy_ == policy) + const ManagedMemoryPolicy& policy, bool zero_budget) { + if (cached_managed_memory_policy_ == policy && zero_budget_ == zero_budget) return; - if (zero_budget_) - DCHECK_EQ(0u, policy.bytes_limit_when_visible); + ManagedMemoryPolicy old_policy = ActualManagedMemoryPolicy(); - // If there is already enough memory to draw everything imaginable and the - // new memory limit does not change this, then do not re-commit. Don't bother - // skipping commits if this is not visible (commits don't happen when not - // visible, there will almost always be a commit when this becomes visible). - bool needs_commit = true; - if (visible() && - policy.bytes_limit_when_visible >= - max_memory_needed_bytes_ && - managed_memory_policy_.bytes_limit_when_visible >= - max_memory_needed_bytes_ && - policy.priority_cutoff_when_visible == - managed_memory_policy_.priority_cutoff_when_visible) { - needs_commit = false; - } + cached_managed_memory_policy_ = policy; + zero_budget_ = zero_budget; + ManagedMemoryPolicy actual_policy = ActualManagedMemoryPolicy(); + + if (old_policy == actual_policy) + return; - managed_memory_policy_ = policy; if (!proxy_->HasImplThread()) { // In single-thread mode, this can be called on the main thread by // GLRenderer::OnMemoryAllocationChanged. DebugScopedSetImplThread impl_thread(proxy_); - EnforceManagedMemoryPolicy(ActualManagedMemoryPolicy()); + EnforceManagedMemoryPolicy(actual_policy); } else { DCHECK(proxy_->IsImplThread()); - EnforceManagedMemoryPolicy(ActualManagedMemoryPolicy()); + EnforceManagedMemoryPolicy(actual_policy); + } + + // If there is already enough memory to draw everything imaginable and the + // new memory limit does not change this, then do not re-commit. Don't bother + // skipping commits if this is not visible (commits don't happen when not + // visible, there will almost always be a commit when this becomes visible). + bool needs_commit = true; + if (visible() && + actual_policy.bytes_limit_when_visible >= max_memory_needed_bytes_ && + old_policy.bytes_limit_when_visible >= max_memory_needed_bytes_ && + actual_policy.priority_cutoff_when_visible == + old_policy.priority_cutoff_when_visible) { + needs_commit = false; } if (needs_commit) @@ -1512,17 +1513,26 @@ void LayerTreeHostImpl::SetVisible(bool visible) { } ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const { - if (!debug_state_.rasterize_only_visible_content) - return managed_memory_policy_; - - ManagedMemoryPolicy actual = managed_memory_policy_; - actual.priority_cutoff_when_not_visible = - ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING; - actual.priority_cutoff_when_visible = - ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY; + ManagedMemoryPolicy actual = cached_managed_memory_policy_; + if (debug_state_.rasterize_only_visible_content) { + actual.priority_cutoff_when_not_visible = + ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING; + actual.priority_cutoff_when_visible = + ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY; + } + + if (zero_budget_) { + actual.bytes_limit_when_visible = 0; + actual.bytes_limit_when_not_visible = 0; + } + return actual; } +size_t LayerTreeHostImpl::memory_allocation_limit_bytes() const { + return ActualManagedMemoryPolicy().bytes_limit_when_visible; +} + void LayerTreeHostImpl::ReleaseTreeResources() { if (active_tree_->root_layer()) SendReleaseResourcesRecursive(active_tree_->root_layer()); @@ -1575,19 +1585,7 @@ void LayerTreeHostImpl::CreateAndSetTileManager( } void LayerTreeHostImpl::EnforceZeroBudget(bool zero_budget) { - if (zero_budget_ == zero_budget) - return; - - zero_budget_ = zero_budget; - - ManagedMemoryPolicy new_policy = managed_memory_policy_; - if (zero_budget_) { - new_policy.bytes_limit_when_visible = 0; - } else { - new_policy.bytes_limit_when_visible = - PrioritizedResourceManager::DefaultMemoryAllocationLimit(); - } - SetManagedMemoryPolicy(new_policy); + SetManagedMemoryPolicy(cached_managed_memory_policy_, zero_budget); } bool LayerTreeHostImpl::InitializeRenderer( diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 6830d6d..ae6f3c1 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -210,9 +210,8 @@ class CC_EXPORT LayerTreeHostImpl virtual void SetExternalStencilTest(bool enabled) OVERRIDE; virtual void DidLoseOutputSurface() OVERRIDE; virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE; - virtual void SetMemoryPolicy( - const ManagedMemoryPolicy& policy, - bool discard_backbuffer_when_not_visible) OVERRIDE; + virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) OVERRIDE; + virtual void SetDiscardBackBufferWhenNotVisible(bool discard) OVERRIDE; virtual void SetTreeActivationCallback(const base::Closure& callback) OVERRIDE; @@ -262,9 +261,7 @@ class CC_EXPORT LayerTreeHostImpl ManagedMemoryPolicy ActualManagedMemoryPolicy() const; - size_t memory_allocation_limit_bytes() const { - return managed_memory_policy_.bytes_limit_when_visible; - } + size_t memory_allocation_limit_bytes() const; void SetViewportSize(gfx::Size device_viewport_size); gfx::Size device_viewport_size() const { return device_viewport_size_; } @@ -450,7 +447,8 @@ class CC_EXPORT LayerTreeHostImpl void UpdateCurrentFrameTime(base::TimeTicks* ticks, base::Time* now) const; void StartScrollbarAnimationRecursive(LayerImpl* layer, base::TimeTicks time); - void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy); + void SetManagedMemoryPolicy(const ManagedMemoryPolicy& policy, + bool zero_budget); void EnforceManagedMemoryPolicy(const ManagedMemoryPolicy& policy); void DidInitializeVisibleTile(); @@ -490,7 +488,7 @@ class CC_EXPORT LayerTreeHostImpl LayerTreeSettings settings_; LayerTreeDebugState debug_state_; bool visible_; - ManagedMemoryPolicy managed_memory_policy_; + ManagedMemoryPolicy cached_managed_memory_policy_; gfx::Vector2dF accumulated_root_overscroll_; gfx::Vector2dF current_fling_velocity_; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index f833655..72a72b4 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -308,7 +308,8 @@ class LayerTreeHostImplTest : public testing::Test, // and make sure that it does not change can_draw. set_reduce_memory_result(false); host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1), true); + host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetDiscardBackBufferWhenNotVisible(true); EXPECT_TRUE(host_impl_->CanDraw()); EXPECT_FALSE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; @@ -316,7 +317,8 @@ class LayerTreeHostImplTest : public testing::Test, // Toggle contents textures purged to make sure it toggles can_draw. set_reduce_memory_result(true); host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1), true); + host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetDiscardBackBufferWhenNotVisible(true); if (always_draw) { EXPECT_TRUE(host_impl_->CanDraw()); } else { @@ -4845,7 +4847,8 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { host_impl_->set_max_memory_needed_bytes( host_impl_->memory_allocation_limit_bytes() - 1); host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1), true); + host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetDiscardBackBufferWhenNotVisible(true); EXPECT_FALSE(did_request_commit_); did_request_commit_ = false; @@ -4856,7 +4859,8 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { host_impl_->set_max_memory_needed_bytes( host_impl_->memory_allocation_limit_bytes()); host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1), true); + host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetDiscardBackBufferWhenNotVisible(true); EXPECT_TRUE(did_request_commit_); did_request_commit_ = false; @@ -4865,14 +4869,16 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { set_reduce_memory_result(true); host_impl_->set_max_memory_needed_bytes(1); host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes() - 1), true); + host_impl_->memory_allocation_limit_bytes() - 1)); + host_impl_->SetDiscardBackBufferWhenNotVisible(true); EXPECT_TRUE(did_request_commit_); did_request_commit_ = false; // But if we set it to the same value that it was before, we shouldn't // re-commit. host_impl_->SetMemoryPolicy(ManagedMemoryPolicy( - host_impl_->memory_allocation_limit_bytes()), true); + host_impl_->memory_allocation_limit_bytes())); + host_impl_->SetDiscardBackBufferWhenNotVisible(true); EXPECT_FALSE(did_request_commit_); } @@ -6209,14 +6215,14 @@ TEST_F(LayerTreeHostImplTest, DefaultMemoryAllocation) { TEST_F(LayerTreeHostImplTest, MemoryPolicy) { ManagedMemoryPolicy policy1( 456, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, - 123, ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE); + 123, ManagedMemoryPolicy::CUTOFF_ALLOW_NICE_TO_HAVE, 1000); int visible_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue( policy1.priority_cutoff_when_visible); int not_visible_cutoff_value = ManagedMemoryPolicy::PriorityCutoffToValue( policy1.priority_cutoff_when_not_visible); host_impl_->SetVisible(true); - host_impl_->SetMemoryPolicy(policy1, false); + host_impl_->SetMemoryPolicy(policy1); EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); EXPECT_EQ(visible_cutoff_value, current_priority_cutoff_value_); @@ -6227,19 +6233,6 @@ TEST_F(LayerTreeHostImplTest, MemoryPolicy) { host_impl_->SetVisible(true); EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); EXPECT_EQ(visible_cutoff_value, current_priority_cutoff_value_); - - // A policy with a 0 allocation is discarded. - ManagedMemoryPolicy actual_policy = host_impl_->ActualManagedMemoryPolicy(); - ManagedMemoryPolicy policy2( - 0, ManagedMemoryPolicy::CUTOFF_ALLOW_REQUIRED_ONLY, - 0, ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING); - host_impl_->SetMemoryPolicy(policy2, false); - EXPECT_EQ(actual_policy, host_impl_->ActualManagedMemoryPolicy()); - EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); - EXPECT_EQ(visible_cutoff_value, current_priority_cutoff_value_); - host_impl_->SetVisible(false); - EXPECT_EQ(policy1.bytes_limit_when_not_visible, current_limit_bytes_); - EXPECT_EQ(not_visible_cutoff_value, current_priority_cutoff_value_); } TEST_F(LayerTreeHostImplTest, UIResourceManagement) { diff --git a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc index c412fd5..a1990b0 100644 --- a/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc +++ b/cc/trees/layer_tree_host_pixeltest_on_demand_raster.cc @@ -30,8 +30,9 @@ class LayerTreeHostOnDemandRasterPixelTest : public LayerTreePixelTest { // Not enough memory available. Enforce on-demand rasterization. impl->SetMemoryPolicy( ManagedMemoryPolicy(1, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, - 1, ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING), - true); + 1, ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING, + 1000)); + impl->SetDiscardBackBufferWhenNotVisible(true); } virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 0a4c236..9f9f653 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -1499,8 +1499,8 @@ class LayerTreeHostTestSurfaceNotAllocatedForLayersOutsideMemoryLimit // Reduce the memory limit to only fit the root layer and one render // surface. This prevents any contents drawing into surfaces // from being allocated. - host_impl->SetMemoryPolicy( - ManagedMemoryPolicy(100 * 100 * 4 * 2), true); + host_impl->SetMemoryPolicy(ManagedMemoryPolicy(100 * 100 * 4 * 2)); + host_impl->SetDiscardBackBufferWhenNotVisible(true); break; case 1: EXPECT_FALSE(renderer->HaveCachedResourcesForRenderPassId( @@ -2052,8 +2052,9 @@ class LayerTreeHostTestShutdownWithOnlySomeResourcesEvicted ManagedMemoryPolicy(100 * 100 * 4 * 2, ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, 100 * 100 * 4 * 1, - ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING), - true); + ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, + 1000)); + host_impl->SetDiscardBackBufferWhenNotVisible(true); break; case 2: // Only two backings should have memory. diff --git a/content/browser/android/in_process/synchronous_compositor_output_surface.cc b/content/browser/android/in_process/synchronous_compositor_output_surface.cc index a65ab1f..fafd06f 100644 --- a/content/browser/android/in_process/synchronous_compositor_output_surface.cc +++ b/content/browser/android/in_process/synchronous_compositor_output_surface.cc @@ -9,6 +9,7 @@ #include "cc/output/begin_frame_args.h" #include "cc/output/compositor_frame.h" #include "cc/output/context_provider.h" +#include "cc/output/managed_memory_policy.h" #include "cc/output/output_surface_client.h" #include "cc/output/software_output_device.h" #include "content/browser/android/in_process/synchronous_compositor_impl.h" @@ -124,6 +125,16 @@ bool SynchronousCompositorOutputSurface::BindToClient( SynchronousCompositorOutputSurfaceDelegate* delegate = GetDelegate(); if (delegate) delegate->DidBindOutputSurface(this); + + const int bytes_limit = 64 * 1024 * 1024; + const int num_resources_limit = 100; + surface_client->SetMemoryPolicy( + cc::ManagedMemoryPolicy(bytes_limit, + cc::ManagedMemoryPolicy::CUTOFF_ALLOW_EVERYTHING, + 0, + cc::ManagedMemoryPolicy::CUTOFF_ALLOW_NOTHING, + num_resources_limit)); + return true; } |