diff options
author | vmiura <vmiura@chromium.org> | 2015-02-13 16:01:17 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-14 00:02:13 +0000 |
commit | 78b692864e7745993b8be343f67968ca071e0642 (patch) | |
tree | ebf75a9d6b58990635a6e3dc7c5a799921c65e74 /cc | |
parent | 84df06528cc5d4218132942d53f10ad32b6f7dac (diff) | |
download | chromium_src-78b692864e7745993b8be343f67968ca071e0642.zip chromium_src-78b692864e7745993b8be343f67968ca071e0642.tar.gz chromium_src-78b692864e7745993b8be343f67968ca071e0642.tar.bz2 |
cc: Add threaded GPU rasterization.
Enable flag: --enable-threaded-gpu-rasterization
This patch enables threaded rasterization in GpuTileTaskWorkerPool.
There are some not yet landed/rolled dependencies:
InProcessContextProvider Context Lost handling (jbauman@).
Without this the feature should be considered unstable on WebViews.
BUG=454500
Review URL: https://codereview.chromium.org/916723002
Cr-Commit-Position: refs/heads/master@{#316333}
Diffstat (limited to 'cc')
31 files changed, 315 insertions, 78 deletions
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 05c7b52..86ce10e 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc @@ -1118,7 +1118,7 @@ PictureLayerImpl::CreatePictureLayerTilingSet() { return PictureLayerTilingSet::Create( this, settings.max_tiles_for_interest_area, layer_tree_impl()->use_gpu_rasterization() - ? 0.f + ? settings.gpu_rasterization_skewport_target_time_in_seconds : settings.skewport_target_time_in_seconds, settings.skewport_extrapolation_limit_in_content_pixels); } diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index b3f3c67..7d4fb40 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -2597,7 +2597,7 @@ TEST_F(DeferredInitPictureLayerImplTest, PreventUpdateTilesDuringLostContext) { FakeOutputSurface* fake_output_surface = static_cast<FakeOutputSurface*>(host_impl_.output_surface()); ASSERT_TRUE(fake_output_surface->InitializeAndSetContext3d( - TestContextProvider::Create())); + TestContextProvider::Create(), TestContextProvider::Create())); // These will crash PictureLayerImpl if this is not true. ASSERT_TRUE(host_impl_.pending_tree()->needs_update_draw_properties()); diff --git a/cc/output/context_provider.h b/cc/output/context_provider.h index 2880915..71d06bd 100644 --- a/cc/output/context_provider.h +++ b/cc/output/context_provider.h @@ -31,6 +31,7 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> { // Once this function has been called, the class should only be accessed // from the same thread. virtual bool BindToCurrentThread() = 0; + virtual void DetachFromThread() {} virtual gpu::gles2::GLES2Interface* ContextGL() = 0; virtual gpu::ContextSupport* ContextSupport() = 0; diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 7a0218b..b1a2b9a 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -134,21 +134,33 @@ bool OutputSurface::BindToClient(OutputSurfaceClient* client) { } bool OutputSurface::InitializeAndSetContext3d( - scoped_refptr<ContextProvider> context_provider) { + scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider) { DCHECK(!context_provider_.get()); DCHECK(context_provider.get()); DCHECK(client_); - bool success = false; - if (context_provider->BindToCurrentThread()) { + bool success = context_provider->BindToCurrentThread(); + if (success) { context_provider_ = context_provider; SetUpContext3d(); - client_->DeferredInitialize(); - success = true; + } + if (success && worker_context_provider.get()) { + success = worker_context_provider->BindToCurrentThread(); + if (success) { + worker_context_provider_ = worker_context_provider; + // The destructor resets the context lost callback, so base::Unretained + // is safe, as long as the worker threads stop using the context before + // the output surface is destroyed. + worker_context_provider_->SetLostContextCallback(base::Bind( + &OutputSurface::DidLoseOutputSurface, base::Unretained(this))); + } } if (!success) ResetContext3d(); + else + client_->DeferredInitialize(); return success; } diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index e0b13ec..3e3b085 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -157,7 +157,8 @@ class CC_EXPORT OutputSurface { // Synchronously initialize context3d and enter hardware mode. // This can only supported in threaded compositing mode. bool InitializeAndSetContext3d( - scoped_refptr<ContextProvider> context_provider); + scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider); void ReleaseGL(); void PostSwapBuffersComplete(); diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc index 21aa911..f32a96f2 100644 --- a/cc/output/output_surface_unittest.cc +++ b/cc/output/output_surface_unittest.cc @@ -41,9 +41,8 @@ class TestOutputSurface : public OutputSurface { client_->DidSwapBuffersComplete(); } - bool InitializeNewContext3d( - scoped_refptr<ContextProvider> new_context_provider) { - return InitializeAndSetContext3d(new_context_provider); + bool InitializeNewContext3d(scoped_refptr<ContextProvider> context_provider) { + return InitializeAndSetContext3d(context_provider, nullptr); } using OutputSurface::ReleaseGL; diff --git a/cc/resources/gpu_rasterizer.cc b/cc/resources/gpu_rasterizer.cc index 369f12c..ee069b9 100644 --- a/cc/resources/gpu_rasterizer.cc +++ b/cc/resources/gpu_rasterizer.cc @@ -43,19 +43,25 @@ GpuRasterizer::GpuRasterizer(ContextProvider* context_provider, bool use_distance_field_text, bool threaded_gpu_rasterization_enabled, int msaa_sample_count) - : context_provider_(context_provider), - resource_provider_(resource_provider), + : resource_provider_(resource_provider), use_distance_field_text_(use_distance_field_text), threaded_gpu_rasterization_enabled_(threaded_gpu_rasterization_enabled), msaa_sample_count_(msaa_sample_count) { - DCHECK(context_provider_); } GpuRasterizer::~GpuRasterizer() { } PrepareTilesMode GpuRasterizer::GetPrepareTilesMode() { - return PrepareTilesMode::PREPARE_NONE; + return threaded_gpu_rasterization_enabled_ + ? PrepareTilesMode::RASTERIZE_PRIORITIZED_TILES + : PrepareTilesMode::PREPARE_NONE; +} + +ContextProvider* GpuRasterizer::GetContextProvider(bool worker_context) { + return worker_context + ? resource_provider_->output_surface()->worker_context_provider() + : resource_provider_->output_surface()->context_provider(); } void GpuRasterizer::RasterizeTiles( @@ -63,7 +69,7 @@ void GpuRasterizer::RasterizeTiles( ResourcePool* resource_pool, ResourceFormat resource_format, const UpdateTileDrawInfoCallback& update_tile_draw_info) { - ScopedGpuRaster gpu_raster(context_provider_); + ScopedGpuRaster gpu_raster(GetContextProvider(false)); ScopedResourceWriteLocks locks; @@ -86,6 +92,39 @@ void GpuRasterizer::RasterizeTiles( multi_picture_draw_.draw(msaa_sample_count_ > 0); } +void GpuRasterizer::RasterizeSource( + bool use_worker_context, + ResourceProvider::ScopedWriteLockGr* write_lock, + const RasterSource* raster_source, + const gfx::Rect& rect, + float scale) { + // Play back raster_source into temp SkPicture. + SkPictureRecorder recorder; + gfx::Size size = write_lock->resource()->size; + const int flags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; + skia::RefPtr<SkCanvas> canvas = skia::SharePtr( + recorder.beginRecording(size.width(), size.height(), NULL, flags)); + canvas->save(); + raster_source->PlaybackToCanvas(canvas.get(), rect, scale); + canvas->restore(); + skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording()); + + // Turn on distance fields for layers that have ever animated. + bool use_distance_field_text = + use_distance_field_text_ || + raster_source->ShouldAttemptToUseDistanceFieldText(); + + // Playback picture into resource. + { + ScopedGpuRaster gpu_raster(GetContextProvider(use_worker_context)); + write_lock->InitSkSurface(use_worker_context, use_distance_field_text, + raster_source->CanUseLCDText(), + msaa_sample_count_); + picture->playback(write_lock->sk_surface()->getCanvas(), nullptr); + write_lock->ReleaseSkSurface(); + } +} + void GpuRasterizer::PerformSolidColorAnalysis( const Tile* tile, RasterSource::SolidColorAnalysis* analysis) { @@ -119,11 +158,14 @@ void GpuRasterizer::AddToMultiPictureDraw(const Tile* tile, use_distance_field_text_ || tile->raster_source()->ShouldAttemptToUseDistanceFieldText(); scoped_ptr<ResourceProvider::ScopedWriteLockGr> lock( - new ResourceProvider::ScopedWriteLockGr( - resource_provider_, resource->id(), use_distance_field_text, - tile->raster_source()->CanUseLCDText(), msaa_sample_count_)); + new ResourceProvider::ScopedWriteLockGr(resource_provider_, + resource->id())); + + lock->InitSkSurface(false, use_distance_field_text, + tile->raster_source()->CanUseLCDText(), + msaa_sample_count_); - SkSurface* sk_surface = lock->get_sk_surface(); + SkSurface* sk_surface = lock->sk_surface(); if (!sk_surface) return; diff --git a/cc/resources/gpu_rasterizer.h b/cc/resources/gpu_rasterizer.h index 79a0596..8c75f32 100644 --- a/cc/resources/gpu_rasterizer.h +++ b/cc/resources/gpu_rasterizer.h @@ -28,6 +28,8 @@ class CC_EXPORT GpuRasterizer : public Rasterizer { bool use_distance_field_text, bool threaded_gpu_rasterization_enabled, int msaa_sample_count); + + // Overriden from Rasterizer. PrepareTilesMode GetPrepareTilesMode() override; void RasterizeTiles( const TileVector& tiles, @@ -35,6 +37,14 @@ class CC_EXPORT GpuRasterizer : public Rasterizer { ResourceFormat resource_format, const UpdateTileDrawInfoCallback& update_tile_draw_info) override; + void RasterizeSource(bool use_worker_context, + ResourceProvider::ScopedWriteLockGr* write_lock, + const RasterSource* raster_source, + const gfx::Rect& rect, + float scale); + + ResourceProvider* resource_provider() { return resource_provider_; } + private: GpuRasterizer(ContextProvider* context_provider, ResourceProvider* resource_provider, @@ -45,13 +55,13 @@ class CC_EXPORT GpuRasterizer : public Rasterizer { using ScopedResourceWriteLocks = ScopedPtrVector<ResourceProvider::ScopedWriteLockGr>; + ContextProvider* GetContextProvider(bool worker_context); void PerformSolidColorAnalysis(const Tile* tile, RasterSource::SolidColorAnalysis* analysis); void AddToMultiPictureDraw(const Tile* tile, const ScopedResource* resource, ScopedResourceWriteLocks* locks); - ContextProvider* context_provider_; ResourceProvider* resource_provider_; SkMultiPictureDraw multi_picture_draw_; diff --git a/cc/resources/gpu_tile_task_worker_pool.cc b/cc/resources/gpu_tile_task_worker_pool.cc index 8249457..dd55b94 100644 --- a/cc/resources/gpu_tile_task_worker_pool.cc +++ b/cc/resources/gpu_tile_task_worker_pool.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "base/trace_event/trace_event.h" +#include "cc/resources/gpu_rasterizer.h" #include "cc/resources/raster_buffer.h" #include "cc/resources/raster_source.h" #include "cc/resources/resource.h" @@ -22,45 +23,78 @@ namespace { class RasterBufferImpl : public RasterBuffer { public: - RasterBufferImpl() {} + RasterBufferImpl(GpuRasterizer* rasterizer, const Resource* resource) + : rasterizer_(rasterizer), + lock_(rasterizer->resource_provider(), resource->id()), + resource_(resource) {} // Overridden from RasterBuffer: void Playback(const RasterSource* raster_source, const gfx::Rect& rect, float scale) override { - // Don't do anything. + TRACE_EVENT0("cc", "RasterBufferImpl::Playback"); + + ContextProvider* context_provider = rasterizer_->resource_provider() + ->output_surface() + ->worker_context_provider(); + + // We must hold the context lock while accessing the context on the + // worker thread. + scoped_ptr<base::AutoLock> scoped_auto_lock; + base::Lock* lock = context_provider->GetLock(); + if (lock) + scoped_auto_lock.reset(new base::AutoLock(*lock)); + + // Rasterize source into resource. + rasterizer_->RasterizeSource(true, &lock_, raster_source, rect, scale); + + // Barrier to sync worker context output to cc context. + context_provider->ContextGL()->OrderingBarrierCHROMIUM(); } private: + GpuRasterizer* rasterizer_; + ResourceProvider::ScopedWriteLockGr lock_; + const Resource* resource_; + DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); }; } // namespace + // static scoped_ptr<TileTaskWorkerPool> GpuTileTaskWorkerPool::Create( base::SequencedTaskRunner* task_runner, TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider) { + GpuRasterizer* rasterizer) { return make_scoped_ptr<TileTaskWorkerPool>( - new GpuTileTaskWorkerPool( - task_runner, task_graph_runner, resource_provider)); + new GpuTileTaskWorkerPool(task_runner, task_graph_runner, rasterizer)); } -// TODO(hendrikw): This class should be removed. See crbug.com/444938. GpuTileTaskWorkerPool::GpuTileTaskWorkerPool( base::SequencedTaskRunner* task_runner, TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider) + GpuRasterizer* rasterizer) : task_runner_(task_runner), task_graph_runner_(task_graph_runner), namespace_token_(task_graph_runner_->GetNamespaceToken()), - resource_provider_(resource_provider), + rasterizer_(rasterizer), task_set_finished_weak_ptr_factory_(this), weak_ptr_factory_(this) { + // Allow |worker_context_provider| to bind to the worker thread. + rasterizer_->resource_provider() + ->output_surface() + ->worker_context_provider() + ->DetachFromThread(); } GpuTileTaskWorkerPool::~GpuTileTaskWorkerPool() { DCHECK_EQ(0u, completed_tasks_.size()); + // Allow |worker_context_provider| to bind to the cc thread. + rasterizer_->resource_provider() + ->output_surface() + ->worker_context_provider() + ->DetachFromThread(); } TileTaskRunner* GpuTileTaskWorkerPool::AsTileTaskRunner() { @@ -129,6 +163,14 @@ void GpuTileTaskWorkerPool::ScheduleTasks(TileTaskQueue* queue) { } ScheduleTasksOnOriginThread(this, &graph_); + + // Barrier to sync any new resources to the worker context. + rasterizer_->resource_provider() + ->output_surface() + ->context_provider() + ->ContextGL() + ->OrderingBarrierCHROMIUM(); + task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); std::copy(new_task_set_finished_tasks, @@ -146,7 +188,7 @@ void GpuTileTaskWorkerPool::CheckForCompletedTasks() { } ResourceFormat GpuTileTaskWorkerPool::GetResourceFormat() { - return resource_provider_->best_texture_format(); + return rasterizer_->resource_provider()->best_texture_format(); } void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) { @@ -164,7 +206,8 @@ void GpuTileTaskWorkerPool::CompleteTasks(const Task::Vector& tasks) { scoped_ptr<RasterBuffer> GpuTileTaskWorkerPool::AcquireBufferForRaster( const Resource* resource) { - return make_scoped_ptr<RasterBuffer>(new RasterBufferImpl()); + return make_scoped_ptr<RasterBuffer>( + new RasterBufferImpl(rasterizer_, resource)); } void GpuTileTaskWorkerPool::ReleaseBufferForRaster( diff --git a/cc/resources/gpu_tile_task_worker_pool.h b/cc/resources/gpu_tile_task_worker_pool.h index 6ac8548..5941852 100644 --- a/cc/resources/gpu_tile_task_worker_pool.h +++ b/cc/resources/gpu_tile_task_worker_pool.h @@ -10,7 +10,7 @@ #include "cc/resources/tile_task_worker_pool.h" namespace cc { -class ResourceProvider; +class GpuRasterizer; class CC_EXPORT GpuTileTaskWorkerPool : public TileTaskWorkerPool, public TileTaskRunner, @@ -21,7 +21,7 @@ class CC_EXPORT GpuTileTaskWorkerPool : public TileTaskWorkerPool, static scoped_ptr<TileTaskWorkerPool> Create( base::SequencedTaskRunner* task_runner, TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider); + GpuRasterizer* rasterizer); // Overridden from TileTaskWorkerPool: TileTaskRunner* AsTileTaskRunner() override; @@ -41,7 +41,7 @@ class CC_EXPORT GpuTileTaskWorkerPool : public TileTaskWorkerPool, private: GpuTileTaskWorkerPool(base::SequencedTaskRunner* task_runner, TaskGraphRunner* task_graph_runner, - ResourceProvider* resource_provider); + GpuRasterizer* rasterizer); void OnTaskSetFinished(TaskSet task_set); void CompleteTasks(const Task::Vector& tasks); @@ -50,7 +50,7 @@ class CC_EXPORT GpuTileTaskWorkerPool : public TileTaskWorkerPool, TaskGraphRunner* task_graph_runner_; const NamespaceToken namespace_token_; TileTaskRunnerClient* client_; - ResourceProvider* resource_provider_; + GpuRasterizer* rasterizer_; TaskSetCollection tasks_pending_; diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index b90b594..42ef4b3 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -1087,17 +1087,25 @@ ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() { ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr( ResourceProvider* resource_provider, - ResourceProvider::ResourceId resource_id, - bool use_distance_field_text, - bool can_use_lcd_text, - int msaa_sample_count) + ResourceProvider::ResourceId resource_id) : resource_provider_(resource_provider), resource_(resource_provider->LockForWrite(resource_id)) { - // Create the sk_surface. + DCHECK(thread_checker_.CalledOnValidThread()); + resource_provider_->LazyAllocate(resource_); +} + +ResourceProvider::ScopedWriteLockGr::~ScopedWriteLockGr() { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(resource_->locked_for_write); + resource_provider_->UnlockForWrite(resource_); +} - resource_provider_->LazyAllocate(resource_); +void ResourceProvider::ScopedWriteLockGr::InitSkSurface( + bool use_worker_context, + bool use_distance_field_text, + bool can_use_lcd_text, + int msaa_sample_count) { + DCHECK(resource_->locked_for_write); GrBackendTextureDesc desc; desc.fFlags = kRenderTarget_GrBackendTextureFlag; @@ -1108,7 +1116,8 @@ ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr( desc.fTextureHandle = resource_->gl_id; desc.fSampleCnt = msaa_sample_count; - class GrContext* gr_context = resource_provider_->GrContext(); + class GrContext* gr_context = + resource_provider_->GrContext(use_worker_context); skia::RefPtr<GrTexture> gr_texture = skia::AdoptRef(gr_context->wrapBackendTexture(desc)); if (gr_texture) { @@ -1124,12 +1133,13 @@ ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr( } sk_surface_ = skia::AdoptRef(SkSurface::NewRenderTargetDirect( gr_texture->asRenderTarget(), &surface_props)); + return; } + sk_surface_.clear(); } -ResourceProvider::ScopedWriteLockGr::~ScopedWriteLockGr() { - DCHECK(thread_checker_.CalledOnValidThread()); - resource_provider_->UnlockForWrite(resource_); +void ResourceProvider::ScopedWriteLockGr::ReleaseSkSurface() { + sk_surface_.clear(); } ResourceProvider::SynchronousFence::SynchronousFence( @@ -2135,8 +2145,10 @@ GLES2Interface* ResourceProvider::ContextGL() const { return context_provider ? context_provider->ContextGL() : NULL; } -class GrContext* ResourceProvider::GrContext() const { - ContextProvider* context_provider = output_surface_->context_provider(); +class GrContext* ResourceProvider::GrContext(bool worker_context) const { + ContextProvider* context_provider = + worker_context ? output_surface_->worker_context_provider() + : output_surface_->context_provider(); return context_provider ? context_provider->GrContext() : NULL; } diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index 1fb5b60..167ef20 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -332,13 +332,17 @@ class CC_EXPORT ResourceProvider { class CC_EXPORT ScopedWriteLockGr { public: ScopedWriteLockGr(ResourceProvider* resource_provider, - ResourceProvider::ResourceId resource_id, - bool use_distance_field_text, - bool can_use_lcd_text, - int msaa_sample_count); + ResourceProvider::ResourceId resource_id); ~ScopedWriteLockGr(); - SkSurface* get_sk_surface() { return sk_surface_.get(); } + void InitSkSurface(bool use_worker_context, + bool use_distance_field_text, + bool can_use_lcd_text, + int msaa_sample_count); + void ReleaseSkSurface(); + + SkSurface* sk_surface() { return sk_surface_.get(); } + ResourceProvider::Resource* resource() { return resource_; } private: ResourceProvider* resource_provider_; @@ -426,6 +430,8 @@ class CC_EXPORT ResourceProvider { static GLint GetActiveTextureUnit(gpu::gles2::GLES2Interface* gl); + OutputSurface* output_surface() { return output_surface_; } + private: struct Resource { enum Origin { Internal, External, Delegated }; @@ -560,7 +566,7 @@ class CC_EXPORT ResourceProvider { // Returns NULL if the output_surface_ does not have a ContextProvider. gpu::gles2::GLES2Interface* ContextGL() const; - class GrContext* GrContext() const; + class GrContext* GrContext(bool worker_context) const; OutputSurface* output_surface_; SharedBitmapManager* shared_bitmap_manager_; diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 53741ab..2bba801 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -3518,7 +3518,7 @@ void InitializeGLAndCheck(ContextSharedData* shared_data, scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(context_owned.Pass()); - output_surface->InitializeAndSetContext3d(context_provider); + output_surface->InitializeAndSetContext3d(context_provider, nullptr); resource_provider->InitializeGL(); CheckCreateResource(ResourceProvider::GLTexture, resource_provider, context); diff --git a/cc/resources/tile_task_worker_pool_perftest.cc b/cc/resources/tile_task_worker_pool_perftest.cc index 449b3af..450bcbe 100644 --- a/cc/resources/tile_task_worker_pool_perftest.cc +++ b/cc/resources/tile_task_worker_pool_perftest.cc @@ -9,6 +9,7 @@ #include "cc/debug/lap_timer.h" #include "cc/output/context_provider.h" #include "cc/resources/bitmap_tile_task_worker_pool.h" +#include "cc/resources/gpu_rasterizer.h" #include "cc/resources/gpu_tile_task_worker_pool.h" #include "cc/resources/one_copy_tile_task_worker_pool.h" #include "cc/resources/pixel_buffer_tile_task_worker_pool.h" @@ -231,6 +232,7 @@ class TileTaskWorkerPoolPerfTestBase { FakeOutputSurfaceClient output_surface_client_; scoped_ptr<FakeOutputSurface> output_surface_; scoped_ptr<ResourceProvider> resource_provider_; + scoped_ptr<Rasterizer> rasterizer_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; scoped_ptr<TaskGraphRunner> task_graph_runner_; LapTimer timer_; @@ -270,7 +272,7 @@ class TileTaskWorkerPoolPerfTest Create3dOutputSurfaceAndResourceProvider(); tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create( task_runner_.get(), task_graph_runner_.get(), - resource_provider_.get()); + static_cast<GpuRasterizer*>(rasterizer_.get())); break; case TILE_TASK_WORKER_POOL_TYPE_BITMAP: CreateSoftwareOutputSurfaceAndResourceProvider(); diff --git a/cc/resources/tile_task_worker_pool_unittest.cc b/cc/resources/tile_task_worker_pool_unittest.cc index 68758f6..1e84674 100644 --- a/cc/resources/tile_task_worker_pool_unittest.cc +++ b/cc/resources/tile_task_worker_pool_unittest.cc @@ -10,6 +10,7 @@ #include "base/cancelable_callback.h" #include "cc/base/unique_notifier.h" #include "cc/resources/bitmap_tile_task_worker_pool.h" +#include "cc/resources/gpu_rasterizer.h" #include "cc/resources/gpu_tile_task_worker_pool.h" #include "cc/resources/one_copy_tile_task_worker_pool.h" #include "cc/resources/picture_pile.h" @@ -126,6 +127,7 @@ class TileTaskWorkerPoolTest TileTaskWorkerPoolTest() : context_provider_(TestContextProvider::Create()), + worker_context_provider_(TestContextProvider::Create()), all_tile_tasks_finished_( base::MessageLoopProxy::current().get(), base::Bind(&TileTaskWorkerPoolTest::AllTileTasksFinished, @@ -160,10 +162,12 @@ class TileTaskWorkerPoolTest break; case TILE_TASK_WORKER_POOL_TYPE_GPU: Create3dOutputSurfaceAndResourceProvider(); + rasterizer_ = GpuRasterizer::Create( + context_provider_.get(), resource_provider_.get(), false, false, 0); tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create( base::MessageLoopProxy::current().get(), TileTaskWorkerPool::GetTaskGraphRunner(), - resource_provider_.get()); + static_cast<GpuRasterizer*>(rasterizer_.get())); break; case TILE_TASK_WORKER_POOL_TYPE_BITMAP: CreateSoftwareOutputSurfaceAndResourceProvider(); @@ -271,7 +275,8 @@ class TileTaskWorkerPoolTest private: void Create3dOutputSurfaceAndResourceProvider() { - output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass(); + output_surface_ = FakeOutputSurface::Create3d( + context_provider_, worker_context_provider_).Pass(); CHECK(output_surface_->BindToClient(&output_surface_client_)); TestWebGraphicsContext3D* context3d = context_provider_->TestContext3d(); context3d->set_support_sync_query(true); @@ -306,6 +311,8 @@ class TileTaskWorkerPoolTest protected: scoped_refptr<TestContextProvider> context_provider_; + scoped_refptr<TestContextProvider> worker_context_provider_; + scoped_ptr<Rasterizer> rasterizer_; FakeOutputSurfaceClient output_surface_client_; scoped_ptr<FakeOutputSurface> output_surface_; scoped_ptr<ResourceProvider> resource_provider_; diff --git a/cc/test/failure_output_surface.cc b/cc/test/failure_output_surface.cc index 2c87853..c0d5fdb 100644 --- a/cc/test/failure_output_surface.cc +++ b/cc/test/failure_output_surface.cc @@ -7,7 +7,7 @@ namespace cc { FailureOutputSurface::FailureOutputSurface(bool is_delegating) - : FakeOutputSurface(nullptr, nullptr, is_delegating) { + : FakeOutputSurface(static_cast<ContextProvider*>(nullptr), is_delegating) { } bool FailureOutputSurface::BindToClient(OutputSurfaceClient* client) { diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index d54d2d1..0279421 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc @@ -16,6 +16,21 @@ namespace cc { FakeOutputSurface::FakeOutputSurface( scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider, + bool delegated_rendering) + : OutputSurface(context_provider, worker_context_provider), + client_(NULL), + num_sent_frames_(0), + has_external_stencil_test_(false), + framebuffer_(0) { + if (delegated_rendering) { + capabilities_.delegated_rendering = true; + capabilities_.max_frames_pending = 1; + } +} + +FakeOutputSurface::FakeOutputSurface( + scoped_refptr<ContextProvider> context_provider, bool delegated_rendering) : OutputSurface(context_provider), client_(NULL), diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index a564eef..39a78ea 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -24,7 +24,7 @@ class FakeOutputSurface : public OutputSurface { static scoped_ptr<FakeOutputSurface> Create3d() { return make_scoped_ptr(new FakeOutputSurface( - TestContextProvider::Create(), false)); + TestContextProvider::Create(), TestContextProvider::Create(), false)); } static scoped_ptr<FakeOutputSurface> Create3d( @@ -33,6 +33,13 @@ class FakeOutputSurface : public OutputSurface { } static scoped_ptr<FakeOutputSurface> Create3d( + scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider) { + return make_scoped_ptr(new FakeOutputSurface( + context_provider, worker_context_provider, false)); + } + + static scoped_ptr<FakeOutputSurface> Create3d( scoped_ptr<TestWebGraphicsContext3D> context) { return make_scoped_ptr(new FakeOutputSurface( TestContextProvider::Create(context.Pass()), false)); @@ -46,7 +53,7 @@ class FakeOutputSurface : public OutputSurface { static scoped_ptr<FakeOutputSurface> CreateDelegating3d() { return make_scoped_ptr(new FakeOutputSurface( - TestContextProvider::Create(), true)); + TestContextProvider::Create(), TestContextProvider::Create(), true)); } static scoped_ptr<FakeOutputSurface> CreateDelegating3d( @@ -128,9 +135,12 @@ class FakeOutputSurface : public OutputSurface { scoped_refptr<ContextProvider> context_provider, bool delegated_rendering); - FakeOutputSurface( - scoped_ptr<SoftwareOutputDevice> software_device, - bool delegated_rendering); + FakeOutputSurface(scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider, + bool delegated_rendering); + + FakeOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device, + bool delegated_rendering); FakeOutputSurface( scoped_refptr<ContextProvider> context_provider, diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc index cf62d53..6b6c00b 100644 --- a/cc/test/layer_tree_pixel_resource_test.cc +++ b/cc/test/layer_tree_pixel_resource_test.cc @@ -183,7 +183,7 @@ void LayerTreeHostPixelResourceTest::CreateResourceAndTileTaskWorkerPool( *tile_task_worker_pool = GpuTileTaskWorkerPool::Create( task_runner, TileTaskWorkerPool::GetTaskGraphRunner(), - resource_provider); + static_cast<GpuRasterizer*>(host_impl->rasterizer())); break; case ZERO_COPY_TILE_TASK_WORKER_POOL: EXPECT_TRUE(context_provider); diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index fbe4e41..f7ab9c2 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc @@ -53,7 +53,8 @@ scoped_ptr<OutputSurface> LayerTreePixelTest::CreateOutputSurface() { case PIXEL_TEST_GL: { bool flipped_output_surface = false; output_surface = make_scoped_ptr(new PixelTestOutputSurface( - new TestInProcessContextProvider, flipped_output_surface)); + new TestInProcessContextProvider, new TestInProcessContextProvider, + flipped_output_surface)); break; } } diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index aecd657..c2dc5b5 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc @@ -127,7 +127,8 @@ void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend, enable_pixel_output_.reset(new gfx::DisableNullDrawGLBindings); output_surface_.reset(new PixelTestOutputSurface( - new TestInProcessContextProvider, flipped_output_surface)); + new TestInProcessContextProvider, new TestInProcessContextProvider, + flipped_output_surface)); output_surface_->BindToClient(output_surface_client_.get()); shared_bitmap_manager_.reset(new TestSharedBitmapManager); diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc index ced1898..616103c 100644 --- a/cc/test/pixel_test_output_surface.cc +++ b/cc/test/pixel_test_output_surface.cc @@ -11,14 +11,25 @@ namespace cc { PixelTestOutputSurface::PixelTestOutputSurface( scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider, bool flipped_output_surface) - : OutputSurface(context_provider), external_stencil_test_(false) { + : OutputSurface(context_provider, worker_context_provider), + external_stencil_test_(false) { capabilities_.flipped_output_surface = flipped_output_surface; } PixelTestOutputSurface::PixelTestOutputSurface( + scoped_refptr<ContextProvider> context_provider, + bool flipped_output_surface) + : PixelTestOutputSurface(context_provider, + nullptr, + flipped_output_surface) { +} + +PixelTestOutputSurface::PixelTestOutputSurface( scoped_ptr<SoftwareOutputDevice> software_device) - : OutputSurface(software_device.Pass()), external_stencil_test_(false) {} + : OutputSurface(software_device.Pass()), external_stencil_test_(false) { +} void PixelTestOutputSurface::Reshape(const gfx::Size& size, float scale_factor) { diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h index a58e2c4..27819c1 100644 --- a/cc/test/pixel_test_output_surface.h +++ b/cc/test/pixel_test_output_surface.h @@ -13,6 +13,10 @@ class PixelTestOutputSurface : public OutputSurface { public: explicit PixelTestOutputSurface( scoped_refptr<ContextProvider> context_provider, + scoped_refptr<ContextProvider> worker_context_provider, + bool flipped_output_surface); + explicit PixelTestOutputSurface( + scoped_refptr<ContextProvider> context_provider, bool flipped_output_surface); explicit PixelTestOutputSurface( scoped_ptr<SoftwareOutputDevice> software_device); diff --git a/cc/test/test_context_provider.cc b/cc/test/test_context_provider.cc index d775826..bf85ea3 100644 --- a/cc/test/test_context_provider.cc +++ b/cc/test/test_context_provider.cc @@ -69,6 +69,10 @@ bool TestContextProvider::BindToCurrentThread() { return true; } +void TestContextProvider::DetachFromThread() { + context_thread_checker_.DetachFromThread(); +} + ContextProvider::Capabilities TestContextProvider::ContextCapabilities() { DCHECK(bound_); DCHECK(context_thread_checker_.CalledOnValidThread()); diff --git a/cc/test/test_context_provider.h b/cc/test/test_context_provider.h index a4c0fa1..9dd7b62 100644 --- a/cc/test/test_context_provider.h +++ b/cc/test/test_context_provider.h @@ -29,6 +29,7 @@ class TestContextProvider : public ContextProvider { scoped_ptr<TestWebGraphicsContext3D> context); bool BindToCurrentThread() override; + void DetachFromThread() override; Capabilities ContextCapabilities() override; gpu::gles2::GLES2Interface* ContextGL() override; gpu::ContextSupport* ContextSupport() override; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index eee50ec..d50bad6 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -2020,7 +2020,7 @@ void LayerTreeHostImpl::CreateResourceAndTileTaskWorkerPool( *tile_task_worker_pool = GpuTileTaskWorkerPool::Create( task_runner, TileTaskWorkerPool::GetTaskGraphRunner(), - resource_provider_.get()); + static_cast<GpuRasterizer*>(rasterizer_.get())); return; } diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index ded20b2d..a192d50 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -313,6 +313,7 @@ class CC_EXPORT LayerTreeHostImpl } ResourcePool* resource_pool() { return resource_pool_.get(); } Renderer* renderer() { return renderer_.get(); } + Rasterizer* rasterizer() { return rasterizer_.get(); } const RendererCapabilitiesImpl& GetRendererCapabilities() const; virtual bool SwapBuffers(const FrameData& frame); diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index afea2d2..dc519e5 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -6646,8 +6646,8 @@ TEST_F(LayerTreeHostImplTestDeferredInitialize, Success) { // DeferredInitialize and hardware draw. did_update_renderer_capabilities_ = false; - EXPECT_TRUE( - output_surface_->InitializeAndSetContext3d(onscreen_context_provider_)); + EXPECT_TRUE(output_surface_->InitializeAndSetContext3d( + onscreen_context_provider_, nullptr)); EXPECT_EQ(onscreen_context_provider_.get(), host_impl_->output_surface()->context_provider()); EXPECT_TRUE(did_update_renderer_capabilities_); @@ -6677,8 +6677,8 @@ TEST_F(LayerTreeHostImplTestDeferredInitialize, Fails) { // DeferredInitialize fails. did_update_renderer_capabilities_ = false; - EXPECT_FALSE( - output_surface_->InitializeAndSetContext3d(onscreen_context_provider_)); + EXPECT_FALSE(output_surface_->InitializeAndSetContext3d( + onscreen_context_provider_, nullptr)); EXPECT_FALSE(host_impl_->output_surface()->context_provider()); EXPECT_FALSE(did_update_renderer_capabilities_); diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 8569686..beceab1 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -2944,8 +2944,10 @@ class LayerTreeHostTestDeferredInitialize : public LayerTreeHostTest { static_cast<FakeOutputSurface*>(host_impl->output_surface()); scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); // Not bound to thread. - EXPECT_TRUE( - fake_output_surface->InitializeAndSetContext3d(context_provider)); + scoped_refptr<TestContextProvider> worker_context_provider = + TestContextProvider::Create(); // Not bound to thread. + EXPECT_TRUE(fake_output_surface->InitializeAndSetContext3d( + context_provider, worker_context_provider)); did_initialize_gl_ = true; } @@ -5823,14 +5825,17 @@ class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest { MULTI_THREAD_IMPL_TEST_F(RasterizeWithGpuRasterizationCreatesResources); -class GpuRasterizationRasterizesVisibleOnly : public LayerTreeHostTest { +class SynchronousGpuRasterizationRasterizesVisibleOnly + : public LayerTreeHostTest { protected: - GpuRasterizationRasterizesVisibleOnly() : viewport_size_(1024, 2048) {} + SynchronousGpuRasterizationRasterizesVisibleOnly() + : viewport_size_(1024, 2048) {} void InitializeSettings(LayerTreeSettings* settings) override { settings->impl_side_painting = true; settings->gpu_rasterization_enabled = true; settings->gpu_rasterization_forced = true; + settings->threaded_gpu_rasterization_enabled = false; } void SetupTree() override { @@ -5882,7 +5887,54 @@ class GpuRasterizationRasterizesVisibleOnly : public LayerTreeHostTest { gfx::Size viewport_size_; }; -MULTI_THREAD_IMPL_TEST_F(GpuRasterizationRasterizesVisibleOnly); +MULTI_THREAD_IMPL_TEST_F(SynchronousGpuRasterizationRasterizesVisibleOnly); + +class ThreadedGpuRasterizationRasterizesBorderTiles : public LayerTreeHostTest { + protected: + ThreadedGpuRasterizationRasterizesBorderTiles() + : viewport_size_(1024, 2048) {} + + void InitializeSettings(LayerTreeSettings* settings) override { + settings->impl_side_painting = true; + settings->gpu_rasterization_enabled = true; + settings->gpu_rasterization_forced = true; + settings->threaded_gpu_rasterization_enabled = true; + } + + void SetupTree() override { + client_.set_fill_with_nonsolid_color(true); + + scoped_ptr<FakePicturePile> pile( + new FakePicturePile(ImplSidePaintingSettings().minimum_contents_scale, + ImplSidePaintingSettings().default_tile_grid_size)); + scoped_refptr<FakePictureLayer> root = + FakePictureLayer::CreateWithRecordingSource(&client_, pile.Pass()); + root->SetBounds(gfx::Size(10000, 10000)); + root->SetContentsOpaque(true); + + layer_tree_host()->SetRootLayer(root); + LayerTreeHostTest::SetupTree(); + layer_tree_host()->SetViewportSize(viewport_size_); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { + EXPECT_EQ(10u, host_impl->resource_provider()->num_resources()); + EndTest(); + return draw_result; + } + + void AfterTest() override {} + + private: + FakeContentLayerClient client_; + gfx::Size viewport_size_; +}; + +MULTI_THREAD_IMPL_TEST_F(ThreadedGpuRasterizationRasterizesBorderTiles); class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles : public LayerTreeHostTest { diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index 07dfc29..d3afbe2 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc @@ -30,6 +30,7 @@ LayerTreeSettings::LayerTreeSettings() gpu_rasterization_enabled(false), gpu_rasterization_forced(false), gpu_rasterization_msaa_sample_count(0), + gpu_rasterization_skewport_target_time_in_seconds(0.0f), threaded_gpu_rasterization_enabled(false), create_low_res_tiling(false), scrollbar_animator(NoAnimator), diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 8ba859a..fd108f4 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h @@ -38,6 +38,7 @@ class CC_EXPORT LayerTreeSettings { bool gpu_rasterization_enabled; bool gpu_rasterization_forced; int gpu_rasterization_msaa_sample_count; + float gpu_rasterization_skewport_target_time_in_seconds; bool threaded_gpu_rasterization_enabled; bool create_low_res_tiling; |