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.
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"
18 class TestPicturePile : public PicturePile {
20 using PicturePile::buffer_pixels;
22 PictureMap& picture_map() { return picture_map_; }
24 typedef PicturePile::PictureInfo PictureInfo;
25 typedef PicturePile::PictureMapKey PictureMapKey;
26 typedef PicturePile::PictureMap PictureMap;
29 virtual ~TestPicturePile() {}
32 TEST(PicturePileTest, SmallInvalidateInflated) {
33 FakeContentLayerClient client;
34 FakeRenderingStatsInstrumentation stats_instrumentation;
35 scoped_refptr<TestPicturePile> pile = new TestPicturePile;
36 SkColor background_color = SK_ColorBLUE;
38 float min_scale = 0.125;
39 gfx::Size base_picture_size = pile->tiling().max_texture_size();
41 gfx::Size layer_size = base_picture_size;
42 pile->Resize(layer_size);
43 pile->SetTileGridSize(gfx::Size(1000, 1000));
44 pile->SetMinContentsScale(min_scale);
46 // Update the whole layer.
50 gfx::Rect(layer_size),
51 gfx::Rect(layer_size),
53 &stats_instrumentation);
55 // Invalidate something inside a tile.
56 gfx::Rect invalidate_rect(50, 50, 1, 1);
61 gfx::Rect(layer_size),
63 &stats_instrumentation);
65 EXPECT_EQ(1, pile->tiling().num_tiles_x());
66 EXPECT_EQ(1, pile->tiling().num_tiles_y());
68 TestPicturePile::PictureInfo& picture_info =
69 pile->picture_map().find(TestPicturePile::PictureMapKey(0, 0))->second;
70 // We should have a picture.
71 EXPECT_TRUE(!!picture_info.GetPicture());
72 gfx::Rect picture_rect = gfx::ScaleToEnclosedRect(
73 picture_info.GetPicture()->LayerRect(), min_scale);
75 // The the picture should be large enough that scaling it never makes a rect
76 // smaller than 1 px wide or tall.
77 EXPECT_FALSE(picture_rect.IsEmpty()) << "Picture rect " <<
78 picture_rect.ToString();
81 TEST(PicturePileTest, LargeInvalidateInflated) {
82 FakeContentLayerClient client;
83 FakeRenderingStatsInstrumentation stats_instrumentation;
84 scoped_refptr<TestPicturePile> pile = new TestPicturePile;
85 SkColor background_color = SK_ColorBLUE;
87 float min_scale = 0.125;
88 gfx::Size base_picture_size = pile->tiling().max_texture_size();
90 gfx::Size layer_size = base_picture_size;
91 pile->Resize(layer_size);
92 pile->SetTileGridSize(gfx::Size(1000, 1000));
93 pile->SetMinContentsScale(min_scale);
95 // Update the whole layer.
99 gfx::Rect(layer_size),
100 gfx::Rect(layer_size),
102 &stats_instrumentation);
104 // Invalidate something inside a tile.
105 gfx::Rect invalidate_rect(50, 50, 100, 100);
106 pile->Update(&client,
110 gfx::Rect(layer_size),
112 &stats_instrumentation);
114 EXPECT_EQ(1, pile->tiling().num_tiles_x());
115 EXPECT_EQ(1, pile->tiling().num_tiles_y());
117 TestPicturePile::PictureInfo& picture_info =
118 pile->picture_map().find(TestPicturePile::PictureMapKey(0, 0))->second;
119 EXPECT_TRUE(!!picture_info.GetPicture());
121 int expected_inflation = pile->buffer_pixels();
123 Picture* base_picture = picture_info.GetPicture();
124 gfx::Rect base_picture_rect(layer_size);
125 base_picture_rect.Inset(-expected_inflation, -expected_inflation);
126 EXPECT_EQ(base_picture_rect.ToString(),
127 base_picture->LayerRect().ToString());
130 TEST(PicturePileTest, InvalidateOnTileBoundaryInflated) {
131 FakeContentLayerClient client;
132 FakeRenderingStatsInstrumentation stats_instrumentation;
133 scoped_refptr<TestPicturePile> pile = new TestPicturePile;
134 SkColor background_color = SK_ColorBLUE;
136 float min_scale = 0.125;
137 gfx::Size base_picture_size = pile->tiling().max_texture_size();
139 gfx::Size layer_size =
140 gfx::ToFlooredSize(gfx::ScaleSize(base_picture_size, 2.f));
141 pile->Resize(layer_size);
142 pile->SetTileGridSize(gfx::Size(1000, 1000));
143 pile->SetMinContentsScale(min_scale);
145 // Due to border pixels, we should have 3 tiles.
146 EXPECT_EQ(3, pile->tiling().num_tiles_x());
147 EXPECT_EQ(3, pile->tiling().num_tiles_y());
149 // We should have 1/.125 - 1 = 7 border pixels.
150 EXPECT_EQ(7, pile->buffer_pixels());
151 EXPECT_EQ(7, pile->tiling().border_texels());
153 // Update the whole layer to create initial pictures.
154 pile->Update(&client,
157 gfx::Rect(layer_size),
158 gfx::Rect(layer_size),
160 &stats_instrumentation);
162 // Invalidate everything again to have a non zero invalidation
164 pile->Update(&client,
167 gfx::Rect(layer_size),
168 gfx::Rect(layer_size),
170 &stats_instrumentation);
172 // Invalidate something just over a tile boundary by a single pixel.
173 // This will invalidate the tile (1, 1), as well as 1 row of pixels in (1, 0).
174 gfx::Rect invalidate_rect(
175 pile->tiling().TileBoundsWithBorder(0, 0).right(),
176 pile->tiling().TileBoundsWithBorder(0, 0).bottom() - 1,
179 pile->Update(&client,
183 gfx::Rect(layer_size),
185 &stats_instrumentation);
187 for (int i = 0; i < pile->tiling().num_tiles_x(); ++i) {
188 for (int j = 0; j < pile->tiling().num_tiles_y(); ++j) {
189 TestPicturePile::PictureInfo& picture_info =
190 pile->picture_map().find(
191 TestPicturePile::PictureMapKey(i, j))->second;
193 // Expect (1, 1) and (1, 0) to be invalidated once more
194 // than the rest of the tiles.
195 if (i == 1 && (j == 0 || j == 1)) {
197 2.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
198 picture_info.GetInvalidationFrequencyForTesting());
201 1.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
202 picture_info.GetInvalidationFrequencyForTesting());
208 TEST(PicturePileTest, StopRecordingOffscreenInvalidations) {
209 FakeContentLayerClient client;
210 FakeRenderingStatsInstrumentation stats_instrumentation;
211 scoped_refptr<TestPicturePile> pile = new TestPicturePile;
212 SkColor background_color = SK_ColorBLUE;
214 float min_scale = 0.125;
215 gfx::Size base_picture_size = pile->tiling().max_texture_size();
217 gfx::Size layer_size =
218 gfx::ToFlooredSize(gfx::ScaleSize(base_picture_size, 4.f));
219 pile->Resize(layer_size);
220 pile->SetTileGridSize(gfx::Size(1000, 1000));
221 pile->SetMinContentsScale(min_scale);
223 gfx::Rect viewport(0, 0, layer_size.width(), 1);
225 // Update the whole layer until the invalidation frequency is high.
227 for (frame = 0; frame < 33; ++frame) {
228 pile->Update(&client,
231 gfx::Rect(layer_size),
234 &stats_instrumentation);
237 // Make sure we have a high invalidation frequency.
238 for (int i = 0; i < pile->tiling().num_tiles_x(); ++i) {
239 for (int j = 0; j < pile->tiling().num_tiles_y(); ++j) {
240 TestPicturePile::PictureInfo& picture_info =
241 pile->picture_map().find(
242 TestPicturePile::PictureMapKey(i, j))->second;
243 EXPECT_FLOAT_EQ(1.0f, picture_info.GetInvalidationFrequencyForTesting())
244 << "i " << i << " j " << j;
248 // Update once more with a small viewport 0,0 layer_width by 1
249 pile->Update(&client,
252 gfx::Rect(layer_size),
255 &stats_instrumentation);
257 for (int i = 0; i < pile->tiling().num_tiles_x(); ++i) {
258 for (int j = 0; j < pile->tiling().num_tiles_y(); ++j) {
259 TestPicturePile::PictureInfo& picture_info =
260 pile->picture_map().find(
261 TestPicturePile::PictureMapKey(i, j))->second;
262 EXPECT_FLOAT_EQ(1.0f, picture_info.GetInvalidationFrequencyForTesting());
264 // If the y far enough away we expect to find no picture (no re-recording
265 // happened). For close y, the picture should change.
267 EXPECT_FALSE(picture_info.GetPicture()) << "i " << i << " j " << j;
269 EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j;
273 // Now update with no invalidation and full viewport
274 pile->Update(&client,
278 gfx::Rect(layer_size),
280 &stats_instrumentation);
282 for (int i = 0; i < pile->tiling().num_tiles_x(); ++i) {
283 for (int j = 0; j < pile->tiling().num_tiles_y(); ++j) {
284 TestPicturePile::PictureInfo& picture_info =
285 pile->picture_map().find(
286 TestPicturePile::PictureMapKey(i, j))->second;
287 // Expect the invalidation frequency to be less than 1, since we just
288 // updated with no invalidations.
289 float expected_frequency =
291 1.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED;
293 EXPECT_FLOAT_EQ(expected_frequency,
294 picture_info.GetInvalidationFrequencyForTesting());
296 // We expect that there are pictures everywhere now.
297 EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j;