Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Unified Diff: cc/resources/image_copy_raster_worker_pool.cc

Issue 236313006: cc: Add initial GPU-to-GPU copy rasterizer implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address review feedback Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/resources/image_copy_raster_worker_pool.cc
diff --git a/cc/resources/image_copy_raster_worker_pool.cc b/cc/resources/image_copy_raster_worker_pool.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0d4f7441e5222be3b78646df74e05dd6e98dbbae
--- /dev/null
+++ b/cc/resources/image_copy_raster_worker_pool.cc
@@ -0,0 +1,260 @@
+// Copyright 2014 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.
+
+#include "cc/resources/image_copy_raster_worker_pool.h"
+
+#include <algorithm>
+
+#include "base/debug/trace_event.h"
+#include "cc/debug/traced_value.h"
+#include "cc/resources/resource_pool.h"
+#include "cc/resources/scoped_resource.h"
+
+namespace cc {
+
+// static
+scoped_ptr<RasterWorkerPool> ImageCopyRasterWorkerPool::Create(
+ base::SequencedTaskRunner* task_runner,
+ TaskGraphRunner* task_graph_runner,
+ ResourceProvider* resource_provider,
+ ResourcePool* resource_pool) {
+ return make_scoped_ptr<RasterWorkerPool>(new ImageCopyRasterWorkerPool(
+ task_runner, task_graph_runner, resource_provider, resource_pool));
+}
+
+ImageCopyRasterWorkerPool::ImageCopyRasterWorkerPool(
+ base::SequencedTaskRunner* task_runner,
+ TaskGraphRunner* task_graph_runner,
+ ResourceProvider* resource_provider,
+ ResourcePool* resource_pool)
+ : task_runner_(task_runner),
+ task_graph_runner_(task_graph_runner),
+ namespace_token_(task_graph_runner->GetNamespaceToken()),
+ resource_provider_(resource_provider),
+ resource_pool_(resource_pool),
+ has_performed_copy_since_last_flush_(false),
+ raster_tasks_pending_(false),
+ raster_tasks_required_for_activation_pending_(false),
+ raster_finished_weak_ptr_factory_(this) {}
+
+ImageCopyRasterWorkerPool::~ImageCopyRasterWorkerPool() {
+ DCHECK_EQ(0u, raster_task_states_.size());
+}
+
+Rasterizer* ImageCopyRasterWorkerPool::AsRasterizer() { return this; }
+
+void ImageCopyRasterWorkerPool::SetClient(RasterizerClient* client) {
+ client_ = client;
+}
+
+void ImageCopyRasterWorkerPool::Shutdown() {
+ TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::Shutdown");
+
+ TaskGraph empty;
+ task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
+ task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
+}
+
+void ImageCopyRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
+ TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::ScheduleTasks");
+
+ DCHECK_EQ(queue->required_for_activation_count,
+ static_cast<size_t>(
+ std::count_if(queue->items.begin(),
+ queue->items.end(),
+ RasterTaskQueue::Item::IsRequiredForActivation)));
+
+ if (!raster_tasks_pending_)
+ TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
+
+ raster_tasks_pending_ = true;
+ raster_tasks_required_for_activation_pending_ = true;
+
+ unsigned priority = kRasterTaskPriorityBase;
+
+ graph_.Reset();
+
+ // Cancel existing OnRasterFinished callbacks.
+ raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
+
+ scoped_refptr<RasterizerTask>
+ new_raster_required_for_activation_finished_task(
+ CreateRasterRequiredForActivationFinishedTask(
+ queue->required_for_activation_count,
+ task_runner_.get(),
+ base::Bind(&ImageCopyRasterWorkerPool::
+ OnRasterRequiredForActivationFinished,
+ raster_finished_weak_ptr_factory_.GetWeakPtr())));
+ scoped_refptr<RasterizerTask> new_raster_finished_task(
+ CreateRasterFinishedTask(
+ task_runner_.get(),
+ base::Bind(&ImageCopyRasterWorkerPool::OnRasterFinished,
+ raster_finished_weak_ptr_factory_.GetWeakPtr())));
+
+ resource_pool_->CheckBusyResources();
+
+ for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
+ it != queue->items.end();
+ ++it) {
+ const RasterTaskQueue::Item& item = *it;
+ RasterTask* task = item.task;
+ DCHECK(!task->HasCompleted());
+
+ if (item.required_for_activation) {
+ graph_.edges.push_back(TaskGraph::Edge(
+ task, new_raster_required_for_activation_finished_task.get()));
+ }
+
+ InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
+
+ graph_.edges.push_back(
+ TaskGraph::Edge(task, new_raster_finished_task.get()));
+ }
+
+ InsertNodeForTask(&graph_,
+ new_raster_required_for_activation_finished_task.get(),
+ kRasterRequiredForActivationFinishedTaskPriority,
+ queue->required_for_activation_count);
+ InsertNodeForTask(&graph_,
+ new_raster_finished_task.get(),
+ kRasterFinishedTaskPriority,
+ queue->items.size());
+
+ ScheduleTasksOnOriginThread(this, &graph_);
+ task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
+
+ raster_finished_task_ = new_raster_finished_task;
+ raster_required_for_activation_finished_task_ =
+ new_raster_required_for_activation_finished_task;
+
+ resource_pool_->ReduceResourceUsage();
+
+ TRACE_EVENT_ASYNC_STEP_INTO1(
+ "cc",
+ "ScheduledTasks",
+ this,
+ "rasterizing",
+ "state",
+ TracedValue::FromValue(StateAsValue().release()));
+}
+
+void ImageCopyRasterWorkerPool::CheckForCompletedTasks() {
+ TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::CheckForCompletedTasks");
+
+ task_graph_runner_->CollectCompletedTasks(namespace_token_,
+ &completed_tasks_);
+ for (Task::Vector::const_iterator it = completed_tasks_.begin();
+ it != completed_tasks_.end();
+ ++it) {
+ RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
+
+ task->WillComplete();
+ task->CompleteOnOriginThread(this);
+ task->DidComplete();
+
+ task->RunReplyOnOriginThread();
+ }
+ completed_tasks_.clear();
+
+ FlushCopies();
+}
+
+SkCanvas* ImageCopyRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) {
+ DCHECK_EQ(task->resource()->format(), resource_pool_->resource_format());
+ scoped_ptr<ScopedResource> resource(
+ resource_pool_->AcquireResource(task->resource()->size()));
+ SkCanvas* canvas = resource_provider_->MapImageRasterBuffer(resource->id());
+ DCHECK(std::find_if(raster_task_states_.begin(),
+ raster_task_states_.end(),
+ RasterTaskState::TaskComparator(task)) ==
+ raster_task_states_.end());
+ raster_task_states_.push_back(RasterTaskState(task, resource.release()));
+ return canvas;
+}
+
+void ImageCopyRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
+ RasterTaskState::Vector::iterator it =
+ std::find_if(raster_task_states_.begin(),
+ raster_task_states_.end(),
+ RasterTaskState::TaskComparator(task));
+ DCHECK(it != raster_task_states_.end());
+ scoped_ptr<ScopedResource> resource(it->resource);
+ std::swap(*it, raster_task_states_.back());
+ raster_task_states_.pop_back();
+
+ bool content_has_changed =
+ resource_provider_->UnmapImageRasterBuffer(resource->id());
+
+ // |content_has_changed| can be false as result of task being canceled or
+ // task implementation deciding not to modify bitmap (ie. analysis of raster
+ // commands detected content as a solid color).
+ if (content_has_changed) {
+ resource_provider_->CopyResource(resource->id(), task->resource()->id());
+ has_performed_copy_since_last_flush_ = true;
+ }
+
+ resource_pool_->ReleaseResource(resource.Pass());
+}
+
+void ImageCopyRasterWorkerPool::OnRasterFinished() {
+ TRACE_EVENT0("cc", "ImageCopyRasterWorkerPool::OnRasterFinished");
+
+ DCHECK(raster_tasks_pending_);
+ raster_tasks_pending_ = false;
+ TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
+ client_->DidFinishRunningTasks();
+}
+
+void ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished() {
+ TRACE_EVENT0(
+ "cc", "ImageCopyRasterWorkerPool::OnRasterRequiredForActivationFinished");
+
+ DCHECK(raster_tasks_required_for_activation_pending_);
+ raster_tasks_required_for_activation_pending_ = false;
+ TRACE_EVENT_ASYNC_STEP_INTO1(
+ "cc",
+ "ScheduledTasks",
+ this,
+ "rasterizing",
+ "state",
+ TracedValue::FromValue(StateAsValue().release()));
+ client_->DidFinishRunningTasksRequiredForActivation();
+}
+
+void ImageCopyRasterWorkerPool::FlushCopies() {
+ if (!has_performed_copy_since_last_flush_)
+ return;
+
+ resource_provider_->ShallowFlushIfSupported();
+ has_performed_copy_since_last_flush_ = false;
+}
+
+scoped_ptr<base::Value> ImageCopyRasterWorkerPool::StateAsValue() const {
+ scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
+
+ state->SetInteger("pending_count", raster_task_states_.size());
+ state->SetBoolean("tasks_required_for_activation_pending",
+ raster_tasks_required_for_activation_pending_);
+ state->Set("staging_state", StagingStateAsValue().release());
+
+ return state.PassAs<base::Value>();
+}
+scoped_ptr<base::Value> ImageCopyRasterWorkerPool::StagingStateAsValue() const {
+ scoped_ptr<base::DictionaryValue> staging_state(new base::DictionaryValue);
+
+ staging_state->SetInteger("staging_resource_count",
+ resource_pool_->total_resource_count());
+ staging_state->SetInteger("bytes_used_for_staging_resources",
+ resource_pool_->total_memory_usage_bytes());
+ staging_state->SetInteger("pending_copy_count",
+ resource_pool_->total_resource_count() -
+ resource_pool_->acquired_resource_count());
+ staging_state->SetInteger("bytes_pending_copy",
+ resource_pool_->total_memory_usage_bytes() -
+ resource_pool_->acquired_memory_usage_bytes());
+
+ return staging_state.PassAs<base::Value>();
+}
+
+} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698