summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Miura <vmiura@chromium.org>2015-05-20 11:03:09 -0700
committerVictor Miura <vmiura@chromium.org>2015-05-20 18:03:58 +0000
commit02f18c1ec7ad7c21f4c61484470182b2d068e1c1 (patch)
tree65b8cf7cd106f4191d33397e06c27d669de9dfdd
parent19dc5f7c3a22ac4b60a4cf40ae514a38769a658f (diff)
downloadchromium_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.cc14
-rw-r--r--cc/output/gl_renderer.cc8
-rw-r--r--cc/test/fake_output_surface.h8
-rw-r--r--cc/trees/layer_tree_host.cc16
-rw-r--r--cc/trees/layer_tree_host.h1
-rw-r--r--cc/trees/layer_tree_host_impl.cc31
-rw-r--r--cc/trees/layer_tree_host_impl.h8
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc77
-rw-r--r--cc/trees/layer_tree_host_unittest.cc18
-rw-r--r--content/common/gpu/client/context_provider_command_buffer.cc2
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();