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 "cc/resources/picture_pile.h" 6#include "cc/test/fake_content_layer_client.h" 7#include "cc/test/fake_rendering_stats_instrumentation.h" 8#include "testing/gtest/include/gtest/gtest.h" 9#include "ui/gfx/rect_conversions.h" 10#include "ui/gfx/size_conversions.h" 11 12namespace cc { 13namespace { 14 15class TestPicturePile : public PicturePile { 16 public: 17 using PicturePile::buffer_pixels; 18 19 PictureListMap& picture_list_map() { return picture_list_map_; } 20 21 typedef PicturePile::PictureList PictureList; 22 typedef PicturePile::PictureListMapKey PictureListMapKey; 23 typedef PicturePile::PictureListMap PictureListMap; 24 25 protected: 26 virtual ~TestPicturePile() {} 27}; 28 29TEST(PicturePileTest, SmallInvalidateInflated) { 30 FakeContentLayerClient client; 31 FakeRenderingStatsInstrumentation stats_instrumentation; 32 scoped_refptr<TestPicturePile> pile = new TestPicturePile; 33 SkColor background_color = SK_ColorBLUE; 34 35 float min_scale = 0.125; 36 gfx::Size base_picture_size = pile->tiling().max_texture_size(); 37 38 gfx::Size layer_size = base_picture_size; 39 pile->Resize(layer_size); 40 pile->SetTileGridSize(gfx::Size(1000, 1000)); 41 pile->SetMinContentsScale(min_scale); 42 43 // Update the whole layer. 44 pile->Update(&client, 45 background_color, 46 false, 47 gfx::Rect(layer_size), 48 gfx::Rect(layer_size), 49 &stats_instrumentation); 50 51 // Invalidate something inside a tile. 52 gfx::Rect invalidate_rect(50, 50, 1, 1); 53 pile->Update(&client, 54 background_color, 55 false, 56 invalidate_rect, 57 gfx::Rect(layer_size), 58 &stats_instrumentation); 59 60 EXPECT_EQ(1, pile->tiling().num_tiles_x()); 61 EXPECT_EQ(1, pile->tiling().num_tiles_y()); 62 63 TestPicturePile::PictureList& picture_list = 64 pile->picture_list_map().find( 65 TestPicturePile::PictureListMapKey(0, 0))->second; 66 EXPECT_EQ(2u, picture_list.size()); 67 for (TestPicturePile::PictureList::iterator it = picture_list.begin(); 68 it != picture_list.end(); 69 ++it) { 70 scoped_refptr<Picture> picture = *it; 71 gfx::Rect picture_rect = 72 gfx::ScaleToEnclosedRect(picture->LayerRect(), min_scale); 73 74 // The invalidation in each tile should have been made large enough 75 // that scaling it never makes a rect smaller than 1 px wide or tall. 76 EXPECT_FALSE(picture_rect.IsEmpty()) << "Picture rect " << 77 picture_rect.ToString(); 78 } 79} 80 81TEST(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 &stats_instrumentation); 102 103 // Invalidate something inside a tile. 104 gfx::Rect invalidate_rect(50, 50, 100, 100); 105 pile->Update(&client, 106 background_color, 107 false, 108 invalidate_rect, 109 gfx::Rect(layer_size), 110 &stats_instrumentation); 111 112 EXPECT_EQ(1, pile->tiling().num_tiles_x()); 113 EXPECT_EQ(1, pile->tiling().num_tiles_y()); 114 115 TestPicturePile::PictureList& picture_list = 116 pile->picture_list_map().find( 117 TestPicturePile::PictureListMapKey(0, 0))->second; 118 EXPECT_EQ(2u, picture_list.size()); 119 120 int expected_inflation = pile->buffer_pixels(); 121 122 scoped_refptr<Picture> base_picture = *picture_list.begin(); 123 gfx::Rect base_picture_rect(layer_size); 124 base_picture_rect.Inset(-expected_inflation, -expected_inflation); 125 EXPECT_EQ(base_picture_rect.ToString(), 126 base_picture->LayerRect().ToString()); 127 128 scoped_refptr<Picture> picture = *(++picture_list.begin()); 129 gfx::Rect picture_rect(invalidate_rect); 130 picture_rect.Inset(-expected_inflation, -expected_inflation); 131 EXPECT_EQ(picture_rect.ToString(), 132 picture->LayerRect().ToString()); 133} 134 135TEST(PicturePileTest, InvalidateOnTileBoundaryInflated) { 136 FakeContentLayerClient client; 137 FakeRenderingStatsInstrumentation stats_instrumentation; 138 scoped_refptr<TestPicturePile> pile = new TestPicturePile; 139 SkColor background_color = SK_ColorBLUE; 140 141 float min_scale = 0.125; 142 gfx::Size base_picture_size = pile->tiling().max_texture_size(); 143 144 gfx::Size layer_size = 145 gfx::ToFlooredSize(gfx::ScaleSize(base_picture_size, 2.f)); 146 pile->Resize(layer_size); 147 pile->SetTileGridSize(gfx::Size(1000, 1000)); 148 pile->SetMinContentsScale(min_scale); 149 150 // Due to border pixels, we should have 3 tiles. 151 EXPECT_EQ(3, pile->tiling().num_tiles_x()); 152 EXPECT_EQ(3, pile->tiling().num_tiles_y()); 153 154 // We should have 1/.125 - 1 = 7 border pixels. 155 EXPECT_EQ(7, pile->buffer_pixels()); 156 EXPECT_EQ(7, pile->tiling().border_texels()); 157 158 // Update the whole layer. 159 pile->Update(&client, 160 background_color, 161 false, 162 gfx::Rect(layer_size), 163 gfx::Rect(layer_size), 164 &stats_instrumentation); 165 166 // Invalidate something just over a tile boundary by a single pixel. 167 // This will invalidate the tile (1, 1), as well as 1 row of pixels in (1, 0). 168 gfx::Rect invalidate_rect( 169 pile->tiling().TileBoundsWithBorder(0, 0).right(), 170 pile->tiling().TileBoundsWithBorder(0, 0).bottom() - 1, 171 50, 172 50); 173 pile->Update(&client, 174 background_color, 175 false, 176 invalidate_rect, 177 gfx::Rect(layer_size), 178 &stats_instrumentation); 179 180 for (int i = 0; i < pile->tiling().num_tiles_x(); ++i) { 181 for (int j = 0; j < pile->tiling().num_tiles_y(); ++j) { 182 // (1, 0) and (1, 1) should be invalidated partially. 183 bool expect_invalidated = i == 1 && (j == 0 || j == 1); 184 185 TestPicturePile::PictureList& picture_list = 186 pile->picture_list_map().find( 187 TestPicturePile::PictureListMapKey(i, j))->second; 188 if (!expect_invalidated) { 189 EXPECT_EQ(1u, picture_list.size()) << "For i,j " << i << "," << j; 190 continue; 191 } 192 193 EXPECT_EQ(2u, picture_list.size()) << "For i,j " << i << "," << j; 194 for (TestPicturePile::PictureList::iterator it = picture_list.begin(); 195 it != picture_list.end(); 196 ++it) { 197 scoped_refptr<Picture> picture = *it; 198 gfx::Rect picture_rect = 199 gfx::ScaleToEnclosedRect(picture->LayerRect(), min_scale); 200 201 // The invalidation in each tile should have been made large enough 202 // that scaling it never makes a rect smaller than 1 px wide or tall. 203 EXPECT_FALSE(picture_rect.IsEmpty()) << "Picture rect " << 204 picture_rect.ToString(); 205 } 206 } 207 } 208} 209 210} // namespace 211} // namespace cc 212