| Index: cc/resources/one_copy_raster_worker_pool.cc
|
| diff --git a/cc/resources/one_copy_raster_worker_pool.cc b/cc/resources/one_copy_raster_worker_pool.cc
|
| index 66b6ea0e22ddde0fe3e51b76481367e234fc27ff..cc5dd19258429af4473467951791c8ad8cac7879 100644
|
| --- a/cc/resources/one_copy_raster_worker_pool.cc
|
| +++ b/cc/resources/one_copy_raster_worker_pool.cc
|
| @@ -5,6 +5,7 @@
|
| #include "cc/resources/one_copy_raster_worker_pool.h"
|
|
|
| #include <algorithm>
|
| +#include <limits>
|
|
|
| #include "base/debug/trace_event.h"
|
| #include "base/debug/trace_event_argument.h"
|
| @@ -21,23 +22,28 @@ namespace {
|
|
|
| class RasterBufferImpl : public RasterBuffer {
|
| public:
|
| - RasterBufferImpl(ResourceProvider* resource_provider,
|
| + RasterBufferImpl(OneCopyRasterWorkerPool* worker_pool,
|
| + ResourceProvider* resource_provider,
|
| ResourcePool* resource_pool,
|
| const Resource* resource)
|
| - : resource_provider_(resource_provider),
|
| + : worker_pool_(worker_pool),
|
| + resource_provider_(resource_provider),
|
| resource_pool_(resource_pool),
|
| resource_(resource),
|
| raster_resource_(resource_pool->AcquireResource(resource->size())),
|
| lock_(new ResourceProvider::ScopedWriteLockGpuMemoryBuffer(
|
| resource_provider_,
|
| - raster_resource_->id())) {}
|
| + raster_resource_->id())),
|
| + sequence_(0) {}
|
|
|
| ~RasterBufferImpl() override {
|
| - // First unlock raster resource.
|
| + // Release write lock in case a copy was never scheduled.
|
| lock_.reset();
|
|
|
| - // Copy contents of raster resource to |resource_|.
|
| - resource_provider_->CopyResource(raster_resource_->id(), resource_->id());
|
| + // Make sure any scheduled copy operations are issued before we release the
|
| + // raster resource.
|
| + if (sequence_)
|
| + worker_pool_->AdvanceLastIssuedCopyTo(sequence_);
|
|
|
| // Return raster resource to pool so it can be used by another RasterBuffer
|
| // instance.
|
| @@ -54,28 +60,46 @@ class RasterBufferImpl : public RasterBuffer {
|
| return;
|
|
|
| RasterWorkerPool::PlaybackToMemory(gpu_memory_buffer->Map(),
|
| - resource_->format(),
|
| - resource_->size(),
|
| + raster_resource_->format(),
|
| + raster_resource_->size(),
|
| gpu_memory_buffer->GetStride(),
|
| picture_pile,
|
| rect,
|
| scale,
|
| stats);
|
| gpu_memory_buffer->Unmap();
|
| +
|
| + sequence_ = worker_pool_->ScheduleCopyOnWorkerThread(
|
| + lock_.Pass(), raster_resource_.get(), resource_);
|
| }
|
|
|
| private:
|
| + OneCopyRasterWorkerPool* worker_pool_;
|
| ResourceProvider* resource_provider_;
|
| ResourcePool* resource_pool_;
|
| const Resource* resource_;
|
| scoped_ptr<ScopedResource> raster_resource_;
|
| scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> lock_;
|
| + CopySequenceNumber sequence_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
|
| };
|
|
|
| +// Flush interval when performing copy operations.
|
| +const int kCopyFlushPeriod = 4;
|
| +
|
| } // namespace
|
|
|
| +OneCopyRasterWorkerPool::CopyOperation::CopyOperation(
|
| + scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
|
| + ResourceProvider::ResourceId src,
|
| + ResourceProvider::ResourceId dst)
|
| + : write_lock(write_lock.Pass()), src(src), dst(dst) {
|
| +}
|
| +
|
| +OneCopyRasterWorkerPool::CopyOperation::~CopyOperation() {
|
| +}
|
| +
|
| // static
|
| scoped_ptr<RasterWorkerPool> OneCopyRasterWorkerPool::Create(
|
| base::SequencedTaskRunner* task_runner,
|
| @@ -103,6 +127,10 @@ OneCopyRasterWorkerPool::OneCopyRasterWorkerPool(
|
| context_provider_(context_provider),
|
| resource_provider_(resource_provider),
|
| resource_pool_(resource_pool),
|
| + last_issued_copy_operation_(0),
|
| + last_flushed_copy_operation_(0),
|
| + next_copy_operation_sequence_(1),
|
| + weak_ptr_factory_(this),
|
| raster_finished_weak_ptr_factory_(this) {
|
| DCHECK(context_provider_);
|
| }
|
| @@ -201,6 +229,7 @@ void OneCopyRasterWorkerPool::CheckForCompletedTasks() {
|
|
|
| task_graph_runner_->CollectCompletedTasks(namespace_token_,
|
| &completed_tasks_);
|
| +
|
| for (Task::Vector::const_iterator it = completed_tasks_.begin();
|
| it != completed_tasks_.end();
|
| ++it) {
|
| @@ -213,15 +242,13 @@ void OneCopyRasterWorkerPool::CheckForCompletedTasks() {
|
| task->RunReplyOnOriginThread();
|
| }
|
| completed_tasks_.clear();
|
| -
|
| - context_provider_->ContextGL()->ShallowFlushCHROMIUM();
|
| }
|
|
|
| scoped_ptr<RasterBuffer> OneCopyRasterWorkerPool::AcquireBufferForRaster(
|
| const Resource* resource) {
|
| DCHECK_EQ(resource->format(), resource_pool_->resource_format());
|
| return make_scoped_ptr<RasterBuffer>(
|
| - new RasterBufferImpl(resource_provider_, resource_pool_, resource));
|
| + new RasterBufferImpl(this, resource_provider_, resource_pool_, resource));
|
| }
|
|
|
| void OneCopyRasterWorkerPool::ReleaseBufferForRaster(
|
| @@ -229,6 +256,55 @@ void OneCopyRasterWorkerPool::ReleaseBufferForRaster(
|
| // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
|
| }
|
|
|
| +CopySequenceNumber OneCopyRasterWorkerPool::ScheduleCopyOnWorkerThread(
|
| + scoped_ptr<ResourceProvider::ScopedWriteLockGpuMemoryBuffer> write_lock,
|
| + const Resource* src,
|
| + const Resource* dst) {
|
| + CopySequenceNumber sequence;
|
| +
|
| + {
|
| + base::AutoLock lock(lock_);
|
| +
|
| + sequence = next_copy_operation_sequence_++;
|
| +
|
| + pending_copy_operations_.push_back(make_scoped_ptr(
|
| + new CopyOperation(write_lock.Pass(), src->id(), dst->id())));
|
| + }
|
| +
|
| + // Post task that will advance last flushed copy operation to |sequence|
|
| + // if we have reached the flush period.
|
| + if ((sequence % kCopyFlushPeriod) == 0) {
|
| + task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&OneCopyRasterWorkerPool::AdvanceLastFlushedCopyTo,
|
| + weak_ptr_factory_.GetWeakPtr(),
|
| + sequence));
|
| + }
|
| +
|
| + return sequence;
|
| +}
|
| +
|
| +void OneCopyRasterWorkerPool::AdvanceLastIssuedCopyTo(
|
| + CopySequenceNumber sequence) {
|
| + if (last_issued_copy_operation_ >= sequence)
|
| + return;
|
| +
|
| + IssueCopyOperations(sequence - last_issued_copy_operation_);
|
| + last_issued_copy_operation_ = sequence;
|
| +}
|
| +
|
| +void OneCopyRasterWorkerPool::AdvanceLastFlushedCopyTo(
|
| + CopySequenceNumber sequence) {
|
| + if (last_flushed_copy_operation_ >= sequence)
|
| + return;
|
| +
|
| + AdvanceLastIssuedCopyTo(sequence);
|
| +
|
| + // Flush all issued copy operations.
|
| + context_provider_->ContextGL()->ShallowFlushCHROMIUM();
|
| + last_flushed_copy_operation_ = last_issued_copy_operation_;
|
| +}
|
| +
|
| void OneCopyRasterWorkerPool::OnRasterFinished(TaskSet task_set) {
|
| TRACE_EVENT1(
|
| "cc", "OneCopyRasterWorkerPool::OnRasterFinished", "task_set", task_set);
|
| @@ -244,6 +320,32 @@ void OneCopyRasterWorkerPool::OnRasterFinished(TaskSet task_set) {
|
| client_->DidFinishRunningTasks(task_set);
|
| }
|
|
|
| +void OneCopyRasterWorkerPool::IssueCopyOperations(int64 count) {
|
| + TRACE_EVENT1(
|
| + "cc", "OneCopyRasterWorkerPool::IssueCopyOperations", "count", count);
|
| +
|
| + CopyOperation::Deque copy_operations;
|
| +
|
| + {
|
| + base::AutoLock lock(lock_);
|
| +
|
| + for (int64 i = 0; i < count; ++i) {
|
| + DCHECK(!pending_copy_operations_.empty());
|
| + copy_operations.push_back(pending_copy_operations_.take_front());
|
| + }
|
| + }
|
| +
|
| + while (!copy_operations.empty()) {
|
| + scoped_ptr<CopyOperation> copy_operation = copy_operations.take_front();
|
| +
|
| + // Remove the write lock.
|
| + copy_operation->write_lock.reset();
|
| +
|
| + // Copy contents of source resource to destination resource.
|
| + resource_provider_->CopyResource(copy_operation->src, copy_operation->dst);
|
| + }
|
| +}
|
| +
|
| scoped_refptr<base::debug::ConvertableToTraceFormat>
|
| OneCopyRasterWorkerPool::StateAsValue() const {
|
| scoped_refptr<base::debug::TracedValue> state =
|
|
|