1 // Copyright 2015 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/layers/content_layer_client.h"
6 #include "cc/layers/picture_layer.h"
7 #include "cc/output/copy_output_request.h"
8 #include "cc/playback/display_item_list.h"
9 #include "cc/playback/display_item_list_settings.h"
10 #include "cc/playback/drawing_display_item.h"
11 #include "cc/test/layer_tree_pixel_test.h"
12 #include "cc/test/test_gpu_memory_buffer_manager.h"
13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "third_party/skia/include/core/SkPictureRecorder.h"
16 #if !defined(OS_ANDROID)
28 class LayerTreeHostTilesPixelTest
: public LayerTreePixelTest
{
30 void InitializeSettings(LayerTreeSettings
* settings
) override
{
31 LayerTreePixelTest::InitializeSettings(settings
);
32 switch (raster_mode_
) {
33 case PARTIAL_ONE_COPY
:
34 settings
->use_zero_copy
= false;
35 settings
->use_persistent_map_for_gpu_memory_buffers
= true;
38 settings
->use_zero_copy
= false;
39 settings
->use_persistent_map_for_gpu_memory_buffers
= false;
42 // This is done via context creation. No settings to change here!
45 settings
->gpu_rasterization_enabled
= true;
46 settings
->gpu_rasterization_forced
= true;
51 void BeginTest() override
{
52 // Don't set up a readback target at the start of the test.
53 PostSetNeedsCommitToMainThread();
58 readback_target_
? readback_target_
: layer_tree_host()->root_layer();
59 target
->RequestCopyOfOutput(CreateCopyOutputRequest());
62 void RunRasterPixelTest(bool threaded
,
64 scoped_refptr
<Layer
> content_root
,
65 base::FilePath file_name
) {
68 PixelTestType test_type
= PIXEL_TEST_SOFTWARE
;
70 case PARTIAL_ONE_COPY
:
73 test_type
= PIXEL_TEST_GL
;
76 test_type
= PIXEL_TEST_SOFTWARE
;
80 RunPixelTest(test_type
, content_root
, file_name
);
82 RunSingleThreadedPixelTest(test_type
, content_root
, file_name
);
85 base::FilePath ref_file_
;
86 scoped_ptr
<SkBitmap
> result_bitmap_
;
87 RasterMode raster_mode_
;
90 class BlueYellowClient
: public ContentLayerClient
{
92 explicit BlueYellowClient(const gfx::Size
& size
)
93 : size_(size
), blue_top_(true) {}
95 void PaintContents(SkCanvas
* canvas
,
96 const gfx::Rect
& clip
,
97 PaintingControlSetting painting_status
) override
{}
99 scoped_refptr
<DisplayItemList
> PaintContentsToDisplayList(
100 const gfx::Rect
& clip
,
101 PaintingControlSetting painting_status
) override
{
102 DisplayItemListSettings settings
;
103 settings
.use_cached_picture
= false;
104 scoped_refptr
<DisplayItemList
> display_list
=
105 DisplayItemList::Create(clip
, settings
);
107 SkPictureRecorder recorder
;
108 skia::RefPtr
<SkCanvas
> canvas
= skia::SharePtr(
109 recorder
.beginRecording(gfx::RectToSkRect(gfx::Rect(size_
))));
110 gfx::Rect
top(0, 0, size_
.width(), size_
.height() / 2);
111 gfx::Rect
bottom(0, size_
.height() / 2, size_
.width(), size_
.height() / 2);
113 gfx::Rect blue_rect
= blue_top_
? top
: bottom
;
114 gfx::Rect yellow_rect
= blue_top_
? bottom
: top
;
117 paint
.setStyle(SkPaint::kFill_Style
);
119 paint
.setColor(SK_ColorBLUE
);
120 canvas
->drawRect(gfx::RectToSkRect(blue_rect
), paint
);
121 paint
.setColor(SK_ColorYELLOW
);
122 canvas
->drawRect(gfx::RectToSkRect(yellow_rect
), paint
);
124 skia::RefPtr
<SkPicture
> picture
=
125 skia::AdoptRef(recorder
.endRecordingAsPicture());
127 auto* item
= display_list
->CreateAndAppendItem
<DrawingDisplayItem
>();
128 item
->SetNew(picture
.Pass());
130 display_list
->Finalize();
134 bool FillsBoundsCompletely() const override
{ return true; }
135 size_t GetApproximateUnsharedMemoryUsage() const override
{ return 0; }
137 void set_blue_top(bool b
) { blue_top_
= b
; }
144 class LayerTreeHostTilesTestPartialInvalidation
145 : public LayerTreeHostTilesPixelTest
{
147 LayerTreeHostTilesTestPartialInvalidation()
148 : client_(gfx::Size(200, 200)),
149 picture_layer_(PictureLayer::Create(layer_settings(), &client_
)) {
150 picture_layer_
->SetBounds(gfx::Size(200, 200));
151 picture_layer_
->SetIsDrawable(true);
154 void DidCommitAndDrawFrame() override
{
155 switch (layer_tree_host()->source_frame_number()) {
157 // We have done one frame, so the layer's content has been rastered.
158 // Now we change the picture behind it to record something completely
159 // different, but we give a smaller invalidation rect. The layer should
160 // only re-raster the stuff in the rect. If it doesn't do partial raster
161 // it would re-raster the whole thing instead.
162 client_
.set_blue_top(false);
164 picture_layer_
->SetNeedsDisplayRect(gfx::Rect(50, 50, 100, 100));
166 // Add a copy request to see what happened!
173 BlueYellowClient client_
;
174 scoped_refptr
<PictureLayer
> picture_layer_
;
177 TEST_F(LayerTreeHostTilesTestPartialInvalidation
,
178 PartialRaster_SingleThread_OneCopy
) {
180 false, PARTIAL_ONE_COPY
, picture_layer_
,
181 base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
184 TEST_F(LayerTreeHostTilesTestPartialInvalidation
,
185 FullRaster_SingleThread_OneCopy
) {
187 false, FULL_ONE_COPY
, picture_layer_
,
188 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
191 TEST_F(LayerTreeHostTilesTestPartialInvalidation
,
192 PartialRaster_MultiThread_OneCopy
) {
194 true, PARTIAL_ONE_COPY
, picture_layer_
,
195 base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
198 TEST_F(LayerTreeHostTilesTestPartialInvalidation
,
199 FullRaster_MultiThread_OneCopy
) {
201 true, FULL_ONE_COPY
, picture_layer_
,
202 base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
205 TEST_F(LayerTreeHostTilesTestPartialInvalidation
,
206 PartialRaster_SingleThread_Software
) {
208 false, BITMAP
, picture_layer_
,
209 base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
212 TEST_F(LayerTreeHostTilesTestPartialInvalidation
,
213 PartialRaster_SingleThread_GpuRaster
) {
215 false, GPU
, picture_layer_
,
216 base::FilePath(FILE_PATH_LITERAL("blue_yellow_partial_flipped.png")));
222 #endif // !defined(OS_ANDROID)