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 
6 
7 #include <cstring>
8 #include <optional>
9 
13 #include "impeller/geometry/size.h"
14 
15 namespace impeller {
16 
18  std::shared_ptr<RuntimeStage> runtime_stage) {
19  runtime_stage_ = std::move(runtime_stage);
20 }
21 
23  std::shared_ptr<std::vector<uint8_t>> uniforms) {
24  uniforms_ = std::move(uniforms);
25 }
26 
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) {
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
static std::shared_ptr< Contents > Make(RenderProc render_proc, CoverageProc coverage_proc)
std::function< std::optional< Rect >(const Entity &entity)> CoverageProc
Definition: contents.h:40
std::function< bool(const ContentContext &renderer, const Entity &entity, RenderPass &pass)> RenderProc
Definition: contents.h:39
std::vector< FilterInput::Ref > Vector
Definition: filter_input.h:33
void SetTextureInputs(std::vector< RuntimeEffectContents::TextureInput > texture_inputs)
void SetUniforms(std::shared_ptr< std::vector< uint8_t >> uniforms)
void SetRuntimeStage(std::shared_ptr< RuntimeStage > runtime_stage)
TRect< Scalar > Rect
Definition: rect.h:792
TSize< Scalar > Size
Definition: size.h:159
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:476
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150
#define VALIDATION_LOG
Definition: validation.h:91