diff options
author | Victor Miura <vmiura@chromium.org> | 2015-05-20 11:03:09 -0700 |
---|---|---|
committer | Victor Miura <vmiura@chromium.org> | 2015-05-20 18:03:58 +0000 |
commit | 02f18c1ec7ad7c21f4c61484470182b2d068e1c1 (patch) | |
tree | 65b8cf7cd106f4191d33397e06c27d669de9dfdd | |
parent | 19dc5f7c3a22ac4b60a4cf40ae514a38769a658f (diff) | |
download | chromium_src-02f18c1ec7ad7c21f4c61484470182b2d068e1c1.zip chromium_src-02f18c1ec7ad7c21f4c61484470182b2d068e1c1.tar.gz chromium_src-02f18c1ec7ad7c21f4c61484470182b2d068e1c1.tar.bz2 |
cc: Add null checks for GrContext created by ContextProviderCommandBuffer.
GrContext::Create may return NULL if the base GL context was lost.
- Check for the NULL case in GlRenderer.
- For the GPU rasterizer, don't allow GPU rasterization to be initialized
with a NULL GrContext.
Testing=cc_unittests, and manual tests of GPU enable/force and loss of context case.
BUG=464892
R=senorblanco@chromium.org, danakj@chromium.org
Review URL: https://codereview.chromium.org/1135743004
Cr-Commit-Position: refs/heads/master@{#330104}
(cherry picked from commit 4e7e199cb73c95ee81c0804cf14a3d6ab015c75c)
Review URL: https://codereview.chromium.org/1144953002
Cr-Commit-Position: refs/branch-heads/2357@{#420}
Cr-Branched-From: 59d4494849b405682265ed5d3f5164573b9a939b-refs/heads/master@{#323860}
-rw-r--r-- | cc/layers/picture_layer_impl_unittest.cc | 14 | ||||
-rw-r--r-- | cc/output/gl_renderer.cc | 8 | ||||
-rw-r--r-- | cc/test/fake_output_surface.h | 8 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.cc | 16 | ||||
-rw-r--r-- | cc/trees/layer_tree_host.h | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 31 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.h | 8 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 77 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest.cc | 18 | ||||
-rw-r--r-- | content/common/gpu/client/context_provider_command_buffer.cc | 2 |
10 files changed, 137 insertions, 46 deletions
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index 1ed3287..fab3b94 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc @@ -2421,7 +2421,7 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { // Gpu rasterization is disabled by default. EXPECT_FALSE(host_impl_.use_gpu_rasterization()); // Toggling the gpu rasterization clears all tilings on both trees. - host_impl_.SetUseGpuRasterization(true); + host_impl_.SetGpuRasterizationStatus(GpuRasterizationStatus::ON); EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); @@ -2442,7 +2442,7 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { // Toggling the gpu rasterization clears all tilings on both trees. EXPECT_TRUE(host_impl_.use_gpu_rasterization()); - host_impl_.SetUseGpuRasterization(false); + host_impl_.SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_DEVICE); EXPECT_EQ(0u, pending_layer_->tilings()->num_tilings()); EXPECT_EQ(0u, active_layer_->tilings()->num_tilings()); } @@ -2487,7 +2487,7 @@ TEST_F(PictureLayerImplTest, LowResTilingWithoutGpuRasterization) { gfx::Size layer_bounds(default_tile_size.width() * 4, default_tile_size.height() * 4); - host_impl_.SetUseGpuRasterization(false); + host_impl_.SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_DEVICE); SetupDefaultTrees(layer_bounds); EXPECT_FALSE(host_impl_.use_gpu_rasterization()); @@ -2500,7 +2500,7 @@ TEST_F(PictureLayerImplTest, NoLowResTilingWithGpuRasterization) { gfx::Size layer_bounds(default_tile_size.width() * 4, default_tile_size.height() * 4); - host_impl_.SetUseGpuRasterization(true); + host_impl_.SetGpuRasterizationStatus(GpuRasterizationStatus::ON); SetupDefaultTrees(layer_bounds); EXPECT_TRUE(host_impl_.use_gpu_rasterization()); @@ -2796,7 +2796,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationForGpuRasterization) { gfx::Size viewport_size(1000, 1000); SetupDefaultTrees(layer_bounds); host_impl_.SetViewportSize(viewport_size); - host_impl_.SetUseGpuRasterization(true); + host_impl_.SetGpuRasterizationStatus(GpuRasterizationStatus::ON); float contents_scale = 1.f; float device_scale = 1.3f; @@ -4929,7 +4929,7 @@ TEST_F(TileSizeTest, TileSizes) { host_impl_.SetViewportSize(gfx::Size(1000, 1000)); gfx::Size result; - host_impl_.SetUseGpuRasterization(false); + host_impl_.SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_DEVICE); // Default tile-size for large layers. result = layer->CalculateTileSize(gfx::Size(10000, 10000)); @@ -4948,7 +4948,7 @@ TEST_F(TileSizeTest, TileSizes) { // Gpu-rasterization uses 25% viewport-height tiles. // The +2's below are for border texels. - host_impl_.SetUseGpuRasterization(true); + host_impl_.SetGpuRasterizationStatus(GpuRasterizationStatus::ON); host_impl_.SetViewportSize(gfx::Size(2000, 2000)); layer->set_gpu_raster_max_texture_size(host_impl_.device_viewport_size()); diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 24e2a30..95ea460 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -162,7 +162,13 @@ class GLRenderer::ScopedUseGrContext { public: static scoped_ptr<ScopedUseGrContext> Create(GLRenderer* renderer, DrawingFrame* frame) { - return make_scoped_ptr(new ScopedUseGrContext(renderer, frame)); + // GrContext for filters is created lazily, and may fail if the context + // is lost. + // TODO(vmiura,bsalomon): crbug.com/487850 Ensure that + // ContextProvider::GrContext() does not return NULL. + if (renderer->output_surface_->context_provider()->GrContext()) + return make_scoped_ptr(new ScopedUseGrContext(renderer, frame)); + return nullptr; } ~ScopedUseGrContext() { diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index 2248b84..cbed2a3 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -29,7 +29,8 @@ class FakeOutputSurface : public OutputSurface { static scoped_ptr<FakeOutputSurface> Create3d( scoped_refptr<ContextProvider> context_provider) { - return make_scoped_ptr(new FakeOutputSurface(context_provider, false)); + return make_scoped_ptr(new FakeOutputSurface( + context_provider, TestContextProvider::Create(), false)); } static scoped_ptr<FakeOutputSurface> Create3d( @@ -41,8 +42,9 @@ class FakeOutputSurface : public OutputSurface { static scoped_ptr<FakeOutputSurface> Create3d( scoped_ptr<TestWebGraphicsContext3D> context) { - return make_scoped_ptr(new FakeOutputSurface( - TestContextProvider::Create(context.Pass()), false)); + return make_scoped_ptr( + new FakeOutputSurface(TestContextProvider::Create(context.Pass()), + TestContextProvider::Create(), false)); } static scoped_ptr<FakeOutputSurface> CreateSoftware( diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 890d304..c12c0c1 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc @@ -338,8 +338,7 @@ void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { sync_tree->set_top_controls_height(top_controls_height_); sync_tree->PushTopControlsFromMainThread(top_controls_shown_ratio_); - host_impl->SetUseGpuRasterization(UseGpuRasterization()); - host_impl->set_gpu_rasterization_status(GetGpuRasterizationStatus()); + host_impl->SetGpuRasterizationStatus(GetGpuRasterizationStatus()); RecordGpuRasterizationHistogram(); host_impl->SetViewportSize(device_viewport_size_); @@ -440,7 +439,7 @@ scoped_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( settings_, client, proxy_.get(), rendering_stats_instrumentation_.get(), shared_bitmap_manager_, gpu_memory_buffer_manager_, task_graph_runner_, id_); - host_impl->SetUseGpuRasterization(UseGpuRasterization()); + host_impl->SetGpuRasterizationStatus(GetGpuRasterizationStatus()); shared_bitmap_manager_ = NULL; gpu_memory_buffer_manager_ = NULL; task_graph_runner_ = NULL; @@ -582,17 +581,6 @@ void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) { proxy_->SetDebugState(debug_state); } -bool LayerTreeHost::UseGpuRasterization() const { - if (settings_.gpu_rasterization_forced) { - return true; - } else if (settings_.gpu_rasterization_enabled) { - return has_gpu_rasterization_trigger_ && - content_is_suitable_for_gpu_rasterization_; - } else { - return false; - } -} - GpuRasterizationStatus LayerTreeHost::GetGpuRasterizationStatus() const { if (settings_.gpu_rasterization_forced) { return GpuRasterizationStatus::ON_FORCED; diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index ef5cb6a..a5bdcaa 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h @@ -193,7 +193,6 @@ class CC_EXPORT LayerTreeHost { return has_gpu_rasterization_trigger_; } void SetHasGpuRasterizationTrigger(bool has_trigger); - bool UseGpuRasterization() const; GpuRasterizationStatus GetGpuRasterizationStatus() const; void SetViewportSize(const gfx::Size& device_viewport_size); diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 56539d1..622c323 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -1616,7 +1616,36 @@ void LayerTreeHostImpl::FinishAllRendering() { renderer_->Finish(); } -void LayerTreeHostImpl::SetUseGpuRasterization(bool use_gpu) { +bool LayerTreeHostImpl::CanUseGpuRasterization() { + if (!(output_surface_ && output_surface_->context_provider() && + output_surface_->worker_context_provider())) + return false; + + ContextProvider* context_provider = + output_surface_->worker_context_provider(); + base::AutoLock context_lock(*context_provider->GetLock()); + if (!context_provider->GrContext()) + return false; + + return true; +} + +void LayerTreeHostImpl::SetGpuRasterizationStatus( + GpuRasterizationStatus gpu_rasterization_status) { + bool use_gpu = gpu_rasterization_status == GpuRasterizationStatus::ON || + gpu_rasterization_status == GpuRasterizationStatus::ON_FORCED; + if (use_gpu && !use_gpu_rasterization_) { + if (!CanUseGpuRasterization()) { + // If GPU rasterization is unusable, e.g. if GlContext could not + // be created due to losing the GL context, force use of software + // raster. + use_gpu = false; + gpu_rasterization_status = GpuRasterizationStatus::OFF_DEVICE; + } + } + + gpu_rasterization_status_ = gpu_rasterization_status; + if (use_gpu == use_gpu_rasterization_) return; diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index f0caf4d..2713240 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -314,16 +314,14 @@ class CC_EXPORT LayerTreeHostImpl virtual bool InitializeRenderer(scoped_ptr<OutputSurface> output_surface); TileManager* tile_manager() { return tile_manager_.get(); } - void SetUseGpuRasterization(bool use_gpu); + bool CanUseGpuRasterization(); + void SetGpuRasterizationStatus( + GpuRasterizationStatus gpu_rasterization_status); bool use_gpu_rasterization() const { return use_gpu_rasterization_; } GpuRasterizationStatus gpu_rasterization_status() const { return gpu_rasterization_status_; } - void set_gpu_rasterization_status( - GpuRasterizationStatus gpu_rasterization_status) { - gpu_rasterization_status_ = gpu_rasterization_status; - } bool create_low_res_tiling() const { return settings_.create_low_res_tiling && !use_gpu_rasterization_; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 442162d..2c1cb2a 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -6701,9 +6701,8 @@ TEST_F(LayerTreeHostImplTest, MemoryPolicy) { // when visible. LayerTreeSettings settings; settings.gpu_rasterization_enabled = true; - host_impl_ = LayerTreeHostImpl::Create( - settings, this, &proxy_, &stats_instrumentation_, NULL, NULL, NULL, 0); - host_impl_->SetUseGpuRasterization(true); + CreateHostImpl(settings, CreateOutputSurface()); + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::ON); host_impl_->SetVisible(true); host_impl_->SetMemoryPolicy(policy1); EXPECT_EQ(policy1.bytes_limit_when_visible, current_limit_bytes_); @@ -6745,20 +6744,84 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { host_impl_->ResetRequiresHighResToDraw(); - host_impl_->SetUseGpuRasterization(false); + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_DEVICE); EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); - host_impl_->SetUseGpuRasterization(true); + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::ON); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); - host_impl_->SetUseGpuRasterization(false); + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_DEVICE); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->ResetRequiresHighResToDraw(); EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); - host_impl_->SetUseGpuRasterization(true); + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::ON); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); } +TEST_F(LayerTreeHostImplTest, SetGpuRasterizationStatus) { + ASSERT_TRUE(host_impl_->active_tree()); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::ON); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_DEVICE); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, + host_impl_->gpu_rasterization_status()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::ON_FORCED); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::ON_FORCED, + host_impl_->gpu_rasterization_status()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_VIEWPORT); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, + host_impl_->gpu_rasterization_status()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_CONTENT); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, + host_impl_->gpu_rasterization_status()); +} + +TEST_F(LayerTreeHostImplTest, SetGpuRasterizationStatusNoContext) { + // Initialize output surface with no worker context privider. + scoped_ptr<FakeOutputSurface> output_surface = + FakeOutputSurface::Create3d(TestContextProvider::Create(), nullptr); + CreateHostImpl(DefaultSettings(), output_surface.Pass()); + + ASSERT_TRUE(host_impl_->active_tree()); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::ON); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, + host_impl_->gpu_rasterization_status()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::ON_FORCED); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, + host_impl_->gpu_rasterization_status()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_DEVICE); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, + host_impl_->gpu_rasterization_status()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_VIEWPORT); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, + host_impl_->gpu_rasterization_status()); + + host_impl_->SetGpuRasterizationStatus(GpuRasterizationStatus::OFF_CONTENT); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, + host_impl_->gpu_rasterization_status()); +} + class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest { public: void SetUp() override { diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 6e50ead..2c59e71 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc @@ -5316,12 +5316,14 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, + layer_tree_host()->GetGpuRasterizationStatus()); // Setting gpu rasterization trigger does not enable gpu rasterization. layer_tree_host()->SetHasGpuRasterizationTrigger(true); EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, + layer_tree_host()->GetGpuRasterizationStatus()); PostSetNeedsCommitToMainThread(); } @@ -5372,12 +5374,14 @@ class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { EXPECT_TRUE(layer->IsSuitableForGpuRasterization()); EXPECT_TRUE(recording_source->IsSuitableForGpuRasterization()); EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - EXPECT_FALSE(layer_tree_host()->UseGpuRasterization()); + EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, + layer_tree_host()->GetGpuRasterizationStatus()); // Gpu rasterization trigger is relevant. layer_tree_host()->SetHasGpuRasterizationTrigger(true); EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); + EXPECT_EQ(GpuRasterizationStatus::ON, + layer_tree_host()->GetGpuRasterizationStatus()); // Content-based veto is relevant as well. recording_source->SetUnsuitableForGpuRasterizationForTesting(); @@ -5440,10 +5444,12 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); // With gpu rasterization forced, gpu rasterization trigger is irrelevant. - EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); + EXPECT_EQ(GpuRasterizationStatus::ON_FORCED, + layer_tree_host()->GetGpuRasterizationStatus()); layer_tree_host()->SetHasGpuRasterizationTrigger(true); EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - EXPECT_TRUE(layer_tree_host()->UseGpuRasterization()); + EXPECT_EQ(GpuRasterizationStatus::ON_FORCED, + layer_tree_host()->GetGpuRasterizationStatus()); // Content-based veto is irrelevant as well. recording_source->SetUnsuitableForGpuRasterizationForTesting(); diff --git a/content/common/gpu/client/context_provider_command_buffer.cc b/content/common/gpu/client/context_provider_command_buffer.cc index 439e14f..11fac15 100644 --- a/content/common/gpu/client/context_provider_command_buffer.cc +++ b/content/common/gpu/client/context_provider_command_buffer.cc @@ -136,7 +136,7 @@ class GrContext* ContextProviderCommandBuffer::GrContext() { new webkit::gpu::GrContextForWebGraphicsContext3D(context3d_.get())); // If GlContext is already lost, also abandon the new GrContext. - if (IsContextLost()) + if (gr_context_->get() && IsContextLost()) gr_context_->get()->abandonContext(); return gr_context_->get(); |