summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-12 17:11:30 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-12 17:11:30 +0000
commit8e1da691f5c68010cd24b6fc468458f248d9b6c8 (patch)
tree40cd5f80d809c7b6eed8f94d10010bb59366188f
parent832c83b1cd554367fed1c53b5d249c6492d08d89 (diff)
downloadchromium_src-8e1da691f5c68010cd24b6fc468458f248d9b6c8.zip
chromium_src-8e1da691f5c68010cd24b6fc468458f248d9b6c8.tar.gz
chromium_src-8e1da691f5c68010cd24b6fc468458f248d9b6c8.tar.bz2
cc: Preserve partial culling from child compositor.
When the child compositor performs occlusion culling and determines what part of the quad is visible, we should preserve this in the browser compositor, and only shrink the visible (unoccluded) rect on quads if we're able due to occlusion in the browser. We should not grow the visible rect ever. Tests: QuadCullerTest.PartialCullingNotDestroyed QuadCullerTest.PartialCullingWithOcclusionNotDestroyed R=alokp@chromium.org, piman BUG=305757 Review URL: https://codereview.chromium.org/26726003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228350 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/layers/picture_layer_impl.cc4
-rw-r--r--cc/layers/tiled_layer_impl.cc5
-rw-r--r--cc/layers/tiled_layer_impl_unittest.cc8
-rw-r--r--cc/layers/ui_resource_layer_impl.cc8
-rw-r--r--cc/quads/draw_quad.cc7
-rw-r--r--cc/quads/draw_quad_unittest.cc16
-rw-r--r--cc/trees/quad_culler.cc6
-rw-r--r--cc/trees/quad_culler_unittest.cc188
-rw-r--r--content/common/cc_messages.cc20
-rw-r--r--content/common/cc_messages_unittest.cc42
10 files changed, 245 insertions, 59 deletions
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 6eba499..d8fe7ab 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -236,7 +236,7 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
case ManagedTileState::TileVersion::RESOURCE_MODE: {
gfx::RectF texture_rect = iter.texture_rect();
gfx::Rect opaque_rect = iter->opaque_rect();
- opaque_rect.Intersect(content_rect);
+ opaque_rect.Intersect(geometry_rect);
if (iter->contents_scale() != ideal_contents_scale_)
append_quads_data->had_incomplete_tile = true;
@@ -255,7 +255,7 @@ void PictureLayerImpl::AppendQuads(QuadSink* quad_sink,
case ManagedTileState::TileVersion::PICTURE_PILE_MODE: {
gfx::RectF texture_rect = iter.texture_rect();
gfx::Rect opaque_rect = iter->opaque_rect();
- opaque_rect.Intersect(content_rect);
+ opaque_rect.Intersect(geometry_rect);
ResourceProvider* resource_provider =
layer_tree_impl()->resource_provider();
diff --git a/cc/layers/tiled_layer_impl.cc b/cc/layers/tiled_layer_impl.cc
index e3852129..b34f71b 100644
--- a/cc/layers/tiled_layer_impl.cc
+++ b/cc/layers/tiled_layer_impl.cc
@@ -232,8 +232,9 @@ void TiledLayerImpl::AppendQuads(QuadSink* quad_sink,
continue;
}
- gfx::Rect tile_opaque_rect = contents_opaque() ? tile_rect :
- gfx::IntersectRects(tile->opaque_rect(), content_rect);
+ gfx::Rect tile_opaque_rect =
+ contents_opaque() ? tile_rect : gfx::IntersectRects(
+ tile->opaque_rect(), tile_rect);
// Keep track of how the top left has moved, so the texture can be
// offset the same amount.
diff --git a/cc/layers/tiled_layer_impl_unittest.cc b/cc/layers/tiled_layer_impl_unittest.cc
index 71e4358..801cbf4 100644
--- a/cc/layers/tiled_layer_impl_unittest.cc
+++ b/cc/layers/tiled_layer_impl_unittest.cc
@@ -57,8 +57,10 @@ class TiledLayerImplTest : public testing::Test {
ResourceProvider::ResourceId resource_id = 1;
for (int i = 0; i < layer->TilingForTesting()->num_tiles_x(); ++i) {
for (int j = 0; j < layer->TilingForTesting()->num_tiles_y(); ++j) {
- layer->PushTileProperties(
- i, j, resource_id++, gfx::Rect(0, 0, 1, 1), false);
+ gfx::Rect opaque_rect(
+ layer->TilingForTesting()->tile_bounds(i, j).origin(),
+ gfx::Size(1, 1));
+ layer->PushTileProperties(i, j, resource_id++, opaque_rect, false);
}
}
@@ -268,7 +270,7 @@ TEST_F(TiledLayerImplTest, TextureInfoForLayerNoBorders) {
<< LayerTestCommon::quad_string << i;
EXPECT_EQ(tile_size, quad->texture_size) << LayerTestCommon::quad_string
<< i;
- EXPECT_EQ(gfx::Rect(0, 0, 1, 1), quad->opaque_rect)
+ EXPECT_EQ(gfx::Size(1, 1).ToString(), quad->opaque_rect.size().ToString())
<< LayerTestCommon::quad_string << i;
}
}
diff --git a/cc/layers/ui_resource_layer_impl.cc b/cc/layers/ui_resource_layer_impl.cc
index cb4d975..faa3171 100644
--- a/cc/layers/ui_resource_layer_impl.cc
+++ b/cc/layers/ui_resource_layer_impl.cc
@@ -80,15 +80,13 @@ void UIResourceLayerImpl::AppendQuads(QuadSink* quad_sink,
DCHECK(!bounds().IsEmpty());
- // TODO(clholgat): Properly calculate opacity: crbug.com/300027
- gfx::Rect opaque_rect;
- if (contents_opaque())
- opaque_rect = gfx::Rect(bounds());
-
gfx::Rect quad_rect(bounds());
gfx::Rect uv_top_left(0.f, 0.f);
gfx::Rect uv_bottom_right(1.f, 1.f);
+ // TODO(clholgat): Properly calculate opacity: crbug.com/300027
+ gfx::Rect opaque_rect(contents_opaque() ? quad_rect : gfx::Rect());
+
const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
scoped_ptr<TextureDrawQuad> quad;
diff --git a/cc/quads/draw_quad.cc b/cc/quads/draw_quad.cc
index 0d021d9..f3cd818 100644
--- a/cc/quads/draw_quad.cc
+++ b/cc/quads/draw_quad.cc
@@ -40,6 +40,13 @@ void DrawQuad::SetAll(const SharedQuadState* shared_quad_state,
gfx::Rect opaque_rect,
gfx::Rect visible_rect,
bool needs_blending) {
+ DCHECK(rect.Contains(visible_rect)) << "rect: " << rect.ToString()
+ << " visible_rect: "
+ << visible_rect.ToString();
+ DCHECK(opaque_rect.IsEmpty() || rect.Contains(opaque_rect))
+ << "rect: " << rect.ToString() << "opaque_rect "
+ << opaque_rect.ToString();
+
this->material = material;
this->rect = rect;
this->opaque_rect = opaque_rect;
diff --git a/cc/quads/draw_quad_unittest.cc b/cc/quads/draw_quad_unittest.cc
index 986d3d6..8180898 100644
--- a/cc/quads/draw_quad_unittest.cc
+++ b/cc/quads/draw_quad_unittest.cc
@@ -352,7 +352,7 @@ TEST(DrawQuadTest, CopyDebugBorderDrawQuad) {
}
TEST(DrawQuadTest, CopyIOSurfaceDrawQuad) {
- gfx::Rect opaque_rect(3, 7, 10, 12);
+ gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::Size size(58, 95);
ResourceProvider::ResourceId resource_id = 72;
IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
@@ -444,7 +444,7 @@ TEST(DrawQuadTest, CopySolidColorDrawQuad) {
}
TEST(DrawQuadTest, CopyStreamVideoDrawQuad) {
- gfx::Rect opaque_rect(3, 7, 10, 12);
+ gfx::Rect opaque_rect(33, 47, 10, 12);
ResourceProvider::ResourceId resource_id = 64;
gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
CREATE_SHARED_STATE();
@@ -462,7 +462,7 @@ TEST(DrawQuadTest, CopyStreamVideoDrawQuad) {
}
TEST(DrawQuadTest, CopyTextureDrawQuad) {
- gfx::Rect opaque_rect(3, 7, 10, 12);
+ gfx::Rect opaque_rect(33, 47, 10, 12);
unsigned resource_id = 82;
bool premultiplied_alpha = true;
gfx::PointF uv_top_left(0.5f, 224.f);
@@ -540,7 +540,7 @@ TEST(DrawQuadTest, CopyTileDrawQuad) {
}
TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
- gfx::Rect opaque_rect(3, 7, 10, 12);
+ gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::SizeF tex_scale(0.75f, 0.5f);
ResourceProvider::ResourceId y_plane_resource_id = 45;
ResourceProvider::ResourceId u_plane_resource_id = 532;
@@ -664,7 +664,7 @@ TEST_F(DrawQuadIteratorTest, DebugBorderDrawQuad) {
}
TEST_F(DrawQuadIteratorTest, IOSurfaceDrawQuad) {
- gfx::Rect opaque_rect(3, 7, 10, 12);
+ gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::Size size(58, 95);
ResourceProvider::ResourceId resource_id = 72;
IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
@@ -719,7 +719,7 @@ TEST_F(DrawQuadIteratorTest, SolidColorDrawQuad) {
}
TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) {
- gfx::Rect opaque_rect(3, 7, 10, 12);
+ gfx::Rect opaque_rect(33, 47, 10, 12);
ResourceProvider::ResourceId resource_id = 64;
gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
@@ -731,7 +731,7 @@ TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) {
}
TEST_F(DrawQuadIteratorTest, TextureDrawQuad) {
- gfx::Rect opaque_rect(3, 7, 10, 12);
+ gfx::Rect opaque_rect(33, 47, 10, 12);
unsigned resource_id = 82;
bool premultiplied_alpha = true;
gfx::PointF uv_top_left(0.5f, 224.f);
@@ -774,7 +774,7 @@ TEST_F(DrawQuadIteratorTest, TileDrawQuad) {
}
TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
- gfx::Rect opaque_rect(3, 7, 10, 12);
+ gfx::Rect opaque_rect(33, 47, 10, 12);
gfx::SizeF tex_scale(0.75f, 0.5f);
ResourceProvider::ResourceId y_plane_resource_id = 45;
ResourceProvider::ResourceId u_plane_resource_id = 532;
diff --git a/cc/trees/quad_culler.cc b/cc/trees/quad_culler.cc
index 6c58d48..2fc8aaa 100644
--- a/cc/trees/quad_culler.cc
+++ b/cc/trees/quad_culler.cc
@@ -88,13 +88,11 @@ bool QuadCuller::Append(scoped_ptr<DrawQuad> draw_quad,
if (for_surface_) {
culled_rect = occlusion_tracker_.UnoccludedContributingSurfaceContentRect(
- layer_,
- false,
- draw_quad->rect);
+ layer_, false, draw_quad->visible_rect);
} else {
culled_rect = occlusion_tracker_.UnoccludedContentRect(
layer_->render_target(),
- draw_quad->rect,
+ draw_quad->visible_rect,
draw_quad->quadTransform(),
impl_draw_transform_is_unknown);
}
diff --git a/cc/trees/quad_culler_unittest.cc b/cc/trees/quad_culler_unittest.cc
index c503de8..28987c7 100644
--- a/cc/trees/quad_culler_unittest.cc
+++ b/cc/trees/quad_culler_unittest.cc
@@ -11,10 +11,13 @@
#include "cc/layers/append_quads_data.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/layers/tiled_layer_impl.h"
+#include "cc/quads/render_pass_draw_quad.h"
+#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/resources/layer_tiling_data.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
+#include "cc/test/occlusion_tracker_test_common.h"
#include "cc/trees/occlusion_tracker.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -24,12 +27,13 @@
namespace cc {
namespace {
-class TestOcclusionTrackerImpl : public OcclusionTrackerImpl {
+class TestOcclusionTrackerImpl
+ : public TestOcclusionTrackerBase<LayerImpl, RenderSurfaceImpl> {
public:
TestOcclusionTrackerImpl(gfx::Rect scissor_rect_in_screen,
bool record_metrics_for_frame = true)
- : OcclusionTrackerImpl(scissor_rect_in_screen, record_metrics_for_frame) {
- }
+ : TestOcclusionTrackerBase(scissor_rect_in_screen,
+ record_metrics_for_frame) {}
private:
DISALLOW_COPY_AND_ASSIGN(TestOcclusionTrackerImpl);
@@ -132,7 +136,7 @@ class QuadCullerTest : public testing::Test {
gfx::Size child_size = gfx::Size(200, 200); \
gfx::Rect child_rect = gfx::Rect(child_size);
-TEST_F(QuadCullerTest, VerifyNoCulling) {
+TEST_F(QuadCullerTest, NoCulling) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
@@ -172,7 +176,7 @@ TEST_F(QuadCullerTest, VerifyNoCulling) {
occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
}
-TEST_F(QuadCullerTest, VerifyCullChildLinesUpTopLeft) {
+TEST_F(QuadCullerTest, CullChildLinesUpTopLeft) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
@@ -212,7 +216,7 @@ TEST_F(QuadCullerTest, VerifyCullChildLinesUpTopLeft) {
1);
}
-TEST_F(QuadCullerTest, VerifyCullWhenChildOpacityNotOne) {
+TEST_F(QuadCullerTest, CullWhenChildOpacityNotOne) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
@@ -252,7 +256,7 @@ TEST_F(QuadCullerTest, VerifyCullWhenChildOpacityNotOne) {
occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
}
-TEST_F(QuadCullerTest, VerifyCullWhenChildOpaqueFlagFalse) {
+TEST_F(QuadCullerTest, CullWhenChildOpaqueFlagFalse) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
@@ -292,7 +296,7 @@ TEST_F(QuadCullerTest, VerifyCullWhenChildOpaqueFlagFalse) {
occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
}
-TEST_F(QuadCullerTest, VerifyCullCenterTileOnly) {
+TEST_F(QuadCullerTest, CullCenterTileOnly) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
child_transform.Translate(50, 50);
@@ -349,7 +353,7 @@ TEST_F(QuadCullerTest, VerifyCullCenterTileOnly) {
1);
}
-TEST_F(QuadCullerTest, VerifyCullCenterTileNonIntegralSize1) {
+TEST_F(QuadCullerTest, CullCenterTileNonIntegralSize1) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
child_transform.Translate(100, 100);
@@ -399,7 +403,7 @@ TEST_F(QuadCullerTest, VerifyCullCenterTileNonIntegralSize1) {
occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
}
-TEST_F(QuadCullerTest, VerifyCullCenterTileNonIntegralSize2) {
+TEST_F(QuadCullerTest, CullCenterTileNonIntegralSize2) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
// Make the child's quad slightly smaller than, and centred over, the root
@@ -450,7 +454,7 @@ TEST_F(QuadCullerTest, VerifyCullCenterTileNonIntegralSize2) {
occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing(), 0, 1);
}
-TEST_F(QuadCullerTest, VerifyCullChildLinesUpBottomRight) {
+TEST_F(QuadCullerTest, CullChildLinesUpBottomRight) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
child_transform.Translate(100, 100);
@@ -491,7 +495,7 @@ TEST_F(QuadCullerTest, VerifyCullChildLinesUpBottomRight) {
1);
}
-TEST_F(QuadCullerTest, VerifyCullSubRegion) {
+TEST_F(QuadCullerTest, CullSubRegion) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
child_transform.Translate(50, 50);
@@ -537,7 +541,7 @@ TEST_F(QuadCullerTest, VerifyCullSubRegion) {
1);
}
-TEST_F(QuadCullerTest, VerifyCullSubRegion2) {
+TEST_F(QuadCullerTest, CullSubRegion2) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
child_transform.Translate(50, 10);
@@ -583,7 +587,7 @@ TEST_F(QuadCullerTest, VerifyCullSubRegion2) {
1);
}
-TEST_F(QuadCullerTest, VerifyCullSubRegionCheckOvercull) {
+TEST_F(QuadCullerTest, CullSubRegionCheckOvercull) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
child_transform.Translate(50, 49);
@@ -629,7 +633,7 @@ TEST_F(QuadCullerTest, VerifyCullSubRegionCheckOvercull) {
1);
}
-TEST_F(QuadCullerTest, VerifyNonAxisAlignedQuadsDontOcclude) {
+TEST_F(QuadCullerTest, NonAxisAlignedQuadsDontOcclude) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
// Use a small rotation so as to not disturb the geometry significantly.
@@ -677,7 +681,7 @@ TEST_F(QuadCullerTest, VerifyNonAxisAlignedQuadsDontOcclude) {
// child would normally occlude, three will move (slightly) out from under the
// child layer, and one moves further under the child. Only this last tile
// should be culled.
-TEST_F(QuadCullerTest, VerifyNonAxisAlignedQuadsSafelyCulled) {
+TEST_F(QuadCullerTest, NonAxisAlignedQuadsSafelyCulled) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
// Use a small rotation so as to not disturb the geometry significantly.
@@ -721,7 +725,7 @@ TEST_F(QuadCullerTest, VerifyNonAxisAlignedQuadsSafelyCulled) {
1);
}
-TEST_F(QuadCullerTest, VerifyWithoutMetrics) {
+TEST_F(QuadCullerTest, WithoutMetrics) {
DECLARE_AND_INITIALIZE_TEST_QUADS();
scoped_ptr<TiledLayerImpl> root_layer = MakeLayer(NULL,
gfx::Transform(),
@@ -761,5 +765,155 @@ TEST_F(QuadCullerTest, VerifyWithoutMetrics) {
occlusion_tracker.overdraw_metrics()->pixels_culled_for_drawing());
}
+TEST_F(QuadCullerTest, PartialCullingNotDestroyed) {
+ DECLARE_AND_INITIALIZE_TEST_QUADS();
+
+ scoped_ptr<TiledLayerImpl> dummy_layer = MakeLayer(NULL,
+ gfx::Transform(),
+ gfx::Rect(),
+ 1.f,
+ true,
+ gfx::Rect(),
+ render_surface_layer_list);
+
+ TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(1000, 1000));
+ LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
+
+ QuadCuller culler(&quad_list,
+ &shared_state_list,
+ dummy_layer.get(),
+ occlusion_tracker,
+ false,
+ false);
+
+ SharedQuadState* sqs = culler.UseSharedQuadState(SharedQuadState::Create());
+
+ scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
+ color_quad->SetNew(sqs, gfx::Rect(100, 100), SK_ColorRED, false);
+
+ scoped_ptr<RenderPassDrawQuad> pass_quad = RenderPassDrawQuad::Create();
+ pass_quad->SetNew(sqs,
+ gfx::Rect(100, 100),
+ RenderPass::Id(10, 10),
+ false,
+ 0,
+ gfx::Rect(),
+ gfx::RectF(),
+ FilterOperations(),
+ FilterOperations());
+
+ scoped_ptr<RenderPassDrawQuad> replica_quad = RenderPassDrawQuad::Create();
+ replica_quad->SetNew(sqs,
+ gfx::Rect(100, 100),
+ RenderPass::Id(10, 10),
+ true,
+ 0,
+ gfx::Rect(),
+ gfx::RectF(),
+ FilterOperations(),
+ FilterOperations());
+
+ // Set a visible rect on the quads.
+ color_quad->visible_rect = gfx::Rect(20, 30, 10, 11);
+ pass_quad->visible_rect = gfx::Rect(50, 60, 13, 14);
+ replica_quad->visible_rect = gfx::Rect(30, 40, 15, 16);
+
+ // Nothing is occluding.
+ occlusion_tracker.EnterLayer(it, false);
+
+ EXPECT_EQ(0u, quad_list.size());
+
+ AppendQuadsData data;
+ culler.Append(color_quad.PassAs<DrawQuad>(), &data);
+ culler.Append(pass_quad.PassAs<DrawQuad>(), &data);
+ culler.Append(replica_quad.PassAs<DrawQuad>(), &data);
+
+ ASSERT_EQ(3u, quad_list.size());
+
+ // The partial culling is preserved.
+ EXPECT_EQ(gfx::Rect(20, 30, 10, 11).ToString(),
+ quad_list[0]->visible_rect.ToString());
+ EXPECT_EQ(gfx::Rect(50, 60, 13, 14).ToString(),
+ quad_list[1]->visible_rect.ToString());
+ EXPECT_EQ(gfx::Rect(30, 40, 15, 16).ToString(),
+ quad_list[2]->visible_rect.ToString());
+}
+
+TEST_F(QuadCullerTest, PartialCullingWithOcclusionNotDestroyed) {
+ DECLARE_AND_INITIALIZE_TEST_QUADS();
+
+ scoped_ptr<TiledLayerImpl> dummy_layer = MakeLayer(NULL,
+ gfx::Transform(),
+ gfx::Rect(),
+ 1.f,
+ true,
+ gfx::Rect(),
+ render_surface_layer_list);
+
+ TestOcclusionTrackerImpl occlusion_tracker(gfx::Rect(1000, 1000));
+ LayerIteratorType it = LayerIteratorType::Begin(&render_surface_layer_list);
+
+ QuadCuller culler(&quad_list,
+ &shared_state_list,
+ dummy_layer.get(),
+ occlusion_tracker,
+ false,
+ false);
+
+ SharedQuadState* sqs = culler.UseSharedQuadState(SharedQuadState::Create());
+
+ scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
+ color_quad->SetNew(sqs, gfx::Rect(100, 100), SK_ColorRED, false);
+
+ scoped_ptr<RenderPassDrawQuad> pass_quad = RenderPassDrawQuad::Create();
+ pass_quad->SetNew(sqs,
+ gfx::Rect(100, 100),
+ RenderPass::Id(10, 10),
+ false,
+ 0,
+ gfx::Rect(),
+ gfx::RectF(),
+ FilterOperations(),
+ FilterOperations());
+
+ scoped_ptr<RenderPassDrawQuad> replica_quad = RenderPassDrawQuad::Create();
+ replica_quad->SetNew(sqs,
+ gfx::Rect(100, 100),
+ RenderPass::Id(10, 10),
+ true,
+ 0,
+ gfx::Rect(),
+ gfx::RectF(),
+ FilterOperations(),
+ FilterOperations());
+
+ // Set a visible rect on the quads.
+ color_quad->visible_rect = gfx::Rect(10, 10, 10, 11);
+ pass_quad->visible_rect = gfx::Rect(10, 20, 13, 14);
+ replica_quad->visible_rect = gfx::Rect(10, 30, 15, 16);
+
+ // Occlude the left part of the visible rects.
+ occlusion_tracker.EnterLayer(it, false);
+ occlusion_tracker.set_occlusion_from_outside_target(gfx::Rect(0, 0, 15, 100));
+
+ EXPECT_EQ(0u, quad_list.size());
+
+ AppendQuadsData data;
+ culler.Append(color_quad.PassAs<DrawQuad>(), &data);
+ culler.Append(pass_quad.PassAs<DrawQuad>(), &data);
+ culler.Append(replica_quad.PassAs<DrawQuad>(), &data);
+
+ ASSERT_EQ(3u, quad_list.size());
+
+ // The partial culling is preserved, while the left side of the quads is newly
+ // occluded.
+ EXPECT_EQ(gfx::Rect(15, 10, 5, 11).ToString(),
+ quad_list[0]->visible_rect.ToString());
+ EXPECT_EQ(gfx::Rect(15, 20, 8, 14).ToString(),
+ quad_list[1]->visible_rect.ToString());
+ EXPECT_EQ(gfx::Rect(15, 30, 10, 16).ToString(),
+ quad_list[2]->visible_rect.ToString());
+}
+
} // namespace
} // namespace cc
diff --git a/content/common/cc_messages.cc b/content/common/cc_messages.cc
index 31cb997..dc389a6 100644
--- a/content/common/cc_messages.cc
+++ b/content/common/cc_messages.cc
@@ -361,6 +361,13 @@ void ParamTraits<cc::RenderPass>::Write(
size_t shared_quad_state_index = 0;
for (size_t i = 0; i < p.quad_list.size(); ++i) {
const cc::DrawQuad* quad = p.quad_list[i];
+ DCHECK(quad->rect.Contains(quad->visible_rect))
+ << quad->material << " rect: " << quad->rect.ToString()
+ << " visible_rect: " << quad->visible_rect.ToString();
+ DCHECK(quad->opaque_rect.IsEmpty() ||
+ quad->rect.Contains(quad->opaque_rect))
+ << quad->material << " rect: " << quad->rect.ToString()
+ << " opaque_rect: " << quad->opaque_rect.ToString();
switch (quad->material) {
case cc::DrawQuad::CHECKERBOARD:
@@ -512,6 +519,19 @@ bool ParamTraits<cc::RenderPass>::Read(
}
if (!draw_quad)
return false;
+ if (!draw_quad->rect.Contains(draw_quad->visible_rect)) {
+ LOG(ERROR) << "Quad with invalid visible rect " << draw_quad->material
+ << " rect: " << draw_quad->rect.ToString()
+ << " visible_rect: " << draw_quad->visible_rect.ToString();
+ return false;
+ }
+ if (!draw_quad->opaque_rect.IsEmpty() &&
+ !draw_quad->rect.Contains(draw_quad->opaque_rect)) {
+ LOG(ERROR) << "Quad with invalid opaque rect " << draw_quad->material
+ << " rect: " << draw_quad->rect.ToString()
+ << " opaque_rect: " << draw_quad->opaque_rect.ToString();
+ return false;
+ }
size_t shared_quad_state_index;
if (!ReadParam(m, iter, &shared_quad_state_index) ||
diff --git a/content/common/cc_messages_unittest.cc b/content/common/cc_messages_unittest.cc
index ab3798c..6ba87ad 100644
--- a/content/common/cc_messages_unittest.cc
+++ b/content/common/cc_messages_unittest.cc
@@ -210,8 +210,14 @@ TEST_F(CCMessagesTest, AllQuads) {
arbitrary_matrix.Translate(-5, 20);
arbitrary_matrix.Rotate(15);
gfx::Rect arbitrary_rect1(-5, 9, 3, 15);
+ gfx::Rect arbitrary_rect1_inside_rect1(-4, 12, 2, 8);
+ gfx::Rect arbitrary_rect2_inside_rect1(-5, 11, 1, 2);
gfx::Rect arbitrary_rect2(40, 23, 11, 7);
+ gfx::Rect arbitrary_rect1_inside_rect2(44, 23, 4, 2);
+ gfx::Rect arbitrary_rect2_inside_rect2(41, 25, 3, 5);
gfx::Rect arbitrary_rect3(7, -53, 22, 19);
+ gfx::Rect arbitrary_rect1_inside_rect3(10, -40, 6, 3);
+ gfx::Rect arbitrary_rect2_inside_rect3(12, -51, 5, 12);
gfx::Size arbitrary_size1(15, 19);
gfx::Size arbitrary_size2(3, 99);
gfx::Size arbitrary_size3(75, 1281);
@@ -262,8 +268,8 @@ TEST_F(CCMessagesTest, AllQuads) {
CheckerboardDrawQuad::Create();
checkerboard_in->SetAll(shared_state1_in.get(),
arbitrary_rect1,
- arbitrary_rect2,
- arbitrary_rect3,
+ arbitrary_rect2_inside_rect1,
+ arbitrary_rect1_inside_rect1,
arbitrary_bool1,
arbitrary_color);
scoped_ptr<DrawQuad> checkerboard_cmp = checkerboard_in->Copy(
@@ -273,8 +279,8 @@ TEST_F(CCMessagesTest, AllQuads) {
DebugBorderDrawQuad::Create();
debugborder_in->SetAll(shared_state1_in.get(),
arbitrary_rect3,
- arbitrary_rect1,
- arbitrary_rect2,
+ arbitrary_rect1_inside_rect3,
+ arbitrary_rect2_inside_rect3,
arbitrary_bool1,
arbitrary_color,
arbitrary_int);
@@ -285,8 +291,8 @@ TEST_F(CCMessagesTest, AllQuads) {
IOSurfaceDrawQuad::Create();
iosurface_in->SetAll(shared_state1_in.get(),
arbitrary_rect2,
- arbitrary_rect3,
- arbitrary_rect1,
+ arbitrary_rect2_inside_rect2,
+ arbitrary_rect1_inside_rect2,
arbitrary_bool1,
arbitrary_size1,
arbitrary_resourceid3,
@@ -298,8 +304,8 @@ TEST_F(CCMessagesTest, AllQuads) {
RenderPassDrawQuad::Create();
renderpass_in->SetAll(shared_state1_in.get(),
arbitrary_rect1,
- arbitrary_rect2,
- arbitrary_rect3,
+ arbitrary_rect2_inside_rect1,
+ arbitrary_rect1_inside_rect1,
arbitrary_bool1,
arbitrary_id,
arbitrary_bool2,
@@ -333,8 +339,8 @@ TEST_F(CCMessagesTest, AllQuads) {
SolidColorDrawQuad::Create();
solidcolor_in->SetAll(shared_state1_in.get(),
arbitrary_rect3,
- arbitrary_rect1,
- arbitrary_rect2,
+ arbitrary_rect1_inside_rect3,
+ arbitrary_rect2_inside_rect3,
arbitrary_bool1,
arbitrary_color,
arbitrary_bool2);
@@ -345,8 +351,8 @@ TEST_F(CCMessagesTest, AllQuads) {
StreamVideoDrawQuad::Create();
streamvideo_in->SetAll(shared_state1_in.get(),
arbitrary_rect2,
- arbitrary_rect3,
- arbitrary_rect1,
+ arbitrary_rect2_inside_rect2,
+ arbitrary_rect1_inside_rect2,
arbitrary_bool1,
arbitrary_resourceid2,
arbitrary_matrix);
@@ -356,8 +362,8 @@ TEST_F(CCMessagesTest, AllQuads) {
scoped_ptr<TextureDrawQuad> texture_in = TextureDrawQuad::Create();
texture_in->SetAll(shared_state1_in.get(),
arbitrary_rect2,
- arbitrary_rect3,
- arbitrary_rect1,
+ arbitrary_rect2_inside_rect2,
+ arbitrary_rect1_inside_rect2,
arbitrary_bool1,
arbitrary_resourceid1,
arbitrary_bool2,
@@ -372,8 +378,8 @@ TEST_F(CCMessagesTest, AllQuads) {
scoped_ptr<TileDrawQuad> tile_in = TileDrawQuad::Create();
tile_in->SetAll(shared_state1_in.get(),
arbitrary_rect2,
- arbitrary_rect3,
- arbitrary_rect1,
+ arbitrary_rect2_inside_rect2,
+ arbitrary_rect1_inside_rect2,
arbitrary_bool1,
arbitrary_resourceid3,
arbitrary_rectf1,
@@ -386,8 +392,8 @@ TEST_F(CCMessagesTest, AllQuads) {
YUVVideoDrawQuad::Create();
yuvvideo_in->SetAll(shared_state1_in.get(),
arbitrary_rect1,
- arbitrary_rect2,
- arbitrary_rect3,
+ arbitrary_rect2_inside_rect1,
+ arbitrary_rect1_inside_rect1,
arbitrary_bool1,
arbitrary_sizef1,
arbitrary_resourceid1,