Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / cc / resources / picture_pile_unittest.cc
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.
4
5 #include <map>
6 #include <utility>
7
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"
14
15 namespace cc {
16 namespace {
17
18 class TestPicturePile : public PicturePile {
19  public:
20   using PicturePile::buffer_pixels;
21
22   PictureMap& picture_map() { return picture_map_; }
23
24   typedef PicturePile::PictureInfo PictureInfo;
25   typedef PicturePile::PictureMapKey PictureMapKey;
26   typedef PicturePile::PictureMap PictureMap;
27
28  protected:
29     virtual ~TestPicturePile() {}
30 };
31
32 TEST(PicturePileTest, SmallInvalidateInflated) {
33   FakeContentLayerClient client;
34   FakeRenderingStatsInstrumentation stats_instrumentation;
35   scoped_refptr<TestPicturePile> pile = new TestPicturePile;
36   SkColor background_color = SK_ColorBLUE;
37
38   float min_scale = 0.125;
39   gfx::Size base_picture_size = pile->tiling().max_texture_size();
40
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);
45
46   // Update the whole layer.
47   pile->Update(&client,
48                background_color,
49                false,
50                gfx::Rect(layer_size),
51                gfx::Rect(layer_size),
52                1,
53                &stats_instrumentation);
54
55   // Invalidate something inside a tile.
56   gfx::Rect invalidate_rect(50, 50, 1, 1);
57   pile->Update(&client,
58                background_color,
59                false,
60                invalidate_rect,
61                gfx::Rect(layer_size),
62                2,
63                &stats_instrumentation);
64
65   EXPECT_EQ(1, pile->tiling().num_tiles_x());
66   EXPECT_EQ(1, pile->tiling().num_tiles_y());
67
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);
74
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();
79 }
80
81 TEST(PicturePileTest, LargeInvalidateInflated) {
82   FakeContentLayerClient client;
83   FakeRenderingStatsInstrumentation stats_instrumentation;
84   scoped_refptr<TestPicturePile> pile = new TestPicturePile;
85   SkColor background_color = SK_ColorBLUE;
86
87   float min_scale = 0.125;
88   gfx::Size base_picture_size = pile->tiling().max_texture_size();
89
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);
94
95   // Update the whole layer.
96   pile->Update(&client,
97                background_color,
98                false,
99                gfx::Rect(layer_size),
100                gfx::Rect(layer_size),
101                1,
102                &stats_instrumentation);
103
104   // Invalidate something inside a tile.
105   gfx::Rect invalidate_rect(50, 50, 100, 100);
106   pile->Update(&client,
107                background_color,
108                false,
109                invalidate_rect,
110                gfx::Rect(layer_size),
111                2,
112                &stats_instrumentation);
113
114   EXPECT_EQ(1, pile->tiling().num_tiles_x());
115   EXPECT_EQ(1, pile->tiling().num_tiles_y());
116
117   TestPicturePile::PictureInfo& picture_info =
118       pile->picture_map().find(TestPicturePile::PictureMapKey(0, 0))->second;
119   EXPECT_TRUE(!!picture_info.GetPicture());
120
121   int expected_inflation = pile->buffer_pixels();
122
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());
128 }
129
130 TEST(PicturePileTest, InvalidateOnTileBoundaryInflated) {
131   FakeContentLayerClient client;
132   FakeRenderingStatsInstrumentation stats_instrumentation;
133   scoped_refptr<TestPicturePile> pile = new TestPicturePile;
134   SkColor background_color = SK_ColorBLUE;
135
136   float min_scale = 0.125;
137   gfx::Size base_picture_size = pile->tiling().max_texture_size();
138
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);
144
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());
148
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());
152
153   // Update the whole layer to create initial pictures.
154   pile->Update(&client,
155                background_color,
156                false,
157                gfx::Rect(layer_size),
158                gfx::Rect(layer_size),
159                0,
160                &stats_instrumentation);
161
162   // Invalidate everything again to have a non zero invalidation
163   // frequency.
164   pile->Update(&client,
165                background_color,
166                false,
167                gfx::Rect(layer_size),
168                gfx::Rect(layer_size),
169                1,
170                &stats_instrumentation);
171
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,
177       50,
178       50);
179   pile->Update(&client,
180                background_color,
181                false,
182                invalidate_rect,
183                gfx::Rect(layer_size),
184                2,
185                &stats_instrumentation);
186
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;
192
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)) {
196         EXPECT_FLOAT_EQ(
197             2.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
198             picture_info.GetInvalidationFrequencyForTesting());
199       } else {
200         EXPECT_FLOAT_EQ(
201             1.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED,
202             picture_info.GetInvalidationFrequencyForTesting());
203       }
204     }
205   }
206 }
207
208 TEST(PicturePileTest, StopRecordingOffscreenInvalidations) {
209   FakeContentLayerClient client;
210   FakeRenderingStatsInstrumentation stats_instrumentation;
211   scoped_refptr<TestPicturePile> pile = new TestPicturePile;
212   SkColor background_color = SK_ColorBLUE;
213
214   float min_scale = 0.125;
215   gfx::Size base_picture_size = pile->tiling().max_texture_size();
216
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);
222
223   gfx::Rect viewport(0, 0, layer_size.width(), 1);
224
225   // Update the whole layer until the invalidation frequency is high.
226   int frame;
227   for (frame = 0; frame < 33; ++frame) {
228     pile->Update(&client,
229                  background_color,
230                  false,
231                  gfx::Rect(layer_size),
232                  viewport,
233                  frame,
234                  &stats_instrumentation);
235   }
236
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;
245     }
246   }
247
248   // Update once more with a small viewport 0,0 layer_width by 1
249   pile->Update(&client,
250                background_color,
251                false,
252                gfx::Rect(layer_size),
253                viewport,
254                frame,
255                &stats_instrumentation);
256
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());
263
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.
266       if (j >= 2)
267         EXPECT_FALSE(picture_info.GetPicture()) << "i " << i << " j " << j;
268       else
269         EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j;
270     }
271   }
272
273   // Now update with no invalidation and full viewport
274   pile->Update(&client,
275                background_color,
276                false,
277                gfx::Rect(),
278                gfx::Rect(layer_size),
279                frame+1,
280                &stats_instrumentation);
281
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 =
290           1.0f -
291           1.0f / TestPicturePile::PictureInfo::INVALIDATION_FRAMES_TRACKED;
292
293       EXPECT_FLOAT_EQ(expected_frequency,
294                       picture_info.GetInvalidationFrequencyForTesting());
295
296       // We expect that there are pictures everywhere now.
297       EXPECT_TRUE(picture_info.GetPicture()) << "i " << i << " j " << j;
298     }
299   }
300 }
301
302 }  // namespace
303 }  // namespace cc