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..8e37b43ce921bac3e61955f9772b56045baca8f2 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 ? |
+ 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,23 @@ 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. |
+ for (RasterTaskVector::iterator it = completed_gpu_raster_tasks_.begin(); |
+ it != completed_gpu_raster_tasks_.end(); ++it) { |
+ internal::RasterWorkerPoolTask* task = it->get(); |
+ task->WillComplete(); |
+ task->CompleteOnOriginThread(); |
+ task->DidComplete(); |
+ } |
+ completed_gpu_raster_tasks_.clear(); |
reveman
2013/12/20 13:44:42
nit: could you make this consistent with PixelBuff
alokp
2014/01/03 22:09:45
Done.
|
+} |
+ |
void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) { |
raster_tasks_.swap(queue->tasks_); |
raster_tasks_required_for_activation_.swap( |
@@ -497,6 +560,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(); |
+ |
+ 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( |