summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-29 00:17:42 +0000
committerccameron@chromium.org <ccameron@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-29 00:17:42 +0000
commitd7626ffdec1bf499baf1be6d1d52badfe95ba49c (patch)
treede9719988184d251757286d4ee558a196c73b950 /cc
parent60e7d52240664fac7ebbbc571173e4c5d0d1fad4 (diff)
downloadchromium_src-d7626ffdec1bf499baf1be6d1d52badfe95ba49c.zip
chromium_src-d7626ffdec1bf499baf1be6d1d52badfe95ba49c.tar.gz
chromium_src-d7626ffdec1bf499baf1be6d1d52badfe95ba49c.tar.bz2
Do not always request a new commit when memory limit is changed.
Skip re-committing if there is already enough memory to for everything, and the new memory limit hasn't changed that situation. In situations where fluctuations in, say, WebGL's memory usage causes the page's limit to move up and down frequently, this will prevent extra commits unless the changes actually change what is being rendered. Add tests for new LTH and PRM functions. BUG=189199 Review URL: https://chromiumcodereview.appspot.com/12958007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@191252 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/resources/prioritized_resource_manager.cc14
-rw-r--r--cc/resources/prioritized_resource_manager.h9
-rw-r--r--cc/resources/prioritized_resource_unittest.cc10
-rw-r--r--cc/trees/layer_tree_host.cc13
-rw-r--r--cc/trees/layer_tree_host_impl.cc26
-rw-r--r--cc/trees/layer_tree_host_impl.h8
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc19
7 files changed, 85 insertions, 14 deletions
diff --git a/cc/resources/prioritized_resource_manager.cc b/cc/resources/prioritized_resource_manager.cc
index 9659a4f..970336d 100644
--- a/cc/resources/prioritized_resource_manager.cc
+++ b/cc/resources/prioritized_resource_manager.cc
@@ -19,6 +19,7 @@ PrioritizedResourceManager::PrioritizedResourceManager(const Proxy* proxy)
max_memory_limit_bytes_(DefaultMemoryAllocationLimit()),
external_priority_cutoff_(PriorityCalculator::AllowEverythingCutoff()),
memory_use_bytes_(0),
+ max_memory_needed_bytes_(0),
memory_above_cutoff_bytes_(0),
memory_available_bytes_(0),
backings_tail_not_sorted_(false),
@@ -120,15 +121,20 @@ void PrioritizedResourceManager::PrioritizeTextures() {
// Only allow textures if they are higher than the cutoff. All textures
// of the same priority are accepted or rejected together, rather than
// being partially allowed randomly.
+ max_memory_needed_bytes_ = 0;
memory_above_cutoff_bytes_ = 0;
for (TextureVector::iterator it = sorted_textures.begin();
it != sorted_textures.end();
++it) {
+ PrioritizedResource* resource = *it;
bool is_above_priority_cutoff = PriorityCalculator::priority_is_higher(
- (*it)->request_priority(), priority_cutoff_);
- (*it)->set_above_priority_cutoff(is_above_priority_cutoff);
- if (is_above_priority_cutoff && !(*it)->is_self_managed())
- memory_above_cutoff_bytes_ += (*it)->bytes();
+ resource->request_priority(), priority_cutoff_);
+ resource->set_above_priority_cutoff(is_above_priority_cutoff);
+ if (!resource->is_self_managed()) {
+ max_memory_needed_bytes_ += resource->bytes();
+ if (is_above_priority_cutoff)
+ memory_above_cutoff_bytes_ += resource->bytes();
+ }
}
sorted_textures.clear();
diff --git a/cc/resources/prioritized_resource_manager.h b/cc/resources/prioritized_resource_manager.h
index 51571fe..a199ea7 100644
--- a/cc/resources/prioritized_resource_manager.h
+++ b/cc/resources/prioritized_resource_manager.h
@@ -56,11 +56,15 @@ class CC_EXPORT PrioritizedResourceManager {
static size_t DefaultMemoryAllocationLimit() { return 64 * 1024 * 1024; }
// MemoryUseBytes() describes the number of bytes used by existing allocated
- // textures. MemoryAboveCutoffBytes() describes the number of bytes that
+ // textures.
+ size_t MemoryUseBytes() const { return memory_use_bytes_; }
+ // MemoryAboveCutoffBytes() describes the number of bytes that
// would be used if all textures that are above the cutoff were allocated.
// MemoryUseBytes() <= MemoryAboveCutoffBytes() should always be true.
- size_t MemoryUseBytes() const { return memory_use_bytes_; }
size_t MemoryAboveCutoffBytes() const { return memory_above_cutoff_bytes_; }
+ // MaxMemoryNeededBytes() describes the number of bytes that would be used
+ // by textures if there were no limit on memory usage.
+ size_t MaxMemoryNeededBytes() const { return max_memory_needed_bytes_; }
size_t MemoryForSelfManagedTextures() const {
return max_memory_limit_bytes_ - memory_available_bytes_;
}
@@ -197,6 +201,7 @@ class CC_EXPORT PrioritizedResourceManager {
int external_priority_cutoff_;
size_t memory_use_bytes_;
size_t memory_above_cutoff_bytes_;
+ size_t max_memory_needed_bytes_;
size_t memory_available_bytes_;
typedef base::hash_set<PrioritizedResource*> TextureSet;
diff --git a/cc/resources/prioritized_resource_unittest.cc b/cc/resources/prioritized_resource_unittest.cc
index 58a938d..1c8de7e 100644
--- a/cc/resources/prioritized_resource_unittest.cc
+++ b/cc/resources/prioritized_resource_unittest.cc
@@ -137,6 +137,8 @@ TEST_F(PrioritizedResourceTest, RequestTextureExceedingMaxLimit) {
resource_manager->MemoryAboveCutoffBytes());
EXPECT_LE(resource_manager->MemoryUseBytes(),
resource_manager->MemoryAboveCutoffBytes());
+ EXPECT_EQ(TexturesMemorySize(2*kMaxTextures),
+ resource_manager->MaxMemoryNeededBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
impl_thread_and_main_thread_blocked(&proxy_);
@@ -185,6 +187,8 @@ TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) {
EXPECT_EQ(TexturesMemorySize(5), resource_manager->MemoryAboveCutoffBytes());
EXPECT_LE(resource_manager->MemoryUseBytes(),
resource_manager->MemoryAboveCutoffBytes());
+ EXPECT_EQ(TexturesMemorySize(kMaxTextures),
+ resource_manager->MaxMemoryNeededBytes());
// Set max limit to 4 textures
resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(4));
@@ -200,6 +204,8 @@ TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) {
EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes());
EXPECT_LE(resource_manager->MemoryUseBytes(),
resource_manager->MemoryAboveCutoffBytes());
+ EXPECT_EQ(TexturesMemorySize(kMaxTextures),
+ resource_manager->MaxMemoryNeededBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
impl_thread_and_main_thread_blocked(&proxy_);
@@ -504,6 +510,8 @@ TEST_F(PrioritizedResourceTest,
resource_manager->MemoryForSelfManagedTextures());
EXPECT_LE(resource_manager->MemoryUseBytes(),
resource_manager->MemoryAboveCutoffBytes());
+ EXPECT_EQ(TexturesMemorySize(8),
+ resource_manager->MaxMemoryNeededBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
impl_thread_and_main_thread_blocked(&proxy_);
@@ -550,6 +558,8 @@ TEST_F(PrioritizedResourceTest,
resource_manager->MemoryForSelfManagedTextures());
EXPECT_LE(resource_manager->MemoryUseBytes(),
resource_manager->MemoryAboveCutoffBytes());
+ EXPECT_EQ(TexturesMemorySize(8),
+ resource_manager->MaxMemoryNeededBytes());
DebugScopedSetImplThreadAndMainThreadBlocked
impl_thread_and_main_thread_blocked(&proxy_);
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index c98c81b..8969324 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -267,6 +267,19 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
bool new_impl_tree_has_no_evicted_resources =
!contents_texture_manager_->LinkedEvictedBackingsExist();
+ // If the memory limit has been increased since this now-finishing
+ // commit began, and the extra now-available memory would have been used,
+ // then request another commit.
+ if (contents_texture_manager_->MaxMemoryLimitBytes() <
+ host_impl->memory_allocation_limit_bytes() &&
+ contents_texture_manager_->MaxMemoryLimitBytes() <
+ contents_texture_manager_->MaxMemoryNeededBytes()) {
+ host_impl->SetNeedsCommit();
+ }
+
+ host_impl->set_max_memory_needed_bytes(
+ contents_texture_manager_->MaxMemoryNeededBytes());
+
contents_texture_manager_->UpdateBackingsInDrawingImplTree();
// In impl-side painting, synchronize to the pending tree so that it has
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 84fc082..76095de 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -174,6 +174,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
paint_time_counter_(PaintTimeCounter::Create()),
memory_history_(MemoryHistory::Create()),
debug_rect_history_(DebugRectHistory::Create()),
+ max_memory_needed_bytes_(0),
last_sent_memory_visible_bytes_(0),
last_sent_memory_visible_and_nearby_bytes_(0),
last_sent_memory_use_bytes_(0),
@@ -899,19 +900,34 @@ void LayerTreeHostImpl::SetManagedMemoryPolicy(
if (managed_memory_policy_ == policy)
return;
+ // 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;
+ }
+
managed_memory_policy_ = policy;
if (!proxy_->HasImplThread()) {
- // TODO(ccameron): In single-thread mode, this can be called on the main
- // thread by GLRenderer::OnMemoryAllocationChanged.
+ // In single-thread mode, this can be called on the main thread by
+ // GLRenderer::OnMemoryAllocationChanged.
DebugScopedSetImplThread impl_thread(proxy_);
EnforceManagedMemoryPolicy(managed_memory_policy_);
} else {
DCHECK(proxy_->IsImplThread());
EnforceManagedMemoryPolicy(managed_memory_policy_);
}
- // We always need to commit after changing the memory policy because the new
- // limit can result in more or less content having texture allocated for it.
- client_->SetNeedsCommitOnImplThread();
+
+ if (needs_commit)
+ client_->SetNeedsCommitOnImplThread();
}
void LayerTreeHostImpl::OnVSyncParametersChanged(base::TimeTicks timebase,
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 89133d0..ea31904 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -261,6 +261,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
size_t memory_visible_and_nearby_bytes,
size_t memory_use_bytes);
+ void set_max_memory_needed_bytes(size_t bytes) {
+ max_memory_needed_bytes_ = bytes;
+ }
+
FrameRateCounter* fps_counter() {
return fps_counter_.get();
}
@@ -456,6 +460,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
int64 cumulative_num_missing_tiles_;
+ // The maximum memory that would be used by the prioritized resource
+ // manager, if there were no limit on memory usage.
+ size_t max_memory_needed_bytes_;
+
size_t last_sent_memory_visible_bytes_;
size_t last_sent_memory_visible_and_nearby_bytes_;
size_t last_sent_memory_use_bytes_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index f98c9bf..873b0bd 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -4197,10 +4197,22 @@ TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) {
TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) {
set_reduce_memory_result(false);
- // Even if changing the memory limit didn't result in anything being
- // evicted, we need to re-commit because the new value may result in us
- // drawing something different than before.
+ // If changing the memory limit wouldn't result in changing what was
+ // committed, then no commit should be requested.
set_reduce_memory_result(false);
+ host_impl_->set_max_memory_needed_bytes(
+ host_impl_->memory_allocation_limit_bytes() - 1);
+ host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy(
+ host_impl_->memory_allocation_limit_bytes() - 1));
+ EXPECT_FALSE(did_request_commit_);
+ did_request_commit_ = false;
+
+ // If changing the memory limit would result in changing what was
+ // committed, then a commit should be requested, even though nothing was
+ // evicted.
+ set_reduce_memory_result(false);
+ host_impl_->set_max_memory_needed_bytes(
+ host_impl_->memory_allocation_limit_bytes());
host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy(
host_impl_->memory_allocation_limit_bytes() - 1));
EXPECT_TRUE(did_request_commit_);
@@ -4209,6 +4221,7 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) {
// Especially if changing the memory limit caused evictions, we need
// to re-commit.
set_reduce_memory_result(true);
+ host_impl_->set_max_memory_needed_bytes(1);
host_impl_->SetManagedMemoryPolicy(ManagedMemoryPolicy(
host_impl_->memory_allocation_limit_bytes() - 1));
EXPECT_TRUE(did_request_commit_);