#include "cc/resources/raster_worker_pool.h"
+#include <algorithm>
+
#include "base/debug/trace_event_synthetic_delay.h"
#include "base/json/json_writer.h"
#include "base/lazy_instance.h"
#include "base/metrics/histogram.h"
+#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/traced_value.h"
#include "cc/resources/picture_pile_impl.h"
#include "cc/resources/resource.h"
#include "cc/resources/resource_provider.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
#include "skia/ext/paint_simplifier.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkPixelRef.h"
#include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/gpu/SkGpuDevice.h"
namespace cc {
-
namespace {
// Subclass of Allocator that takes a suitably allocated pointer and uses
int layer_id,
const void* tile_id,
int source_frame_number,
- bool use_gpu_rasterization,
RenderingStatsInstrumentation* rendering_stats,
const RasterWorkerPool::RasterTask::Reply& reply,
- internal::Task::Vector* dependencies)
- : internal::RasterWorkerPoolTask(resource,
- dependencies,
- use_gpu_rasterization),
+ internal::WorkerPoolTask::Vector* dependencies,
+ ContextProvider* context_provider)
+ : internal::RasterWorkerPoolTask(resource, dependencies),
picture_pile_(picture_pile),
content_rect_(content_rect),
contents_scale_(contents_scale),
tile_id_(tile_id),
source_frame_number_(source_frame_number),
rendering_stats_(rendering_stats),
- reply_(reply) {}
+ reply_(reply),
+ context_provider_(context_provider),
+ canvas_(NULL) {}
+
+ // Overridden from internal::Task:
+ virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
+ TRACE_EVENT0("cc", "RasterWorkerPoolTaskImpl::RunOnWorkerThread");
+
+ DCHECK(picture_pile_);
+ Analyze(picture_pile_->GetCloneForDrawingOnThread(thread_index));
+ if (!canvas_ || analysis_.is_solid_color)
+ return;
+ Raster(picture_pile_->GetCloneForDrawingOnThread(thread_index));
+ }
+
+ // Overridden from internal::WorkerPoolTask:
+ virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client)
+ OVERRIDE {
+ DCHECK(!canvas_);
+ canvas_ = client->AcquireCanvasForRaster(this);
+ }
+ virtual void RunOnOriginThread() OVERRIDE {
+ TRACE_EVENT0("cc", "RasterWorkerPoolTaskImpl::RunOnOriginThread");
+
+ Analyze(picture_pile_);
+ if (!canvas_ || analysis_.is_solid_color)
+ return;
+ // TODO(alokp): Use a trace macro to push/pop markers.
+ // Using push/pop functions directly incurs cost to evaluate function
+ // arguments even when tracing is disabled.
+ DCHECK(context_provider_);
+ context_provider_->ContextGL()->PushGroupMarkerEXT(
+ 0,
+ base::StringPrintf(
+ "Raster-%d-%d-%p", source_frame_number_, layer_id_, tile_id_)
+ .c_str());
+ Raster(picture_pile_);
+ context_provider_->ContextGL()->PopGroupMarkerEXT();
+ }
+ virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client)
+ OVERRIDE {
+ canvas_ = NULL;
+ client->OnRasterCompleted(this, analysis_);
+ }
+ virtual void RunReplyOnOriginThread() OVERRIDE {
+ DCHECK(!canvas_);
+ reply_.Run(analysis_, !HasFinishedRunning());
+ }
+
+ protected:
+ virtual ~RasterWorkerPoolTaskImpl() { DCHECK(!canvas_); }
+
+ private:
+ scoped_ptr<base::Value> DataAsValue() const {
+ scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
+ res->Set("tile_id", TracedValue::CreateIDRef(tile_id_).release());
+ res->Set("resolution", TileResolutionAsValue(tile_resolution_).release());
+ res->SetInteger("source_frame_number", source_frame_number_);
+ res->SetInteger("layer_id", layer_id_);
+ return res.PassAs<base::Value>();
+ }
- void RunAnalysisOnThread(unsigned thread_index) {
+ void Analyze(PicturePileImpl* picture_pile) {
TRACE_EVENT1("cc",
- "RasterWorkerPoolTaskImpl::RunAnalysisOnThread",
+ "RasterWorkerPoolTaskImpl::Analyze",
"data",
TracedValue::FromValue(DataAsValue().release()));
- DCHECK(picture_pile_.get());
- DCHECK(rendering_stats_);
-
- PicturePileImpl* picture_clone =
- picture_pile_->GetCloneForDrawingOnThread(thread_index);
+ DCHECK(picture_pile);
- DCHECK(picture_clone);
-
- picture_clone->AnalyzeInRect(
+ picture_pile->AnalyzeInRect(
content_rect_, contents_scale_, &analysis_, rendering_stats_);
// Record the solid color prediction.
analysis_.is_solid_color &= kUseColorEstimator;
}
- bool RunRasterOnThread(unsigned thread_index,
- void* buffer,
- gfx::Size size,
- int stride) {
+ void Raster(PicturePileImpl* picture_pile) {
TRACE_EVENT2(
"cc",
- "RasterWorkerPoolTaskImpl::RunRasterOnThread",
+ "RasterWorkerPoolTaskImpl::Raster",
"data",
TracedValue::FromValue(DataAsValue().release()),
"raster_mode",
devtools_instrumentation::ScopedLayerTask raster_task(
devtools_instrumentation::kRasterTask, layer_id_);
- DCHECK(picture_pile_.get());
- DCHECK(buffer);
-
- if (analysis_.is_solid_color)
- return false;
-
- SkBitmap bitmap;
- switch (resource()->format()) {
- case RGBA_4444:
- // Use the default stride if we will eventually convert this
- // bitmap to 4444.
- bitmap.setConfig(
- SkBitmap::kARGB_8888_Config, size.width(), size.height());
- bitmap.allocPixels();
- break;
- case RGBA_8888:
- case BGRA_8888:
- bitmap.setConfig(
- SkBitmap::kARGB_8888_Config, size.width(), size.height(), stride);
- bitmap.setPixels(buffer);
- break;
- case LUMINANCE_8:
- case RGB_565:
- case ETC1:
- NOTREACHED();
- break;
- }
-
- SkBitmapDevice device(bitmap);
- SkCanvas canvas(&device);
- Raster(picture_pile_->GetCloneForDrawingOnThread(thread_index), &canvas);
- ChangeBitmapConfigIfNeeded(bitmap, buffer);
-
- return true;
- }
-
- // Overridden from internal::RasterWorkerPoolTask:
- virtual bool RunOnWorkerThread(unsigned thread_index,
- void* buffer,
- gfx::Size size,
- int stride) OVERRIDE {
- // TODO(alokp): For now run-on-worker-thread implies software rasterization.
- DCHECK(!use_gpu_rasterization());
- RunAnalysisOnThread(thread_index);
- return RunRasterOnThread(thread_index, buffer, size, stride);
- }
-
- virtual void RunOnOriginThread(ResourceProvider* resource_provider,
- ContextProvider* context_provider) OVERRIDE {
- // TODO(alokp): For now run-on-origin-thread implies gpu rasterization.
- DCHECK(use_gpu_rasterization());
- ResourceProvider::ScopedWriteLockGL lock(resource_provider,
- resource()->id());
- DCHECK_NE(lock.texture_id(), 0u);
-
- GrBackendTextureDesc desc;
- desc.fFlags = kRenderTarget_GrBackendTextureFlag;
- desc.fWidth = content_rect_.width();
- desc.fHeight = content_rect_.height();
- desc.fConfig = ToGrFormat(resource()->format());
- desc.fOrigin = kTopLeft_GrSurfaceOrigin;
- desc.fTextureHandle = lock.texture_id();
-
- GrContext* gr_context = context_provider->GrContext();
- skia::RefPtr<GrTexture> texture =
- skia::AdoptRef(gr_context->wrapBackendTexture(desc));
- skia::RefPtr<SkGpuDevice> device =
- skia::AdoptRef(SkGpuDevice::Create(texture.get()));
- skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(new SkCanvas(device.get()));
-
- Raster(picture_pile_, canvas.get());
- }
-
- virtual void CompleteOnOriginThread() OVERRIDE {
- reply_.Run(analysis_, !HasFinishedRunning() || WasCanceled());
- }
-
- protected:
- virtual ~RasterWorkerPoolTaskImpl() {}
-
- private:
- scoped_ptr<base::Value> DataAsValue() const {
- scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
- res->Set("tile_id", TracedValue::CreateIDRef(tile_id_).release());
- res->Set("resolution", TileResolutionAsValue(tile_resolution_).release());
- res->SetInteger("source_frame_number", source_frame_number_);
- res->SetInteger("layer_id", layer_id_);
- return res.PassAs<base::Value>();
- }
-
- static GrPixelConfig ToGrFormat(ResourceFormat format) {
- switch (format) {
- case RGBA_8888:
- return kRGBA_8888_GrPixelConfig;
- case BGRA_8888:
- return kBGRA_8888_GrPixelConfig;
- case RGBA_4444:
- return kRGBA_4444_GrPixelConfig;
- default:
- break;
- }
- DCHECK(false) << "Unsupported resource format.";
- return kSkia8888_GrPixelConfig;
- }
-
- void Raster(PicturePileImpl* picture_pile, SkCanvas* canvas) {
skia::RefPtr<SkDrawFilter> draw_filter;
switch (raster_mode_) {
case LOW_QUALITY_RASTER_MODE:
default:
NOTREACHED();
}
- canvas->setDrawFilter(draw_filter.get());
+ canvas_->setDrawFilter(draw_filter.get());
base::TimeDelta prev_rasterize_time =
rendering_stats_->impl_thread_rendering_stats().rasterize_time;
// before we draw and sometimes they aren't)
RenderingStatsInstrumentation* stats =
tile_resolution_ == HIGH_RESOLUTION ? rendering_stats_ : NULL;
- picture_pile->RasterToBitmap(canvas, content_rect_, contents_scale_, stats);
+ DCHECK(picture_pile);
+ picture_pile->RasterToBitmap(
+ canvas_, content_rect_, contents_scale_, stats);
if (rendering_stats_->record_rendering_stats()) {
base::TimeDelta current_rasterize_time =
}
}
- void ChangeBitmapConfigIfNeeded(const SkBitmap& bitmap, void* buffer) {
- TRACE_EVENT0("cc", "RasterWorkerPoolTaskImpl::ChangeBitmapConfigIfNeeded");
- SkBitmap::Config config = SkBitmapConfig(resource()->format());
- if (bitmap.getConfig() != config) {
- SkBitmap bitmap_dest;
- IdentityAllocator allocator(buffer);
- bitmap.copyTo(&bitmap_dest, config, &allocator);
- // TODO(kaanb): The GL pipeline assumes a 4-byte alignment for the
- // bitmap data. This check will be removed once crbug.com/293728 is fixed.
- CHECK_EQ(0u, bitmap_dest.rowBytes() % 4);
- }
- }
-
PicturePileImpl::Analysis analysis_;
scoped_refptr<PicturePileImpl> picture_pile_;
gfx::Rect content_rect_;
int source_frame_number_;
RenderingStatsInstrumentation* rendering_stats_;
const RasterWorkerPool::RasterTask::Reply reply_;
+ ContextProvider* context_provider_;
+ SkCanvas* canvas_;
DISALLOW_COPY_AND_ASSIGN(RasterWorkerPoolTaskImpl);
};
// Overridden from internal::Task:
virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
TRACE_EVENT0("cc", "ImageDecodeWorkerPoolTaskImpl::RunOnWorkerThread");
- devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
- pixel_ref_.get());
- // This will cause the image referred to by pixel ref to be decoded.
- pixel_ref_->lockPixels();
- pixel_ref_->unlockPixels();
+ Decode();
}
// Overridden from internal::WorkerPoolTask:
- virtual void CompleteOnOriginThread() OVERRIDE {
+ virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client)
+ OVERRIDE {}
+ virtual void RunOnOriginThread() OVERRIDE {
+ TRACE_EVENT0("cc", "ImageDecodeWorkerPoolTaskImpl::RunOnOriginThread");
+ Decode();
+ }
+ virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client)
+ OVERRIDE {
+ client->OnImageDecodeCompleted(this);
+ }
+ virtual void RunReplyOnOriginThread() OVERRIDE {
reply_.Run(!HasFinishedRunning());
}
virtual ~ImageDecodeWorkerPoolTaskImpl() {}
private:
+ void Decode() {
+ devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
+ pixel_ref_.get());
+ // This will cause the image referred to by pixel ref to be decoded.
+ pixel_ref_->lockPixels();
+ pixel_ref_->unlockPixels();
+ }
+
skia::RefPtr<SkPixelRef> pixel_ref_;
int layer_id_;
RenderingStatsInstrumentation* rendering_stats_;
: origin_loop_(base::MessageLoopProxy::current().get()),
on_raster_finished_callback_(on_raster_finished_callback) {}
- // Overridden from internal::WorkerPoolTask:
+ // Overridden from internal::Task:
virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnWorkerThread");
- origin_loop_->PostTask(
- FROM_HERE,
- base::Bind(&RasterFinishedWorkerPoolTaskImpl::RunOnOriginThread, this));
+ RasterFinished();
+ }
+
+ // Overridden from internal::WorkerPoolTask:
+ virtual void ScheduleOnOriginThread(internal::WorkerPoolTaskClient* client)
+ OVERRIDE {}
+ virtual void RunOnOriginThread() OVERRIDE {
+ TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnOriginThread");
+ RasterFinished();
}
- virtual void CompleteOnOriginThread() OVERRIDE {}
+ virtual void CompleteOnOriginThread(internal::WorkerPoolTaskClient* client)
+ OVERRIDE {}
+ virtual void RunReplyOnOriginThread() OVERRIDE {}
protected:
virtual ~RasterFinishedWorkerPoolTaskImpl() {}
+ void RasterFinished() {
+ origin_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &RasterFinishedWorkerPoolTaskImpl::OnRasterFinishedOnOriginThread,
+ this));
+ }
+
private:
- void RunOnOriginThread() const { on_raster_finished_callback_.Run(this); }
+ void OnRasterFinishedOnOriginThread() const {
+ on_raster_finished_callback_.Run(this);
+ }
scoped_refptr<base::MessageLoopProxy> origin_loop_;
const Callback on_raster_finished_callback_;
}
}
- // Overridden from RasterFinishedWorkerPoolTaskImpl:
+ // Overridden from internal::Task:
virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
TRACE_EVENT0("cc",
"RasterRequiredForActivationFinishedWorkerPoolTaskImpl::"
"RunOnWorkerThread");
+ RunRasterFinished();
+ }
+
+ // Overridden from internal::WorkerPoolTask:
+ virtual void RunOnOriginThread() OVERRIDE {
+ TRACE_EVENT0("cc",
+ "RasterRequiredForActivationFinishedWorkerPoolTaskImpl::"
+ "RunOnOriginThread");
+ RunRasterFinished();
+ }
+
+ private:
+ virtual ~RasterRequiredForActivationFinishedWorkerPoolTaskImpl() {}
+
+ void RunRasterFinished() {
if (tasks_required_for_activation_count_) {
g_raster_required_for_activation_delay.Get().delay->EndParallel(
activation_delay_end_time_);
}
- RasterFinishedWorkerPoolTaskImpl::RunOnWorkerThread(thread_index);
+ RasterFinished();
}
- private:
- virtual ~RasterRequiredForActivationFinishedWorkerPoolTaskImpl() {}
-
base::TimeTicks activation_delay_end_time_;
const size_t tasks_required_for_activation_count_;
namespace internal {
-WorkerPoolTask::WorkerPoolTask() : did_complete_(false) {}
+WorkerPoolTask::WorkerPoolTask() : did_schedule_(false), did_complete_(false) {}
WorkerPoolTask::~WorkerPoolTask() {
- DCHECK_EQ(did_schedule_, did_complete_);
+ DCHECK(!did_schedule_);
DCHECK(!did_run_ || did_complete_);
}
+void WorkerPoolTask::WillSchedule() { DCHECK(!did_schedule_); }
+
+void WorkerPoolTask::DidSchedule() {
+ did_schedule_ = true;
+ did_complete_ = false;
+}
+
+bool WorkerPoolTask::HasBeenScheduled() const { return did_schedule_; }
+
void WorkerPoolTask::WillComplete() { DCHECK(!did_complete_); }
void WorkerPoolTask::DidComplete() {
DCHECK(did_schedule_);
DCHECK(!did_complete_);
+ did_schedule_ = false;
did_complete_ = true;
}
bool WorkerPoolTask::HasCompleted() const { return did_complete_; }
-RasterWorkerPoolTask::RasterWorkerPoolTask(const Resource* resource,
- internal::Task::Vector* dependencies,
- bool use_gpu_rasterization)
- : did_run_(false),
- did_complete_(false),
- was_canceled_(false),
- resource_(resource),
- use_gpu_rasterization_(use_gpu_rasterization) {
+RasterWorkerPoolTask::RasterWorkerPoolTask(
+ const Resource* resource,
+ internal::WorkerPoolTask::Vector* dependencies)
+ : resource_(resource) {
dependencies_.swap(*dependencies);
}
RasterWorkerPoolTask::~RasterWorkerPoolTask() {}
-void RasterWorkerPoolTask::DidRun(bool was_canceled) {
- DCHECK(!did_run_);
- did_run_ = true;
- was_canceled_ = was_canceled;
-}
-
-bool RasterWorkerPoolTask::HasFinishedRunning() const { return did_run_; }
-
-bool RasterWorkerPoolTask::WasCanceled() const { return was_canceled_; }
-
-void RasterWorkerPoolTask::WillComplete() { DCHECK(!did_complete_); }
-
-void RasterWorkerPoolTask::DidComplete() {
- DCHECK(!did_complete_);
- did_complete_ = true;
-}
-
-bool RasterWorkerPoolTask::HasCompleted() const { return did_complete_; }
-
} // namespace internal
RasterWorkerPool::Task::Set::Set() {}
void RasterWorkerPool::Task::Reset() { internal_ = NULL; }
-RasterWorkerPool::RasterTask::Queue::Queue() {}
+RasterWorkerPool::RasterTask::Queue::QueuedTask::QueuedTask(
+ internal::RasterWorkerPoolTask* task,
+ bool required_for_activation)
+ : task(task), required_for_activation(required_for_activation) {}
+
+RasterWorkerPool::RasterTask::Queue::QueuedTask::~QueuedTask() {}
+
+RasterWorkerPool::RasterTask::Queue::Queue()
+ : required_for_activation_count_(0u) {}
RasterWorkerPool::RasterTask::Queue::~Queue() {}
+void RasterWorkerPool::RasterTask::Queue::Reset() {
+ tasks_.clear();
+ required_for_activation_count_ = 0u;
+}
+
void RasterWorkerPool::RasterTask::Queue::Append(const RasterTask& task,
bool required_for_activation) {
DCHECK(!task.is_null());
- tasks_.push_back(task.internal_);
- if (required_for_activation)
- tasks_required_for_activation_.insert(task.internal_.get());
+ tasks_.push_back(QueuedTask(task.internal_, required_for_activation));
+ required_for_activation_count_ += required_for_activation;
+}
+
+void RasterWorkerPool::RasterTask::Queue::Swap(Queue* other) {
+ tasks_.swap(other->tasks_);
+ std::swap(required_for_activation_count_,
+ other->required_for_activation_count_);
}
RasterWorkerPool::RasterTask::RasterTask() {}
RasterWorkerPool::RasterTask::~RasterTask() {}
-RasterWorkerPool::RasterWorkerPool(ResourceProvider* resource_provider,
- ContextProvider* context_provider)
- : namespace_token_(g_task_graph_runner.Pointer()->GetNamespaceToken()),
+// This allows an external rasterize on-demand system to run raster tasks
+// with highest priority using the same task graph runner instance.
+unsigned RasterWorkerPool::kOnDemandRasterTaskPriority = 0u;
+// Task priorities that make sure raster finished tasks run before any
+// remaining raster tasks.
+unsigned RasterWorkerPool::kRasterFinishedTaskPriority = 2u;
+unsigned RasterWorkerPool::kRasterRequiredForActivationFinishedTaskPriority =
+ 1u;
+unsigned RasterWorkerPool::kRasterTaskPriorityBase = 3u;
+
+RasterWorkerPool::RasterWorkerPool(internal::TaskGraphRunner* task_graph_runner,
+ ResourceProvider* resource_provider)
+ : task_graph_runner_(task_graph_runner),
client_(NULL),
resource_provider_(resource_provider),
- context_provider_(context_provider),
- weak_ptr_factory_(this) {}
+ weak_ptr_factory_(this) {
+ if (task_graph_runner_)
+ namespace_token_ = task_graph_runner_->GetNamespaceToken();
+}
RasterWorkerPool::~RasterWorkerPool() {}
}
// static
+internal::TaskGraphRunner* RasterWorkerPool::GetTaskGraphRunner() {
+ return g_task_graph_runner.Pointer();
+}
+
+// static
RasterWorkerPool::RasterTask RasterWorkerPool::CreateRasterTask(
const Resource* resource,
PicturePileImpl* picture_pile,
int layer_id,
const void* tile_id,
int source_frame_number,
- bool use_gpu_rasterization,
RenderingStatsInstrumentation* rendering_stats,
const RasterTask::Reply& reply,
- Task::Set* dependencies) {
+ Task::Set* dependencies,
+ ContextProvider* context_provider) {
return RasterTask(new RasterWorkerPoolTaskImpl(resource,
picture_pile,
content_rect,
layer_id,
tile_id,
source_frame_number,
- use_gpu_rasterization,
rendering_stats,
reply,
- &dependencies->tasks_));
+ &dependencies->tasks_,
+ context_provider));
}
// static
RasterWorkerPool::Task RasterWorkerPool::CreateImageDecodeTask(
SkPixelRef* pixel_ref,
int layer_id,
- RenderingStatsInstrumentation* stats_instrumentation,
+ RenderingStatsInstrumentation* rendering_stats,
const Task::Reply& reply) {
return Task(new ImageDecodeWorkerPoolTaskImpl(
- pixel_ref, layer_id, stats_instrumentation, reply));
+ pixel_ref, layer_id, rendering_stats, reply));
}
void RasterWorkerPool::SetClient(RasterWorkerPoolClient* client) {
void RasterWorkerPool::Shutdown() {
TRACE_EVENT0("cc", "RasterWorkerPool::Shutdown");
- raster_tasks_.clear();
- TaskGraph empty;
- SetTaskGraph(&empty);
- g_task_graph_runner.Pointer()->WaitForTasksToFinishRunning(namespace_token_);
- weak_ptr_factory_.InvalidateWeakPtrs();
-}
-
-void RasterWorkerPool::CheckForCompletedTasks() {
- TRACE_EVENT0("cc", "RasterWorkerPool::CheckForCompletedTasks");
-
- CheckForCompletedWorkerPoolTasks();
-
- // Complete gpu rasterization tasks.
- while (!completed_gpu_raster_tasks_.empty()) {
- internal::RasterWorkerPoolTask* task =
- completed_gpu_raster_tasks_.front().get();
-
- task->WillComplete();
- task->CompleteOnOriginThread();
- task->DidComplete();
-
- completed_gpu_raster_tasks_.pop_front();
+ if (task_graph_runner_) {
+ internal::TaskGraph empty;
+ task_graph_runner_->SetTaskGraph(namespace_token_, &empty);
+ task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
}
+
+ weak_ptr_factory_.InvalidateWeakPtrs();
}
-void RasterWorkerPool::CheckForCompletedWorkerPoolTasks() {
- internal::Task::Vector completed_tasks;
- g_task_graph_runner.Pointer()->CollectCompletedTasks(namespace_token_,
- &completed_tasks);
+void RasterWorkerPool::SetTaskGraph(internal::TaskGraph* graph) {
+ TRACE_EVENT0("cc", "RasterWorkerPool::SetTaskGraph");
- for (internal::Task::Vector::const_iterator it = completed_tasks.begin();
- it != completed_tasks.end();
+ DCHECK(task_graph_runner_);
+ for (internal::TaskGraph::Node::Vector::iterator it = graph->nodes.begin();
+ it != graph->nodes.end();
++it) {
+ internal::TaskGraph::Node& node = *it;
internal::WorkerPoolTask* task =
- static_cast<internal::WorkerPoolTask*>(it->get());
+ static_cast<internal::WorkerPoolTask*>(node.task);
- task->WillComplete();
- task->CompleteOnOriginThread();
- task->DidComplete();
+ if (!task->HasBeenScheduled()) {
+ task->WillSchedule();
+ task->ScheduleOnOriginThread(this);
+ task->DidSchedule();
+ }
}
-}
-
-void RasterWorkerPool::SetTaskGraph(TaskGraph* graph) {
- TRACE_EVENT1(
- "cc", "RasterWorkerPool::SetTaskGraph", "num_tasks", graph->size());
- g_task_graph_runner.Pointer()->SetTaskGraph(namespace_token_, graph);
+ task_graph_runner_->SetTaskGraph(namespace_token_, graph);
}
-void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) {
- raster_tasks_.swap(queue->tasks_);
- raster_tasks_required_for_activation_.swap(
- queue->tasks_required_for_activation_);
-}
-
-bool RasterWorkerPool::IsRasterTaskRequiredForActivation(
- internal::RasterWorkerPoolTask* task) const {
- return raster_tasks_required_for_activation_.find(task) !=
- raster_tasks_required_for_activation_.end();
-}
-
-void RasterWorkerPool::RunGpuRasterTasks(const RasterTaskVector& tasks) {
- if (tasks.empty())
- return;
-
- GrContext* gr_context = context_provider_->GrContext();
- // TODO(alokp): Implement TestContextProvider::GrContext().
- if (gr_context)
- gr_context->resetContext();
-
- for (RasterTaskVector::const_iterator it = tasks.begin(); it != tasks.end();
- ++it) {
- internal::RasterWorkerPoolTask* task = it->get();
- DCHECK(task->use_gpu_rasterization());
-
- task->RunOnOriginThread(resource_provider_, context_provider_);
- task->DidRun(false);
- completed_gpu_raster_tasks_.push_back(task);
- }
-
- // TODO(alokp): Implement TestContextProvider::GrContext().
- if (gr_context)
- gr_context->flush();
+void RasterWorkerPool::CollectCompletedWorkerPoolTasks(
+ internal::Task::Vector* completed_tasks) {
+ DCHECK(task_graph_runner_);
+ task_graph_runner_->CollectCompletedTasks(namespace_token_, completed_tasks);
}
scoped_refptr<internal::WorkerPoolTask>
tasks_required_for_activation_count));
}
+void RasterWorkerPool::RunTaskOnOriginThread(internal::WorkerPoolTask* task) {
+ task->WillSchedule();
+ task->ScheduleOnOriginThread(this);
+ task->DidSchedule();
+
+ task->WillRun();
+ task->RunOnOriginThread();
+ task->DidRun();
+
+ task->WillComplete();
+ task->CompleteOnOriginThread(this);
+ task->DidComplete();
+}
+
void RasterWorkerPool::OnRasterFinished(
const internal::WorkerPoolTask* source) {
TRACE_EVENT0("cc", "RasterWorkerPool::OnRasterFinished");
OnRasterTasksRequiredForActivationFinished();
}
-scoped_ptr<base::Value> RasterWorkerPool::ScheduledStateAsValue() const {
- scoped_ptr<base::DictionaryValue> scheduled_state(new base::DictionaryValue);
- scheduled_state->SetInteger("task_count", raster_tasks_.size());
- scheduled_state->SetInteger("task_required_for_activation_count",
- raster_tasks_required_for_activation_.size());
- return scheduled_state.PassAs<base::Value>();
-}
-
// static
-internal::GraphNode* RasterWorkerPool::CreateGraphNodeForTask(
- internal::WorkerPoolTask* task,
- unsigned priority,
- TaskGraph* graph) {
- internal::GraphNode* node = new internal::GraphNode(task, priority);
- DCHECK(graph->find(task) == graph->end());
- graph->set(task, make_scoped_ptr(node));
- return node;
+void RasterWorkerPool::InsertNodeForTask(internal::TaskGraph* graph,
+ internal::WorkerPoolTask* task,
+ unsigned priority,
+ size_t dependencies) {
+ DCHECK(std::find_if(graph->nodes.begin(),
+ graph->nodes.end(),
+ internal::TaskGraph::Node::TaskComparator(task)) ==
+ graph->nodes.end());
+ graph->nodes.push_back(
+ internal::TaskGraph::Node(task, priority, dependencies));
}
// static
-internal::GraphNode* RasterWorkerPool::CreateGraphNodeForRasterTask(
+void RasterWorkerPool::InsertNodeForRasterTask(
+ internal::TaskGraph* graph,
internal::WorkerPoolTask* raster_task,
- const internal::Task::Vector& decode_tasks,
- unsigned priority,
- TaskGraph* graph) {
- DCHECK(!raster_task->HasCompleted());
-
- internal::GraphNode* raster_node =
- CreateGraphNodeForTask(raster_task, priority, graph);
+ const internal::WorkerPoolTask::Vector& decode_tasks,
+ unsigned priority) {
+ size_t dependencies = 0u;
// Insert image decode tasks.
- for (internal::Task::Vector::const_iterator it = decode_tasks.begin();
+ for (internal::WorkerPoolTask::Vector::const_iterator it =
+ decode_tasks.begin();
it != decode_tasks.end();
++it) {
- internal::WorkerPoolTask* decode_task =
- static_cast<internal::WorkerPoolTask*>(it->get());
+ internal::WorkerPoolTask* decode_task = it->get();
// Skip if already decoded.
if (decode_task->HasCompleted())
continue;
- raster_node->add_dependency();
+ dependencies++;
- // Check if decode task already exists in graph.
- internal::GraphNode::Map::iterator decode_it = graph->find(decode_task);
- if (decode_it != graph->end()) {
- internal::GraphNode* decode_node = decode_it->second;
- decode_node->add_dependent(raster_node);
- continue;
- }
+ // Add decode task if it doesn't already exists in graph.
+ internal::TaskGraph::Node::Vector::iterator decode_it =
+ std::find_if(graph->nodes.begin(),
+ graph->nodes.end(),
+ internal::TaskGraph::Node::TaskComparator(decode_task));
+ if (decode_it == graph->nodes.end())
+ InsertNodeForTask(graph, decode_task, priority, 0u);
- internal::GraphNode* decode_node =
- CreateGraphNodeForTask(decode_task, priority, graph);
- decode_node->add_dependent(raster_node);
+ graph->edges.push_back(internal::TaskGraph::Edge(decode_task, raster_task));
}
- return raster_node;
+ InsertNodeForTask(graph, raster_task, priority, dependencies);
}
} // namespace cc