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 "cc/test/fake_picture_pile_impl.h"
11 #include "base/synchronization/waitable_event.h"
12 #include "cc/resources/picture_pile.h"
13 #include "cc/test/fake_picture_pile.h"
14 #include "cc/test/impl_side_painting_settings.h"
15 #include "testing/gtest/include/gtest/gtest.h"
19 FakePicturePileImpl::FakePicturePileImpl() : playback_allowed_event_(nullptr) {
22 FakePicturePileImpl::FakePicturePileImpl(
23 const PicturePile
* other
,
24 base::WaitableEvent
* playback_allowed_event
)
25 : PicturePileImpl(other
),
26 playback_allowed_event_(playback_allowed_event
),
27 tile_grid_info_(other
->GetTileGridInfoForTesting()) {
30 FakePicturePileImpl::~FakePicturePileImpl() {}
32 scoped_refptr
<FakePicturePileImpl
> FakePicturePileImpl::CreateFilledPile(
33 const gfx::Size
& tile_size
,
34 const gfx::Size
& layer_bounds
) {
36 pile
.tiling().SetTilingSize(layer_bounds
);
37 pile
.tiling().SetMaxTextureSize(tile_size
);
38 pile
.SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size
);
39 pile
.SetRecordedViewport(gfx::Rect(layer_bounds
));
40 pile
.SetHasAnyRecordings(true);
42 scoped_refptr
<FakePicturePileImpl
> pile_impl(
43 new FakePicturePileImpl(&pile
, nullptr));
44 for (int x
= 0; x
< pile_impl
->tiling().num_tiles_x(); ++x
) {
45 for (int y
= 0; y
< pile_impl
->tiling().num_tiles_y(); ++y
)
46 pile_impl
->AddRecordingAt(x
, y
);
51 scoped_refptr
<FakePicturePileImpl
> FakePicturePileImpl::CreateEmptyPile(
52 const gfx::Size
& tile_size
,
53 const gfx::Size
& layer_bounds
) {
55 pile
.tiling().SetTilingSize(layer_bounds
);
56 pile
.tiling().SetMaxTextureSize(tile_size
);
57 pile
.SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size
);
58 pile
.SetRecordedViewport(gfx::Rect());
59 pile
.SetHasAnyRecordings(false);
60 return make_scoped_refptr(new FakePicturePileImpl(&pile
, nullptr));
63 scoped_refptr
<FakePicturePileImpl
>
64 FakePicturePileImpl::CreateEmptyPileThatThinksItHasRecordings(
65 const gfx::Size
& tile_size
,
66 const gfx::Size
& layer_bounds
) {
68 pile
.tiling().SetTilingSize(layer_bounds
);
69 pile
.tiling().SetMaxTextureSize(tile_size
);
70 pile
.SetTileGridSize(ImplSidePaintingSettings().default_tile_grid_size
);
71 // This simulates a false positive for this flag.
72 pile
.SetRecordedViewport(gfx::Rect());
73 pile
.SetHasAnyRecordings(true);
74 return make_scoped_refptr(new FakePicturePileImpl(&pile
, nullptr));
77 scoped_refptr
<FakePicturePileImpl
>
78 FakePicturePileImpl::CreateInfiniteFilledPile() {
80 gfx::Size
size(std::numeric_limits
<int>::max(),
81 std::numeric_limits
<int>::max());
82 pile
.tiling().SetTilingSize(size
);
83 pile
.tiling().SetMaxTextureSize(size
);
84 pile
.SetTileGridSize(size
);
85 pile
.SetRecordedViewport(gfx::Rect(size
));
86 pile
.SetHasAnyRecordings(true);
88 scoped_refptr
<FakePicturePileImpl
> pile_impl(
89 new FakePicturePileImpl(&pile
, nullptr));
90 pile_impl
->AddRecordingAt(0, 0);
94 scoped_refptr
<FakePicturePileImpl
> FakePicturePileImpl::CreateFromPile(
95 const PicturePile
* other
,
96 base::WaitableEvent
* playback_allowed_event
) {
97 return make_scoped_refptr(
98 new FakePicturePileImpl(other
, playback_allowed_event
));
101 void FakePicturePileImpl::PlaybackToCanvas(SkCanvas
* canvas
,
102 const gfx::Rect
& canvas_rect
,
103 float contents_scale
) const {
104 if (playback_allowed_event_
)
105 playback_allowed_event_
->Wait();
106 PicturePileImpl::PlaybackToCanvas(canvas
, canvas_rect
, contents_scale
);
109 void FakePicturePileImpl::AddRecordingAt(int x
, int y
) {
112 EXPECT_LT(x
, tiling_
.num_tiles_x());
113 EXPECT_LT(y
, tiling_
.num_tiles_y());
115 if (HasRecordingAt(x
, y
))
117 gfx::Rect
bounds(tiling().TileBounds(x
, y
));
118 bounds
.Inset(-buffer_pixels(), -buffer_pixels());
120 scoped_refptr
<Picture
> picture(Picture::Create(
121 bounds
, &client_
, tile_grid_info_
, true, Picture::RECORD_NORMALLY
));
122 picture_map_
[std::pair
<int, int>(x
, y
)].SetPicture(picture
);
123 EXPECT_TRUE(HasRecordingAt(x
, y
));
125 has_any_recordings_
= true;
128 void FakePicturePileImpl::RemoveRecordingAt(int x
, int y
) {
131 EXPECT_LT(x
, tiling_
.num_tiles_x());
132 EXPECT_LT(y
, tiling_
.num_tiles_y());
134 if (!HasRecordingAt(x
, y
))
136 picture_map_
.erase(std::pair
<int, int>(x
, y
));
137 EXPECT_FALSE(HasRecordingAt(x
, y
));
140 bool FakePicturePileImpl::HasRecordingAt(int x
, int y
) const {
141 PictureMap::const_iterator found
= picture_map_
.find(PictureMapKey(x
, y
));
142 if (found
== picture_map_
.end())
144 return !!found
->second
.GetPicture();
147 void FakePicturePileImpl::RerecordPile() {
148 for (int y
= 0; y
< num_tiles_y(); ++y
) {
149 for (int x
= 0; x
< num_tiles_x(); ++x
) {
150 RemoveRecordingAt(x
, y
);
151 AddRecordingAt(x
, y
);
156 void FakePicturePileImpl::SetMinContentsScale(float min_contents_scale
) {
157 if (min_contents_scale_
== min_contents_scale
)
160 // Picture contents are played back scaled. When the final contents scale is
161 // less than 1 (i.e. low res), then multiple recorded pixels will be used
162 // to raster one final pixel. To avoid splitting a final pixel across
163 // pictures (which would result in incorrect rasterization due to blending), a
164 // buffer margin is added so that any picture can be snapped to integral
167 // For example, if a 1/4 contents scale is used, then that would be 3 buffer
168 // pixels, since that's the minimum number of pixels to add so that resulting
169 // content can be snapped to a four pixel aligned grid.
170 int buffer_pixels
= static_cast<int>(ceil(1 / min_contents_scale
) - 1);
171 buffer_pixels
= std::max(0, buffer_pixels
);
172 SetBufferPixels(buffer_pixels
);
173 min_contents_scale_
= min_contents_scale
;
176 void FakePicturePileImpl::SetBufferPixels(int new_buffer_pixels
) {
177 if (new_buffer_pixels
== buffer_pixels())
181 tiling_
.SetBorderTexels(new_buffer_pixels
);
184 void FakePicturePileImpl::Clear() {
185 picture_map_
.clear();
186 recorded_viewport_
= gfx::Rect();