1// Copyright 2013 The Flutter 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#define FML_USED_ON_EMBEDDER
6
7#include "flutter/flow/layers/picture_layer.h"
8
9#include "flutter/flow/testing/skia_gpu_object_layer_test.h"
10#include "flutter/fml/macros.h"
11#include "flutter/testing/mock_canvas.h"
12#include "third_party/skia/include/core/SkPicture.h"
13
14#ifndef SUPPORT_FRACTIONAL_TRANSLATION
15#include "flutter/flow/raster_cache.h"
16#endif
17
18namespace flutter {
19namespace testing {
20
21using PictureLayerTest = SkiaGPUObjectLayerTest;
22
23#ifndef NDEBUG
24TEST_F(PictureLayerTest, PaintBeforePrerollInvalidPictureDies) {
25 const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
26 auto layer = std::make_shared<PictureLayer>(
27 layer_offset, SkiaGPUObject<SkPicture>(), false, false);
28
29 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
30 "picture_\\.get\\(\\)");
31}
32
33TEST_F(PictureLayerTest, PaintBeforePreollDies) {
34 const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
35 const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
36 auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
37 auto layer = std::make_shared<PictureLayer>(
38 layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
39
40 EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
41 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
42 "needs_painting\\(\\)");
43}
44
45TEST_F(PictureLayerTest, PaintingEmptyLayerDies) {
46 const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
47 const SkRect picture_bounds = SkRect::MakeEmpty();
48 auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
49 auto layer = std::make_shared<PictureLayer>(
50 layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
51
52 layer->Preroll(preroll_context(), SkMatrix());
53 EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
54 EXPECT_FALSE(layer->needs_painting());
55 EXPECT_FALSE(layer->needs_system_composite());
56
57 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
58 "needs_painting\\(\\)");
59}
60#endif
61
62TEST_F(PictureLayerTest, InvalidPictureDies) {
63 const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
64 auto layer = std::make_shared<PictureLayer>(
65 layer_offset, SkiaGPUObject<SkPicture>(), false, false);
66
67 // Crashes reading a nullptr.
68 EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix()), "");
69}
70
71TEST_F(PictureLayerTest, SimplePicture) {
72 const SkPoint layer_offset = SkPoint::Make(1.5f, -0.5f);
73 const SkMatrix layer_offset_matrix =
74 SkMatrix::Translate(layer_offset.fX, layer_offset.fY);
75 const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
76 auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
77 auto layer = std::make_shared<PictureLayer>(
78 layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
79
80 layer->Preroll(preroll_context(), SkMatrix());
81 EXPECT_EQ(layer->paint_bounds(),
82 picture_bounds.makeOffset(layer_offset.fX, layer_offset.fY));
83 EXPECT_EQ(layer->picture(), mock_picture.get());
84 EXPECT_TRUE(layer->needs_painting());
85 EXPECT_FALSE(layer->needs_system_composite());
86
87 layer->Paint(paint_context());
88 auto expected_draw_calls = std::vector(
89 {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
90 MockCanvas::DrawCall{1,
91 MockCanvas::ConcatMatrixData{layer_offset_matrix}},
92#ifndef SUPPORT_FRACTIONAL_TRANSLATION
93 MockCanvas::DrawCall{
94 1, MockCanvas::SetMatrixData{RasterCache::GetIntegralTransCTM(
95 layer_offset_matrix)}},
96#endif
97 MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}});
98 EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls);
99}
100
101} // namespace testing
102} // namespace flutter
103