diff options
author | reveman <reveman@chromium.org> | 2015-09-04 17:14:12 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-05 00:14:54 +0000 |
commit | 4dc4f0b1ce10639526da587ca087157521407346 (patch) | |
tree | 8eb1299d965e8b62776fc4538b75ba94b8dac2be /cc/raster | |
parent | 6b41488951893e6f65e0d736a6e9b034e096f3ee (diff) | |
download | chromium_src-4dc4f0b1ce10639526da587ca087157521407346.zip chromium_src-4dc4f0b1ce10639526da587ca087157521407346.tar.gz chromium_src-4dc4f0b1ce10639526da587ca087157521407346.tar.bz2 |
cc: Implement the staging buffer limit in bytes instead of number of buffers.
No changes to the general throttling logic. Simply use a byte limit
instead of a buffer count to throttle copy operations.
By using a byte limit rather than a buffer count, tile size
has no effect on how likely we are to be blocked on copy
operations to complete.
The default byte limit is set to 32MB. Same limit as before when
using 512x512 tiles.
BUG=527887
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1317263006
Cr-Commit-Position: refs/heads/master@{#347540}
Diffstat (limited to 'cc/raster')
-rw-r--r-- | cc/raster/one_copy_tile_task_worker_pool.cc | 90 | ||||
-rw-r--r-- | cc/raster/one_copy_tile_task_worker_pool.h | 14 |
2 files changed, 86 insertions, 18 deletions
diff --git a/cc/raster/one_copy_tile_task_worker_pool.cc b/cc/raster/one_copy_tile_task_worker_pool.cc index b2f8c11..c5518e3 100644 --- a/cc/raster/one_copy_tile_task_worker_pool.cc +++ b/cc/raster/one_copy_tile_task_worker_pool.cc @@ -169,11 +169,11 @@ scoped_ptr<TileTaskWorkerPool> OneCopyTileTaskWorkerPool::Create( ResourceProvider* resource_provider, int max_copy_texture_chromium_size, bool use_persistent_gpu_memory_buffers, - int max_staging_buffers) { + int max_staging_buffer_usage_in_bytes) { return make_scoped_ptr<TileTaskWorkerPool>(new OneCopyTileTaskWorkerPool( task_runner, task_graph_runner, resource_provider, max_copy_texture_chromium_size, use_persistent_gpu_memory_buffers, - max_staging_buffers)); + max_staging_buffer_usage_in_bytes)); } OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool( @@ -182,7 +182,7 @@ OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool( ResourceProvider* resource_provider, int max_copy_texture_chromium_size, bool use_persistent_gpu_memory_buffers, - int max_staging_buffers) + int max_staging_buffer_usage_in_bytes) : task_runner_(task_runner), task_graph_runner_(task_graph_runner), namespace_token_(task_graph_runner->GetNamespaceToken()), @@ -194,7 +194,9 @@ OneCopyTileTaskWorkerPool::OneCopyTileTaskWorkerPool( : kMaxBytesPerCopyOperation), use_persistent_gpu_memory_buffers_(use_persistent_gpu_memory_buffers), bytes_scheduled_since_last_flush_(0), - max_staging_buffers_(max_staging_buffers), + max_staging_buffer_usage_in_bytes_(max_staging_buffer_usage_in_bytes), + staging_buffer_usage_in_bytes_(0), + free_staging_buffer_usage_in_bytes_(0), staging_buffer_expiration_delay_( base::TimeDelta::FromMilliseconds(kStagingBufferExpirationDelayMs)), reduce_memory_usage_pending_(false), @@ -233,6 +235,8 @@ void OneCopyTileTaskWorkerPool::Shutdown() { return; ReleaseBuffersNotUsedSince(base::TimeTicks() + base::TimeDelta::Max()); + DCHECK_EQ(staging_buffer_usage_in_bytes_, 0); + DCHECK_EQ(free_staging_buffer_usage_in_bytes_, 0); } void OneCopyTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) { @@ -534,6 +538,52 @@ bool OneCopyTileTaskWorkerPool::OnMemoryDump( return true; } +void OneCopyTileTaskWorkerPool::AddStagingBuffer( + const StagingBuffer* staging_buffer) { + lock_.AssertAcquired(); + + DCHECK(buffers_.find(staging_buffer) == buffers_.end()); + buffers_.insert(staging_buffer); + int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( + staging_buffer->size, + resource_provider_->memory_efficient_texture_format()); + staging_buffer_usage_in_bytes_ += buffer_usage_in_bytes; +} + +void OneCopyTileTaskWorkerPool::RemoveStagingBuffer( + const StagingBuffer* staging_buffer) { + lock_.AssertAcquired(); + + DCHECK(buffers_.find(staging_buffer) != buffers_.end()); + buffers_.erase(staging_buffer); + int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( + staging_buffer->size, + resource_provider_->memory_efficient_texture_format()); + DCHECK_GE(staging_buffer_usage_in_bytes_, buffer_usage_in_bytes); + staging_buffer_usage_in_bytes_ -= buffer_usage_in_bytes; +} + +void OneCopyTileTaskWorkerPool::MarkStagingBufferAsFree( + const StagingBuffer* staging_buffer) { + lock_.AssertAcquired(); + + int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( + staging_buffer->size, + resource_provider_->memory_efficient_texture_format()); + free_staging_buffer_usage_in_bytes_ += buffer_usage_in_bytes; +} + +void OneCopyTileTaskWorkerPool::MarkStagingBufferAsBusy( + const StagingBuffer* staging_buffer) { + lock_.AssertAcquired(); + + int buffer_usage_in_bytes = ResourceUtil::UncheckedSizeInBytes<int>( + staging_buffer->size, + resource_provider_->memory_efficient_texture_format()); + DCHECK_GE(free_staging_buffer_usage_in_bytes_, buffer_usage_in_bytes); + free_staging_buffer_usage_in_bytes_ -= buffer_usage_in_bytes; +} + scoped_ptr<OneCopyTileTaskWorkerPool::StagingBuffer> OneCopyTileTaskWorkerPool::AcquireStagingBuffer(const Resource* resource, uint64_t previous_content_id) { @@ -556,24 +606,30 @@ OneCopyTileTaskWorkerPool::AcquireStagingBuffer(const Resource* resource, if (!CheckForQueryResult(gl, busy_buffers_.front()->query_id)) break; + MarkStagingBufferAsFree(busy_buffers_.front()); free_buffers_.push_back(busy_buffers_.take_front()); } } - // Wait for number of non-free buffers to become less than the limit. - while ((buffers_.size() - free_buffers_.size()) >= max_staging_buffers_) { + // Wait for memory usage of non-free buffers to become less than the limit. + while ( + (staging_buffer_usage_in_bytes_ - free_staging_buffer_usage_in_bytes_) >= + max_staging_buffer_usage_in_bytes_) { // Stop when there are no more busy buffers to wait for. if (busy_buffers_.empty()) break; if (resource_provider_->use_sync_query()) { WaitForQueryResult(gl, busy_buffers_.front()->query_id); + MarkStagingBufferAsFree(busy_buffers_.front()); free_buffers_.push_back(busy_buffers_.take_front()); } else { // Fall-back to glFinish if CHROMIUM_sync_query is not available. gl->Finish(); - while (!busy_buffers_.empty()) + while (!busy_buffers_.empty()) { + MarkStagingBufferAsFree(busy_buffers_.front()); free_buffers_.push_back(busy_buffers_.take_front()); + } } } @@ -585,8 +641,10 @@ OneCopyTileTaskWorkerPool::AcquireStagingBuffer(const Resource* resource, [previous_content_id](const StagingBuffer* buffer) { return buffer->content_id == previous_content_id; }); - if (it != free_buffers_.end()) + if (it != free_buffers_.end()) { staging_buffer = free_buffers_.take(it); + MarkStagingBufferAsBusy(staging_buffer.get()); + } } // Find staging buffer of correct size. @@ -596,23 +654,26 @@ OneCopyTileTaskWorkerPool::AcquireStagingBuffer(const Resource* resource, [resource](const StagingBuffer* buffer) { return buffer->size == resource->size(); }); - if (it != free_buffers_.end()) + if (it != free_buffers_.end()) { staging_buffer = free_buffers_.take(it); + MarkStagingBufferAsBusy(staging_buffer.get()); + } } // Create new staging buffer if necessary. if (!staging_buffer) { staging_buffer = make_scoped_ptr(new StagingBuffer(resource->size())); - buffers_.insert(staging_buffer.get()); + AddStagingBuffer(staging_buffer.get()); } // Release enough free buffers to stay within the limit. - while (buffers_.size() > max_staging_buffers_) { + while (staging_buffer_usage_in_bytes_ > max_staging_buffer_usage_in_bytes_) { if (free_buffers_.empty()) break; free_buffers_.front()->DestroyGLResources(gl); - buffers_.erase(free_buffers_.front()); + MarkStagingBufferAsBusy(free_buffers_.front()); + RemoveStagingBuffer(free_buffers_.front()); free_buffers_.take_front(); } @@ -693,7 +754,8 @@ void OneCopyTileTaskWorkerPool::ReleaseBuffersNotUsedSince( return; free_buffers_.front()->DestroyGLResources(gl); - buffers_.erase(free_buffers_.front()); + MarkStagingBufferAsBusy(free_buffers_.front()); + RemoveStagingBuffer(free_buffers_.front()); free_buffers_.take_front(); } @@ -702,7 +764,7 @@ void OneCopyTileTaskWorkerPool::ReleaseBuffersNotUsedSince( return; busy_buffers_.front()->DestroyGLResources(gl); - buffers_.erase(busy_buffers_.front()); + RemoveStagingBuffer(busy_buffers_.front()); busy_buffers_.take_front(); } } diff --git a/cc/raster/one_copy_tile_task_worker_pool.h b/cc/raster/one_copy_tile_task_worker_pool.h index 851f1b4..783d103 100644 --- a/cc/raster/one_copy_tile_task_worker_pool.h +++ b/cc/raster/one_copy_tile_task_worker_pool.h @@ -49,7 +49,7 @@ class CC_EXPORT OneCopyTileTaskWorkerPool ResourceProvider* resource_provider, int max_copy_texture_chromium_size, bool use_persistent_gpu_memory_buffers, - int max_staging_buffers); + int max_staging_buffer_usage_in_bytes); // Overridden from TileTaskWorkerPool: TileTaskRunner* AsTileTaskRunner() override; @@ -91,7 +91,7 @@ class CC_EXPORT OneCopyTileTaskWorkerPool ResourceProvider* resource_provider, int max_copy_texture_chromium_size, bool use_persistent_gpu_memory_buffers, - int max_staging_buffers); + int max_staging_buffer_usage_in_bytes); private: struct StagingBuffer { @@ -112,6 +112,10 @@ class CC_EXPORT OneCopyTileTaskWorkerPool uint64_t content_id; }; + void AddStagingBuffer(const StagingBuffer* staging_buffer); + void RemoveStagingBuffer(const StagingBuffer* staging_buffer); + void MarkStagingBufferAsFree(const StagingBuffer* staging_buffer); + void MarkStagingBufferAsBusy(const StagingBuffer* staging_buffer); scoped_ptr<StagingBuffer> AcquireStagingBuffer(const Resource* resource, uint64_t previous_content_id); base::TimeTicks GetUsageTimeForLRUBuffer(); @@ -142,13 +146,15 @@ class CC_EXPORT OneCopyTileTaskWorkerPool mutable base::Lock lock_; // |lock_| must be acquired when accessing the following members. - using StagingBufferSet = std::set<StagingBuffer*>; + using StagingBufferSet = std::set<const StagingBuffer*>; StagingBufferSet buffers_; using StagingBufferDeque = ScopedPtrDeque<StagingBuffer>; StagingBufferDeque free_buffers_; StagingBufferDeque busy_buffers_; int bytes_scheduled_since_last_flush_; - size_t max_staging_buffers_; + const int max_staging_buffer_usage_in_bytes_; + int staging_buffer_usage_in_bytes_; + int free_staging_buffer_usage_in_bytes_; const base::TimeDelta staging_buffer_expiration_delay_; bool reduce_memory_usage_pending_; base::Closure reduce_memory_usage_callback_; |