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/solid_color_layer.h"
8#include "cc/layers/texture_layer.h"
9#include "cc/output/copy_output_request.h"
10#include "cc/output/copy_output_result.h"
11#include "cc/test/layer_tree_pixel_test.h"
12#include "cc/test/paths.h"
13#include "cc/test/solid_color_content_layer_client.h"
14#include "cc/trees/layer_tree_impl.h"
15
16#if !defined(OS_ANDROID)
17
18namespace cc {
19namespace {
20
21class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest {
22 protected:
23  virtual scoped_ptr<CopyOutputRequest> CreateCopyOutputRequest() OVERRIDE {
24    scoped_ptr<CopyOutputRequest> request;
25
26    switch (test_type_) {
27      case GL_WITH_BITMAP:
28      case SOFTWARE_WITH_BITMAP:
29        request = CopyOutputRequest::CreateBitmapRequest(
30            base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
31                       base::Unretained(this)));
32        break;
33      case SOFTWARE_WITH_DEFAULT:
34        request = CopyOutputRequest::CreateRequest(
35            base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsBitmap,
36                       base::Unretained(this)));
37        break;
38      case GL_WITH_DEFAULT:
39        request = CopyOutputRequest::CreateRequest(
40            base::Bind(&LayerTreeHostReadbackPixelTest::ReadbackResultAsTexture,
41                       base::Unretained(this)));
42        break;
43    }
44
45    if (!copy_subrect_.IsEmpty())
46      request->set_area(copy_subrect_);
47    return request.Pass();
48  }
49
50  void ReadbackResultAsBitmap(scoped_ptr<CopyOutputResult> result) {
51    EXPECT_TRUE(proxy()->IsMainThread());
52    EXPECT_TRUE(result->HasBitmap());
53    result_bitmap_ = result->TakeBitmap().Pass();
54    EndTest();
55  }
56
57  void ReadbackResultAsTexture(scoped_ptr<CopyOutputResult> result) {
58    EXPECT_TRUE(proxy()->IsMainThread());
59    EXPECT_TRUE(result->HasTexture());
60
61    scoped_ptr<TextureMailbox> texture_mailbox = result->TakeTexture().Pass();
62    EXPECT_TRUE(texture_mailbox->IsValid());
63    EXPECT_TRUE(texture_mailbox->IsTexture());
64
65    scoped_ptr<SkBitmap> bitmap =
66        CopyTextureMailboxToBitmap(result->size(), *texture_mailbox);
67    texture_mailbox->RunReleaseCallback(0, false);
68
69    ReadbackResultAsBitmap(CopyOutputResult::CreateBitmapResult(bitmap.Pass()));
70  }
71
72  gfx::Rect copy_subrect_;
73};
74
75TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software) {
76  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
77      gfx::Rect(200, 200), SK_ColorWHITE);
78
79  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
80      gfx::Rect(200, 200), SK_ColorGREEN);
81  background->AddChild(green);
82
83  RunPixelTest(SOFTWARE_WITH_DEFAULT,
84               background,
85               base::FilePath(FILE_PATH_LITERAL(
86                   "green.png")));
87}
88
89TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_Software_Bitmap) {
90  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
91      gfx::Rect(200, 200), SK_ColorWHITE);
92
93  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
94      gfx::Rect(200, 200), SK_ColorGREEN);
95  background->AddChild(green);
96
97  RunPixelTest(SOFTWARE_WITH_BITMAP,
98               background,
99               base::FilePath(FILE_PATH_LITERAL(
100                   "green.png")));
101}
102
103TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL_Bitmap) {
104  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
105      gfx::Rect(200, 200), SK_ColorWHITE);
106
107  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
108      gfx::Rect(200, 200), SK_ColorGREEN);
109  background->AddChild(green);
110
111  RunPixelTest(GL_WITH_BITMAP,
112               background,
113               base::FilePath(FILE_PATH_LITERAL(
114                   "green.png")));
115}
116
117TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayer_GL) {
118  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
119      gfx::Rect(200, 200), SK_ColorWHITE);
120
121  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
122      gfx::Rect(200, 200), SK_ColorGREEN);
123  background->AddChild(green);
124
125  RunPixelTest(GL_WITH_DEFAULT,
126               background,
127               base::FilePath(FILE_PATH_LITERAL(
128                   "green.png")));
129}
130
131TEST_F(LayerTreeHostReadbackPixelTest,
132       ReadbackRootLayerWithChild_Software) {
133  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
134      gfx::Rect(200, 200), SK_ColorWHITE);
135
136  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
137      gfx::Rect(200, 200), SK_ColorGREEN);
138  background->AddChild(green);
139
140  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
141      gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
142  green->AddChild(blue);
143
144  RunPixelTest(SOFTWARE_WITH_DEFAULT,
145               background,
146               base::FilePath(FILE_PATH_LITERAL(
147                   "green_with_blue_corner.png")));
148}
149
150TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL_Bitmap) {
151  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
152      gfx::Rect(200, 200), SK_ColorWHITE);
153
154  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
155      gfx::Rect(200, 200), SK_ColorGREEN);
156  background->AddChild(green);
157
158  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
159      gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
160  green->AddChild(blue);
161
162  RunPixelTest(GL_WITH_BITMAP,
163               background,
164               base::FilePath(FILE_PATH_LITERAL(
165                   "green_with_blue_corner.png")));
166}
167
168TEST_F(LayerTreeHostReadbackPixelTest, ReadbackRootLayerWithChild_GL) {
169  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
170      gfx::Rect(200, 200), SK_ColorWHITE);
171
172  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
173      gfx::Rect(200, 200), SK_ColorGREEN);
174  background->AddChild(green);
175
176  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
177      gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
178  green->AddChild(blue);
179
180  RunPixelTest(GL_WITH_DEFAULT,
181               background,
182               base::FilePath(FILE_PATH_LITERAL(
183                   "green_with_blue_corner.png")));
184}
185
186TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_Software) {
187  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
188      gfx::Rect(200, 200), SK_ColorWHITE);
189
190  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
191      gfx::Rect(200, 200), SK_ColorGREEN);
192  background->AddChild(green);
193
194  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
195                                 background,
196                                 green.get(),
197                                 base::FilePath(FILE_PATH_LITERAL(
198                                     "green.png")));
199}
200
201TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL_Bitmap) {
202  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
203      gfx::Rect(200, 200), SK_ColorWHITE);
204
205  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
206      gfx::Rect(200, 200), SK_ColorGREEN);
207  background->AddChild(green);
208
209  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
210                                 background,
211                                 green.get(),
212                                 base::FilePath(FILE_PATH_LITERAL(
213                                     "green.png")));
214}
215
216TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayer_GL) {
217  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
218      gfx::Rect(200, 200), SK_ColorWHITE);
219
220  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
221      gfx::Rect(200, 200), SK_ColorGREEN);
222  background->AddChild(green);
223
224  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
225                                 background,
226                                 green.get(),
227                                 base::FilePath(FILE_PATH_LITERAL(
228                                     "green.png")));
229}
230
231TEST_F(LayerTreeHostReadbackPixelTest,
232       ReadbackSmallNonRootLayer_Software) {
233  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
234      gfx::Rect(200, 200), SK_ColorWHITE);
235
236  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
237      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
238  background->AddChild(green);
239
240  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
241                                 background,
242                                 green.get(),
243                                 base::FilePath(FILE_PATH_LITERAL(
244                                     "green_small.png")));
245}
246
247TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL_Bitmap) {
248  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
249      gfx::Rect(200, 200), SK_ColorWHITE);
250
251  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
252      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
253  background->AddChild(green);
254
255  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
256                                 background,
257                                 green.get(),
258                                 base::FilePath(FILE_PATH_LITERAL(
259                                     "green_small.png")));
260}
261
262TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayer_GL) {
263  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
264      gfx::Rect(200, 200), SK_ColorWHITE);
265
266  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
267      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
268  background->AddChild(green);
269
270  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
271                                 background,
272                                 green.get(),
273                                 base::FilePath(FILE_PATH_LITERAL(
274                                     "green_small.png")));
275}
276
277TEST_F(LayerTreeHostReadbackPixelTest,
278       ReadbackSmallNonRootLayerWithChild_Software) {
279  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
280      gfx::Rect(200, 200), SK_ColorWHITE);
281
282  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
283      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
284  background->AddChild(green);
285
286  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
287      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
288  green->AddChild(blue);
289
290  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
291                                 background,
292                                 green.get(),
293                                 base::FilePath(FILE_PATH_LITERAL(
294                                     "green_small_with_blue_corner.png")));
295}
296
297TEST_F(LayerTreeHostReadbackPixelTest,
298       ReadbackSmallNonRootLayerWithChild_GL_Bitmap) {
299  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
300      gfx::Rect(200, 200), SK_ColorWHITE);
301
302  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
303      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
304  background->AddChild(green);
305
306  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
307      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
308  green->AddChild(blue);
309
310  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
311                                 background,
312                                 green.get(),
313                                 base::FilePath(FILE_PATH_LITERAL(
314                                     "green_small_with_blue_corner.png")));
315}
316
317TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSmallNonRootLayerWithChild_GL) {
318  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
319      gfx::Rect(200, 200), SK_ColorWHITE);
320
321  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
322      gfx::Rect(100, 100, 100, 100), SK_ColorGREEN);
323  background->AddChild(green);
324
325  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
326      gfx::Rect(50, 50, 50, 50), SK_ColorBLUE);
327  green->AddChild(blue);
328
329  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
330                                 background,
331                                 green.get(),
332                                 base::FilePath(FILE_PATH_LITERAL(
333                                     "green_small_with_blue_corner.png")));
334}
335
336TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_Software) {
337  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
338      gfx::Rect(200, 200), SK_ColorWHITE);
339
340  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
341      gfx::Rect(200, 200), SK_ColorGREEN);
342  background->AddChild(green);
343
344  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
345      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
346  green->AddChild(blue);
347
348  // Grab the middle of the root layer.
349  copy_subrect_ = gfx::Rect(50, 50, 100, 100);
350
351  RunPixelTest(SOFTWARE_WITH_DEFAULT,
352               background,
353               base::FilePath(FILE_PATH_LITERAL(
354                   "green_small_with_blue_corner.png")));
355}
356
357TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_GL_Bitmap) {
358  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
359      gfx::Rect(200, 200), SK_ColorWHITE);
360
361  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
362      gfx::Rect(200, 200), SK_ColorGREEN);
363  background->AddChild(green);
364
365  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
366      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
367  green->AddChild(blue);
368
369  // Grab the middle of the root layer.
370  copy_subrect_ = gfx::Rect(50, 50, 100, 100);
371
372  RunPixelTest(GL_WITH_BITMAP,
373               background,
374               base::FilePath(FILE_PATH_LITERAL(
375                   "green_small_with_blue_corner.png")));
376}
377
378TEST_F(LayerTreeHostReadbackPixelTest, ReadbackSubrect_GL) {
379  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
380      gfx::Rect(200, 200), SK_ColorWHITE);
381
382  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
383      gfx::Rect(200, 200), SK_ColorGREEN);
384  background->AddChild(green);
385
386  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
387      gfx::Rect(100, 100, 50, 50), SK_ColorBLUE);
388  green->AddChild(blue);
389
390  // Grab the middle of the root layer.
391  copy_subrect_ = gfx::Rect(50, 50, 100, 100);
392
393  RunPixelTest(GL_WITH_DEFAULT,
394               background,
395               base::FilePath(FILE_PATH_LITERAL(
396                   "green_small_with_blue_corner.png")));
397}
398
399TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_Software) {
400  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
401      gfx::Rect(200, 200), SK_ColorWHITE);
402
403  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
404      gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
405  background->AddChild(green);
406
407  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
408      gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
409  green->AddChild(blue);
410
411  // Grab the middle of the green layer.
412  copy_subrect_ = gfx::Rect(25, 25, 100, 100);
413
414  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
415                                 background,
416                                 green.get(),
417                                 base::FilePath(FILE_PATH_LITERAL(
418                                     "green_small_with_blue_corner.png")));
419}
420
421TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_GL_Bitmap) {
422  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
423      gfx::Rect(200, 200), SK_ColorWHITE);
424
425  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
426      gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
427  background->AddChild(green);
428
429  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
430      gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
431  green->AddChild(blue);
432
433  // Grab the middle of the green layer.
434  copy_subrect_ = gfx::Rect(25, 25, 100, 100);
435
436  RunPixelTestWithReadbackTarget(GL_WITH_BITMAP,
437                                 background,
438                                 green.get(),
439                                 base::FilePath(FILE_PATH_LITERAL(
440                                     "green_small_with_blue_corner.png")));
441}
442
443TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerSubrect_GL) {
444  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
445      gfx::Rect(200, 200), SK_ColorWHITE);
446
447  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
448      gfx::Rect(25, 25, 150, 150), SK_ColorGREEN);
449  background->AddChild(green);
450
451  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
452      gfx::Rect(75, 75, 50, 50), SK_ColorBLUE);
453  green->AddChild(blue);
454
455  // Grab the middle of the green layer.
456  copy_subrect_ = gfx::Rect(25, 25, 100, 100);
457
458  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
459                                 background,
460                                 green.get(),
461                                 base::FilePath(FILE_PATH_LITERAL(
462                                     "green_small_with_blue_corner.png")));
463}
464
465class LayerTreeHostReadbackDeviceScalePixelTest
466    : public LayerTreeHostReadbackPixelTest {
467 protected:
468  LayerTreeHostReadbackDeviceScalePixelTest()
469      : device_scale_factor_(1.f),
470        white_client_(SK_ColorWHITE),
471        green_client_(SK_ColorGREEN),
472        blue_client_(SK_ColorBLUE) {}
473
474  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
475    // Cause the device scale factor to be inherited by contents scales.
476    settings->layer_transforms_should_scale_layer_contents = true;
477  }
478
479  virtual void SetupTree() OVERRIDE {
480    layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
481    LayerTreePixelTest::SetupTree();
482  }
483
484  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
485    LayerImpl* root_impl = host_impl->active_tree()->root_layer();
486
487    LayerImpl* background_impl = root_impl->children()[0];
488    EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_x());
489    EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_y());
490
491    LayerImpl* green_impl = background_impl->children()[0];
492    EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_x());
493    EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_y());
494
495    LayerImpl* blue_impl = green_impl->children()[0];
496    EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_x());
497    EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_y());
498  }
499
500  float device_scale_factor_;
501  SolidColorContentLayerClient white_client_;
502  SolidColorContentLayerClient green_client_;
503  SolidColorContentLayerClient blue_client_;
504};
505
506TEST_F(LayerTreeHostReadbackDeviceScalePixelTest,
507       ReadbackSubrect_Software) {
508  scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_);
509  background->SetAnchorPoint(gfx::PointF());
510  background->SetBounds(gfx::Size(100, 100));
511  background->SetIsDrawable(true);
512
513  scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_);
514  green->SetAnchorPoint(gfx::PointF());
515  green->SetBounds(gfx::Size(100, 100));
516  green->SetIsDrawable(true);
517  background->AddChild(green);
518
519  scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_);
520  blue->SetAnchorPoint(gfx::PointF());
521  blue->SetPosition(gfx::Point(50, 50));
522  blue->SetBounds(gfx::Size(25, 25));
523  blue->SetIsDrawable(true);
524  green->AddChild(blue);
525
526  // Grab the middle of the root layer.
527  copy_subrect_ = gfx::Rect(25, 25, 50, 50);
528  device_scale_factor_ = 2.f;
529
530  RunPixelTest(SOFTWARE_WITH_DEFAULT,
531               background,
532               base::FilePath(FILE_PATH_LITERAL(
533                   "green_small_with_blue_corner.png")));
534}
535
536TEST_F(LayerTreeHostReadbackDeviceScalePixelTest,
537       ReadbackSubrect_GL) {
538  scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_);
539  background->SetAnchorPoint(gfx::PointF());
540  background->SetBounds(gfx::Size(100, 100));
541  background->SetIsDrawable(true);
542
543  scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_);
544  green->SetAnchorPoint(gfx::PointF());
545  green->SetBounds(gfx::Size(100, 100));
546  green->SetIsDrawable(true);
547  background->AddChild(green);
548
549  scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_);
550  blue->SetAnchorPoint(gfx::PointF());
551  blue->SetPosition(gfx::Point(50, 50));
552  blue->SetBounds(gfx::Size(25, 25));
553  blue->SetIsDrawable(true);
554  green->AddChild(blue);
555
556  // Grab the middle of the root layer.
557  copy_subrect_ = gfx::Rect(25, 25, 50, 50);
558  device_scale_factor_ = 2.f;
559
560  RunPixelTest(GL_WITH_DEFAULT,
561               background,
562               base::FilePath(FILE_PATH_LITERAL(
563                   "green_small_with_blue_corner.png")));
564}
565
566TEST_F(LayerTreeHostReadbackDeviceScalePixelTest,
567       ReadbackNonRootLayerSubrect_Software) {
568  scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_);
569  background->SetAnchorPoint(gfx::PointF());
570  background->SetBounds(gfx::Size(100, 100));
571  background->SetIsDrawable(true);
572
573  scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_);
574  green->SetAnchorPoint(gfx::PointF());
575  green->SetPosition(gfx::Point(10, 20));
576  green->SetBounds(gfx::Size(90, 80));
577  green->SetIsDrawable(true);
578  background->AddChild(green);
579
580  scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_);
581  blue->SetAnchorPoint(gfx::PointF());
582  blue->SetPosition(gfx::Point(50, 50));
583  blue->SetBounds(gfx::Size(25, 25));
584  blue->SetIsDrawable(true);
585  green->AddChild(blue);
586
587  // Grab the green layer's content with blue in the bottom right.
588  copy_subrect_ = gfx::Rect(25, 25, 50, 50);
589  device_scale_factor_ = 2.f;
590
591  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
592                                 background,
593                                 green.get(),
594                                 base::FilePath(FILE_PATH_LITERAL(
595                                     "green_small_with_blue_corner.png")));
596}
597
598TEST_F(LayerTreeHostReadbackDeviceScalePixelTest,
599       ReadbackNonRootLayerSubrect_GL) {
600  scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_);
601  background->SetAnchorPoint(gfx::PointF());
602  background->SetBounds(gfx::Size(100, 100));
603  background->SetIsDrawable(true);
604
605  scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_);
606  green->SetAnchorPoint(gfx::PointF());
607  green->SetPosition(gfx::Point(10, 20));
608  green->SetBounds(gfx::Size(90, 80));
609  green->SetIsDrawable(true);
610  background->AddChild(green);
611
612  scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_);
613  blue->SetAnchorPoint(gfx::PointF());
614  blue->SetPosition(gfx::Point(50, 50));
615  blue->SetBounds(gfx::Size(25, 25));
616  blue->SetIsDrawable(true);
617  green->AddChild(blue);
618
619  // Grab the green layer's content with blue in the bottom right.
620  copy_subrect_ = gfx::Rect(25, 25, 50, 50);
621  device_scale_factor_ = 2.f;
622
623  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
624                                 background,
625                                 green.get(),
626                                 base::FilePath(FILE_PATH_LITERAL(
627                                     "green_small_with_blue_corner.png")));
628}
629
630class LayerTreeHostReadbackViaCompositeAndReadbackPixelTest
631    : public LayerTreePixelTest {
632 protected:
633  LayerTreeHostReadbackViaCompositeAndReadbackPixelTest()
634      : device_scale_factor_(1.f),
635        white_client_(SK_ColorWHITE),
636        green_client_(SK_ColorGREEN),
637        blue_client_(SK_ColorBLUE) {}
638
639  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
640    // Cause the device scale factor to be inherited by contents scales.
641    settings->layer_transforms_should_scale_layer_contents = true;
642  }
643
644  virtual void SetupTree() OVERRIDE {
645    layer_tree_host()->SetDeviceScaleFactor(device_scale_factor_);
646    LayerTreePixelTest::SetupTree();
647  }
648
649  virtual void BeginTest() OVERRIDE {
650    EXPECT_EQ(device_scale_factor_, layer_tree_host()->device_scale_factor());
651    if (TestEnded())
652      return;
653
654    gfx::Rect device_viewport_copy_rect(
655        layer_tree_host()->device_viewport_size());
656    if (!device_viewport_copy_subrect_.IsEmpty())
657      device_viewport_copy_rect.Intersect(device_viewport_copy_subrect_);
658
659    scoped_ptr<SkBitmap> bitmap(new SkBitmap);
660    bitmap->setConfig(SkBitmap::kARGB_8888_Config,
661                      device_viewport_copy_rect.width(),
662                      device_viewport_copy_rect.height());
663    bitmap->allocPixels();
664    {
665      scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap));
666      layer_tree_host()->CompositeAndReadback(bitmap->getPixels(),
667                                              device_viewport_copy_rect);
668    }
669
670    result_bitmap_ = bitmap.Pass();
671    EndTest();
672  }
673
674  virtual void DrawLayersOnThread(LayerTreeHostImpl* host_impl) OVERRIDE {
675    LayerImpl* root_impl = host_impl->active_tree()->root_layer();
676
677    LayerImpl* background_impl = root_impl->children()[0];
678    EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_x());
679    EXPECT_EQ(device_scale_factor_, background_impl->contents_scale_y());
680
681    LayerImpl* green_impl = background_impl->children()[0];
682    EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_x());
683    EXPECT_EQ(device_scale_factor_, green_impl->contents_scale_y());
684
685    LayerImpl* blue_impl = green_impl->children()[0];
686    EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_x());
687    EXPECT_EQ(device_scale_factor_, blue_impl->contents_scale_y());
688  }
689
690  gfx::Rect device_viewport_copy_subrect_;
691  float device_scale_factor_;
692  SolidColorContentLayerClient white_client_;
693  SolidColorContentLayerClient green_client_;
694  SolidColorContentLayerClient blue_client_;
695};
696
697TEST_F(LayerTreeHostReadbackViaCompositeAndReadbackPixelTest,
698       CompositeAndReadback_Software_1) {
699  scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_);
700  background->SetAnchorPoint(gfx::PointF());
701  background->SetBounds(gfx::Size(200, 200));
702  background->SetIsDrawable(true);
703
704  scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_);
705  green->SetAnchorPoint(gfx::PointF());
706  green->SetBounds(gfx::Size(200, 200));
707  green->SetIsDrawable(true);
708  background->AddChild(green);
709
710  scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_);
711  blue->SetAnchorPoint(gfx::PointF());
712  blue->SetPosition(gfx::Point(100, 100));
713  blue->SetBounds(gfx::Size(50, 50));
714  blue->SetIsDrawable(true);
715  green->AddChild(blue);
716
717  // Grab the middle of the device viewport.
718  device_viewport_copy_subrect_ = gfx::Rect(50, 50, 100, 100);
719  device_scale_factor_ = 1.f;
720
721  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
722                                 background,
723                                 green.get(),
724                                 base::FilePath(FILE_PATH_LITERAL(
725                                     "green_small_with_blue_corner.png")));
726}
727
728TEST_F(LayerTreeHostReadbackViaCompositeAndReadbackPixelTest,
729       CompositeAndReadback_Software_2) {
730  scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_);
731  background->SetAnchorPoint(gfx::PointF());
732  background->SetBounds(gfx::Size(100, 100));
733  background->SetIsDrawable(true);
734
735  scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_);
736  green->SetAnchorPoint(gfx::PointF());
737  green->SetBounds(gfx::Size(100, 100));
738  green->SetIsDrawable(true);
739  background->AddChild(green);
740
741  scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_);
742  blue->SetAnchorPoint(gfx::PointF());
743  blue->SetPosition(gfx::Point(50, 50));
744  blue->SetBounds(gfx::Size(25, 25));
745  blue->SetIsDrawable(true);
746  green->AddChild(blue);
747
748  // Grab the middle of the device viewport.
749  device_viewport_copy_subrect_ = gfx::Rect(50, 50, 100, 100);
750  device_scale_factor_ = 2.f;
751
752  RunPixelTestWithReadbackTarget(SOFTWARE_WITH_DEFAULT,
753                                 background,
754                                 green.get(),
755                                 base::FilePath(FILE_PATH_LITERAL(
756                                     "green_small_with_blue_corner.png")));
757}
758
759TEST_F(LayerTreeHostReadbackViaCompositeAndReadbackPixelTest,
760       CompositeAndReadback_GL_1) {
761  scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_);
762  background->SetAnchorPoint(gfx::PointF());
763  background->SetBounds(gfx::Size(200, 200));
764  background->SetIsDrawable(true);
765
766  scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_);
767  green->SetAnchorPoint(gfx::PointF());
768  green->SetBounds(gfx::Size(200, 200));
769  green->SetIsDrawable(true);
770  background->AddChild(green);
771
772  scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_);
773  blue->SetAnchorPoint(gfx::PointF());
774  blue->SetPosition(gfx::Point(100, 100));
775  blue->SetBounds(gfx::Size(50, 50));
776  blue->SetIsDrawable(true);
777  green->AddChild(blue);
778
779  // Grab the middle of the device viewport.
780  device_viewport_copy_subrect_ = gfx::Rect(50, 50, 100, 100);
781  device_scale_factor_ = 1.f;
782
783  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
784                                 background,
785                                 green.get(),
786                                 base::FilePath(FILE_PATH_LITERAL(
787                                     "green_small_with_blue_corner.png")));
788}
789
790TEST_F(LayerTreeHostReadbackViaCompositeAndReadbackPixelTest,
791       CompositeAndReadback_GL_2) {
792  scoped_refptr<ContentLayer> background = ContentLayer::Create(&white_client_);
793  background->SetAnchorPoint(gfx::PointF());
794  background->SetBounds(gfx::Size(100, 100));
795  background->SetIsDrawable(true);
796
797  scoped_refptr<ContentLayer> green = ContentLayer::Create(&green_client_);
798  green->SetAnchorPoint(gfx::PointF());
799  green->SetBounds(gfx::Size(100, 100));
800  green->SetIsDrawable(true);
801  background->AddChild(green);
802
803  scoped_refptr<ContentLayer> blue = ContentLayer::Create(&blue_client_);
804  blue->SetAnchorPoint(gfx::PointF());
805  blue->SetPosition(gfx::Point(50, 50));
806  blue->SetBounds(gfx::Size(25, 25));
807  blue->SetIsDrawable(true);
808  green->AddChild(blue);
809
810  // Grab the middle of the device viewport.
811  device_viewport_copy_subrect_ = gfx::Rect(50, 50, 100, 100);
812  device_scale_factor_ = 2.f;
813
814  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
815                                 background,
816                                 green.get(),
817                                 base::FilePath(FILE_PATH_LITERAL(
818                                     "green_small_with_blue_corner.png")));
819}
820
821TEST_F(LayerTreeHostReadbackPixelTest, ReadbackNonRootLayerOutsideViewport) {
822  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
823      gfx::Rect(200, 200), SK_ColorWHITE);
824
825  scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer(
826      gfx::Rect(200, 200), SK_ColorGREEN);
827  // Only the top left quarter of the layer is inside the viewport, so the
828  // blue layer is entirely outside.
829  green->SetPosition(gfx::Point(100, 100));
830  background->AddChild(green);
831
832  scoped_refptr<SolidColorLayer> blue = CreateSolidColorLayer(
833      gfx::Rect(150, 150, 50, 50), SK_ColorBLUE);
834  green->AddChild(blue);
835
836  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
837                                 background,
838                                 green.get(),
839                                 base::FilePath(FILE_PATH_LITERAL(
840                                     "green_with_blue_corner.png")));
841}
842
843// TextureLayers are clipped differently than SolidColorLayers, verify they
844// also can be copied when outside of the viewport.
845TEST_F(LayerTreeHostReadbackPixelTest,
846       ReadbackNonRootTextureLayerOutsideViewport) {
847  scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
848      gfx::Rect(200, 200), SK_ColorWHITE);
849
850  SkBitmap bitmap;
851  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200);
852  bitmap.allocPixels();
853  bitmap.eraseColor(SK_ColorGREEN);
854  {
855    SkDevice device(bitmap);
856    skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(new SkCanvas(&device));
857    SkPaint paint;
858    paint.setStyle(SkPaint::kFill_Style);
859    paint.setColor(SK_ColorBLUE);
860    canvas->drawRect(SkRect::MakeXYWH(150, 150, 50, 50), paint);
861  }
862
863  scoped_refptr<TextureLayer> texture = CreateTextureLayer(
864      gfx::Rect(200, 200), bitmap);
865
866  // Tests with solid color layers verify correctness when CanClipSelf is false.
867  EXPECT_FALSE(background->CanClipSelf());
868  // This test verifies correctness when CanClipSelf is true.
869  EXPECT_TRUE(texture->CanClipSelf());
870
871  // Only the top left quarter of the layer is inside the viewport, so the
872  // blue corner is entirely outside.
873  texture->SetPosition(gfx::Point(100, 100));
874  background->AddChild(texture);
875
876  RunPixelTestWithReadbackTarget(GL_WITH_DEFAULT,
877                                 background,
878                                 texture.get(),
879                                 base::FilePath(FILE_PATH_LITERAL(
880                                     "green_with_blue_corner.png")));
881}
882
883}  // namespace
884}  // namespace cc
885
886#endif  // OS_ANDROID
887