Flutter Impeller
framebuffer_blend_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 
9 
10 namespace impeller {
11 
13 
15 
17  return nullptr;
18 }
19 
21  blend_mode_ = blend_mode;
22 }
23 
25  std::shared_ptr<Contents> child_contents) {
26  child_contents_ = std::move(child_contents);
27 }
28 
29 // |Contents|
30 std::optional<Rect> FramebufferBlendContents::GetCoverage(
31  const Entity& entity) const {
32  return child_contents_->GetCoverage(entity);
33 }
34 
35 bool FramebufferBlendContents::Render(const ContentContext& renderer,
36  const Entity& entity,
37  RenderPass& pass) const {
38  if (!renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
39  return false;
40  }
41 
44 
45  auto& data_host_buffer = renderer.GetTransientsDataBuffer();
46 
47  auto src_snapshot = child_contents_->RenderToSnapshot(
48  renderer, entity,
49  {.coverage_limit = Rect::MakeSize(pass.GetRenderTargetSize()),
50  .sampler_descriptor = std::nullopt,
51  .msaa_enabled = true,
52  .mip_count = 1,
53  .label = "FramebufferBlendContents Snapshot"});
54 
55  if (!src_snapshot.has_value()) {
56  return true;
57  }
58 
59  auto size = src_snapshot->texture->GetSize();
60 
61  std::array<VS::PerVertexData, 4> vertices = {
62  VS::PerVertexData{Point(0, 0), Point(0, 0)},
63  VS::PerVertexData{Point(size.width, 0), Point(1, 0)},
64  VS::PerVertexData{Point(0, size.height), Point(0, 1)},
65  VS::PerVertexData{Point(size.width, size.height), Point(1, 1)},
66  };
67 
68  auto options = OptionsFromPass(pass);
69  options.blend_mode = BlendMode::kSrc;
70  options.primitive_type = PrimitiveType::kTriangleStrip;
71 
72  pass.SetCommandLabel("Framebuffer Advanced Blend Filter");
73  pass.SetVertexBuffer(
74  CreateVertexBuffer(vertices, renderer.GetTransientsDataBuffer()));
75 
76  switch (blend_mode_) {
77  case BlendMode::kScreen:
78  pass.SetPipeline(renderer.GetFramebufferBlendScreenPipeline(options));
79  break;
81  pass.SetPipeline(renderer.GetFramebufferBlendOverlayPipeline(options));
82  break;
83  case BlendMode::kDarken:
84  pass.SetPipeline(renderer.GetFramebufferBlendDarkenPipeline(options));
85  break;
87  pass.SetPipeline(renderer.GetFramebufferBlendLightenPipeline(options));
88  break;
90  pass.SetPipeline(renderer.GetFramebufferBlendColorDodgePipeline(options));
91  break;
93  pass.SetPipeline(renderer.GetFramebufferBlendColorBurnPipeline(options));
94  break;
96  pass.SetPipeline(renderer.GetFramebufferBlendHardLightPipeline(options));
97  break;
99  pass.SetPipeline(renderer.GetFramebufferBlendSoftLightPipeline(options));
100  break;
102  pass.SetPipeline(renderer.GetFramebufferBlendDifferencePipeline(options));
103  break;
105  pass.SetPipeline(renderer.GetFramebufferBlendExclusionPipeline(options));
106  break;
108  pass.SetPipeline(renderer.GetFramebufferBlendMultiplyPipeline(options));
109  break;
110  case BlendMode::kHue:
111  pass.SetPipeline(renderer.GetFramebufferBlendHuePipeline(options));
112  break;
114  pass.SetPipeline(renderer.GetFramebufferBlendSaturationPipeline(options));
115  break;
116  case BlendMode::kColor:
117  pass.SetPipeline(renderer.GetFramebufferBlendColorPipeline(options));
118  break;
120  pass.SetPipeline(renderer.GetFramebufferBlendLuminosityPipeline(options));
121  break;
122  default:
123  return false;
124  }
125 
126  VS::FrameInfo frame_info;
127  FS::FragInfo frag_info;
128 
129  auto src_sampler_descriptor = src_snapshot->sampler_descriptor;
130  if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
131  src_sampler_descriptor.width_address_mode = SamplerAddressMode::kDecal;
132  src_sampler_descriptor.height_address_mode = SamplerAddressMode::kDecal;
133  }
134  raw_ptr<const Sampler> src_sampler =
135  renderer.GetContext()->GetSamplerLibrary()->GetSampler(
136  src_sampler_descriptor);
137  FS::BindTextureSamplerSrc(pass, src_snapshot->texture, src_sampler);
138 
139  frame_info.mvp = Entity::GetShaderTransform(entity.GetShaderClipDepth(), pass,
140  src_snapshot->transform);
141  frame_info.src_y_coord_scale = src_snapshot->texture->GetYCoordScale();
142  VS::BindFrameInfo(pass, data_host_buffer.EmplaceUniform(frame_info));
143 
144  frag_info.src_input_alpha = src_snapshot->opacity;
145  frag_info.dst_input_alpha = 1.0;
146  FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
147 
148  return pass.Draw().ok();
149 }
150 
151 } // namespace impeller
Matrix GetShaderTransform(const RenderPass &pass) const
Definition: entity.cc:50
void SetChildContents(std::shared_ptr< Contents > child_contents)
const Geometry * GetGeometry() const override
Get the geometry that this contents will use to render.
FragmentShader_ FragmentShader
Definition: pipeline.h:169
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
TPoint< Scalar > Point
Definition: point.h:426
LinePipeline::FragmentShader FS
VertexBuffer CreateVertexBuffer(std::array< VertexType, size > input, HostBuffer &data_host_buffer)
Create an index-less vertex buffer from a fixed size array.
BlendMode
Definition: color.h:58
LinePipeline::VertexShader VS
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150