Flutter Impeller
aiks_dl_runtime_effect_unittests.cc
Go to the documentation of this file.
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 #include <memory>
6 
7 #include "flutter/display_list/dl_builder.h"
8 #include "flutter/display_list/dl_paint.h"
9 #include "flutter/display_list/effects/dl_color_source.h"
10 #include "flutter/display_list/effects/dl_image_filter.h"
11 #include "flutter/display_list/effects/dl_runtime_effect.h"
14 
15 namespace impeller {
16 namespace testing {
17 
18 using namespace flutter;
19 
20 namespace {
21 std::shared_ptr<DlColorSource> MakeRuntimeEffect(
22  AiksTest* test,
23  std::string_view name,
24  const std::shared_ptr<std::vector<uint8_t>>& uniform_data = {},
25  const std::vector<std::shared_ptr<DlColorSource>>& samplers = {}) {
26  auto runtime_stages = test->OpenAssetAsRuntimeStage(name.data());
27  auto runtime_stage = runtime_stages[PlaygroundBackendToRuntimeStageBackend(
28  test->GetBackend())];
29  FML_CHECK(runtime_stage);
30  FML_CHECK(runtime_stage->IsDirty());
31 
32  auto dl_runtime_effect = DlRuntimeEffectImpeller::Make(runtime_stage);
33 
34  return DlColorSource::MakeRuntimeEffect(dl_runtime_effect, samplers,
35  uniform_data);
36 }
37 } // namespace
38 
39 // Regression test for https://github.com/flutter/flutter/issues/126701 .
40 TEST_P(AiksTest, CanRenderClippedRuntimeEffects) {
41  struct FragUniforms {
42  Vector2 iResolution;
43  Scalar iTime;
44  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
45  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
46  uniform_data->resize(sizeof(FragUniforms));
47  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
48 
49  DlPaint paint;
50  paint.setColorSource(
51  MakeRuntimeEffect(this, "runtime_stage_example.frag.iplr", uniform_data));
52 
53  DisplayListBuilder builder;
54  builder.Save();
55  builder.ClipRoundRect(
56  DlRoundRect::MakeRectXY(DlRect::MakeXYWH(0, 0, 400, 400), 10.0, 10.0),
57  DlClipOp::kIntersect);
58  builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
59  builder.Restore();
60 
61  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
62 }
63 
64 TEST_P(AiksTest, DrawPaintTransformsBounds) {
65  struct FragUniforms {
66  Size size;
67  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
68  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
69  uniform_data->resize(sizeof(FragUniforms));
70  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
71 
72  DlPaint paint;
73  paint.setColorSource(
74  MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data));
75 
76  DisplayListBuilder builder;
77  builder.Save();
78  builder.Scale(GetContentScale().x, GetContentScale().y);
79  builder.DrawPaint(paint);
80  builder.Restore();
81 
82  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
83 }
84 
85 TEST_P(AiksTest, CanRenderRuntimeEffectFilter) {
86  auto runtime_stages =
87  OpenAssetAsRuntimeStage("runtime_stage_filter_example.frag.iplr");
88 
89  std::shared_ptr<RuntimeStage> runtime_stage =
90  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
91  ASSERT_TRUE(runtime_stage);
92  ASSERT_TRUE(runtime_stage->IsDirty());
93 
94  std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
95  nullptr,
96  };
97  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
98  uniform_data->resize(sizeof(Vector2));
99 
100  DlPaint paint;
101  paint.setColor(DlColor::kAqua());
102  paint.setImageFilter(DlImageFilter::MakeRuntimeEffect(
103  DlRuntimeEffectImpeller::Make(runtime_stage), sampler_inputs,
104  uniform_data));
105 
106  DisplayListBuilder builder;
107  builder.DrawRect(DlRect::MakeXYWH(0, 0, 400, 400), paint);
108 
109  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
110 }
111 
112 TEST_P(AiksTest, RuntimeEffectWithInvalidSamplerDoesNotCrash) {
113  ScopedValidationDisable disable_validation;
114 
115  // Create a sampler that is not usable as an input to the runtime effect.
116  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
117  flutter::DlColor::kRed()};
118  const float stops[2] = {0.0, 1.0};
119  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
120  2, colors.data(), stops,
121  flutter::DlTileMode::kClamp);
122  std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
123  linear,
124  };
125 
126  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
127  uniform_data->resize(sizeof(Vector2));
128 
129  DlPaint paint;
130  paint.setColorSource(
131  MakeRuntimeEffect(this, "runtime_stage_filter_example.frag.iplr",
132  uniform_data, sampler_inputs));
133 
134  DisplayListBuilder builder;
135  builder.DrawPaint(paint);
136 
137  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
138 }
139 
140 } // namespace testing
141 } // namespace impeller
static sk_sp< DlRuntimeEffect > Make(std::shared_ptr< impeller::RuntimeStage > runtime_stage)
int32_t x
AiksPlayground AiksTest
TEST_P(AiksTest, DrawAtlasNoColor)
Point Vector2
Definition: point.h:331
float Scalar
Definition: scalar.h:19
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:33
static constexpr TSize MakeWH(Type width, Type height)
Definition: size.h:43