Chromium Code Reviews| Index: cc/resources/raster_worker_pool.cc |
| diff --git a/cc/resources/raster_worker_pool.cc b/cc/resources/raster_worker_pool.cc |
| index 06fd18e62e0ec2bdc9d440ee0ae6eb925c867ef4..2310241e9075ca43b1df54708076c2b88fc5691d 100644 |
| --- a/cc/resources/raster_worker_pool.cc |
| +++ b/cc/resources/raster_worker_pool.cc |
| @@ -13,6 +13,9 @@ |
| #include "skia/ext/lazy_pixel_ref.h" |
| #include "skia/ext/paint_simplifier.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| +#include "third_party/skia/include/gpu/GrContext.h" |
| +#include "third_party/skia/include/gpu/SkGpuDevice.h" |
| +#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" |
| namespace cc { |
| @@ -58,10 +61,13 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { |
| int layer_id, |
| const void* tile_id, |
| int source_frame_number, |
| + bool use_gpu_rasterization, |
| RenderingStatsInstrumentation* rendering_stats, |
| const RasterWorkerPool::RasterTask::Reply& reply, |
| TaskVector* dependencies) |
| - : internal::RasterWorkerPoolTask(resource, dependencies), |
| + : internal::RasterWorkerPoolTask(resource, |
| + dependencies, |
| + use_gpu_rasterization), |
| picture_pile_(picture_pile), |
| content_rect_(content_rect), |
| contents_scale_(contents_scale), |
| @@ -118,9 +124,6 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { |
| if (analysis_.is_solid_color) |
| return false; |
| - PicturePileImpl* picture_clone = |
| - picture_pile_->GetCloneForDrawingOnThread(thread_index); |
| - |
| SkBitmap bitmap; |
| switch (resource()->format()) { |
| case RGBA_4444: |
| @@ -148,6 +151,78 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { |
| 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: |
| @@ -162,8 +237,7 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { |
| 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; |
| @@ -172,13 +246,9 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { |
| // lowres tiles are not required for activation and therefore |
| // introduce noise in the measurement (sometimes they get rasterized |
| // before we draw and sometimes they aren't) |
| - if (tile_resolution_ == HIGH_RESOLUTION) { |
| - picture_clone->RasterToBitmap( |
| - &canvas, content_rect_, contents_scale_, rendering_stats_); |
| - } else { |
| - picture_clone->RasterToBitmap( |
| - &canvas, content_rect_, contents_scale_, NULL); |
| - } |
| + RenderingStatsInstrumentation* stats = tile_resolution_ == HIGH_RESOLUTION ? |
|
vmpstr
2014/01/06 19:15:45
nit: methinks clang-format would do
Renderin
alokp
2014/01/06 22:05:24
Done.
|
| + rendering_stats_ : NULL; |
| + picture_pile->RasterToBitmap(canvas, content_rect_, contents_scale_, stats); |
| if (rendering_stats_->record_rendering_stats()) { |
| base::TimeDelta current_rasterize_time = |
| @@ -190,36 +260,6 @@ class RasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { |
| 100000, |
| 100); |
| } |
| - |
| - ChangeBitmapConfigIfNeeded(bitmap, buffer); |
| - |
| - return true; |
| - } |
| - |
| - // Overridden from internal::RasterWorkerPoolTask: |
| - virtual bool RunOnWorkerThread(unsigned thread_index, |
| - void* buffer, |
| - gfx::Size size, |
| - int stride) |
| - OVERRIDE { |
| - RunAnalysisOnThread(thread_index); |
| - return RunRasterOnThread(thread_index, buffer, size, stride); |
| - } |
| - 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>(); |
| } |
| void ChangeBitmapConfigIfNeeded(const SkBitmap& bitmap, |
| @@ -325,12 +365,14 @@ const char* kWorkerThreadNamePrefix = "CompositorRaster"; |
| namespace internal { |
| -RasterWorkerPoolTask::RasterWorkerPoolTask( |
| - const Resource* resource, TaskVector* dependencies) |
| +RasterWorkerPoolTask::RasterWorkerPoolTask(const Resource* resource, |
| + TaskVector* dependencies, |
| + bool use_gpu_rasterization) |
| : did_run_(false), |
| did_complete_(false), |
| was_canceled_(false), |
| - resource_(resource) { |
| + resource_(resource), |
| + use_gpu_rasterization_(use_gpu_rasterization) { |
| dependencies_.swap(*dependencies); |
| } |
| @@ -431,6 +473,7 @@ RasterWorkerPool::RasterTask RasterWorkerPool::CreateRasterTask( |
| 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) { |
| @@ -444,6 +487,7 @@ RasterWorkerPool::RasterTask RasterWorkerPool::CreateRasterTask( |
| layer_id, |
| tile_id, |
| source_frame_number, |
| + use_gpu_rasterization, |
| rendering_stats, |
| reply, |
| &dependencies->tasks_)); |
| @@ -462,10 +506,12 @@ RasterWorkerPool::Task RasterWorkerPool::CreateImageDecodeTask( |
| } |
| RasterWorkerPool::RasterWorkerPool(ResourceProvider* resource_provider, |
| + ContextProvider* context_provider, |
| size_t num_threads) |
| : WorkerPool(num_threads, kWorkerThreadNamePrefix), |
| client_(NULL), |
| resource_provider_(resource_provider), |
| + context_provider_(context_provider), |
| weak_ptr_factory_(this) { |
| } |
| @@ -484,6 +530,24 @@ void RasterWorkerPool::Shutdown() { |
| weak_ptr_factory_.InvalidateWeakPtrs(); |
| } |
| +void RasterWorkerPool::CheckForCompletedTasks() { |
| + TRACE_EVENT0("cc", "RasterWorkerPool::CheckForCompletedTasks"); |
| + |
| + // Check for completed worker-thread tasks. |
| + CheckForCompletedWorkerTasks(); |
| + |
| + // 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(); |
| + } |
| +} |
| + |
| void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) { |
| raster_tasks_.swap(queue->tasks_); |
| raster_tasks_required_for_activation_.swap( |
| @@ -497,6 +561,29 @@ bool RasterWorkerPool::IsRasterTaskRequiredForActivation( |
| raster_tasks_required_for_activation_.end(); |
| } |
| +void RasterWorkerPool::RunGpuRasterTasks(const RasterTaskVector& tasks) { |
| + if (tasks.empty()) |
| + return; |
| + |
| + blink::WebGraphicsContext3D* context = context_provider_->Context3d(); |
| + context->makeContextCurrent(); |
|
vmpstr
2014/01/06 19:15:45
You should check the return value... although I do
alokp
2014/01/06 22:05:24
Done. Added a return.
|
| + |
| + GrContext* gr_context = context_provider_->GrContext(); |
| + 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); |
| + } |
| + |
| + gr_context->flush(); |
| +} |
| + |
| scoped_refptr<internal::WorkerPoolTask> |
| RasterWorkerPool::CreateRasterFinishedTask() { |
| return make_scoped_refptr( |