Temporarily re-enabling SizeAfterPrefChange test with traces.
[chromium-blink-merge.git] / cc / resources / picture_pile_unittest.cc
blob03878630f6329831d46fa68ed629586c11f93697
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <map>
6 #include <utility>
8 #include "cc/resources/picture_pile.h"
9 #include "cc/test/fake_content_layer_client.h"
10 #include "cc/test/fake_rendering_stats_instrumentation.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gfx/rect_conversions.h"
13 #include "ui/gfx/size_conversions.h"
15 namespace cc {
16 namespace {
18 class TestPicturePile : public PicturePile {
19 public:
20 using PicturePile::buffer_pixels;
21 using PicturePile::CanRasterSlowTileCheck;
22 using PicturePile::Clear;
24 PictureMap& picture_map() { return picture_map_; }
25 const gfx::Rect& recorded_viewport() const { return recorded_viewport_; }
27 bool CanRasterLayerRect(const gfx::Rect& layer_rect) {
28 return CanRaster(1.f, layer_rect);
31 typedef PicturePile::PictureInfo PictureInfo;
32 typedef PicturePile::PictureMapKey PictureMapKey;
33 typedef PicturePile::PictureMap PictureMap;
35 protected:
36 virtual ~TestPicturePile() {}
39 class PicturePileTest : public testing::Test {
40 public:
41 PicturePileTest()
42 : pile_(new TestPicturePile()),
43 background_color_(SK_ColorBLUE),
44 min_scale_(0.125),
45 frame_number_(0),
46 contents_opaque_(false) {
47 pile_->SetTilingRect(gfx::Rect(pile_->tiling().max_texture_size()));
48 pile_->SetTileGridSize(gfx::Size(1000, 1000));
49 pile_->SetMinContentsScale(min_scale_);
52 gfx::Rect tiling_rect() const { return pile_->tiling_rect(); }
54 bool Update(const Region& invalidation, const gfx::Rect& visible_layer_rect) {
55 frame_number_++;
56 return pile_->Update(&client_,
57 background_color_,
58 contents_opaque_,
59 false,
60 invalidation,
61 visible_layer_rect,
62 frame_number_,
63 Picture::RECORD_NORMALLY,
64 &stats_instrumentation_);
67 bool UpdateWholePile() { return Update(tiling_rect(), tiling_rect()); }
69 FakeContentLayerClient client_;
70 FakeRenderingStatsInstrumentation stats_instrumentation_;
71 scoped_refptr<TestPicturePile> pile_;
72 SkColor background_color_;
73 float min_scale_;
74 int frame_number_;
75 bool contents_opaque_;
78 TEST_F(PicturePileTest, SmallInvalidateInflated) {
79 UpdateWholePile();
81 // Invalidate something inside a tile.
82 gfx::Rect invalidate_rect(50, 50, 1, 1);
83 Update(invalidate_rect, tiling_rect());
85 EXPECT_EQ(1, pile_->tiling().num_tiles_x());
86 EXPECT_EQ(1, pile_->tiling().num_tiles_y());
88 TestPicturePile::PictureInfo& picture_info =
89 pile_->picture_map().find(TestPicturePile::PictureMapKey(0, 0))->second;
90 // We should have a picture.
91 EXPECT_TRUE(!!picture_info.GetPicture());
92 gfx::Rect picture_rect = gfx::ScaleToEnclosedRect(
93 picture_info.GetPicture()->LayerRect(), min_scale_);
95 // The the picture should be large enough that scaling it never makes a rect
96 // smaller than 1 px wide or tall.
97 EXPECT_FALSE(picture_rect.IsEmpty()) << "Picture rect " <<
98 picture_rect.ToString();
101 TEST_F(PicturePileTest, LargeInvalidateInflated) {
102 UpdateWholePile();
104 // Invalidate something inside a tile.
105 gfx::Rect invalidate_rect(50, 50, 100, 100);
106 Update(invalidate_rect, tiling_rect());
108 EXPECT_EQ(1, pile_->tiling().num_tiles_x());
109 EXPECT_EQ(1, pile_->tiling().num_tiles_y());
111 TestPicturePile::PictureInfo& picture_info =
112 pile_->picture_map().find(TestPicturePile::PictureMapKey(0, 0))->second;
113 EXPECT_TRUE(!!picture_info.GetPicture());
115 int expected_inflation = pile_->buffer_pixels();
117 Picture* base_picture = picture_info.GetPicture();
118 gfx::Rect base_picture_rect = pile_->tiling_rect();
119 base_picture_rect.Inset(-expected_inflation, -expected_inflation);
120 EXPECT_EQ(base_picture_rect.ToString(),
121 base_picture->LayerRect().ToString());
124 TEST_F(PicturePileTest, InvalidateOnTileBoundaryInflated) {
125 gfx::Rect new_tiling_rect =
126 gfx::ToEnclosedRect(gfx::ScaleRect(pile_->tiling_rect(), 2.f));
127 pile_->SetTilingRect(new_tiling_rect);
129 // Due to border pixels, we should have 3 tiles.
130 EXPECT_EQ(3, pile_->tiling().num_tiles_x());
131 EXPECT_EQ(3, pile_->tiling().num_tiles_y());
133 // We should have 1/.125 - 1 = 7 border pixels.
134 EXPECT_EQ(7, pile_->buffer_pixels());
135 EXPECT_EQ(7, pile_->tiling().border_texels());
137 // Update the whole layer to create initial pictures.
138 UpdateWholePile();
140 // Invalidate everything again to have a non zero invalidation
141 // frequency.
142 UpdateWholePile();
144 // Invalidate something just over a tile boundary by a single pixel.
145 // This will invalidate the tile (1, 1), as well as 1 row of pixels in (1, 0).
146 gfx::Rect invalidate_rect(
147 pile_->tiling().TileBoundsWithBorder(0, 0).right(),
148 pile_->tiling().TileBoundsWithBorder(0, 0).bottom() - 1,
150 50);
151 Update(invalidate_rect, tiling_rect());
153 for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
154 for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
155 TestPicturePile::PictureInfo& picture_info =
156 pile_->picture_map()
157 .find(TestPicturePile::PictureMapKey(i, j))
158 ->second;
160 // Expect (1, 1) and (1, 0) to be invalidated once more
161 // than the rest of the tiles.
162 if (i == 1 && (j == 0 || j == 1)) {
163 EXPECT_FLOAT_EQ(
164 2.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
165 picture_info.GetInvalidationFrequencyForTesting());
166 } else {
167 EXPECT_FLOAT_EQ(
168 1.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
169 picture_info.GetInvalidationFrequencyForTesting());
175 TEST_F(PicturePileTest, StopRecordingOffscreenInvalidations) {
176 gfx::Rect new_tiling_rect =
177 gfx::ToEnclosedRect(gfx::ScaleRect(pile_->tiling_rect(), 4.f));
178 pile_->SetTilingRect(new_tiling_rect);
180 gfx::Rect viewport(
181 tiling_rect().x(), tiling_rect().y(), tiling_rect().width(), 1);
183 // Update the whole pile until the invalidation frequency is high.
184 for (int frame = 0; frame < 33; ++frame) {
185 UpdateWholePile();
188 // Make sure we have a high invalidation frequency.
189 for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
190 for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
191 TestPicturePile::PictureInfo& picture_info =
192 pile_->picture_map()
193 .find(TestPicturePile::PictureMapKey(i, j))
194 ->second;
195 EXPECT_FLOAT_EQ(1.0f, picture_info.GetInvalidationFrequencyForTesting())
196 << "i " << i << " j " << j;
200 // Update once more with a small viewport tiilng_rect.x(), tiilng_rect.y(),
201 // tiling_rect.width() by 1
202 Update(tiling_rect(), viewport);
204 for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
205 for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
206 TestPicturePile::PictureInfo& picture_info =
207 pile_->picture_map()
208 .find(TestPicturePile::PictureMapKey(i, j))
209 ->second;
210 EXPECT_FLOAT_EQ(1.0f, picture_info.GetInvalidationFrequencyForTesting());
212 // If the y far enough away we expect to find no picture (no re-recording
213 // happened). For close y, the picture should change.
214 if (j >= 2)
215 EXPECT_FALSE(picture_info.GetPicture()) << "i " << i << " j " << j;
216 else
217 EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j;
221 // Now update with no invalidation and full viewport
222 Update(gfx::Rect(), tiling_rect());
224 for (int i = 0; i < pile_->tiling().num_tiles_x(); ++i) {
225 for (int j = 0; j < pile_->tiling().num_tiles_y(); ++j) {
226 TestPicturePile::PictureInfo& picture_info =
227 pile_->picture_map()
228 .find(TestPicturePile::PictureMapKey(i, j))
229 ->second;
230 // Expect the invalidation frequency to be less than 1, since we just
231 // updated with no invalidations.
232 float expected_frequency =
233 1.0f -
234 1.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED;
236 EXPECT_FLOAT_EQ(expected_frequency,
237 picture_info.GetInvalidationFrequencyForTesting());
239 // We expect that there are pictures everywhere now.
240 EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j;
245 TEST_F(PicturePileTest, ClearingInvalidatesRecordedRect) {
246 UpdateWholePile();
248 gfx::Rect rect(0, 0, 5, 5);
249 EXPECT_TRUE(pile_->CanRasterLayerRect(rect));
250 EXPECT_TRUE(pile_->CanRasterSlowTileCheck(rect));
252 pile_->Clear();
254 // Make sure both the cache-aware check (using recorded region) and the normal
255 // check are both false after clearing.
256 EXPECT_FALSE(pile_->CanRasterLayerRect(rect));
257 EXPECT_FALSE(pile_->CanRasterSlowTileCheck(rect));
260 TEST_F(PicturePileTest, FrequentInvalidationCanRaster) {
261 // This test makes sure that if part of the page is frequently invalidated
262 // and doesn't get re-recorded, then CanRaster is not true for any
263 // tiles touching it, but is true for adjacent tiles, even if it
264 // overlaps on borders (edge case).
265 gfx::Rect new_tiling_rect =
266 gfx::ToEnclosedRect(gfx::ScaleRect(pile_->tiling_rect(), 4.f));
267 pile_->SetTilingRect(new_tiling_rect);
269 gfx::Rect tile01_borders = pile_->tiling().TileBoundsWithBorder(0, 1);
270 gfx::Rect tile02_borders = pile_->tiling().TileBoundsWithBorder(0, 2);
271 gfx::Rect tile01_noborders = pile_->tiling().TileBounds(0, 1);
272 gfx::Rect tile02_noborders = pile_->tiling().TileBounds(0, 2);
274 // Sanity check these two tiles are overlapping with borders, since this is
275 // what the test is trying to repro.
276 EXPECT_TRUE(tile01_borders.Intersects(tile02_borders));
277 EXPECT_FALSE(tile01_noborders.Intersects(tile02_noborders));
278 UpdateWholePile();
279 EXPECT_TRUE(pile_->CanRasterLayerRect(tile01_noborders));
280 EXPECT_TRUE(pile_->CanRasterSlowTileCheck(tile01_noborders));
281 EXPECT_TRUE(pile_->CanRasterLayerRect(tile02_noborders));
282 EXPECT_TRUE(pile_->CanRasterSlowTileCheck(tile02_noborders));
283 // Sanity check that an initial paint goes down the fast path of having
284 // a valid recorded viewport.
285 EXPECT_TRUE(!pile_->recorded_viewport().IsEmpty());
287 // Update the whole layer until the invalidation frequency is high.
288 for (int frame = 0; frame < 33; ++frame) {
289 UpdateWholePile();
292 // Update once more with a small viewport.
293 gfx::Rect viewport(0, 0, tiling_rect().width(), 1);
294 Update(tiling_rect(), viewport);
296 // Sanity check some pictures exist and others don't.
297 EXPECT_TRUE(pile_->picture_map()
298 .find(TestPicturePile::PictureMapKey(0, 1))
299 ->second.GetPicture());
300 EXPECT_FALSE(pile_->picture_map()
301 .find(TestPicturePile::PictureMapKey(0, 2))
302 ->second.GetPicture());
304 EXPECT_TRUE(pile_->CanRasterLayerRect(tile01_noborders));
305 EXPECT_TRUE(pile_->CanRasterSlowTileCheck(tile01_noborders));
306 EXPECT_FALSE(pile_->CanRasterLayerRect(tile02_noborders));
307 EXPECT_FALSE(pile_->CanRasterSlowTileCheck(tile02_noborders));
310 TEST_F(PicturePileTest, NoInvalidationValidViewport) {
311 // This test validates that the recorded_viewport cache of full tiles
312 // is still valid for some use cases. If it's not, it's a performance
313 // issue because CanRaster checks will go down the slow path.
314 UpdateWholePile();
315 EXPECT_TRUE(!pile_->recorded_viewport().IsEmpty());
317 // No invalidation, same viewport.
318 Update(gfx::Rect(), tiling_rect());
319 EXPECT_TRUE(!pile_->recorded_viewport().IsEmpty());
321 // Partial invalidation, same viewport.
322 Update(gfx::Rect(gfx::Rect(0, 0, 1, 1)), tiling_rect());
323 EXPECT_TRUE(!pile_->recorded_viewport().IsEmpty());
325 // No invalidation, changing viewport.
326 Update(gfx::Rect(), gfx::Rect(5, 5, 5, 5));
327 EXPECT_TRUE(!pile_->recorded_viewport().IsEmpty());
330 } // namespace
331 } // namespace cc