diff options
-rw-r--r-- | cc/layers/append_quads_data.h | 8 | ||||
-rw-r--r-- | cc/layers/tiled_layer.cc | 3 | ||||
-rw-r--r-- | cc/output/direct_renderer.cc | 27 | ||||
-rw-r--r-- | cc/output/direct_renderer.h | 26 | ||||
-rw-r--r-- | cc/output/gl_renderer.cc | 2 | ||||
-rw-r--r-- | cc/output/renderer.cc | 4 | ||||
-rw-r--r-- | cc/output/renderer.h | 1 | ||||
-rw-r--r-- | cc/output/software_renderer.cc | 2 | ||||
-rw-r--r-- | cc/quads/render_pass.cc | 16 | ||||
-rw-r--r-- | cc/quads/render_pass.h | 7 | ||||
-rw-r--r-- | cc/quads/render_pass_unittest.cc | 17 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 36 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.h | 20 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 1499 | ||||
-rw-r--r-- | cc/trees/layer_tree_settings.cc | 4 | ||||
-rw-r--r-- | cc/trees/layer_tree_settings.h | 1 | ||||
-rw-r--r-- | cc/trees/occlusion_tracker.cc | 40 | ||||
-rw-r--r-- | cc/trees/occlusion_tracker.h | 9 | ||||
-rw-r--r-- | cc/trees/occlusion_tracker_unittest.cc | 310 | ||||
-rw-r--r-- | cc/trees/quad_culler.cc | 10 | ||||
-rw-r--r-- | content/common/cc_messages.cc | 8 | ||||
-rw-r--r-- | content/common/cc_messages_unittest.cc | 8 |
22 files changed, 76 insertions, 1982 deletions
diff --git a/cc/layers/append_quads_data.h b/cc/layers/append_quads_data.h index 1ec8184..5e19731 100644 --- a/cc/layers/append_quads_data.h +++ b/cc/layers/append_quads_data.h @@ -12,19 +12,15 @@ namespace cc { struct AppendQuadsData { AppendQuadsData() - : had_occlusion_from_outside_target_surface(false), - had_incomplete_tile(false), + : had_incomplete_tile(false), num_missing_tiles(0), render_pass_id(0, 0) {} explicit AppendQuadsData(RenderPass::Id render_pass_id) - : had_occlusion_from_outside_target_surface(false), - had_incomplete_tile(false), + : had_incomplete_tile(false), num_missing_tiles(0), render_pass_id(render_pass_id) {} - // Set by the QuadCuller. - bool had_occlusion_from_outside_target_surface; // Set by the layer appending quads. bool had_incomplete_tile; // Set by the layer appending quads. diff --git a/cc/layers/tiled_layer.cc b/cc/layers/tiled_layer.cc index 8bbf227..bf4aac9 100644 --- a/cc/layers/tiled_layer.cc +++ b/cc/layers/tiled_layer.cc @@ -380,8 +380,7 @@ void TiledLayer::MarkOcclusionsAndRequestTextures( draw_transform(), draw_transform_is_animating(), is_clipped(), - clip_rect(), - NULL)) { + clip_rect())) { tile->occluded = true; occluded_tile_count++; } else { diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc index bb85de9..d46f46d 100644 --- a/cc/output/direct_renderer.cc +++ b/cc/output/direct_renderer.cc @@ -154,7 +154,7 @@ void DirectRenderer::DecideRenderPassAllocationsForFrame( render_passes_in_draw_order[i]->id, render_passes_in_draw_order[i])); std::vector<RenderPass::Id> passes_to_delete; - base::ScopedPtrHashMap<RenderPass::Id, CachedResource>::const_iterator + base::ScopedPtrHashMap<RenderPass::Id, ScopedResource>::const_iterator pass_iter; for (pass_iter = render_pass_textures_.begin(); pass_iter != render_pass_textures_.end(); @@ -170,7 +170,7 @@ void DirectRenderer::DecideRenderPassAllocationsForFrame( gfx::Size required_size = RenderPassTextureSize(render_pass_in_frame); ResourceFormat required_format = RenderPassTextureFormat(render_pass_in_frame); - CachedResource* texture = pass_iter->second; + ScopedResource* texture = pass_iter->second; DCHECK(texture); bool size_appropriate = texture->size().width() >= required_size.width() && @@ -187,8 +187,8 @@ void DirectRenderer::DecideRenderPassAllocationsForFrame( for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) { if (!render_pass_textures_.contains(render_passes_in_draw_order[i]->id)) { - scoped_ptr<CachedResource> texture = - CachedResource::Create(resource_provider_); + scoped_ptr<ScopedResource> texture = + ScopedResource::create(resource_provider_); render_pass_textures_.set(render_passes_in_draw_order[i]->id, texture.Pass()); } @@ -381,12 +381,6 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame, DoDrawQuad(frame, *it); } FinishDrawingQuadList(); - - CachedResource* texture = render_pass_textures_.get(render_pass->id); - if (texture) { - texture->set_is_complete( - !render_pass->has_occlusion_from_outside_target_surface); - } } bool DirectRenderer::UseRenderPass(DrawingFrame* frame, @@ -406,7 +400,7 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame, if (!resource_provider_) return false; - CachedResource* texture = render_pass_textures_.get(render_pass->id); + ScopedResource* texture = render_pass_textures_.get(render_pass->id); DCHECK(texture); gfx::Size size = RenderPassTextureSize(render_pass); @@ -421,18 +415,9 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame, return BindFramebufferToTexture(frame, texture, render_pass->output_rect); } -bool DirectRenderer::HaveCachedResourcesForRenderPassId(RenderPass::Id id) - const { - if (!settings_->cache_render_pass_contents) - return false; - - CachedResource* texture = render_pass_textures_.get(id); - return texture && texture->id() && texture->is_complete(); -} - bool DirectRenderer::HasAllocatedResourcesForTesting(RenderPass::Id id) const { - CachedResource* texture = render_pass_textures_.get(id); + ScopedResource* texture = render_pass_textures_.get(id); return texture && texture->id(); } diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h index dcb0426..a73c62d 100644 --- a/cc/output/direct_renderer.h +++ b/cc/output/direct_renderer.h @@ -29,8 +29,6 @@ class CC_EXPORT DirectRenderer : public Renderer { virtual bool CanReadPixels() const OVERRIDE; virtual void DecideRenderPassAllocationsForFrame( const RenderPassList& render_passes_in_draw_order) OVERRIDE; - virtual bool HaveCachedResourcesForRenderPassId(RenderPass::Id id) const - OVERRIDE; virtual bool HasAllocatedResourcesForTesting(RenderPass::Id id) const OVERRIDE; virtual void DrawFrame(RenderPassList* render_passes_in_draw_order, @@ -62,28 +60,6 @@ class CC_EXPORT DirectRenderer : public Renderer { OutputSurface* output_surface, ResourceProvider* resource_provider); - class CachedResource : public ScopedResource { - public: - static scoped_ptr<CachedResource> Create( - ResourceProvider* resource_provider) { - return make_scoped_ptr(new CachedResource(resource_provider)); - } - virtual ~CachedResource() {} - - bool is_complete() const { return is_complete_; } - void set_is_complete(bool is_complete) { is_complete_ = is_complete; } - - protected: - explicit CachedResource(ResourceProvider* resource_provider) - : ScopedResource(resource_provider), - is_complete_(false) {} - - private: - bool is_complete_; - - DISALLOW_COPY_AND_ASSIGN(CachedResource); - }; - static gfx::RectF QuadVertexRect(); static void QuadRectTransform(gfx::Transform* quad_rect_transform, const gfx::Transform& quad_transform, @@ -138,7 +114,7 @@ class CC_EXPORT DirectRenderer : public Renderer { DrawingFrame* frame, scoped_ptr<CopyOutputRequest> request) = 0; - base::ScopedPtrHashMap<RenderPass::Id, CachedResource> render_pass_textures_; + base::ScopedPtrHashMap<RenderPass::Id, ScopedResource> render_pass_textures_; OutputSurface* output_surface_; ResourceProvider* resource_provider_; diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 99c4573..68fb456 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -732,7 +732,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, const RenderPassDrawQuad* quad) { SetBlendEnabled(quad->ShouldDrawWithBlending()); - CachedResource* contents_texture = + ScopedResource* contents_texture = render_pass_textures_.get(quad->render_pass_id); if (!contents_texture || !contents_texture->id()) return; diff --git a/cc/output/renderer.cc b/cc/output/renderer.cc index bec001b..2fe0ef7 100644 --- a/cc/output/renderer.cc +++ b/cc/output/renderer.cc @@ -6,10 +6,6 @@ namespace cc { -bool Renderer::HaveCachedResourcesForRenderPassId(RenderPass::Id id) const { - return false; -} - bool Renderer::HasAllocatedResourcesForTesting(RenderPass::Id id) const { return false; } diff --git a/cc/output/renderer.h b/cc/output/renderer.h index 59d41f4..b3ff65b 100644 --- a/cc/output/renderer.h +++ b/cc/output/renderer.h @@ -42,7 +42,6 @@ class CC_EXPORT Renderer { virtual void DecideRenderPassAllocationsForFrame( const RenderPassList& render_passes_in_draw_order) {} - virtual bool HaveCachedResourcesForRenderPassId(RenderPass::Id id) const; virtual bool HasAllocatedResourcesForTesting(RenderPass::Id id) const; // This passes ownership of the render passes to the renderer. It should diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index ace1b30..86d35c6 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -415,7 +415,7 @@ void SoftwareRenderer::DrawTileQuad(const DrawingFrame* frame, void SoftwareRenderer::DrawRenderPassQuad(const DrawingFrame* frame, const RenderPassDrawQuad* quad) { - CachedResource* content_texture = + ScopedResource* content_texture = render_pass_textures_.get(quad->render_pass_id); if (!content_texture || !content_texture->id()) return; diff --git a/cc/quads/render_pass.cc b/cc/quads/render_pass.cc index 485898d..e61a463 100644 --- a/cc/quads/render_pass.cc +++ b/cc/quads/render_pass.cc @@ -26,8 +26,7 @@ scoped_ptr<RenderPass> RenderPass::Create() { RenderPass::RenderPass() : id(Id(-1, -1)), - has_transparent_background(true), - has_occlusion_from_outside_target_surface(false) {} + has_transparent_background(true) {} RenderPass::~RenderPass() { TRACE_EVENT_OBJECT_DELETED_WITH_ID( @@ -41,8 +40,7 @@ scoped_ptr<RenderPass> RenderPass::Copy(Id new_id) const { output_rect, damage_rect, transform_to_root_target, - has_transparent_background, - has_occlusion_from_outside_target_surface); + has_transparent_background); return copy_pass.Pass(); } @@ -61,8 +59,7 @@ void RenderPass::CopyAll(const ScopedPtrVector<RenderPass>& in, source->output_rect, source->damage_rect, source->transform_to_root_target, - source->has_transparent_background, - source->has_occlusion_from_outside_target_surface); + source->has_transparent_background); for (size_t i = 0; i < source->shared_quad_state_list.size(); ++i) { copy_pass->shared_quad_state_list.push_back( source->shared_quad_state_list[i]->Copy()); @@ -112,8 +109,7 @@ void RenderPass::SetAll(Id id, gfx::Rect output_rect, gfx::RectF damage_rect, const gfx::Transform& transform_to_root_target, - bool has_transparent_background, - bool has_occlusion_from_outside_target_surface) { + bool has_transparent_background) { DCHECK_GT(id.layer_id, 0); DCHECK_GE(id.index, 0); @@ -122,8 +118,6 @@ void RenderPass::SetAll(Id id, this->damage_rect = damage_rect; this->transform_to_root_target = transform_to_root_target; this->has_transparent_background = has_transparent_background; - this->has_occlusion_from_outside_target_surface = - has_occlusion_from_outside_target_surface; DCHECK(quad_list.empty()); DCHECK(shared_quad_state_list.empty()); @@ -134,8 +128,6 @@ scoped_ptr<base::Value> RenderPass::AsValue() const { value->Set("output_rect", MathUtil::AsValue(output_rect).release()); value->Set("damage_rect", MathUtil::AsValue(damage_rect).release()); value->SetBoolean("has_transparent_background", has_transparent_background); - value->SetBoolean("has_occlusion_from_outside_target_surface", - has_occlusion_from_outside_target_surface); value->SetInteger("copy_requests", copy_requests.size()); scoped_ptr<base::ListValue> shared_states_value(new base::ListValue()); for (size_t i = 0; i < shared_quad_state_list.size(); ++i) { diff --git a/cc/quads/render_pass.h b/cc/quads/render_pass.h index fdeefb9..c6a81af 100644 --- a/cc/quads/render_pass.h +++ b/cc/quads/render_pass.h @@ -83,8 +83,7 @@ class CC_EXPORT RenderPass { gfx::Rect output_rect, gfx::RectF damage_rect, const gfx::Transform& transform_to_root_target, - bool has_transparent_background, - bool has_occlusion_from_outside_target_surface); + bool has_transparent_background); scoped_ptr<base::Value> AsValue() const; @@ -102,10 +101,6 @@ class CC_EXPORT RenderPass { // If false, the pixels in the render pass' texture are all opaque. bool has_transparent_background; - // If true, then there may be pixels in the render pass' texture that are not - // complete, since they are occluded. - bool has_occlusion_from_outside_target_surface; - // If non-empty, the renderer should produce a copy of the render pass' // contents as a bitmap, and give a copy of the bitmap to each callback in // this list. This property should not be serialized between compositors, as diff --git a/cc/quads/render_pass_unittest.cc b/cc/quads/render_pass_unittest.cc index 5dfe39c..259ecad 100644 --- a/cc/quads/render_pass_unittest.cc +++ b/cc/quads/render_pass_unittest.cc @@ -30,7 +30,6 @@ struct RenderPassSize { gfx::Rect output_rect; gfx::RectF damage_rect; bool has_transparent_background; - bool has_occlusion_from_outside_target_surface; ScopedPtrVector<CopyOutputRequest> copy_callbacks; }; @@ -41,15 +40,13 @@ TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) { gfx::Transform(1.0, 0.5, 0.5, -0.5, -1.0, 0.0); gfx::Rect damage_rect(56, 123, 19, 43); bool has_transparent_background = true; - bool has_occlusion_from_outside_target_surface = true; scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); pass->SetAll(id, output_rect, damage_rect, transform_to_root, - has_transparent_background, - has_occlusion_from_outside_target_surface); + has_transparent_background); pass->copy_requests.push_back(CopyOutputRequest::CreateEmptyRequest()); // Stick a quad in the pass, this should not get copied. @@ -72,8 +69,6 @@ TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) { EXPECT_EQ(pass->transform_to_root_target, copy->transform_to_root_target); EXPECT_RECT_EQ(pass->damage_rect, copy->damage_rect); EXPECT_EQ(pass->has_transparent_background, copy->has_transparent_background); - EXPECT_EQ(pass->has_occlusion_from_outside_target_surface, - copy->has_occlusion_from_outside_target_surface); EXPECT_EQ(0u, copy->quad_list.size()); // The copy request should not be copied/duplicated. @@ -92,15 +87,13 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) { gfx::Transform(1.0, 0.5, 0.5, -0.5, -1.0, 0.0); gfx::Rect damage_rect(56, 123, 19, 43); bool has_transparent_background = true; - bool has_occlusion_from_outside_target_surface = true; scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); pass->SetAll(id, output_rect, damage_rect, transform_to_root, - has_transparent_background, - has_occlusion_from_outside_target_surface); + has_transparent_background); // Two quads using one shared state. scoped_ptr<SharedQuadState> shared_state1 = SharedQuadState::Create(); @@ -145,15 +138,13 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) { gfx::Transform(1.0, 0.5, 0.5, -0.5, -1.0, 0.0); gfx::Rect contrib_damage_rect(11, 16, 10, 15); bool contrib_has_transparent_background = true; - bool contrib_has_occlusion_from_outside_target_surface = true; scoped_ptr<TestRenderPass> contrib = TestRenderPass::Create(); contrib->SetAll(contrib_id, contrib_output_rect, contrib_damage_rect, contrib_transform_to_root, - contrib_has_transparent_background, - contrib_has_occlusion_from_outside_target_surface); + contrib_has_transparent_background); scoped_ptr<SharedQuadState> contrib_shared_state = SharedQuadState::Create(); contrib_shared_state->SetAll( @@ -197,8 +188,6 @@ TEST(RenderPassTest, CopyAllShouldBeIdentical) { EXPECT_RECT_EQ(pass->damage_rect, copy->damage_rect); EXPECT_EQ(pass->has_transparent_background, copy->has_transparent_background); - EXPECT_EQ(pass->has_occlusion_from_outside_target_surface, - copy->has_occlusion_from_outside_target_surface); EXPECT_EQ(pass->shared_quad_state_list.size(), copy->shared_quad_state_list.size()); diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 60272111..461e1d6 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -762,19 +762,15 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { &append_quads_data); } else if (it.represents_itself() && !it->visible_content_rect().IsEmpty()) { - bool has_occlusion_from_outside_target_surface; bool impl_draw_transform_is_unknown = false; - if (occlusion_tracker.Occluded( + bool occluded = occlusion_tracker.Occluded( it->render_target(), it->visible_content_rect(), it->draw_transform(), impl_draw_transform_is_unknown, it->is_clipped(), - it->clip_rect(), - &has_occlusion_from_outside_target_surface)) { - append_quads_data.had_occlusion_from_outside_target_surface |= - has_occlusion_from_outside_target_surface; - } else if (it->WillDraw(draw_mode, resource_provider_.get())) { + it->clip_rect()); + if (!occluded && it->WillDraw(draw_mode, resource_provider_.get())) { DCHECK_EQ(active_tree_, it->layer_tree_impl()); frame->will_draw_layers.push_back(*it); @@ -807,9 +803,6 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { ++layers_drawn; } - if (append_quads_data.had_occlusion_from_outside_target_surface) - target_render_pass->has_occlusion_from_outside_target_surface = true; - if (append_quads_data.num_missing_tiles) { rendering_stats_instrumentation_->AddMissingTiles( append_quads_data.num_missing_tiles); @@ -860,8 +853,6 @@ bool LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { RemoveRenderPasses(CullRenderPassesWithNoQuads(), frame); renderer_->DecideRenderPassAllocationsForFrame(frame->render_passes); - RemoveRenderPasses(CullRenderPassesWithCachedTextures(renderer_.get()), - frame); // Any copy requests left in the tree are not going to get serviced, and // should be aborted. @@ -959,24 +950,6 @@ static void RemoveRenderPassesRecursive(RenderPass::Id remove_render_pass_id, } } -bool LayerTreeHostImpl::CullRenderPassesWithCachedTextures:: - ShouldRemoveRenderPass(const RenderPassDrawQuad& quad, - const FrameData& frame) const { - DCHECK(renderer_); - bool quad_has_damage = !quad.contents_changed_since_last_frame.IsEmpty(); - bool quad_has_cached_resource = - renderer_->HaveCachedResourcesForRenderPassId(quad.render_pass_id); - if (quad_has_damage) { - TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have damage"); - return false; - } else if (!quad_has_cached_resource) { - TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures have no texture"); - return false; - } - TRACE_EVENT0("cc", "CullRenderPassesWithCachedTextures dropped!"); - return true; -} - bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass( const RenderPassDrawQuad& quad, const FrameData& frame) const { const RenderPass* render_pass = @@ -1005,9 +978,6 @@ bool LayerTreeHostImpl::CullRenderPassesWithNoQuads::ShouldRemoveRenderPass( // Defined for linking tests. template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses< - LayerTreeHostImpl::CullRenderPassesWithCachedTextures>( - CullRenderPassesWithCachedTextures culler, FrameData* frame); -template CC_EXPORT void LayerTreeHostImpl::RemoveRenderPasses< LayerTreeHostImpl::CullRenderPassesWithNoQuads>( CullRenderPassesWithNoQuads culler, FrameData*); diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 14766a0..d71a0aa 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h @@ -345,26 +345,6 @@ class CC_EXPORT LayerTreeHostImpl void SetDebugState(const LayerTreeDebugState& new_debug_state); const LayerTreeDebugState& debug_state() const { return debug_state_; } - class CC_EXPORT CullRenderPassesWithCachedTextures { - public: - bool ShouldRemoveRenderPass(const RenderPassDrawQuad& quad, - const FrameData& frame) const; - - // Iterates from the root first, in order to remove the surfaces closest - // to the root with cached textures, and all surfaces that draw into - // them. - size_t RenderPassListBegin(const RenderPassList& list) const { - return list.size() - 1; - } - size_t RenderPassListEnd(const RenderPassList& list) const { return 0 - 1; } - size_t RenderPassListNext(size_t it) const { return it - 1; } - - explicit CullRenderPassesWithCachedTextures(Renderer* renderer) - : renderer_(renderer) {} - private: - Renderer* renderer_; - }; - class CC_EXPORT CullRenderPassesWithNoQuads { public: bool ShouldRemoveRenderPass(const RenderPassDrawQuad& quad, diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 2ce764d..65c6454 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -4000,1113 +4000,6 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { Mock::VerifyAndClearExpectations(&mock_context); } -static void AddDrawingLayerTo(LayerImpl* parent, - int id, - gfx::Rect layer_rect, - LayerImpl** result) { - scoped_ptr<LayerImpl> layer = - FakeLayerWithQuads::Create(parent->layer_tree_impl(), id); - LayerImpl* layer_ptr = layer.get(); - layer_ptr->SetAnchorPoint(gfx::PointF()); - layer_ptr->SetPosition(gfx::PointF(layer_rect.origin())); - layer_ptr->SetBounds(layer_rect.size()); - layer_ptr->SetContentBounds(layer_rect.size()); - layer_ptr->SetDrawsContent(true); // only children draw content - layer_ptr->SetContentsOpaque(true); - parent->AddChild(layer.Pass()); - if (result) - *result = layer_ptr; -} - -static void SetupLayersForTextureCaching( - LayerTreeHostImpl* layer_tree_host_impl, - LayerImpl*& root_ptr, - LayerImpl*& intermediate_layer_ptr, - LayerImpl*& surface_layer_ptr, - LayerImpl*& child_ptr, - gfx::Size root_size) { - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext))); - - layer_tree_host_impl->InitializeRenderer(output_surface.Pass()); - layer_tree_host_impl->SetViewportSize(root_size); - - scoped_ptr<LayerImpl> root = - LayerImpl::Create(layer_tree_host_impl->active_tree(), 1); - root_ptr = root.get(); - - root->SetAnchorPoint(gfx::PointF()); - root->SetPosition(gfx::PointF()); - root->SetBounds(root_size); - root->SetContentBounds(root_size); - root->SetDrawsContent(true); - layer_tree_host_impl->active_tree()->SetRootLayer(root.Pass()); - - AddDrawingLayerTo(root_ptr, - 2, - gfx::Rect(10, 10, root_size.width(), root_size.height()), - &intermediate_layer_ptr); - // Only children draw content. - intermediate_layer_ptr->SetDrawsContent(false); - - // Surface layer is the layer that changes its opacity - // It will contain other layers that draw content. - AddDrawingLayerTo(intermediate_layer_ptr, - 3, - gfx::Rect(10, 10, root_size.width(), root_size.height()), - &surface_layer_ptr); - // Only children draw content. - surface_layer_ptr->SetDrawsContent(false); - surface_layer_ptr->SetOpacity(0.5f); - surface_layer_ptr->SetForceRenderSurface(true); - - // Child of the surface layer will produce some quads - AddDrawingLayerTo(surface_layer_ptr, - 4, - gfx::Rect(5, - 5, - root_size.width() - 25, - root_size.height() - 25), - &child_ptr); -} - -class GLRendererWithReleaseTextures : public GLRenderer { - public: - using GLRenderer::ReleaseRenderPassTextures; -}; - -TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusion) { - LayerTreeSettings settings; - settings.minimum_occlusion_tracking_size = gfx::Size(); - settings.cache_render_pass_contents = true; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); - - // Layers are structure as follows: - // - // R +-- S1 +- L10 (owning) - // | +- L11 - // | +- L12 - // | - // +-- S2 +- L20 (owning) - // +- L21 - // - // Occlusion: - // L12 occludes L11 (internal) - // L20 occludes L10 (external) - // L21 occludes L20 (internal) - - LayerImpl* root_ptr; - LayerImpl* layer_s1_ptr; - LayerImpl* layer_s2_ptr; - - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext))); - - gfx::Size root_size(1000, 1000); - - my_host_impl->InitializeRenderer(output_surface.Pass()); - my_host_impl->SetViewportSize(root_size); - - scoped_ptr<LayerImpl> root = - LayerImpl::Create(my_host_impl->active_tree(), 1); - root_ptr = root.get(); - - root->SetAnchorPoint(gfx::PointF()); - root->SetPosition(gfx::PointF()); - root->SetBounds(root_size); - root->SetContentBounds(root_size); - root->SetDrawsContent(true); - root->SetMasksToBounds(true); - my_host_impl->active_tree()->SetRootLayer(root.Pass()); - - AddDrawingLayerTo(root_ptr, 2, gfx::Rect(300, 300, 300, 300), &layer_s1_ptr); - layer_s1_ptr->SetForceRenderSurface(true); - - AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(10, 10, 10, 10), 0); // L11 - AddDrawingLayerTo(layer_s1_ptr, 4, gfx::Rect(0, 0, 30, 30), 0); // L12 - - AddDrawingLayerTo(root_ptr, 5, gfx::Rect(550, 250, 300, 400), &layer_s2_ptr); - layer_s2_ptr->SetForceRenderSurface(true); - - AddDrawingLayerTo(layer_s2_ptr, 6, gfx::Rect(20, 20, 5, 5), 0); // L21 - - // Initial draw - must receive all quads - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 3 render passes. - // For Root, there are 2 quads; for S1, there are 2 quads (1 is occluded); - // for S2, there is 2 quads. - ASSERT_EQ(3U, frame.render_passes.size()); - - EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size()); - EXPECT_EQ(2U, frame.render_passes[2]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // "Unocclude" surface S1 and repeat draw. - // Must remove S2's render pass since it's cached; - // Must keep S1 quads because texture contained external occlusion. - gfx::Transform transform = layer_s2_ptr->transform(); - transform.Translate(150.0, 150.0); - layer_s2_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 2 render passes. - // For Root, there are 2 quads - // For S1, the number of quads depends on what got unoccluded, so not - // asserted beyond being positive. - // For S2, there is no render pass - ASSERT_EQ(2U, frame.render_passes.size()); - - EXPECT_GT(frame.render_passes[0]->quad_list.size(), 0U); - EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // "Re-occlude" surface S1 and repeat draw. - // Must remove S1's render pass since it is now available in full. - // S2 has no change so must also be removed. - transform = layer_s2_ptr->transform(); - transform.Translate(-15.0, -15.0); - layer_s2_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 1 render pass - for the root. - ASSERT_EQ(1U, frame.render_passes.size()); - - EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } -} - -TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionEarlyOut) { - LayerTreeSettings settings; - settings.minimum_occlusion_tracking_size = gfx::Size(); - settings.cache_render_pass_contents = true; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); - - // Layers are structure as follows: - // - // R +-- S1 +- L10 (owning, non drawing) - // | +- L11 (corner, unoccluded) - // | +- L12 (corner, unoccluded) - // | +- L13 (corner, unoccluded) - // | +- L14 (corner, entirely occluded) - // | - // +-- S2 +- L20 (owning, drawing) - // - - LayerImpl* root_ptr; - LayerImpl* layer_s1_ptr; - LayerImpl* layer_s2_ptr; - - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext))); - - gfx::Size root_size(1000, 1000); - - my_host_impl->InitializeRenderer(output_surface.Pass()); - my_host_impl->SetViewportSize(root_size); - - scoped_ptr<LayerImpl> root = - LayerImpl::Create(my_host_impl->active_tree(), 1); - root_ptr = root.get(); - - root->SetAnchorPoint(gfx::PointF()); - root->SetPosition(gfx::PointF()); - root->SetBounds(root_size); - root->SetContentBounds(root_size); - root->SetDrawsContent(true); - root->SetMasksToBounds(true); - my_host_impl->active_tree()->SetRootLayer(root.Pass()); - - AddDrawingLayerTo(root_ptr, 2, gfx::Rect(0, 0, 800, 800), &layer_s1_ptr); - layer_s1_ptr->SetForceRenderSurface(true); - layer_s1_ptr->SetDrawsContent(false); - - AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(0, 0, 300, 300), 0); // L11 - AddDrawingLayerTo(layer_s1_ptr, 4, gfx::Rect(0, 500, 300, 300), 0); // L12 - AddDrawingLayerTo(layer_s1_ptr, 5, gfx::Rect(500, 0, 300, 300), 0); // L13 - AddDrawingLayerTo(layer_s1_ptr, 6, gfx::Rect(500, 500, 300, 300), 0); // L14 - AddDrawingLayerTo(layer_s1_ptr, 9, gfx::Rect(500, 500, 300, 300), 0); // L14 - - AddDrawingLayerTo(root_ptr, 7, gfx::Rect(450, 450, 450, 450), &layer_s2_ptr); - layer_s2_ptr->SetForceRenderSurface(true); - - // Initial draw - must receive all quads - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 3 render passes. - // For Root, there are 2 quads; for S1, there are 3 quads; for S2, there is - // 1 quad. - ASSERT_EQ(3U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - - // L14 is culled, so only 3 quads. - EXPECT_EQ(3U, frame.render_passes[1]->quad_list.size()); - EXPECT_EQ(2U, frame.render_passes[2]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // "Unocclude" surface S1 and repeat draw. - // Must remove S2's render pass since it's cached; - // Must keep S1 quads because texture contained external occlusion. - gfx::Transform transform = layer_s2_ptr->transform(); - transform.Translate(100.0, 100.0); - layer_s2_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 2 render passes. - // For Root, there are 2 quads - // For S1, the number of quads depends on what got unoccluded, so not - // asserted beyond being positive. - // For S2, there is no render pass - ASSERT_EQ(2U, frame.render_passes.size()); - - EXPECT_GT(frame.render_passes[0]->quad_list.size(), 0U); - EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // "Re-occlude" surface S1 and repeat draw. - // Must remove S1's render pass since it is now available in full. - // S2 has no change so must also be removed. - transform = layer_s2_ptr->transform(); - transform.Translate(-15.0, -15.0); - layer_s2_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 1 render pass - for the root. - ASSERT_EQ(1U, frame.render_passes.size()); - - EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } -} - -TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionExternalOverInternal) { - LayerTreeSettings settings; - settings.minimum_occlusion_tracking_size = gfx::Size(); - settings.cache_render_pass_contents = true; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); - - // Layers are structured as follows: - // - // R +-- S1 +- L10 (owning, drawing) - // | +- L11 (corner, occluded by L12) - // | +- L12 (opposite corner) - // | - // +-- S2 +- L20 (owning, drawing) - // - - LayerImpl* root_ptr; - LayerImpl* layer_s1_ptr; - LayerImpl* layer_s2_ptr; - - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext))); - - gfx::Size root_size(1000, 1000); - - my_host_impl->InitializeRenderer(output_surface.Pass()); - my_host_impl->SetViewportSize(root_size); - - scoped_ptr<LayerImpl> root = - LayerImpl::Create(my_host_impl->active_tree(), 1); - root_ptr = root.get(); - - root->SetAnchorPoint(gfx::PointF()); - root->SetPosition(gfx::PointF()); - root->SetBounds(root_size); - root->SetContentBounds(root_size); - root->SetDrawsContent(true); - root->SetMasksToBounds(true); - my_host_impl->active_tree()->SetRootLayer(root.Pass()); - - AddDrawingLayerTo(root_ptr, 2, gfx::Rect(0, 0, 400, 400), &layer_s1_ptr); - layer_s1_ptr->SetForceRenderSurface(true); - - AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(0, 0, 300, 300), 0); // L11 - AddDrawingLayerTo(layer_s1_ptr, 4, gfx::Rect(100, 0, 300, 300), 0); // L12 - - AddDrawingLayerTo(root_ptr, 7, gfx::Rect(200, 0, 300, 300), &layer_s2_ptr); - layer_s2_ptr->SetForceRenderSurface(true); - - // Initial draw - must receive all quads - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 3 render passes. - // For Root, there are 2 quads; for S1, there are 3 quads; for S2, there is - // 1 quad. - ASSERT_EQ(3U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(3U, frame.render_passes[1]->quad_list.size()); - EXPECT_EQ(2U, frame.render_passes[2]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // "Unocclude" surface S1 and repeat draw. - // Must remove S2's render pass since it's cached; - // Must keep S1 quads because texture contained external occlusion. - gfx::Transform transform = layer_s2_ptr->transform(); - transform.Translate(300.0, 0.0); - layer_s2_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 2 render passes. - // For Root, there are 2 quads - // For S1, the number of quads depends on what got unoccluded, so not - // asserted beyond being positive. - // For S2, there is no render pass - ASSERT_EQ(2U, frame.render_passes.size()); - - EXPECT_GT(frame.render_passes[0]->quad_list.size(), 0U); - EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } -} - -TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionExternalNotAligned) { - LayerTreeSettings settings; - settings.cache_render_pass_contents = true; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); - - // Layers are structured as follows: - // - // R +-- S1 +- L10 (rotated, drawing) - // +- L11 (occupies half surface) - - LayerImpl* root_ptr; - LayerImpl* layer_s1_ptr; - - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext))); - - gfx::Size root_size(1000, 1000); - - my_host_impl->InitializeRenderer(output_surface.Pass()); - my_host_impl->SetViewportSize(root_size); - - scoped_ptr<LayerImpl> root = - LayerImpl::Create(my_host_impl->active_tree(), 1); - root_ptr = root.get(); - - root->SetAnchorPoint(gfx::PointF()); - root->SetPosition(gfx::PointF()); - root->SetBounds(root_size); - root->SetContentBounds(root_size); - root->SetDrawsContent(true); - root->SetMasksToBounds(true); - my_host_impl->active_tree()->SetRootLayer(root.Pass()); - - AddDrawingLayerTo(root_ptr, 2, gfx::Rect(0, 0, 400, 400), &layer_s1_ptr); - layer_s1_ptr->SetForceRenderSurface(true); - gfx::Transform transform = layer_s1_ptr->transform(); - transform.Translate(200.0, 200.0); - transform.Rotate(45.0); - transform.Translate(-200.0, -200.0); - layer_s1_ptr->SetTransform(transform); - - AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(200, 0, 200, 400), 0); // L11 - - // Initial draw - must receive all quads - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 2 render passes. - ASSERT_EQ(2U, frame.render_passes.size()); - - EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change opacity and draw. Verify we used cached texture. - layer_s1_ptr->SetOpacity(0.2f); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // One render pass must be gone due to cached texture. - ASSERT_EQ(1U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } -} - -TEST_F(LayerTreeHostImplTest, TextureCachingWithOcclusionPartialSwap) { - LayerTreeSettings settings; - settings.minimum_occlusion_tracking_size = gfx::Size(); - settings.partial_swap_enabled = true; - settings.cache_render_pass_contents = true; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); - - // Layers are structure as follows: - // - // R +-- S1 +- L10 (owning) - // | +- L11 - // | +- L12 - // | - // +-- S2 +- L20 (owning) - // +- L21 - // - // Occlusion: - // L12 occludes L11 (internal) - // L20 occludes L10 (external) - // L21 occludes L20 (internal) - - LayerImpl* root_ptr; - LayerImpl* layer_s1_ptr; - LayerImpl* layer_s2_ptr; - - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext))); - - gfx::Size root_size(1000, 1000); - - my_host_impl->InitializeRenderer(output_surface.Pass()); - my_host_impl->SetViewportSize(root_size); - - scoped_ptr<LayerImpl> root = - LayerImpl::Create(my_host_impl->active_tree(), 1); - root_ptr = root.get(); - - root->SetAnchorPoint(gfx::PointF()); - root->SetPosition(gfx::PointF()); - root->SetBounds(root_size); - root->SetContentBounds(root_size); - root->SetDrawsContent(true); - root->SetMasksToBounds(true); - my_host_impl->active_tree()->SetRootLayer(root.Pass()); - - AddDrawingLayerTo(root_ptr, 2, gfx::Rect(300, 300, 300, 300), &layer_s1_ptr); - layer_s1_ptr->SetForceRenderSurface(true); - - AddDrawingLayerTo(layer_s1_ptr, 3, gfx::Rect(10, 10, 10, 10), 0); // L11 - AddDrawingLayerTo(layer_s1_ptr, 4, gfx::Rect(0, 0, 30, 30), 0); // L12 - - AddDrawingLayerTo(root_ptr, 5, gfx::Rect(550, 250, 300, 400), &layer_s2_ptr); - layer_s2_ptr->SetForceRenderSurface(true); - - AddDrawingLayerTo(layer_s2_ptr, 6, gfx::Rect(20, 20, 5, 5), 0); // L21 - - // Initial draw - must receive all quads - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 3 render passes. - // For Root, there are 2 quads; for S1, there are 2 quads (one is occluded); - // for S2, there is 2 quads. - ASSERT_EQ(3U, frame.render_passes.size()); - - EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size()); - EXPECT_EQ(2U, frame.render_passes[2]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // "Unocclude" surface S1 and repeat draw. - // Must remove S2's render pass since it's cached; - // Must keep S1 quads because texture contained external occlusion. - gfx::Transform transform = layer_s2_ptr->transform(); - transform.Translate(150.0, 150.0); - layer_s2_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive 2 render passes. - // For Root, there are 2 quads. - // For S1, there are 2 quads. - // For S2, there is no render pass - ASSERT_EQ(2U, frame.render_passes.size()); - - EXPECT_EQ(2U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(2U, frame.render_passes[1]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // "Re-occlude" surface S1 and repeat draw. - // Must remove S1's render pass since it is now available in full. - // S2 has no change so must also be removed. - transform = layer_s2_ptr->transform(); - transform.Translate(-15.0, -15.0); - layer_s2_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Root render pass only. - ASSERT_EQ(1U, frame.render_passes.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } -} - -TEST_F(LayerTreeHostImplTest, TextureCachingWithScissor) { - LayerTreeSettings settings; - settings.minimum_occlusion_tracking_size = gfx::Size(); - settings.cache_render_pass_contents = true; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); - - /* - Layers are created as follows: - - +--------------------+ - | 1 | - | +-----------+ | - | | 2 | | - | | +-------------------+ - | | | 3 | - | | +-------------------+ - | | | | - | +-----------+ | - | | - | | - +--------------------+ - - Layers 1, 2 have render surfaces - */ - scoped_ptr<LayerImpl> root = - LayerImpl::Create(my_host_impl->active_tree(), 1); - scoped_ptr<TiledLayerImpl> child = - TiledLayerImpl::Create(my_host_impl->active_tree(), 2); - scoped_ptr<LayerImpl> grand_child = - LayerImpl::Create(my_host_impl->active_tree(), 3); - - gfx::Rect root_rect(0, 0, 100, 100); - gfx::Rect child_rect(10, 10, 50, 50); - gfx::Rect grand_child_rect(5, 5, 150, 150); - - scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - scoped_ptr<TestWebGraphicsContext3D>(new PartialSwapContext))); - my_host_impl->InitializeRenderer(output_surface.Pass()); - - root->SetAnchorPoint(gfx::PointF()); - root->SetPosition(gfx::PointF(root_rect.x(), root_rect.y())); - root->SetBounds(gfx::Size(root_rect.width(), root_rect.height())); - root->SetContentBounds(root->bounds()); - root->SetDrawsContent(true); - root->SetMasksToBounds(true); - - child->SetAnchorPoint(gfx::PointF()); - child->SetPosition(gfx::PointF(child_rect.x(), child_rect.y())); - child->SetOpacity(0.5f); - child->SetBounds(gfx::Size(child_rect.width(), child_rect.height())); - child->SetContentBounds(child->bounds()); - child->SetDrawsContent(true); - child->set_skips_draw(false); - - // child layer has 10x10 tiles. - scoped_ptr<LayerTilingData> tiler = - LayerTilingData::Create(gfx::Size(10, 10), - LayerTilingData::HAS_BORDER_TEXELS); - tiler->SetBounds(child->content_bounds()); - child->SetTilingData(*tiler.get()); - - grand_child->SetAnchorPoint(gfx::PointF()); - grand_child->SetPosition(grand_child_rect.origin()); - grand_child->SetBounds(grand_child_rect.size()); - grand_child->SetContentBounds(grand_child->bounds()); - grand_child->SetDrawsContent(true); - - TiledLayerImpl* child_ptr = child.get(); - RenderPass::Id child_pass_id(child_ptr->id(), 0); - - child->AddChild(grand_child.Pass()); - root->AddChild(child.PassAs<LayerImpl>()); - my_host_impl->active_tree()->SetRootLayer(root.Pass()); - my_host_impl->SetViewportSize(root_rect.size()); - - EXPECT_FALSE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId( - child_pass_id)); - { - LayerTreeHostImpl::FrameData frame; - host_impl_->SetFullRootLayerDamage(); - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // We should have cached textures for surface 2. - EXPECT_TRUE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId( - child_pass_id)); - { - LayerTreeHostImpl::FrameData frame; - host_impl_->SetFullRootLayerDamage(); - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // We should still have cached textures for surface 2 after drawing with no - // damage. - EXPECT_TRUE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId( - child_pass_id)); - - // Damage a single tile of surface 2. - child_ptr->set_update_rect(gfx::Rect(10, 10, 10, 10)); - { - LayerTreeHostImpl::FrameData frame; - host_impl_->SetFullRootLayerDamage(); - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // We should have a cached texture for surface 2 again even though it was - // damaged. - EXPECT_TRUE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId( - child_pass_id)); -} - -TEST_F(LayerTreeHostImplTest, SurfaceTextureCaching) { - LayerTreeSettings settings; - settings.minimum_occlusion_tracking_size = gfx::Size(); - settings.partial_swap_enabled = true; - settings.cache_render_pass_contents = true; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); - - LayerImpl* root_ptr; - LayerImpl* intermediate_layer_ptr; - LayerImpl* surface_layer_ptr; - LayerImpl* child_ptr; - - SetupLayersForTextureCaching(my_host_impl.get(), - root_ptr, - intermediate_layer_ptr, - surface_layer_ptr, - child_ptr, - gfx::Size(100, 100)); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive two render passes, each with one quad - ASSERT_EQ(2U, frame.render_passes.size()); - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size()); - - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]); - RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id]; - ASSERT_TRUE(target_pass); - EXPECT_FALSE(target_pass->damage_rect.IsEmpty()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Draw without any change - { - LayerTreeHostImpl::FrameData frame; - my_host_impl->SetFullRootLayerDamage(); - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive one render pass, as the other one should be culled - ASSERT_EQ(1U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) == - frame.render_passes_by_id.end()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change opacity and draw - surface_layer_ptr->SetOpacity(0.6f); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive one render pass, as the other one should be culled - ASSERT_EQ(1U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) == - frame.render_passes_by_id.end()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change less benign property and draw - should have contents changed flag - surface_layer_ptr->SetStackingOrderChanged(true); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive two render passes, each with one quad - ASSERT_EQ(2U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(DrawQuad::SOLID_COLOR, - frame.render_passes[0]->quad_list[0]->material); - - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]); - RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id]; - ASSERT_TRUE(target_pass); - EXPECT_FALSE(target_pass->damage_rect.IsEmpty()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change opacity again, and evict the cached surface texture. - surface_layer_ptr->SetOpacity(0.5f); - static_cast<GLRendererWithReleaseTextures*>( - my_host_impl->renderer())->ReleaseRenderPassTextures(); - - // Change opacity and draw - surface_layer_ptr->SetOpacity(0.6f); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive two render passes - ASSERT_EQ(2U, frame.render_passes.size()); - - // Even though not enough properties changed, the entire thing must be - // redrawn as we don't have cached textures - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size()); - - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]); - RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id]; - ASSERT_TRUE(target_pass); - EXPECT_TRUE(target_pass->damage_rect.IsEmpty()); - - // Was our surface evicted? - EXPECT_FALSE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId( - target_pass->id)); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Draw without any change, to make sure the state is clear - { - LayerTreeHostImpl::FrameData frame; - my_host_impl->SetFullRootLayerDamage(); - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive one render pass, as the other one should be culled - ASSERT_EQ(1U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) == - frame.render_passes_by_id.end()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change location of the intermediate layer - gfx::Transform transform = intermediate_layer_ptr->transform(); - transform.matrix().set(0, 3, 1.0001f); - intermediate_layer_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive one render pass, as the other one should be culled. - ASSERT_EQ(1U, frame.render_passes.size()); - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) == - frame.render_passes_by_id.end()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } -} - -TEST_F(LayerTreeHostImplTest, SurfaceTextureCachingNoPartialSwap) { - LayerTreeSettings settings; - settings.minimum_occlusion_tracking_size = gfx::Size(); - settings.cache_render_pass_contents = true; - scoped_ptr<LayerTreeHostImpl> my_host_impl = - LayerTreeHostImpl::Create(settings, - this, - &proxy_, - &stats_instrumentation_); - - LayerImpl* root_ptr; - LayerImpl* intermediate_layer_ptr; - LayerImpl* surface_layer_ptr; - LayerImpl* child_ptr; - - SetupLayersForTextureCaching(my_host_impl.get(), - root_ptr, - intermediate_layer_ptr, - surface_layer_ptr, - child_ptr, - gfx::Size(100, 100)); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive two render passes, each with one quad - ASSERT_EQ(2U, frame.render_passes.size()); - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size()); - - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]); - RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id]; - EXPECT_FALSE(target_pass->damage_rect.IsEmpty()); - - EXPECT_FALSE(frame.render_passes[0]->damage_rect.IsEmpty()); - EXPECT_FALSE(frame.render_passes[1]->damage_rect.IsEmpty()); - - EXPECT_FALSE( - frame.render_passes[0]->has_occlusion_from_outside_target_surface); - EXPECT_FALSE( - frame.render_passes[1]->has_occlusion_from_outside_target_surface); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Draw without any change - { - LayerTreeHostImpl::FrameData frame; - my_host_impl->SetFullRootLayerDamage(); - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Even though there was no change, we set the damage to entire viewport. - // One of the passes should be culled as a result, since contents didn't - // change and we have cached texture. - ASSERT_EQ(1U, frame.render_passes.size()); - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change opacity and draw - surface_layer_ptr->SetOpacity(0.6f); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive one render pass, as the other one should be culled - ASSERT_EQ(1U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) == - frame.render_passes_by_id.end()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change less benign property and draw - should have contents changed flag - surface_layer_ptr->SetStackingOrderChanged(true); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive two render passes, each with one quad - ASSERT_EQ(2U, frame.render_passes.size()); - - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(DrawQuad::SOLID_COLOR, - frame.render_passes[0]->quad_list[0]->material); - - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]); - RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id]; - ASSERT_TRUE(target_pass); - EXPECT_FALSE(target_pass->damage_rect.IsEmpty()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change opacity again, and evict the cached surface texture. - surface_layer_ptr->SetOpacity(0.5f); - static_cast<GLRendererWithReleaseTextures*>( - my_host_impl->renderer())->ReleaseRenderPassTextures(); - - // Change opacity and draw - surface_layer_ptr->SetOpacity(0.6f); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive two render passes - ASSERT_EQ(2U, frame.render_passes.size()); - - // Even though not enough properties changed, the entire thing must be - // redrawn as we don't have cached textures - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - EXPECT_EQ(1U, frame.render_passes[1]->quad_list.size()); - - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[1]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[1]->quad_list[0]); - RenderPass* target_pass = frame.render_passes_by_id[quad->render_pass_id]; - ASSERT_TRUE(target_pass); - EXPECT_TRUE(target_pass->damage_rect.IsEmpty()); - - // Was our surface evicted? - EXPECT_FALSE(my_host_impl->renderer()->HaveCachedResourcesForRenderPassId( - target_pass->id)); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Draw without any change, to make sure the state is clear - { - LayerTreeHostImpl::FrameData frame; - my_host_impl->SetFullRootLayerDamage(); - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Even though there was no change, we set the damage to entire viewport. - // One of the passes should be culled as a result, since contents didn't - // change and we have cached texture. - ASSERT_EQ(1U, frame.render_passes.size()); - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } - - // Change location of the intermediate layer - gfx::Transform transform = intermediate_layer_ptr->transform(); - transform.matrix().set(0, 3, 1.0001f); - intermediate_layer_ptr->SetTransform(transform); - { - LayerTreeHostImpl::FrameData frame; - EXPECT_TRUE(my_host_impl->PrepareToDraw(&frame, gfx::Rect())); - - // Must receive one render pass, as the other one should be culled. - ASSERT_EQ(1U, frame.render_passes.size()); - EXPECT_EQ(1U, frame.render_passes[0]->quad_list.size()); - - EXPECT_EQ(DrawQuad::RENDER_PASS, - frame.render_passes[0]->quad_list[0]->material); - const RenderPassDrawQuad* quad = - RenderPassDrawQuad::MaterialCast(frame.render_passes[0]->quad_list[0]); - EXPECT_TRUE(frame.render_passes_by_id.find(quad->render_pass_id) == - frame.render_passes_by_id.end()); - - my_host_impl->DrawLayers(&frame, base::TimeTicks::Now()); - my_host_impl->DidDrawAllLayers(frame); - } -} - TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { set_reduce_memory_result(false); @@ -5151,398 +4044,6 @@ TEST_F(LayerTreeHostImplTest, ReleaseContentsTextureShouldTriggerCommit) { EXPECT_FALSE(did_request_commit_); } -struct RenderPassRemovalTestData : public LayerTreeHostImpl::FrameData { - base::ScopedPtrHashMap<RenderPass::Id, TestRenderPass> render_pass_cache; - scoped_ptr<SharedQuadState> shared_quad_state; -}; - -class TestRenderer : public GLRenderer, public RendererClient { - public: - static scoped_ptr<TestRenderer> Create(const LayerTreeSettings* settings, - ResourceProvider* resource_provider, - OutputSurface* output_surface, - Proxy* proxy) { - scoped_ptr<TestRenderer> renderer( - new TestRenderer(settings, resource_provider, output_surface, proxy)); - if (!renderer->Initialize()) - return scoped_ptr<TestRenderer>(); - - return renderer.Pass(); - } - - void ClearCachedTextures() { textures_.clear(); } - void SetHaveCachedResourcesForRenderPassId(RenderPass::Id id) { - textures_.insert(id); - } - - virtual bool HaveCachedResourcesForRenderPassId(RenderPass::Id id) const - OVERRIDE { - return textures_.count(id); - } - - // RendererClient implementation. - virtual gfx::Rect DeviceViewport() const OVERRIDE { - return gfx::Rect(viewport_size_); - } - virtual gfx::Rect DeviceClip() const OVERRIDE { return DeviceViewport(); } - virtual void SetFullRootLayerDamage() OVERRIDE {} - virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const OVERRIDE { - return CompositorFrameMetadata(); - } - - protected: - TestRenderer(const LayerTreeSettings* settings, - ResourceProvider* resource_provider, - OutputSurface* output_surface, - Proxy* proxy) - : GLRenderer(this, settings, output_surface, resource_provider, NULL, 0) { - } - - private: - LayerTreeSettings settings_; - gfx::Size viewport_size_; - base::hash_set<RenderPass::Id> textures_; -}; - -static void ConfigureRenderPassTestData(const char* test_script, - RenderPassRemovalTestData* test_data, - TestRenderer* renderer) { - renderer->ClearCachedTextures(); - - // One shared state for all quads - we don't need the correct details - test_data->shared_quad_state = SharedQuadState::Create(); - test_data->shared_quad_state->SetAll(gfx::Transform(), - gfx::Size(), - gfx::Rect(), - gfx::Rect(), - false, - 1.f); - - const char* current_char = test_script; - - // Pre-create root pass - RenderPass::Id root_render_pass_id = - RenderPass::Id(test_script[0], test_script[1]); - scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); - pass->SetNew(root_render_pass_id, gfx::Rect(), gfx::Rect(), gfx::Transform()); - test_data->render_pass_cache.add(root_render_pass_id, pass.Pass()); - while (*current_char) { - int layer_id = *current_char; - current_char++; - ASSERT_TRUE(current_char); - int index = *current_char; - current_char++; - - RenderPass::Id render_pass_id = RenderPass::Id(layer_id, index); - - bool is_replica = false; - if (!test_data->render_pass_cache.contains(render_pass_id)) - is_replica = true; - - scoped_ptr<TestRenderPass> render_pass = - test_data->render_pass_cache.take(render_pass_id); - - // Cycle through quad data and create all quads. - while (*current_char && *current_char != '\n') { - if (*current_char == 's') { - // Solid color draw quad. - scoped_ptr<SolidColorDrawQuad> quad = SolidColorDrawQuad::Create(); - quad->SetNew(test_data->shared_quad_state.get(), - gfx::Rect(0, 0, 10, 10), - SK_ColorWHITE, - false); - - render_pass->AppendQuad(quad.PassAs<DrawQuad>()); - current_char++; - } else if ((*current_char >= 'A') && (*current_char <= 'Z')) { - // RenderPass draw quad. - int layer_id = *current_char; - current_char++; - ASSERT_TRUE(current_char); - int index = *current_char; - current_char++; - RenderPass::Id new_render_pass_id = RenderPass::Id(layer_id, index); - ASSERT_NE(root_render_pass_id, new_render_pass_id); - bool has_texture = false; - bool contents_changed = true; - - if (*current_char == '[') { - current_char++; - while (*current_char && *current_char != ']') { - switch (*current_char) { - case 'c': - contents_changed = false; - break; - case 't': - has_texture = true; - break; - } - current_char++; - } - if (*current_char == ']') - current_char++; - } - - if (test_data->render_pass_cache.find(new_render_pass_id) == - test_data->render_pass_cache.end()) { - if (has_texture) - renderer->SetHaveCachedResourcesForRenderPassId(new_render_pass_id); - - scoped_ptr<TestRenderPass> pass = TestRenderPass::Create(); - pass->SetNew(new_render_pass_id, - gfx::Rect(), - gfx::Rect(), - gfx::Transform()); - test_data->render_pass_cache.add(new_render_pass_id, pass.Pass()); - } - - gfx::Rect quad_rect = gfx::Rect(0, 0, 1, 1); - gfx::Rect contents_changed_rect = - contents_changed ? quad_rect : gfx::Rect(); - scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create(); - quad->SetNew(test_data->shared_quad_state.get(), - quad_rect, - new_render_pass_id, - is_replica, - 1, - contents_changed_rect, - gfx::RectF(0.f, 0.f, 1.f, 1.f), - FilterOperations(), - FilterOperations()); - render_pass->AppendQuad(quad.PassAs<DrawQuad>()); - } - } - test_data->render_passes_by_id[render_pass_id] = render_pass.get(); - test_data->render_passes.insert(test_data->render_passes.begin(), - render_pass.PassAs<RenderPass>()); - if (*current_char) - current_char++; - } -} - -void DumpRenderPassTestData(const RenderPassRemovalTestData& test_data, - char* buffer) { - char* pos = buffer; - for (RenderPassList::const_reverse_iterator it = - test_data.render_passes.rbegin(); - it != test_data.render_passes.rend(); - ++it) { - const RenderPass* current_pass = *it; - *pos = current_pass->id.layer_id; - pos++; - *pos = current_pass->id.index; - pos++; - - QuadList::const_iterator quad_list_iterator = - current_pass->quad_list.begin(); - while (quad_list_iterator != current_pass->quad_list.end()) { - DrawQuad* current_quad = *quad_list_iterator; - switch (current_quad->material) { - case DrawQuad::SOLID_COLOR: - *pos = 's'; - pos++; - break; - case DrawQuad::RENDER_PASS: - *pos = RenderPassDrawQuad::MaterialCast(current_quad)-> - render_pass_id.layer_id; - pos++; - *pos = RenderPassDrawQuad::MaterialCast(current_quad)-> - render_pass_id.index; - pos++; - break; - default: - *pos = 'x'; - pos++; - break; - } - - quad_list_iterator++; - } - *pos = '\n'; - pos++; - } - *pos = '\0'; -} - -// Each RenderPassList is represented by a string which describes the -// configuration. -// The syntax of the string is as follows: -// -// RsssssX[c]ssYsssZ[t]ssW[ct] -// Identifies the render pass------------------------^ ^^^ ^ ^ ^ ^ ^ -// These are solid color quads--------------------------+ | | | | | -// Identifies RenderPassDrawQuad's RenderPass--------------+ | | | | -// This quad's contents didn't change------------------------+ | | | -// This quad's contents changed and it has no texture------------+ | | -// This quad has texture but its contents changed----------------------+ | -// This quad's contents didn't change and it has texture - will be removed---+ -// -// Expected results have exactly the same syntax, except they do not use square -// brackets, since we only check the structure, not attributes. -// -// Test case configuration consists of initialization script and expected -// results, all in the same format. -struct TestCase { - const char* name; - const char* init_script; - const char* expected_result; -}; - -TestCase remove_render_passes_cases[] = { - { - "Single root pass", - "R0ssss\n", - "R0ssss\n" - }, { - "Single pass - no quads", - "R0\n", - "R0\n" - }, { - "Two passes, no removal", - "R0ssssA0sss\n" - "A0ssss\n", - "R0ssssA0sss\n" - "A0ssss\n" - }, { - "Two passes, remove last", - "R0ssssA0[ct]sss\n" - "A0ssss\n", - "R0ssssA0sss\n" - }, { - "Have texture but contents changed - leave pass", - "R0ssssA0[t]sss\n" - "A0ssss\n", - "R0ssssA0sss\n" - "A0ssss\n" - }, { - "Contents didn't change but no texture - leave pass", - "R0ssssA0[c]sss\n" - "A0ssss\n", - "R0ssssA0sss\n" - "A0ssss\n" - }, { - "Replica: two quads reference the same pass; remove", - "R0ssssA0[ct]A0[ct]sss\n" - "A0ssss\n", - "R0ssssA0A0sss\n" - }, { - "Replica: two quads reference the same pass; leave", - "R0ssssA0[c]A0[c]sss\n" - "A0ssss\n", - "R0ssssA0A0sss\n" - "A0ssss\n", - }, { - "Many passes, remove all", - "R0ssssA0[ct]sss\n" - "A0sssB0[ct]C0[ct]s\n" - "B0sssD0[ct]ssE0[ct]F0[ct]\n" - "E0ssssss\n" - "C0G0[ct]\n" - "D0sssssss\n" - "F0sssssss\n" - "G0sss\n", - - "R0ssssA0sss\n" - }, { - "Deep recursion, remove all", - - "R0sssssA0[ct]ssss\n" - "A0ssssB0sss\n" - "B0C0\n" - "C0D0\n" - "D0E0\n" - "E0F0\n" - "F0G0\n" - "G0H0\n" - "H0sssI0sss\n" - "I0J0\n" - "J0ssss\n", - - "R0sssssA0ssss\n" - }, { - "Wide recursion, remove all", - "R0A0[ct]B0[ct]C0[ct]D0[ct]E0[ct]F0[ct]G0[ct]H0[ct]I0[ct]J0[ct]\n" - "A0s\n" - "B0s\n" - "C0ssss\n" - "D0ssss\n" - "E0s\n" - "F0\n" - "G0s\n" - "H0s\n" - "I0s\n" - "J0ssss\n", - - "R0A0B0C0D0E0F0G0H0I0J0\n" - }, { - "Remove passes regardless of cache state", - "R0ssssA0[ct]sss\n" - "A0sssB0C0s\n" - "B0sssD0[c]ssE0[t]F0\n" - "E0ssssss\n" - "C0G0\n" - "D0sssssss\n" - "F0sssssss\n" - "G0sss\n", - - "R0ssssA0sss\n" - }, { - "Leave some passes, remove others", - - "R0ssssA0[c]sss\n" - "A0sssB0[t]C0[ct]s\n" - "B0sssD0[c]ss\n" - "C0G0\n" - "D0sssssss\n" - "G0sss\n", - - "R0ssssA0sss\n" - "A0sssB0C0s\n" - "B0sssD0ss\n" - "D0sssssss\n" - }, { - 0, 0, 0 - } -}; - -static void VerifyRenderPassTestData( - const TestCase& test_case, - const RenderPassRemovalTestData& test_data) { - char actual_result[1024]; - DumpRenderPassTestData(test_data, actual_result); - EXPECT_STREQ(test_case.expected_result, actual_result) << "In test case: " << - test_case.name; -} - -TEST_F(LayerTreeHostImplTest, TestRemoveRenderPasses) { - LayerTreeSettings settings; - FakeOutputSurfaceClient output_surface_client; - scoped_ptr<OutputSurface> output_surface(CreateOutputSurface()); - ASSERT_TRUE(output_surface->BindToClient(&output_surface_client)); - ASSERT_TRUE(output_surface->context_provider()); - - scoped_ptr<ResourceProvider> resource_provider = - ResourceProvider::Create(output_surface.get(), 0, false); - - scoped_ptr<TestRenderer> renderer = TestRenderer::Create( - &settings, resource_provider.get(), output_surface.get(), &proxy_); - - int test_case_index = 0; - while (remove_render_passes_cases[test_case_index].name) { - RenderPassRemovalTestData test_data; - ConfigureRenderPassTestData( - remove_render_passes_cases[test_case_index].init_script, - &test_data, - renderer.get()); - LayerTreeHostImpl::RemoveRenderPasses( - LayerTreeHostImpl::CullRenderPassesWithCachedTextures(renderer.get()), - &test_data); - VerifyRenderPassTestData(remove_render_passes_cases[test_case_index], - test_data); - test_case_index++; - } -} - class LayerTreeHostImplTestWithDelegatingRenderer : public LayerTreeHostImplTest { protected: diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc index 067bd09..6f9c8d1 100644 --- a/cc/trees/layer_tree_settings.cc +++ b/cc/trees/layer_tree_settings.cc @@ -21,7 +21,6 @@ LayerTreeSettings::LayerTreeSettings() using_synchronous_renderer_compositor(false), per_tile_painting_enabled(false), partial_swap_enabled(false), - cache_render_pass_contents(true), accelerated_animation_enabled(true), background_color_instead_of_checkerboard(false), show_overdraw_in_tracing(false), @@ -60,9 +59,6 @@ LayerTreeSettings::LayerTreeSettings() ignore_root_layer_flings(false), use_rgba_4444_textures(false), always_overscroll(false) { - // TODO(danakj): Renable surface caching when we can do it more realiably. - // crbug.com/170713 - cache_render_pass_contents = false; } LayerTreeSettings::~LayerTreeSettings() {} diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index f6436b8..4b51069 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h @@ -26,7 +26,6 @@ class CC_EXPORT LayerTreeSettings { bool using_synchronous_renderer_compositor; bool per_tile_painting_enabled; bool partial_swap_enabled; - bool cache_render_pass_contents; bool accelerated_animation_enabled; bool background_color_instead_of_checkerboard; bool show_overdraw_in_tracing; diff --git a/cc/trees/occlusion_tracker.cc b/cc/trees/occlusion_tracker.cc index abaefa7..7e24e84 100644 --- a/cc/trees/occlusion_tracker.cc +++ b/cc/trees/occlusion_tracker.cc @@ -347,10 +347,10 @@ void OcclusionTrackerBase<LayerType, RenderSurfaceType>::LeaveToRenderTarget( gfx::Rect unoccluded_replica_rect; if (old_target->background_filters().HasFilterThatMovesPixels()) { unoccluded_surface_rect = UnoccludedContributingSurfaceContentRect( - old_target, false, old_surface->content_rect(), NULL); + old_target, false, old_surface->content_rect()); if (old_target->has_replica()) { unoccluded_replica_rect = UnoccludedContributingSurfaceContentRect( - old_target, true, old_surface->content_rect(), NULL); + old_target, true, old_surface->content_rect()); } } @@ -510,10 +510,7 @@ bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( const gfx::Transform& draw_transform, bool impl_draw_transform_is_unknown, bool is_clipped, - gfx::Rect clip_rect_in_target, - bool* has_occlusion_from_outside_target_surface) const { - if (has_occlusion_from_outside_target_surface) - *has_occlusion_from_outside_target_surface = false; + gfx::Rect clip_rect_in_target) const { if (prevent_occlusion_) return false; @@ -562,13 +559,6 @@ bool OcclusionTrackerBase<LayerType, RenderSurfaceType>::Occluded( gfx::RectF unoccluded_rect_in_target_surface = unoccluded_region_in_target_surface.bounds(); - if (has_occlusion_from_outside_target_surface) { - // Check if the unoccluded rect shrank when applying outside occlusion. - *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( - unoccluded_rect_in_target_surface_without_outside_occlusion, - unoccluded_rect_in_target_surface).IsEmpty(); - } - return unoccluded_rect_in_target_surface.IsEmpty(); } @@ -580,10 +570,7 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: const gfx::Transform& draw_transform, bool impl_draw_transform_is_unknown, bool is_clipped, - gfx::Rect clip_rect_in_target, - bool* has_occlusion_from_outside_target_surface) const { - if (has_occlusion_from_outside_target_surface) - *has_occlusion_from_outside_target_surface = false; + gfx::Rect clip_rect_in_target) const { if (prevent_occlusion_) return content_rect; @@ -636,13 +623,6 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: unoccluded_rect_in_target_surface)); unoccluded_rect.Intersect(content_rect); - if (has_occlusion_from_outside_target_surface) { - // Check if the unoccluded rect shrank when applying outside occlusion. - *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( - unoccluded_rect_in_target_surface_without_outside_occlusion, - unoccluded_rect_in_target_surface).IsEmpty(); - } - return unoccluded_rect; } @@ -651,8 +631,7 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: UnoccludedContributingSurfaceContentRect( const LayerType* layer, bool for_replica, - gfx::Rect content_rect, - bool* has_occlusion_from_outside_target_surface) const { + gfx::Rect content_rect) const { DCHECK(!stack_.empty()); // The layer is a contributing render_target so it should have a surface. DCHECK(layer->render_surface()); @@ -664,8 +643,6 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: // target in the occlusion tracker. DCHECK_EQ(layer, stack_.back().target); - if (has_occlusion_from_outside_target_surface) - *has_occlusion_from_outside_target_surface = false; if (prevent_occlusion_) return content_rect; @@ -726,13 +703,6 @@ gfx::Rect OcclusionTrackerBase<LayerType, RenderSurfaceType>:: unoccluded_rect_in_target_surface)); unoccluded_rect.Intersect(content_rect); - if (has_occlusion_from_outside_target_surface) { - // Check if the unoccluded rect shrank when applying outside occlusion. - *has_occlusion_from_outside_target_surface = !gfx::SubtractRects( - unoccluded_rect_in_target_surface_without_outside_occlusion, - unoccluded_rect_in_target_surface).IsEmpty(); - } - return unoccluded_rect; } diff --git a/cc/trees/occlusion_tracker.h b/cc/trees/occlusion_tracker.h index 132b3fa..1b86d72 100644 --- a/cc/trees/occlusion_tracker.h +++ b/cc/trees/occlusion_tracker.h @@ -55,8 +55,7 @@ class CC_EXPORT OcclusionTrackerBase { const gfx::Transform& draw_transform, bool impl_draw_transform_is_unknown, bool is_clipped, - gfx::Rect clip_rect_in_target, - bool* has_occlusion_from_outside_target_surface) const; + gfx::Rect clip_rect_in_target) const; // Gives an unoccluded sub-rect of |content_rect| in the content space of a // layer. Used when considering occlusion for a layer that paints/draws @@ -69,8 +68,7 @@ class CC_EXPORT OcclusionTrackerBase { const gfx::Transform& draw_transform, bool impl_draw_transform_is_unknown, bool is_clipped, - gfx::Rect clip_rect_in_target, - bool* has_occlusion_from_outside_target_surface) const; + gfx::Rect clip_rect_in_target) const; // Gives an unoccluded sub-rect of |content_rect| in the content space of the // render_target owned by the layer. Used when considering occlusion for a @@ -78,8 +76,7 @@ class CC_EXPORT OcclusionTrackerBase { gfx::Rect UnoccludedContributingSurfaceContentRect( const LayerType* layer, bool for_replica, - gfx::Rect content_rect, - bool* has_occlusion_from_outside_target_surface) const; + gfx::Rect content_rect) const; // Report operations for recording overdraw metrics. OverdrawMetrics* overdraw_metrics() const { diff --git a/cc/trees/occlusion_tracker_unittest.cc b/cc/trees/occlusion_tracker_unittest.cc index 469d65a..9d7e9c8 100644 --- a/cc/trees/occlusion_tracker_unittest.cc +++ b/cc/trees/occlusion_tracker_unittest.cc @@ -92,42 +92,27 @@ class TestOcclusionTrackerWithClip : TestOcclusionTrackerBase<LayerType, RenderSurfaceType>(viewport_rect, false) {} - bool OccludedLayer(const LayerType* layer, gfx::Rect content_rect) { - bool temp; - return OccludedLayer(layer, content_rect, &temp); - } - bool OccludedLayer(const LayerType* layer, - gfx::Rect content_rect, - bool* has_occlusion_from_outside_target_surface) const { + gfx::Rect content_rect) const { return this->Occluded(layer->render_target(), content_rect, layer->draw_transform(), LayerImplDrawTransformIsUnknown(layer), layer->is_clipped(), - layer->clip_rect(), - has_occlusion_from_outside_target_surface); + layer->clip_rect()); } + // Gives an unoccluded sub-rect of |content_rect| in the content space of the // layer. Simple wrapper around UnoccludedContentRect. gfx::Rect UnoccludedLayerContentRect(const LayerType* layer, gfx::Rect content_rect) const { - bool temp; - return UnoccludedLayerContentRect(layer, content_rect, &temp); - } - - gfx::Rect UnoccludedLayerContentRect( - const LayerType* layer, - gfx::Rect content_rect, - bool* has_occlusion_from_outside_target_surface) const { return this->UnoccludedContentRect( layer->render_target(), content_rect, layer->draw_transform(), LayerImplDrawTransformIsUnknown(layer), layer->is_clipped(), - layer->clip_rect(), - has_occlusion_from_outside_target_surface); + layer->clip_rect()); } }; @@ -654,40 +639,35 @@ class OcclusionTrackerTestQuadsMismatchLayer quad_transform, false, true, - clip_rect_in_target, - NULL).IsEmpty()); + clip_rect_in_target).IsEmpty()); EXPECT_RECT_EQ(gfx::Rect(0, 0, 10, 10), occlusion.UnoccludedContentRect(parent, gfx::Rect(0, 0, 10, 10), quad_transform, true, true, - clip_rect_in_target, - NULL)); + clip_rect_in_target)); EXPECT_RECT_EQ(gfx::Rect(40, 40, 10, 10), occlusion.UnoccludedContentRect(parent, gfx::Rect(40, 40, 10, 10), quad_transform, false, true, - clip_rect_in_target, - NULL)); + clip_rect_in_target)); EXPECT_RECT_EQ(gfx::Rect(40, 30, 5, 10), occlusion.UnoccludedContentRect(parent, gfx::Rect(35, 30, 10, 10), quad_transform, false, true, - clip_rect_in_target, - NULL)); + clip_rect_in_target)); EXPECT_RECT_EQ(gfx::Rect(40, 40, 5, 5), occlusion.UnoccludedContentRect(parent, gfx::Rect(40, 40, 10, 10), quad_transform, false, true, - gfx::Rect(0, 0, 75, 75), - NULL)); + gfx::Rect(0, 0, 75, 75))); } }; @@ -1418,7 +1398,7 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings // There is nothing above child2's surface in the z-order. EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion.UnoccludedContributingSurfaceContentRect( - child2, false, gfx::Rect(-10, 420, 70, 80), NULL)); + child2, false, gfx::Rect(-10, 420, 70, 80))); this->LeaveContributingSurface(child2, &occlusion); this->VisitLayer(layer1, &occlusion); @@ -1432,7 +1412,7 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings // child2's contents will occlude child1 below it. EXPECT_RECT_EQ(gfx::Rect(-10, 430, 10, 70), occlusion.UnoccludedContributingSurfaceContentRect( - child1, false, gfx::Rect(-10, 430, 80, 70), NULL)); + child1, false, gfx::Rect(-10, 430, 80, 70))); this->LeaveContributingSurface(child1, &occlusion); this->EnterLayer(parent, &occlusion, false); @@ -1542,7 +1522,7 @@ class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms // There is nothing above child2's surface in the z-order. EXPECT_RECT_EQ(gfx::Rect(-10, 420, 70, 80), occlusion.UnoccludedContributingSurfaceContentRect( - child2, false, gfx::Rect(-10, 420, 70, 80), NULL)); + child2, false, gfx::Rect(-10, 420, 70, 80))); this->LeaveContributingSurface(child2, &occlusion); this->VisitLayer(layer1, &occlusion); @@ -1556,13 +1536,13 @@ class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms // child2's contents will occlude child1 below it. EXPECT_RECT_EQ(gfx::Rect(420, -20, 80, 90), occlusion.UnoccludedContributingSurfaceContentRect( - child1, false, gfx::Rect(420, -20, 80, 90), NULL)); + child1, false, gfx::Rect(420, -20, 80, 90))); EXPECT_RECT_EQ(gfx::Rect(490, -10, 10, 80), occlusion.UnoccludedContributingSurfaceContentRect( - child1, false, gfx::Rect(420, -10, 80, 90), NULL)); + child1, false, gfx::Rect(420, -10, 80, 90))); EXPECT_RECT_EQ(gfx::Rect(420, -20, 70, 10), occlusion.UnoccludedContributingSurfaceContentRect( - child1, false, gfx::Rect(420, -20, 70, 90), NULL)); + child1, false, gfx::Rect(420, -20, 70, 90))); this->LeaveContributingSurface(child1, &occlusion); this->EnterLayer(parent, &occlusion, false); @@ -2735,7 +2715,7 @@ class OcclusionTrackerTestAnimationOpacity1OnMainThread occlusion.occlusion_from_outside_target().ToString()); EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 300, 300), NULL)); + surface, false, gfx::Rect(0, 0, 300, 300))); this->LeaveContributingSurface(surface, &occlusion); // Occlusion from outside the animating surface still exists. @@ -2856,7 +2836,7 @@ class OcclusionTrackerTestAnimationOpacity0OnMainThread occlusion.occlusion_from_outside_target().ToString()); EXPECT_RECT_EQ(gfx::Rect(0, 0, 250, 300), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 300, 300), NULL)); + surface, false, gfx::Rect(0, 0, 300, 300))); this->LeaveContributingSurface(surface, &occlusion); // Occlusion from outside the animating surface still exists. @@ -3007,7 +2987,7 @@ class OcclusionTrackerTestAnimationTranslateOnMainThread // The contributing |surface| is animating so it can't be occluded. EXPECT_RECT_EQ(gfx::Rect(0, 0, 300, 300), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 300, 300), NULL)); + surface, false, gfx::Rect(0, 0, 300, 300))); this->LeaveContributingSurface(surface, &occlusion); this->EnterLayer(layer, &occlusion, false); @@ -3172,7 +3152,7 @@ class OcclusionTrackerTestReplicaOccluded : public OcclusionTrackerTest<Types> { // Surface is not occluded so it shouldn't think it is. EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100), NULL)); + surface, false, gfx::Rect(0, 0, 100, 100))); } }; @@ -3229,10 +3209,10 @@ class OcclusionTrackerTestSurfaceWithReplicaUnoccluded // Surface is occluded, but only the top 10px of the replica. EXPECT_RECT_EQ(gfx::Rect(0, 0, 0, 0), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100), NULL)); + surface, false, gfx::Rect(0, 0, 100, 100))); EXPECT_RECT_EQ(gfx::Rect(0, 10, 100, 90), occlusion.UnoccludedContributingSurfaceContentRect( - surface, true, gfx::Rect(0, 0, 100, 100), NULL)); + surface, true, gfx::Rect(0, 0, 100, 100))); } }; @@ -3296,10 +3276,10 @@ class OcclusionTrackerTestSurfaceAndReplicaOccludedDifferently // Surface and replica are occluded different amounts. EXPECT_RECT_EQ(gfx::Rect(40, 0, 60, 100), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100), NULL)); + surface, false, gfx::Rect(0, 0, 100, 100))); EXPECT_RECT_EQ(gfx::Rect(50, 0, 50, 100), occlusion.UnoccludedContributingSurfaceContentRect( - surface, true, gfx::Rect(0, 0, 100, 100), NULL)); + surface, true, gfx::Rect(0, 0, 100, 100))); } }; @@ -3368,7 +3348,7 @@ class OcclusionTrackerTestSurfaceChildOfSurface // inappropriately. EXPECT_RECT_EQ(gfx::Rect(0, 40, 100, 10), occlusion.UnoccludedContributingSurfaceContentRect( - surface_child, false, gfx::Rect(0, 0, 100, 50), NULL)); + surface_child, false, gfx::Rect(0, 0, 100, 50))); this->LeaveContributingSurface(surface_child, &occlusion); // When the surface_child's occlusion is transformed up to its parent, make @@ -3384,7 +3364,7 @@ class OcclusionTrackerTestSurfaceChildOfSurface // The surface's parent does have a clip rect as it is the root layer. EXPECT_RECT_EQ(gfx::Rect(0, 50, 100, 50), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100), NULL)); + surface, false, gfx::Rect(0, 0, 100, 100))); } }; @@ -3425,7 +3405,7 @@ class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport // child surface. EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 200), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 300), NULL)); + surface, false, gfx::Rect(0, 0, 100, 300))); } this->ResetLayerIterator(); { @@ -3443,7 +3423,7 @@ class OcclusionTrackerTestTopmostSurfaceIsClippedToViewport // surface. EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 300), NULL)); + surface, false, gfx::Rect(0, 0, 100, 300))); } } }; @@ -3514,7 +3494,7 @@ class OcclusionTrackerTestSurfaceChildOfClippingSurface EXPECT_EQ( gfx::Rect(0, 50, 80, 50).ToString(), occlusion.UnoccludedContributingSurfaceContentRect( - surface_child, false, gfx::Rect(0, 0, 100, 100), NULL).ToString()); + surface_child, false, gfx::Rect(0, 0, 100, 100)).ToString()); this->LeaveContributingSurface(surface_child, &occlusion); this->VisitLayer(surface, &occlusion); @@ -3522,7 +3502,7 @@ class OcclusionTrackerTestSurfaceChildOfClippingSurface // The surface's parent does have a clip rect as it is the root layer. EXPECT_EQ(gfx::Rect(0, 50, 80, 50).ToString(), occlusion.UnoccludedContributingSurfaceContentRect( - surface, false, gfx::Rect(0, 0, 100, 100), NULL).ToString()); + surface, false, gfx::Rect(0, 0, 100, 100)).ToString()); } }; @@ -4381,191 +4361,6 @@ class OcclusionTrackerTestMinimumTrackingSize ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestMinimumTrackingSize); template <class Types> -class OcclusionTrackerTestViewportClipIsExternalOcclusion - : public OcclusionTrackerTest<Types> { - protected: - explicit OcclusionTrackerTestViewportClipIsExternalOcclusion( - bool opaque_layers) - : OcclusionTrackerTest<Types>(opaque_layers) {} - void RunMyTest() { - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); - typename Types::LayerType* small = - this->CreateDrawingSurface(parent, - this->identity_matrix, - gfx::PointF(), - gfx::Size(200, 200), - false); - typename Types::LayerType* large = - this->CreateDrawingLayer(small, - this->identity_matrix, - gfx::PointF(), - gfx::Size(400, 400), - false); - small->SetMasksToBounds(true); - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType, - typename Types::RenderSurfaceType> occlusion( - gfx::Rect(0, 0, 100, 100)); - - this->EnterLayer(large, &occlusion, false); - - bool has_occlusion_from_outside_target_surface = false; - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), - occlusion.UnoccludedLayerContentRect( - large, - gfx::Rect(0, 0, 400, 400), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - has_occlusion_from_outside_target_surface = false; - EXPECT_FALSE( - occlusion.OccludedLayer(large, - gfx::Rect(0, 0, 400, 400), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - this->LeaveLayer(large, &occlusion); - this->VisitLayer(small, &occlusion); - - has_occlusion_from_outside_target_surface = false; - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), - occlusion.UnoccludedLayerContentRect( - small, - gfx::Rect(0, 0, 200, 200), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - has_occlusion_from_outside_target_surface = false; - EXPECT_FALSE( - occlusion.OccludedLayer(small, - gfx::Rect(0, 0, 200, 200), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - this->EnterContributingSurface(small, &occlusion, false); - - has_occlusion_from_outside_target_surface = false; - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), - occlusion.UnoccludedContributingSurfaceContentRect( - small, - false, - gfx::Rect(0, 0, 200, 200), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - } -}; - -ALL_OCCLUSIONTRACKER_TEST( - OcclusionTrackerTestViewportClipIsExternalOcclusion) - -template <class Types> -class OcclusionTrackerTestLayerClipIsExternalOcclusion - : public OcclusionTrackerTest<Types> { - protected: - explicit OcclusionTrackerTestLayerClipIsExternalOcclusion(bool opaque_layers) - : OcclusionTrackerTest<Types>(opaque_layers) {} - void RunMyTest() { - typename Types::ContentLayerType* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); - typename Types::LayerType* smallest = this->CreateDrawingLayer( - parent, this->identity_matrix, gfx::PointF(), gfx::Size(50, 50), false); - typename Types::LayerType* smaller = - this->CreateDrawingSurface(smallest, - this->identity_matrix, - gfx::PointF(), - gfx::Size(100, 100), - false); - typename Types::LayerType* small = - this->CreateDrawingSurface(smaller, - this->identity_matrix, - gfx::PointF(), - gfx::Size(200, 200), - false); - typename Types::LayerType* large = - this->CreateDrawingLayer(small, - this->identity_matrix, - gfx::PointF(), - gfx::Size(400, 400), - false); - smallest->SetMasksToBounds(true); - smaller->SetMasksToBounds(true); - small->SetMasksToBounds(true); - this->CalcDrawEtc(parent); - - TestOcclusionTrackerWithClip<typename Types::LayerType, - typename Types::RenderSurfaceType> occlusion( - gfx::Rect(0, 0, 1000, 1000)); - - this->EnterLayer(large, &occlusion, false); - - // Clipping from the smaller layer is from outside the target surface. - bool has_occlusion_from_outside_target_surface = false; - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), - occlusion.UnoccludedLayerContentRect( - large, - gfx::Rect(0, 0, 400, 400), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - has_occlusion_from_outside_target_surface = false; - EXPECT_FALSE( - occlusion.OccludedLayer(large, - gfx::Rect(0, 0, 400, 400), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - this->LeaveLayer(large, &occlusion); - this->VisitLayer(small, &occlusion); - - // Clipping from the smaller layer is from outside the target surface. - has_occlusion_from_outside_target_surface = false; - EXPECT_RECT_EQ(gfx::Rect(0, 0, 100, 100), - occlusion.UnoccludedLayerContentRect( - small, - gfx::Rect(0, 0, 200, 200), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - has_occlusion_from_outside_target_surface = false; - EXPECT_FALSE( - occlusion.OccludedLayer(small, - gfx::Rect(0, 0, 200, 200), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - this->EnterContributingSurface(small, &occlusion, false); - - // The |small| surface is clipped from outside its target by |smallest|. - has_occlusion_from_outside_target_surface = false; - EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), - occlusion.UnoccludedContributingSurfaceContentRect( - small, - false, - gfx::Rect(0, 0, 200, 200), - &has_occlusion_from_outside_target_surface)); - EXPECT_TRUE(has_occlusion_from_outside_target_surface); - - this->LeaveContributingSurface(small, &occlusion); - this->VisitLayer(smaller, &occlusion); - this->EnterContributingSurface(smaller, &occlusion, false); - - // The |smaller| surface is clipped from inside its target by |smallest|. - has_occlusion_from_outside_target_surface = false; - EXPECT_RECT_EQ(gfx::Rect(0, 0, 50, 50), - occlusion.UnoccludedContributingSurfaceContentRect( - smaller, - false, - gfx::Rect(0, 0, 100, 100), - &has_occlusion_from_outside_target_surface)); - EXPECT_FALSE(has_occlusion_from_outside_target_surface); - } -}; - -ALL_OCCLUSIONTRACKER_TEST(OcclusionTrackerTestLayerClipIsExternalOcclusion) - -template <class Types> class OcclusionTrackerTestPreventOcclusionOnLayer : public OcclusionTrackerTest<Types> { protected: @@ -4585,39 +4380,30 @@ class OcclusionTrackerTestPreventOcclusionOnLayer TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion( gfx::Rect(0, 0, 1000, 1000)); - bool external_occlusion = false; this->VisitLayer(occluding, &occlusion); this->EnterLayer(prevented, &occlusion, true); // This layer is not occluded because it is prevented. EXPECT_FALSE(occlusion.OccludedLayer(prevented, - gfx::Rect(50, 50), - &external_occlusion)); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50))); EXPECT_EQ(gfx::Rect(50, 50).ToString(), occlusion.UnoccludedLayerContentRect( prevented, - gfx::Rect(50, 50), - &external_occlusion).ToString()); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50)).ToString()); this->LeaveLayer(prevented, &occlusion); this->EnterLayer(unprevented, &occlusion, false); // This layer is fully occluded. EXPECT_TRUE(occlusion.OccludedLayer(unprevented, - gfx::Rect(50, 50), - &external_occlusion)); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50))); EXPECT_EQ(gfx::Rect().ToString(), occlusion.UnoccludedLayerContentRect( unprevented, - gfx::Rect(50, 50), - &external_occlusion).ToString()); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50)).ToString()); this->LeaveLayer(unprevented, &occlusion); } @@ -4646,7 +4432,6 @@ class OcclusionTrackerTestPreventOcclusionOnContributingSurface TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion( gfx::Rect(0, 0, 1000, 1000)); - bool external_occlusion = false; this->VisitLayer(occluding, &occlusion); this->EnterLayer(prevented, &occlusion, true); @@ -4655,9 +4440,7 @@ class OcclusionTrackerTestPreventOcclusionOnContributingSurface EXPECT_EQ(gfx::Rect(50, 50).ToString(), occlusion.UnoccludedLayerContentRect( prevented, - gfx::Rect(50, 50), - &external_occlusion).ToString()); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50)).ToString()); this->LeaveLayer(prevented, &occlusion); this->EnterContributingSurface(prevented, &occlusion, true); @@ -4667,9 +4450,7 @@ class OcclusionTrackerTestPreventOcclusionOnContributingSurface occlusion.UnoccludedContributingSurfaceContentRect( prevented, false, // is_replica - gfx::Rect(50, 50), - &external_occlusion).ToString()); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50)).ToString()); this->LeaveContributingSurface(prevented, &occlusion); this->EnterLayer(unprevented, &occlusion, false); @@ -4678,9 +4459,7 @@ class OcclusionTrackerTestPreventOcclusionOnContributingSurface EXPECT_EQ(gfx::Rect().ToString(), occlusion.UnoccludedLayerContentRect( unprevented, - gfx::Rect(50, 50), - &external_occlusion).ToString()); - EXPECT_TRUE(external_occlusion); + gfx::Rect(50, 50)).ToString()); this->LeaveLayer(unprevented, &occlusion); this->EnterContributingSurface(unprevented, &occlusion, false); @@ -4690,9 +4469,7 @@ class OcclusionTrackerTestPreventOcclusionOnContributingSurface occlusion.UnoccludedContributingSurfaceContentRect( unprevented, false, // is_replica - gfx::Rect(50, 50), - &external_occlusion).ToString()); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50)).ToString()); this->LeaveContributingSurface(unprevented, &occlusion); } @@ -4719,22 +4496,17 @@ class OcclusionTrackerTestPreventOcclusionByClipping TestOcclusionTrackerWithClip<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion( gfx::Rect(0, 0, 10, 10)); - bool external_occlusion = false; this->EnterLayer(prevented, &occlusion, true); // This layer is not occluded because it is prevented. EXPECT_FALSE(occlusion.OccludedLayer(prevented, - gfx::Rect(50, 50), - &external_occlusion)); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50))); EXPECT_EQ(gfx::Rect(50, 50).ToString(), occlusion.UnoccludedLayerContentRect( prevented, - gfx::Rect(50, 50), - &external_occlusion).ToString()); - EXPECT_FALSE(external_occlusion); + gfx::Rect(50, 50)).ToString()); this->LeaveLayer(prevented, &occlusion); this->EnterLayer(unprevented, &occlusion, false); @@ -4743,9 +4515,7 @@ class OcclusionTrackerTestPreventOcclusionByClipping EXPECT_EQ(gfx::Rect(10, 10).ToString(), occlusion.UnoccludedLayerContentRect( unprevented, - gfx::Rect(50, 50), - &external_occlusion).ToString()); - EXPECT_TRUE(external_occlusion); + gfx::Rect(50, 50)).ToString()); this->LeaveLayer(unprevented, &occlusion); } diff --git a/cc/trees/quad_culler.cc b/cc/trees/quad_culler.cc index 760c79d..2e63020 100644 --- a/cc/trees/quad_culler.cc +++ b/cc/trees/quad_culler.cc @@ -84,15 +84,13 @@ bool QuadCuller::Append(scoped_ptr<DrawQuad> draw_quad, DCHECK(shared_quad_state_list_->back() == current_shared_quad_state_); gfx::Rect culled_rect; - bool has_occlusion_from_outside_target_surface; bool impl_draw_transform_is_unknown = false; if (for_surface_) { culled_rect = occlusion_tracker_.UnoccludedContributingSurfaceContentRect( layer_, false, - draw_quad->rect, - &has_occlusion_from_outside_target_surface); + draw_quad->rect); } else { culled_rect = occlusion_tracker_.UnoccludedContentRect( layer_->render_target(), @@ -100,13 +98,9 @@ bool QuadCuller::Append(scoped_ptr<DrawQuad> draw_quad, draw_quad->quadTransform(), impl_draw_transform_is_unknown, draw_quad->isClipped(), - draw_quad->clipRect(), - &has_occlusion_from_outside_target_surface); + draw_quad->clipRect()); } - append_quads_data->had_occlusion_from_outside_target_surface |= - has_occlusion_from_outside_target_surface; - return AppendQuadInternal(draw_quad.Pass(), culled_rect, quad_list_, diff --git a/content/common/cc_messages.cc b/content/common/cc_messages.cc index ccf58e7..6d7c0c7 100644 --- a/content/common/cc_messages.cc +++ b/content/common/cc_messages.cc @@ -352,7 +352,6 @@ void ParamTraits<cc::RenderPass>::Write( WriteParam(m, p.damage_rect); WriteParam(m, p.transform_to_root_target); WriteParam(m, p.has_transparent_background); - WriteParam(m, p.has_occlusion_from_outside_target_surface); WriteParam(m, p.shared_quad_state_list.size()); WriteParam(m, p.quad_list.size()); @@ -444,7 +443,6 @@ bool ParamTraits<cc::RenderPass>::Read( gfx::RectF damage_rect; gfx::Transform transform_to_root_target; bool has_transparent_background; - bool has_occlusion_from_outside_target_surface; size_t shared_quad_state_list_size; size_t quad_list_size; @@ -453,7 +451,6 @@ bool ParamTraits<cc::RenderPass>::Read( !ReadParam(m, iter, &damage_rect) || !ReadParam(m, iter, &transform_to_root_target) || !ReadParam(m, iter, &has_transparent_background) || - !ReadParam(m, iter, &has_occlusion_from_outside_target_surface) || !ReadParam(m, iter, &shared_quad_state_list_size) || !ReadParam(m, iter, &quad_list_size)) return false; @@ -462,8 +459,7 @@ bool ParamTraits<cc::RenderPass>::Read( output_rect, damage_rect, transform_to_root_target, - has_transparent_background, - has_occlusion_from_outside_target_surface); + has_transparent_background); for (size_t i = 0; i < shared_quad_state_list_size; ++i) { scoped_ptr<cc::SharedQuadState> state(cc::SharedQuadState::Create()); @@ -548,8 +544,6 @@ void ParamTraits<cc::RenderPass>::Log( l->append(", "); LogParam(p.has_transparent_background, l); l->append(", "); - LogParam(p.has_occlusion_from_outside_target_surface, l); - l->append(", "); l->append("["); for (size_t i = 0; i < p.shared_quad_state_list.size(); ++i) { diff --git a/content/common/cc_messages_unittest.cc b/content/common/cc_messages_unittest.cc index 4654419..678eca1 100644 --- a/content/common/cc_messages_unittest.cc +++ b/content/common/cc_messages_unittest.cc @@ -46,8 +46,6 @@ class CCMessagesTest : public testing::Test { EXPECT_EQ(a->damage_rect.ToString(), b->damage_rect.ToString()); EXPECT_EQ(a->transform_to_root_target, b->transform_to_root_target); EXPECT_EQ(a->has_transparent_background, b->has_transparent_background); - EXPECT_EQ(a->has_occlusion_from_outside_target_surface, - b->has_occlusion_from_outside_target_surface); } void Compare(const SharedQuadState* a, const SharedQuadState* b) { @@ -404,8 +402,7 @@ TEST_F(CCMessagesTest, AllQuads) { arbitrary_rect1, arbitrary_rectf1, arbitrary_matrix, - arbitrary_bool1, - arbitrary_bool2); + arbitrary_bool1); pass_in->shared_quad_state_list.push_back(shared_state1_in.Pass()); pass_in->quad_list.push_back(checkerboard_in.PassAs<DrawQuad>()); @@ -425,8 +422,7 @@ TEST_F(CCMessagesTest, AllQuads) { arbitrary_rect1, arbitrary_rectf1, arbitrary_matrix, - arbitrary_bool1, - arbitrary_bool2); + arbitrary_bool1); pass_cmp->shared_quad_state_list.push_back(shared_state1_cmp.Pass()); pass_cmp->quad_list.push_back(checkerboard_cmp.PassAs<DrawQuad>()); |