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  blend_mode_ = blend_mode;
18 }
19 
21  std::shared_ptr<Contents> child_contents) {
22  child_contents_ = std::move(child_contents);
23 }
24 
25 // |Contents|
26 std::optional<Rect> FramebufferBlendContents::GetCoverage(
27  const Entity& entity) const {
28  return child_contents_->GetCoverage(entity);
29 }
30 
31 bool FramebufferBlendContents::Render(const ContentContext& renderer,
32  const Entity& entity,
33  RenderPass& pass) const {
34  if (!renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
35  return false;
36  }
37 
40 
41  auto& data_host_buffer = renderer.GetTransientsDataBuffer();
42 
43  auto src_snapshot = child_contents_->RenderToSnapshot(
44  renderer, entity,
45  {.coverage_limit = Rect::MakeSize(pass.GetRenderTargetSize()),
46  .sampler_descriptor = std::nullopt,
47  .msaa_enabled = true,
48  .mip_count = 1,
49  .label = "FramebufferBlendContents Snapshot"});
50 
51  if (!src_snapshot.has_value()) {
52  return true;
53  }
54 
55  auto size = src_snapshot->texture->GetSize();
56 
57  std::array<VS::PerVertexData, 4> vertices = {
58  VS::PerVertexData{Point(0, 0), Point(0, 0)},
59  VS::PerVertexData{Point(size.width, 0), Point(1, 0)},
60  VS::PerVertexData{Point(0, size.height), Point(0, 1)},
61  VS::PerVertexData{Point(size.width, size.height), Point(1, 1)},
62  };
63 
64  auto options = OptionsFromPass(pass);
65  options.blend_mode = BlendMode::kSrc;
66  options.primitive_type = PrimitiveType::kTriangleStrip;
67 
68  pass.SetCommandLabel("Framebuffer Advanced Blend Filter");
69  pass.SetVertexBuffer(
70  CreateVertexBuffer(vertices, renderer.GetTransientsDataBuffer()));
71 
72  switch (blend_mode_) {
73  case BlendMode::kScreen:
74  pass.SetPipeline(renderer.GetFramebufferBlendScreenPipeline(options));
75  break;
77  pass.SetPipeline(renderer.GetFramebufferBlendOverlayPipeline(options));
78  break;
79  case BlendMode::kDarken:
80  pass.SetPipeline(renderer.GetFramebufferBlendDarkenPipeline(options));
81  break;
83  pass.SetPipeline(renderer.GetFramebufferBlendLightenPipeline(options));
84  break;
86  pass.SetPipeline(renderer.GetFramebufferBlendColorDodgePipeline(options));
87  break;
89  pass.SetPipeline(renderer.GetFramebufferBlendColorBurnPipeline(options));
90  break;
92  pass.SetPipeline(renderer.GetFramebufferBlendHardLightPipeline(options));
93  break;
95  pass.SetPipeline(renderer.GetFramebufferBlendSoftLightPipeline(options));
96  break;
98  pass.SetPipeline(renderer.GetFramebufferBlendDifferencePipeline(options));
99  break;
101  pass.SetPipeline(renderer.GetFramebufferBlendExclusionPipeline(options));
102  break;
104  pass.SetPipeline(renderer.GetFramebufferBlendMultiplyPipeline(options));
105  break;
106  case BlendMode::kHue:
107  pass.SetPipeline(renderer.GetFramebufferBlendHuePipeline(options));
108  break;
110  pass.SetPipeline(renderer.GetFramebufferBlendSaturationPipeline(options));
111  break;
112  case BlendMode::kColor:
113  pass.SetPipeline(renderer.GetFramebufferBlendColorPipeline(options));
114  break;
116  pass.SetPipeline(renderer.GetFramebufferBlendLuminosityPipeline(options));
117  break;
118  default:
119  return false;
120  }
121 
122  VS::FrameInfo frame_info;
123  FS::FragInfo frag_info;
124 
125  auto src_sampler_descriptor = src_snapshot->sampler_descriptor;
126  if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
127  src_sampler_descriptor.width_address_mode = SamplerAddressMode::kDecal;
128  src_sampler_descriptor.height_address_mode = SamplerAddressMode::kDecal;
129  }
130  raw_ptr<const Sampler> src_sampler =
131  renderer.GetContext()->GetSamplerLibrary()->GetSampler(
132  src_sampler_descriptor);
133  FS::BindTextureSamplerSrc(pass, src_snapshot->texture, src_sampler);
134 
135  frame_info.mvp = Entity::GetShaderTransform(entity.GetShaderClipDepth(), pass,
136  src_snapshot->transform);
137  frame_info.src_y_coord_scale = src_snapshot->texture->GetYCoordScale();
138  VS::BindFrameInfo(pass, data_host_buffer.EmplaceUniform(frame_info));
139 
140  frag_info.src_input_alpha = src_snapshot->opacity;
141  frag_info.dst_input_alpha = 1.0;
142  FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
143 
144  return pass.Draw().ok();
145 }
146 
147 } // namespace impeller
Matrix GetShaderTransform(const RenderPass &pass) const
Definition: entity.cc:50
void SetChildContents(std::shared_ptr< Contents > child_contents)
FragmentShader_ FragmentShader
Definition: pipeline.h:164
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
TPoint< Scalar > Point
Definition: point.h:425
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