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 "build/build_config.h"
6#include "cc/layers/content_layer.h"
7#include "cc/layers/content_layer_client.h"
8#include "cc/layers/image_layer.h"
9#include "cc/layers/solid_color_layer.h"
10#include "cc/test/layer_tree_pixel_test.h"
11#include "cc/test/pixel_comparator.h"
12
13#if !defined(OS_ANDROID)
14
15namespace cc {
16namespace {
17
18class LayerTreeHostMasksPixelTest : public LayerTreePixelTest {};
19
20class MaskContentLayerClient : public ContentLayerClient {
21 public:
22  MaskContentLayerClient() {}
23  virtual ~MaskContentLayerClient() {}
24
25  virtual void DidChangeLayerCanUseLCDText() OVERRIDE {}
26
27  virtual bool FillsBoundsCompletely() const OVERRIDE { return false; }
28
29  virtual void PaintContents(
30      SkCanvas* canvas,
31      const gfx::Rect& rect,
32      ContentLayerClient::GraphicsContextStatus gc_status) OVERRIDE {
33    SkPaint paint;
34    paint.setStyle(SkPaint::kStroke_Style);
35    paint.setStrokeWidth(SkIntToScalar(2));
36    paint.setColor(SK_ColorWHITE);
37
38    canvas->clear(SK_ColorTRANSPARENT);
39    gfx::Rect inset_rect(rect);
40    while (!inset_rect.IsEmpty()) {
41      inset_rect.Inset(3, 3, 2, 2);
42      canvas->drawRect(
43          SkRect::MakeXYWH(inset_rect.x(), inset_rect.y(),
44                           inset_rect.width(), inset_rect.height()),
45          paint);
46      inset_rect.Inset(3, 3, 2, 2);
47    }
48  }
49};
50
51TEST_F(LayerTreeHostMasksPixelTest, MaskOfLayer) {
52  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
53      gfx::Rect(200, 200), SK_ColorWHITE);
54
55  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
56      gfx::Rect(50, 50, 100, 100), kCSSGreen, 1, SK_ColorBLACK);
57  background->AddChild(green);
58
59  MaskContentLayerClient client;
60  scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client);
61  mask->SetBounds(gfx::Size(100, 100));
62  mask->SetIsDrawable(true);
63  mask->SetIsMask(true);
64  green->SetMaskLayer(mask.get());
65
66  this->impl_side_painting_ = false;
67  RunPixelTest(GL_WITH_BITMAP,
68               background,
69               base::FilePath(FILE_PATH_LITERAL("mask_of_layer.png")));
70}
71
72TEST_F(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) {
73  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
74      gfx::Rect(200, 200), SK_ColorWHITE);
75
76  scoped_refptr<ImageLayer> mask = ImageLayer::Create();
77  mask->SetIsDrawable(true);
78  mask->SetIsMask(true);
79  mask->SetBounds(gfx::Size(100, 100));
80
81  SkBitmap bitmap;
82  bitmap.allocN32Pixels(400, 400);
83  SkCanvas canvas(bitmap);
84  canvas.scale(SkIntToScalar(4), SkIntToScalar(4));
85  MaskContentLayerClient client;
86  client.PaintContents(&canvas,
87                       gfx::Rect(100, 100),
88                       ContentLayerClient::GRAPHICS_CONTEXT_ENABLED);
89  mask->SetBitmap(bitmap);
90
91  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
92      gfx::Rect(50, 50, 100, 100), kCSSGreen, 1, SK_ColorBLACK);
93  green->SetMaskLayer(mask.get());
94  background->AddChild(green);
95
96  this->impl_side_painting_ = false;
97  RunPixelTest(GL_WITH_BITMAP,
98               background,
99               base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png")));
100}
101
102TEST_F(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) {
103  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
104      gfx::Rect(200, 200), SK_ColorWHITE);
105
106  // Clip to the top half of the green layer.
107  scoped_refptr<Layer> clip = Layer::Create();
108  clip->SetPosition(gfx::Point(0, 0));
109  clip->SetBounds(gfx::Size(200, 100));
110  clip->SetMasksToBounds(true);
111  background->AddChild(clip);
112
113  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
114      gfx::Rect(50, 50, 100, 100), kCSSGreen, 1, SK_ColorBLACK);
115  clip->AddChild(green);
116
117  MaskContentLayerClient client;
118  scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client);
119  mask->SetBounds(gfx::Size(100, 100));
120  mask->SetIsDrawable(true);
121  mask->SetIsMask(true);
122  green->SetMaskLayer(mask.get());
123
124  this->impl_side_painting_ = false;
125  RunPixelTest(GL_WITH_BITMAP,
126               background,
127               base::FilePath(FILE_PATH_LITERAL("mask_of_clipped_layer.png")));
128}
129
130TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplica) {
131  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
132      gfx::Rect(200, 200), SK_ColorWHITE);
133
134  MaskContentLayerClient client;
135  scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client);
136  mask->SetBounds(gfx::Size(100, 100));
137  mask->SetIsDrawable(true);
138  mask->SetIsMask(true);
139
140  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
141      gfx::Rect(0, 0, 100, 100), kCSSGreen, 1, SK_ColorBLACK);
142  background->AddChild(green);
143  green->SetMaskLayer(mask.get());
144
145  gfx::Transform replica_transform;
146  replica_transform.Rotate(-90.0);
147
148  scoped_refptr<Layer> replica = Layer::Create();
149  replica->SetTransformOrigin(gfx::Point3F(50.f, 50.f, 0.f));
150  replica->SetPosition(gfx::Point(100, 100));
151  replica->SetTransform(replica_transform);
152  green->SetReplicaLayer(replica.get());
153
154  this->impl_side_painting_ = false;
155  RunPixelTest(GL_WITH_BITMAP,
156               background,
157               base::FilePath(FILE_PATH_LITERAL("mask_with_replica.png")));
158}
159
160TEST_F(LayerTreeHostMasksPixelTest, MaskWithReplicaOfClippedLayer) {
161  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
162      gfx::Rect(200, 200), SK_ColorWHITE);
163
164  MaskContentLayerClient client;
165  scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client);
166  mask->SetBounds(gfx::Size(100, 100));
167  mask->SetIsDrawable(true);
168  mask->SetIsMask(true);
169
170  // Clip to the bottom half of the green layer, and the left half of the
171  // replica.
172  scoped_refptr<Layer> clip = Layer::Create();
173  clip->SetPosition(gfx::Point(0, 50));
174  clip->SetBounds(gfx::Size(150, 150));
175  clip->SetMasksToBounds(true);
176  background->AddChild(clip);
177
178  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
179      gfx::Rect(0, -50, 100, 100), kCSSGreen, 1, SK_ColorBLACK);
180  clip->AddChild(green);
181  green->SetMaskLayer(mask.get());
182
183  gfx::Transform replica_transform;
184  replica_transform.Rotate(-90.0);
185
186  scoped_refptr<Layer> replica = Layer::Create();
187  replica->SetTransformOrigin(gfx::Point3F(50.f, 50.f, 0.f));
188  replica->SetPosition(gfx::Point(100, 100));
189  replica->SetTransform(replica_transform);
190  green->SetReplicaLayer(replica.get());
191
192  this->impl_side_painting_ = false;
193  RunPixelTest(GL_WITH_BITMAP,
194               background,
195               base::FilePath(FILE_PATH_LITERAL(
196                   "mask_with_replica_of_clipped_layer.png")));
197}
198
199TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplica) {
200  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
201      gfx::Rect(200, 200), SK_ColorWHITE);
202
203  MaskContentLayerClient client;
204  scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client);
205  mask->SetBounds(gfx::Size(100, 100));
206  mask->SetIsDrawable(true);
207  mask->SetIsMask(true);
208
209  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
210      gfx::Rect(50, 0, 100, 100), kCSSGreen, 1, SK_ColorBLACK);
211  background->AddChild(green);
212
213  scoped_refptr<SolidColorLayer> orange = CreateSolidColorLayer(
214      gfx::Rect(-50, 50, 50, 50), kCSSOrange);
215  green->AddChild(orange);
216
217  gfx::Transform replica_transform;
218  replica_transform.Rotate(180.0);
219  replica_transform.Translate(100.0, 0.0);
220
221  scoped_refptr<Layer> replica = Layer::Create();
222  replica->SetTransformOrigin(gfx::Point3F(100.f, 100.f, 0.f));
223  replica->SetPosition(gfx::Point());
224  replica->SetTransform(replica_transform);
225  replica->SetMaskLayer(mask.get());
226  green->SetReplicaLayer(replica.get());
227
228  this->impl_side_painting_ = false;
229  RunPixelTest(GL_WITH_BITMAP,
230               background,
231               base::FilePath(FILE_PATH_LITERAL("mask_of_replica.png")));
232}
233
234TEST_F(LayerTreeHostMasksPixelTest, MaskOfReplicaOfClippedLayer) {
235  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
236      gfx::Rect(200, 200), SK_ColorWHITE);
237
238  MaskContentLayerClient client;
239  scoped_refptr<ContentLayer> mask = ContentLayer::Create(&client);
240  mask->SetBounds(gfx::Size(100, 100));
241  mask->SetIsDrawable(true);
242  mask->SetIsMask(true);
243
244  // Clip to the bottom 3/4 of the green layer, and the top 3/4 of the replica.
245  scoped_refptr<Layer> clip = Layer::Create();
246  clip->SetPosition(gfx::Point(0, 25));
247  clip->SetBounds(gfx::Size(200, 150));
248  clip->SetMasksToBounds(true);
249  background->AddChild(clip);
250
251  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayerWithBorder(
252      gfx::Rect(50, -25, 100, 100), kCSSGreen, 1, SK_ColorBLACK);
253  clip->AddChild(green);
254
255  scoped_refptr<SolidColorLayer> orange = CreateSolidColorLayer(
256      gfx::Rect(-50, 50, 50, 50), kCSSOrange);
257  green->AddChild(orange);
258
259  gfx::Transform replica_transform;
260  replica_transform.Rotate(180.0);
261  replica_transform.Translate(100.0, 0.0);
262
263  scoped_refptr<Layer> replica = Layer::Create();
264  replica->SetTransformOrigin(gfx::Point3F(100.f, 100.f, 0.f));
265  replica->SetPosition(gfx::Point());
266  replica->SetTransform(replica_transform);
267  replica->SetMaskLayer(mask.get());
268  green->SetReplicaLayer(replica.get());
269
270  this->impl_side_painting_ = false;
271  RunPixelTest(GL_WITH_BITMAP,
272               background,
273               base::FilePath(FILE_PATH_LITERAL(
274                   "mask_of_replica_of_clipped_layer.png")));
275}
276
277}  // namespace
278}  // namespace cc
279
280#endif  // OS_ANDROID
281