| Flutter Impeller |

runtime_effect_filter_contents.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 "impeller/entity/contents/filters/runtime_effect_filter_contents.h"
6
7 #include <cstring>
8 #include <optional>
9
10 #include "impeller/base/validation.h"
11 #include "impeller/entity/contents/anonymous_contents.h"
12 #include "impeller/entity/contents/runtime_effect_contents.h"
13 #include "impeller/geometry/size.h"
14
15 namespace impeller {
16
17 void RuntimeEffectFilterContents::SetRuntimeStage(
18 std::shared_ptr<RuntimeStage> runtime_stage) {
19 runtime_stage_ = std::move(runtime_stage);
20 }
21
22 void RuntimeEffectFilterContents::SetUniforms(
23 std::shared_ptr<std::vector<uint8_t>> uniforms) {
24 uniforms_ = std::move(uniforms);
25 }
26
27 void RuntimeEffectFilterContents::SetTextureInputs(
28 std::vector<RuntimeEffectContents::TextureInput> texture_inputs) {
29 texture_inputs_ = std::move(texture_inputs);
30 }
31
32 // |FilterContents|
33 std::optional<Entity> RuntimeEffectFilterContents::RenderFilter(
34 const FilterInput::Vector& inputs,
35 const ContentContext& renderer,
36 const Entity& entity,
37 const Matrix& effect_transform,
38 const Rect& coverage,
39 const std::optional<Rect>& coverage_hint) const {
40 if (inputs.empty()) {
41 return std::nullopt;
42 }
43
44 auto input_snapshot =
45 inputs[0]->GetSnapshot("RuntimeEffectContents", renderer, entity);
46 if (!input_snapshot.has_value()) {
47 return std::nullopt;
48 }
49 std::optional<Rect> maybe_input_coverage = input_snapshot->GetCoverage();
50 if (!maybe_input_coverage.has_value()) {
51 return std::nullopt;
52 }
53 Rect input_coverage = maybe_input_coverage.value();
54 // The shader is required to have at least one sampler, the first of
55 // which is treated as the input and a vec2 size uniform to compute the
56 // offsets. These are validated at the dart:ui layer, but to avoid crashes we
57 // check here too.
58 if (texture_inputs_.size() < 1 || uniforms_->size() < 8) {
59 VALIDATION_LOG
60 << "Invalid fragment shader in RuntimeEffectFilterContents. "
61 << "Shader must have at least one sampler and a vec2 size uniform.";
62 return std::nullopt;
63 }
64
65 // Update uniform values.
66 std::vector<RuntimeEffectContents::TextureInput> texture_input_copy =
67 texture_inputs_;
68 texture_input_copy[0].texture = input_snapshot->texture;
69
70 Size size = Size(input_snapshot->texture->GetSize());
71 memcpy(uniforms_->data(), &size, sizeof(Size));
72
73 //----------------------------------------------------------------------------
74 /// Create AnonymousContents for rendering.
75 ///
76 RenderProc render_proc =
77 [input_snapshot, runtime_stage = runtime_stage_, uniforms = uniforms_,
78 texture_inputs = texture_input_copy,
79 input_coverage](const ContentContext& renderer, const Entity& entity,
80 RenderPass& pass) -> bool {
81 RuntimeEffectContents contents;
82 FillRectGeometry geom(Rect::MakeSize(input_coverage.GetSize()));
83 contents.SetRuntimeStage(runtime_stage);
84 contents.SetUniformData(uniforms);
85 contents.SetTextureInputs(texture_inputs);
86 contents.SetGeometry(&geom);
87 return contents.Render(renderer, entity, pass);
88 };
89
90 CoverageProc coverage_proc =
91 [coverage](const Entity& entity) -> std::optional<Rect> {
92 return coverage.TransformBounds(entity.GetTransform());
93 };
94
95 auto contents = AnonymousContents::Make(render_proc, coverage_proc);
96
97 Entity sub_entity;
98 sub_entity.SetContents(std::move(contents));
99 sub_entity.SetBlendMode(entity.GetBlendMode());
100 sub_entity.SetTransform(input_snapshot->transform);
101 return sub_entity;
102 }
103
104 // |FilterContents|
105 std::optional<Rect> RuntimeEffectFilterContents::GetFilterSourceCoverage(
106 const Matrix& effect_transform,
107 const Rect& output_limit) const {
108 return output_limit;
109 }
110
111 } // namespace impeller
anonymous_contents.h
impeller::AnonymousContents::Make
static std::shared_ptr< Contents > Make(RenderProc render_proc, CoverageProc coverage_proc)
Definition: anonymous_contents.cc:11
impeller::ContentContext
Definition: content_context.h:138
impeller::Contents::CoverageProc
std::function< std::optional< Rect >(const Entity &entity)> CoverageProc
Definition: contents.h:40
impeller::Contents::RenderProc
std::function< bool(const ContentContext &renderer, const Entity &entity, RenderPass &pass)> RenderProc
Definition: contents.h:39
impeller::Entity
Definition: entity.h:26
impeller::FilterInput::Vector
std::vector< FilterInput::Ref > Vector
Definition: filter_input.h:33
impeller::RuntimeEffectFilterContents::SetTextureInputs
void SetTextureInputs(std::vector< RuntimeEffectContents::TextureInput > texture_inputs)
Definition: runtime_effect_filter_contents.cc:27
impeller::RuntimeEffectFilterContents::SetUniforms
void SetUniforms(std::shared_ptr< std::vector< uint8_t >> uniforms)
Definition: runtime_effect_filter_contents.cc:22
impeller::RuntimeEffectFilterContents::SetRuntimeStage
void SetRuntimeStage(std::shared_ptr< RuntimeStage > runtime_stage)
Definition: runtime_effect_filter_contents.cc:17
impeller
Definition: allocation.cc:12
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:792
impeller::Size
TSize< Scalar > Size
Definition: size.h:159
runtime_effect_contents.h
runtime_effect_filter_contents.h
size.h
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::TRect< Scalar >
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:476
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150
validation.h
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91