summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-21 18:41:10 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-21 18:41:10 +0000
commitba0f8d96f0b836e450aba1828769c4313278d3d1 (patch)
tree46baad36af7345108a66dd2e18a9f80292d365f1 /cc
parent6cde1bf32a99da8b48e73f0d9e27bdd939a4e47c (diff)
downloadchromium_src-ba0f8d96f0b836e450aba1828769c4313278d3d1.zip
chromium_src-ba0f8d96f0b836e450aba1828769c4313278d3d1.tar.gz
chromium_src-ba0f8d96f0b836e450aba1828769c4313278d3d1.tar.bz2
cc: Apply occlusion before creating quads in RenderSurfaceImpl.
This makes the AppendQuads method query occlusion directly and subtract it from the quads it would create before they are created, skipping quads that are completely occluded and avoiding a malloc/free for them. Depends on: https://codereview.chromium.org/205443002/ Depends on: https://codereview.chromium.org/203463015/ R=enne BUG=344962 Review URL: https://codereview.chromium.org/205503002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258633 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r--cc/cc_tests.gyp1
-rw-r--r--cc/layers/quad_sink.h5
-rw-r--r--cc/layers/render_surface_impl.cc15
-rw-r--r--cc/layers/render_surface_impl_unittest.cc68
-rw-r--r--cc/test/layer_test_common.cc12
-rw-r--r--cc/test/layer_test_common.h4
-rw-r--r--cc/test/mock_quad_culler.cc11
-rw-r--r--cc/test/mock_quad_culler.h9
-rw-r--r--cc/trees/quad_culler.cc7
-rw-r--r--cc/trees/quad_culler.h3
10 files changed, 129 insertions, 6 deletions
diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp
index 0c7bb62..14696e7 100644
--- a/cc/cc_tests.gyp
+++ b/cc/cc_tests.gyp
@@ -41,6 +41,7 @@
'layers/picture_layer_impl_unittest.cc',
'layers/picture_layer_unittest.cc',
'layers/render_surface_unittest.cc',
+ 'layers/render_surface_impl_unittest.cc',
'layers/scrollbar_layer_unittest.cc',
'layers/solid_color_layer_impl_unittest.cc',
'layers/solid_color_scrollbar_layer_impl_unittest.cc',
diff --git a/cc/layers/quad_sink.h b/cc/layers/quad_sink.h
index 1b82470..add4e99 100644
--- a/cc/layers/quad_sink.h
+++ b/cc/layers/quad_sink.h
@@ -16,6 +16,7 @@ class Transform;
namespace cc {
class DrawQuad;
+class LayerImpl;
class SharedQuadState;
class CC_EXPORT QuadSink {
@@ -32,6 +33,10 @@ class CC_EXPORT QuadSink {
const gfx::Rect& content_rect,
const gfx::Transform& draw_transform) = 0;
+ virtual gfx::Rect UnoccludedContributingSurfaceContentRect(
+ const gfx::Rect& content_rect,
+ const gfx::Transform& draw_transform) = 0;
+
// Returns true if the quad is added to the list, and false if the quad is
// entirely culled.
virtual bool MaybeAppend(scoped_ptr<DrawQuad> draw_quad) = 0;
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc
index 9a1edbf..ddb7158 100644
--- a/cc/layers/render_surface_impl.cc
+++ b/cc/layers/render_surface_impl.cc
@@ -143,6 +143,12 @@ void RenderSurfaceImpl::AppendQuads(QuadSink* quad_sink,
const gfx::Transform& draw_transform =
for_replica ? replica_draw_transform_ : draw_transform_;
+ gfx::Rect visible_content_rect =
+ quad_sink->UnoccludedContributingSurfaceContentRect(content_rect_,
+ draw_transform);
+ if (visible_content_rect.IsEmpty())
+ return;
+
SharedQuadState* shared_quad_state =
quad_sink->UseSharedQuadState(SharedQuadState::Create());
shared_quad_state->SetAll(draw_transform,
@@ -154,8 +160,6 @@ void RenderSurfaceImpl::AppendQuads(QuadSink* quad_sink,
owning_layer_->blend_mode());
if (owning_layer_->ShowDebugBorders()) {
- gfx::Rect quad_rect = content_rect_;
- gfx::Rect visible_quad_rect = quad_rect;
SkColor color = for_replica ?
DebugColors::SurfaceReplicaBorderColor() :
DebugColors::SurfaceBorderColor();
@@ -167,8 +171,8 @@ void RenderSurfaceImpl::AppendQuads(QuadSink* quad_sink,
scoped_ptr<DebugBorderDrawQuad> debug_border_quad =
DebugBorderDrawQuad::Create();
debug_border_quad->SetNew(
- shared_quad_state, quad_rect, visible_quad_rect, color, width);
- quad_sink->MaybeAppend(debug_border_quad.PassAs<DrawQuad>());
+ shared_quad_state, content_rect_, visible_content_rect, color, width);
+ quad_sink->Append(debug_border_quad.PassAs<DrawQuad>());
}
// TODO(shawnsingh): By using the same RenderSurfaceImpl for both the content
@@ -212,7 +216,6 @@ void RenderSurfaceImpl::AppendQuads(QuadSink* quad_sink,
uv_scale_y);
}
- gfx::Rect visible_content_rect(content_rect_);
ResourceProvider::ResourceId mask_resource_id =
mask_layer ? mask_layer->ContentsResourceId() : 0;
gfx::Rect contents_changed_since_last_frame =
@@ -229,7 +232,7 @@ void RenderSurfaceImpl::AppendQuads(QuadSink* quad_sink,
mask_uv_rect,
owning_layer_->filters(),
owning_layer_->background_filters());
- quad_sink->MaybeAppend(quad.PassAs<DrawQuad>());
+ quad_sink->Append(quad.PassAs<DrawQuad>());
}
} // namespace cc
diff --git a/cc/layers/render_surface_impl_unittest.cc b/cc/layers/render_surface_impl_unittest.cc
new file mode 100644
index 0000000..20c2afb
--- /dev/null
+++ b/cc/layers/render_surface_impl_unittest.cc
@@ -0,0 +1,68 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/layers/render_surface_impl.h"
+
+#include "cc/test/layer_test_common.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+namespace {
+
+TEST(RenderSurfaceLayerImplTest, Occlusion) {
+ gfx::Size layer_size(1000, 1000);
+ gfx::Size viewport_size(1000, 1000);
+
+ LayerTestCommon::LayerImplTest impl;
+
+ LayerImpl* owning_layer_impl = impl.AddChildToRoot<LayerImpl>();
+ owning_layer_impl->SetAnchorPoint(gfx::PointF());
+ owning_layer_impl->SetBounds(layer_size);
+ owning_layer_impl->SetContentBounds(layer_size);
+ owning_layer_impl->SetDrawsContent(true);
+ owning_layer_impl->SetForceRenderSurface(true);
+
+ impl.CalcDrawProps(viewport_size);
+
+ RenderSurfaceImpl* render_surface_impl = owning_layer_impl->render_surface();
+ ASSERT_TRUE(render_surface_impl);
+
+ {
+ SCOPED_TRACE("No occlusion");
+ gfx::Rect occluded;
+ impl.AppendSurfaceQuadsWithOcclusion(render_surface_impl, occluded);
+
+ LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
+ gfx::Rect(layer_size));
+ EXPECT_EQ(1u, impl.quad_list().size());
+ }
+
+ {
+ SCOPED_TRACE("Full occlusion");
+ gfx::Rect occluded(owning_layer_impl->visible_content_rect());
+ impl.AppendSurfaceQuadsWithOcclusion(render_surface_impl, occluded);
+
+ LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
+ EXPECT_EQ(impl.quad_list().size(), 0u);
+ }
+
+ {
+ SCOPED_TRACE("Partial occlusion");
+ gfx::Rect occluded(200, 0, 800, 1000);
+ impl.AppendSurfaceQuadsWithOcclusion(render_surface_impl, occluded);
+
+ size_t partially_occluded_count = 0;
+ LayerTestCommon::VerifyQuadsCoverRectWithOcclusion(
+ impl.quad_list(),
+ gfx::Rect(layer_size),
+ occluded,
+ &partially_occluded_count);
+ // The layer outputs one quad, which is partially occluded.
+ EXPECT_EQ(1u, impl.quad_list().size());
+ EXPECT_EQ(1u, partially_occluded_count);
+ }
+}
+
+} // namespace
+} // namespace cc
diff --git a/cc/test/layer_test_common.cc b/cc/test/layer_test_common.cc
index 31a16e1..beffb20 100644
--- a/cc/test/layer_test_common.cc
+++ b/cc/test/layer_test_common.cc
@@ -120,4 +120,16 @@ void LayerTestCommon::LayerImplTest::AppendQuadsWithOcclusion(
layer_impl->DidDraw(resource_provider());
}
+void LayerTestCommon::LayerImplTest::AppendSurfaceQuadsWithOcclusion(
+ RenderSurfaceImpl* surface_impl,
+ const gfx::Rect& occluded) {
+ AppendQuadsData data;
+
+ quad_culler_.clear_lists();
+ quad_culler_.set_occluded_content_rect_for_contributing_surface(occluded);
+ bool for_replica = false;
+ RenderPass::Id id(1, 1);
+ surface_impl->AppendQuads(&quad_culler_, &data, for_replica, id);
+}
+
} // namespace cc
diff --git a/cc/test/layer_test_common.h b/cc/test/layer_test_common.h
index cb56417..0652183 100644
--- a/cc/test/layer_test_common.h
+++ b/cc/test/layer_test_common.h
@@ -28,8 +28,10 @@
namespace gfx { class Rect; }
namespace cc {
+class LayerImpl;
class OutputSurface;
class QuadList;
+class RenderSurfaceImpl;
class ResourceProvider;
class LayerTestCommon {
@@ -78,6 +80,8 @@ class LayerTestCommon {
void CalcDrawProps(const gfx::Size& viewport_size);
void AppendQuadsWithOcclusion(LayerImpl* layer_impl,
const gfx::Rect& occluded);
+ void AppendSurfaceQuadsWithOcclusion(RenderSurfaceImpl* surface_impl,
+ const gfx::Rect& occluded);
OutputSurface* output_surface() const {
return host_->host_impl()->output_surface();
diff --git a/cc/test/mock_quad_culler.cc b/cc/test/mock_quad_culler.cc
index d15f126..54d631c 100644
--- a/cc/test/mock_quad_culler.cc
+++ b/cc/test/mock_quad_culler.cc
@@ -30,11 +30,22 @@ SharedQuadState* MockQuadCuller::UseSharedQuadState(
gfx::Rect MockQuadCuller::UnoccludedContentRect(
const gfx::Rect& content_rect,
const gfx::Transform& draw_transform) {
+ DCHECK(draw_transform.IsIdentity() || occluded_content_rect_.IsEmpty());
gfx::Rect result = content_rect;
result.Subtract(occluded_content_rect_);
return result;
}
+gfx::Rect MockQuadCuller::UnoccludedContributingSurfaceContentRect(
+ const gfx::Rect& content_rect,
+ const gfx::Transform& draw_transform) {
+ DCHECK(draw_transform.IsIdentity() ||
+ occluded_content_rect_for_contributing_surface_.IsEmpty());
+ gfx::Rect result = content_rect;
+ result.Subtract(occluded_content_rect_for_contributing_surface_);
+ return result;
+}
+
bool MockQuadCuller::MaybeAppend(scoped_ptr<DrawQuad> draw_quad) {
if (!draw_quad->rect.IsEmpty()) {
active_quad_list_->push_back(draw_quad.Pass());
diff --git a/cc/test/mock_quad_culler.h b/cc/test/mock_quad_culler.h
index 543b8ec..2d9486b 100644
--- a/cc/test/mock_quad_culler.h
+++ b/cc/test/mock_quad_culler.h
@@ -26,6 +26,9 @@ class MockQuadCuller : public QuadSink {
virtual gfx::Rect UnoccludedContentRect(const gfx::Rect& content_rect,
const gfx::Transform& draw_transform)
OVERRIDE;
+ virtual gfx::Rect UnoccludedContributingSurfaceContentRect(
+ const gfx::Rect& content_rect,
+ const gfx::Transform& draw_transform) OVERRIDE;
virtual bool MaybeAppend(scoped_ptr<DrawQuad> draw_quad) OVERRIDE;
virtual void Append(scoped_ptr<DrawQuad> draw_quad) OVERRIDE;
@@ -38,6 +41,11 @@ class MockQuadCuller : public QuadSink {
occluded_content_rect_ = occluded;
}
+ void set_occluded_content_rect_for_contributing_surface(
+ const gfx::Rect& occluded) {
+ occluded_content_rect_for_contributing_surface_ = occluded;
+ }
+
void clear_lists() {
active_quad_list_->clear();
active_shared_quad_state_list_->clear();
@@ -49,6 +57,7 @@ class MockQuadCuller : public QuadSink {
SharedQuadStateList* active_shared_quad_state_list_;
SharedQuadStateList shared_quad_state_storage_;
gfx::Rect occluded_content_rect_;
+ gfx::Rect occluded_content_rect_for_contributing_surface_;
};
} // namespace cc
diff --git a/cc/trees/quad_culler.cc b/cc/trees/quad_culler.cc
index f161f64..68ef157 100644
--- a/cc/trees/quad_culler.cc
+++ b/cc/trees/quad_culler.cc
@@ -44,6 +44,13 @@ gfx::Rect QuadCuller::UnoccludedContentRect(
layer_->render_target(), content_rect, draw_transform);
}
+gfx::Rect QuadCuller::UnoccludedContributingSurfaceContentRect(
+ const gfx::Rect& content_rect,
+ const gfx::Transform& draw_transform) {
+ return occlusion_tracker_.UnoccludedContributingSurfaceContentRect(
+ layer_, content_rect, draw_transform);
+}
+
static inline bool AppendQuadInternal(
scoped_ptr<DrawQuad> draw_quad,
const gfx::Rect& culled_rect,
diff --git a/cc/trees/quad_culler.h b/cc/trees/quad_culler.h
index 74aae6d..de2aa3e 100644
--- a/cc/trees/quad_culler.h
+++ b/cc/trees/quad_culler.h
@@ -30,6 +30,9 @@ class CC_EXPORT QuadCuller : public QuadSink {
virtual gfx::Rect UnoccludedContentRect(const gfx::Rect& content_rect,
const gfx::Transform& draw_transform)
OVERRIDE;
+ virtual gfx::Rect UnoccludedContributingSurfaceContentRect(
+ const gfx::Rect& content_rect,
+ const gfx::Transform& draw_transform) OVERRIDE;
virtual bool MaybeAppend(scoped_ptr<DrawQuad> draw_quad) OVERRIDE;
virtual void Append(scoped_ptr<DrawQuad> draw_quad) OVERRIDE;