diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-10 01:38:18 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-10 01:38:18 +0000 |
commit | ae277377c2c66a24eb9386e72e33aa686ecc39da (patch) | |
tree | b86e47b5cea437818969b3cbb6b24d3195b1777c /cc | |
parent | e5839c54fa854e546a9f9547d14e65a06f1e19d1 (diff) | |
download | chromium_src-ae277377c2c66a24eb9386e72e33aa686ecc39da.zip chromium_src-ae277377c2c66a24eb9386e72e33aa686ecc39da.tar.gz chromium_src-ae277377c2c66a24eb9386e72e33aa686ecc39da.tar.bz2 |
cc: Tell the LayerTreeHost that the filter context is needed.
Delegated frames may contain an offscreen filter. If they do, then the
LayerTreeHost needs to know about it so it can create an offscreen
context.
R=piman
BUG=287870
Review URL: https://chromiumcodereview.appspot.com/23451023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@222169 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/layers/delegated_renderer_layer.cc | 28 | ||||
-rw-r--r-- | cc/layers/delegated_renderer_layer.h | 1 | ||||
-rw-r--r-- | cc/output/software_renderer.cc | 1 | ||||
-rw-r--r-- | cc/quads/render_pass.h | 2 | ||||
-rw-r--r-- | cc/quads/render_pass_draw_quad.cc | 1 | ||||
-rw-r--r-- | cc/test/render_pass_test_utils.cc | 2 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_delegated.cc | 159 |
7 files changed, 191 insertions, 3 deletions
diff --git a/cc/layers/delegated_renderer_layer.cc b/cc/layers/delegated_renderer_layer.cc index 1e1a8a0..5286874 100644 --- a/cc/layers/delegated_renderer_layer.cc +++ b/cc/layers/delegated_renderer_layer.cc @@ -7,6 +7,8 @@ #include "cc/layers/delegated_renderer_layer_client.h" #include "cc/layers/delegated_renderer_layer_impl.h" #include "cc/output/delegated_frame_data.h" +#include "cc/quads/render_pass_draw_quad.h" +#include "cc/trees/layer_tree_host.h" namespace cc { @@ -19,7 +21,8 @@ scoped_refptr<DelegatedRendererLayer> DelegatedRendererLayer::Create( DelegatedRendererLayer::DelegatedRendererLayer( DelegatedRendererLayerClient* client) : Layer(), - client_(client) {} + client_(client), + needs_filter_context_(false) {} DelegatedRendererLayer::~DelegatedRendererLayer() {} @@ -41,6 +44,9 @@ void DelegatedRendererLayer::SetLayerTreeHost(LayerTreeHost* host) { // TODO(danakj): Don't need to do this if the last frame commited was empty // or we never commited a frame with resources. SetNextCommitWaitsForActivation(); + } else { + if (needs_filter_context_) + host->set_needs_filter_context(); } Layer::SetLayerTreeHost(host); @@ -99,6 +105,26 @@ void DelegatedRendererLayer::SetFrameData( } else { frame_size_ = gfx::Size(); } + + // If any RenderPassDrawQuad has a filter operation, then we need a filter + // context to draw this layer's content. + for (size_t i = 0; + !needs_filter_context_ && i < frame_data_->render_pass_list.size(); + ++i) { + const QuadList& quad_list = frame_data_->render_pass_list[i]->quad_list; + for (size_t j = 0; !needs_filter_context_ && j < quad_list.size(); ++j) { + if (quad_list[j]->material != DrawQuad::RENDER_PASS) + continue; + const RenderPassDrawQuad* render_pass_quad = + RenderPassDrawQuad::MaterialCast(quad_list[j]); + if (!render_pass_quad->filters.IsEmpty() || + !render_pass_quad->background_filters.IsEmpty()) + needs_filter_context_ = true; + } + } + if (needs_filter_context_ && layer_tree_host()) + layer_tree_host()->set_needs_filter_context(); + SetNeedsCommit(); // The active frame needs to be replaced and resources returned before the // commit is called complete. diff --git a/cc/layers/delegated_renderer_layer.h b/cc/layers/delegated_renderer_layer.h index afee475f..b3a078f 100644 --- a/cc/layers/delegated_renderer_layer.h +++ b/cc/layers/delegated_renderer_layer.h @@ -49,6 +49,7 @@ class CC_EXPORT DelegatedRendererLayer : public Layer { ReturnedResourceArray unused_resources_for_child_compositor_; DelegatedRendererLayerClient* client_; + bool needs_filter_context_; DISALLOW_COPY_AND_ASSIGN(DelegatedRendererLayer); }; diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index 7e8f4f8..241968e 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -22,6 +22,7 @@ #include "skia/ext/opacity_draw_filter.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkShader.h" #include "third_party/skia/include/effects/SkLayerRasterizer.h" diff --git a/cc/quads/render_pass.h b/cc/quads/render_pass.h index 7889829..cf2a02d 100644 --- a/cc/quads/render_pass.h +++ b/cc/quads/render_pass.h @@ -13,8 +13,6 @@ #include "cc/base/cc_export.h" #include "cc/base/scoped_ptr_vector.h" #include "skia/ext/refptr.h" -#include "third_party/skia/include/core/SkColor.h" -#include "third_party/skia/include/core/SkImageFilter.h" #include "ui/gfx/rect.h" #include "ui/gfx/rect_f.h" #include "ui/gfx/transform.h" diff --git a/cc/quads/render_pass_draw_quad.cc b/cc/quads/render_pass_draw_quad.cc index 0528cd5..73b2553 100644 --- a/cc/quads/render_pass_draw_quad.cc +++ b/cc/quads/render_pass_draw_quad.cc @@ -7,6 +7,7 @@ #include "base/values.h" #include "cc/base/math_util.h" #include "cc/debug/traced_value.h" +#include "third_party/skia/include/core/SkImageFilter.h" namespace cc { diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc index ef79fb5..0044f6a 100644 --- a/cc/test/render_pass_test_utils.cc +++ b/cc/test/render_pass_test_utils.cc @@ -12,6 +12,8 @@ #include "cc/resources/resource_provider.h" #include "cc/test/mock_quad_culler.h" #include "cc/test/render_pass_test_common.h" +#include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkImageFilter.h" #include "ui/gfx/rect.h" namespace cc { diff --git a/cc/trees/layer_tree_host_unittest_delegated.cc b/cc/trees/layer_tree_host_unittest_delegated.cc index 3fd040bc..5363d68 100644 --- a/cc/trees/layer_tree_host_unittest_delegated.cc +++ b/cc/trees/layer_tree_host_unittest_delegated.cc @@ -16,6 +16,7 @@ #include "cc/output/compositor_frame.h" #include "cc/output/compositor_frame_ack.h" #include "cc/output/delegated_frame_data.h" +#include "cc/quads/render_pass_draw_quad.h" #include "cc/quads/shared_quad_state.h" #include "cc/quads/texture_draw_quad.h" #include "cc/resources/returned_resource.h" @@ -154,6 +155,39 @@ class LayerTreeHostDelegatedTest : public LayerTreeTest { frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>()); } + void AddRenderPass(DelegatedFrameData* frame, + RenderPass::Id id, + gfx::Rect output_rect, + gfx::Rect damage_rect, + const FilterOperations& filters, + const FilterOperations& background_filters) { + for (size_t i = 0; i < frame->render_pass_list.size(); ++i) + DCHECK(id != frame->render_pass_list[i]->id); + + scoped_ptr<RenderPass> pass(RenderPass::Create()); + pass->SetNew(id, + output_rect, + damage_rect, + gfx::Transform()); + frame->render_pass_list.push_back(pass.Pass()); + + scoped_ptr<SharedQuadState> sqs = SharedQuadState::Create(); + scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create(); + + quad->SetNew(sqs.get(), + output_rect, + id, + false, // is_replica + 0, // mask_resource_id + damage_rect, + gfx::Rect(0, 0, 1, 1), // mask_uv_rect + filters, + skia::RefPtr<SkImageFilter>(), + background_filters); + frame->render_pass_list[0]->shared_quad_state_list.push_back(sqs.Pass()); + frame->render_pass_list[0]->quad_list.push_back(quad.PassAs<DrawQuad>()); + } + scoped_ptr<DelegatedFrameData> CreateEmptyFrameData() { scoped_ptr<DelegatedFrameData> frame(new DelegatedFrameData); return frame.Pass(); @@ -338,6 +372,131 @@ class LayerTreeHostDelegatedTestCreateChildId SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDelegatedTestCreateChildId); +class LayerTreeHostDelegatedTestOffscreenContext_NoFilters + : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { + protected: + virtual void BeginTest() OVERRIDE { + scoped_ptr<DelegatedFrameData> frame = + CreateFrameData(gfx::Rect(0, 0, 1, 1), + gfx::Rect(0, 0, 1, 1)); + delegated_->SetFrameData(frame.Pass()); + + PostSetNeedsCommitToMainThread(); + } + + virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + EXPECT_FALSE(host_impl->offscreen_context_provider()); + EndTest(); + } + + virtual void AfterTest() OVERRIDE {} +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostDelegatedTestOffscreenContext_NoFilters); + +class LayerTreeHostDelegatedTestOffscreenContext_Filters + : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { + protected: + virtual void BeginTest() OVERRIDE { + scoped_ptr<DelegatedFrameData> frame = + CreateFrameData(gfx::Rect(0, 0, 1, 1), + gfx::Rect(0, 0, 1, 1)); + + FilterOperations filters; + filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); + AddRenderPass(frame.get(), + RenderPass::Id(2, 1), + gfx::Rect(0, 0, 1, 1), + gfx::Rect(0, 0, 1, 1), + filters, + FilterOperations()); + delegated_->SetFrameData(frame.Pass()); + + PostSetNeedsCommitToMainThread(); + } + + virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + bool expect_context = !delegating_renderer(); + EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider()); + EndTest(); + } + + virtual void AfterTest() OVERRIDE {} +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostDelegatedTestOffscreenContext_Filters); + +class LayerTreeHostDelegatedTestOffscreenContext_BackgroundFilters + : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { + protected: + virtual void BeginTest() OVERRIDE { + scoped_ptr<DelegatedFrameData> frame = + CreateFrameData(gfx::Rect(0, 0, 1, 1), + gfx::Rect(0, 0, 1, 1)); + + FilterOperations filters; + filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); + AddRenderPass(frame.get(), + RenderPass::Id(2, 1), + gfx::Rect(0, 0, 1, 1), + gfx::Rect(0, 0, 1, 1), + FilterOperations(), + filters); + delegated_->SetFrameData(frame.Pass()); + + PostSetNeedsCommitToMainThread(); + } + + virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + bool expect_context = !delegating_renderer(); + EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider()); + EndTest(); + } + + virtual void AfterTest() OVERRIDE {} +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostDelegatedTestOffscreenContext_BackgroundFilters); + +class LayerTreeHostDelegatedTestOffscreenContext_Filters_AddedToTree + : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { + protected: + virtual void BeginTest() OVERRIDE { + scoped_ptr<DelegatedFrameData> frame = + CreateFrameData(gfx::Rect(0, 0, 1, 1), + gfx::Rect(0, 0, 1, 1)); + + FilterOperations filters; + filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); + AddRenderPass(frame.get(), + RenderPass::Id(2, 1), + gfx::Rect(0, 0, 1, 1), + gfx::Rect(0, 0, 1, 1), + filters, + FilterOperations()); + + delegated_->RemoveFromParent(); + delegated_->SetFrameData(frame.Pass()); + layer_tree_host()->root_layer()->AddChild(delegated_); + + PostSetNeedsCommitToMainThread(); + } + + virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { + bool expect_context = !delegating_renderer(); + EXPECT_EQ(expect_context, !!host_impl->offscreen_context_provider()); + EndTest(); + } + + virtual void AfterTest() OVERRIDE {} +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostDelegatedTestOffscreenContext_Filters_AddedToTree); + class LayerTreeHostDelegatedTestLayerUsesFrameDamage : public LayerTreeHostDelegatedTestCaseSingleDelegatedLayer { public: |