| Index: cc/raster_worker.cc
|
| diff --git a/cc/raster_worker.cc b/cc/raster_worker.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a962035c8d6a371254d29c7c333799fab62b291b
|
| --- /dev/null
|
| +++ b/cc/raster_worker.cc
|
| @@ -0,0 +1,169 @@
|
| +// Copyright 2012 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/raster_worker.h"
|
| +
|
| +#include <algorithm>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/debug/trace_event.h"
|
| +#include "base/stringprintf.h"
|
| +#include "cc/picture_pile_impl.h"
|
| +#include "third_party/skia/include/core/SkDevice.h"
|
| +
|
| +namespace cc {
|
| +
|
| +namespace {
|
| +
|
| +void RunRasterTask(PicturePileImpl* picture_pile,
|
| + uint8_t* buffer,
|
| + const gfx::Rect& rect,
|
| + float contents_scale,
|
| + RenderingStats* stats) {
|
| + TRACE_EVENT0("cc", "RunRasterTask");
|
| + DCHECK(picture_pile);
|
| + DCHECK(buffer);
|
| + SkBitmap bitmap;
|
| + bitmap.setConfig(SkBitmap::kARGB_8888_Config, rect.width(), rect.height());
|
| + bitmap.setPixels(buffer);
|
| + SkDevice device(bitmap);
|
| + SkCanvas canvas(&device);
|
| + picture_pile->Raster(&canvas, rect, contents_scale, stats);
|
| +}
|
| +
|
| +void OnRasterTaskCompleted(scoped_refptr<PicturePileImpl> picture_pile_clone,
|
| + const base::Closure& reply) {
|
| + reply.Run();
|
| +}
|
| +
|
| +void RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, RenderingStats* stats) {
|
| + TRACE_EVENT0("cc", "RunImageDecodeTask");
|
| + base::TimeTicks decode_begin_time = base::TimeTicks::Now();
|
| + pixel_ref->Decode();
|
| + stats->totalDeferredImageDecodeCount++;
|
| + stats->totalDeferredImageDecodeTimeInSeconds +=
|
| + (base::TimeTicks::Now() - decode_begin_time).InSecondsF();
|
| +}
|
| +
|
| +const char* kRasterThreadNamePrefix = "CompositorRaster";
|
| +
|
| +// Allow two pending raster tasks per thread. This keeps resource usage
|
| +// low while making sure raster threads aren't unnecessarily idle.
|
| +const int kNumPendingRasterTasksPerThread = 2;
|
| +
|
| +} // namespace
|
| +
|
| +RasterWorker::Thread::Thread(const std::string name)
|
| + : base::Thread(name.c_str()),
|
| + num_pending_tasks_(0) {
|
| + Start();
|
| +}
|
| +
|
| +RasterWorker::Thread::~Thread() {
|
| + Stop();
|
| +}
|
| +
|
| +RasterWorker::RasterWorker(size_t num_raster_threads) {
|
| + const std::string thread_name_prefix = kRasterThreadNamePrefix;
|
| + while (raster_threads_.size() < num_raster_threads) {
|
| + int thread_number = raster_threads_.size() + 1;
|
| + raster_threads_.append(
|
| + make_scoped_ptr(
|
| + new Thread(thread_name_prefix +
|
| + StringPrintf("Worker%d", thread_number).c_str())));
|
| + }
|
| +}
|
| +
|
| +RasterWorker::~RasterWorker() {
|
| +}
|
| +
|
| +bool RasterWorker::IsBusy() {
|
| + Thread* thread = raster_threads_.first();
|
| + return thread->num_pending_tasks_ >= kNumPendingRasterTasksPerThread;
|
| +}
|
| +
|
| +void RasterWorker::PostRasterTaskAndReply(PicturePileImpl* picture_pile,
|
| + uint8_t* buffer,
|
| + const gfx::Rect& rect,
|
| + float contents_scale,
|
| + const base::Closure& reply) {
|
| + Thread* thread = raster_threads_.first();
|
| +
|
| + scoped_refptr<PicturePileImpl> picture_pile_clone =
|
| + picture_pile->GetCloneForDrawingOnThread(thread);
|
| +
|
| + PostTaskAndReply(base::Bind(&RunRasterTask,
|
| + base::Unretained(picture_pile_clone.get()),
|
| + buffer,
|
| + rect,
|
| + contents_scale),
|
| + base::Bind(&OnRasterTaskCompleted,
|
| + picture_pile_clone,
|
| + reply));
|
| +}
|
| +
|
| +void RasterWorker::PostImageDecodingTaskAndReply(
|
| + skia::LazyPixelRef* pixel_ref,
|
| + const base::Closure& reply) {
|
| + PostTaskAndReply(base::Bind(&RunImageDecodeTask, pixel_ref), reply);
|
| +}
|
| +
|
| +void RasterWorker::PostTaskAndReply(const TaskCallback& task,
|
| + const base::Closure& reply) {
|
| + Thread* thread = raster_threads_.first();
|
| + DCHECK(thread->num_pending_tasks_ < kNumPendingRasterTasksPerThread);
|
| + thread->num_pending_tasks_++;
|
| + std::sort(raster_threads_.begin(), raster_threads_.end(),
|
| + PendingTaskComparator());
|
| +
|
| + RenderingStats* stats = new RenderingStats;
|
| + thread->message_loop_proxy()->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&RasterWorker::RunTaskOnRasterThread,
|
| + base::Unretained(this),
|
| + task,
|
| + stats),
|
| + base::Bind(&RasterWorker::OnTaskCompleted,
|
| + base::Unretained(this),
|
| + thread,
|
| + stats,
|
| + reply));
|
| +}
|
| +
|
| +void RasterWorker::RunTaskOnRasterThread(
|
| + const RasterWorker::TaskCallback& task, RenderingStats* stats) {
|
| + task.Run(stats);
|
| +}
|
| +
|
| +void RasterWorker::OnTaskCompleted(Thread* thread,
|
| + RenderingStats* stats,
|
| + const base::Closure& reply) {
|
| + // Update rendering stats.
|
| + rendering_stats_.totalRasterizeTimeInSeconds +=
|
| + stats->totalRasterizeTimeInSeconds;
|
| + rendering_stats_.totalPixelsRasterized += stats->totalPixelsRasterized;
|
| + rendering_stats_.totalDeferredImageDecodeTimeInSeconds +=
|
| + stats->totalDeferredImageDecodeTimeInSeconds;
|
| + rendering_stats_.totalDeferredImageDecodeCount +=
|
| + stats->totalDeferredImageDecodeCount;
|
| + delete stats;
|
| +
|
| + thread->num_pending_tasks_--;
|
| + std::sort(raster_threads_.begin(), raster_threads_.end(),
|
| + PendingTaskComparator());
|
| +
|
| + reply.Run();
|
| +}
|
| +
|
| +void RasterWorker::GetRenderingStats(RenderingStats* stats) {
|
| + stats->totalRasterizeTimeInSeconds =
|
| + rendering_stats_.totalRasterizeTimeInSeconds;
|
| + stats->totalPixelsRasterized = rendering_stats_.totalPixelsRasterized;
|
| + stats->totalDeferredImageDecodeCount =
|
| + rendering_stats_.totalDeferredImageDecodeCount;
|
| + stats->totalDeferredImageDecodeTimeInSeconds =
|
| + rendering_stats_.totalDeferredImageDecodeTimeInSeconds;
|
| +}
|
| +
|
| +} // namespace cc
|
|
|