| 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
5 #include "framebuffer_blend_contents.h"
6
7 #include "impeller/entity/contents/content_context.h"
8 #include "impeller/renderer/render_pass.h"
9 #include "impeller/renderer/sampler_library.h"
10
11 namespace impeller {
12
13 FramebufferBlendContents::FramebufferBlendContents() = default;
14
15 FramebufferBlendContents::~FramebufferBlendContents() = default;
16
17 void FramebufferBlendContents::SetBlendMode(BlendMode blend_mode) {
18 blend_mode_ = blend_mode;
19 }
20
21 void FramebufferBlendContents::SetChildContents(
22 std::shared_ptr<Contents> child_contents) {
23 child_contents_ = std::move(child_contents);
24 }
25
26 // |Contents|
27 std::optional<Rect> FramebufferBlendContents::GetCoverage(
28 const Entity& entity) const {
29 return child_contents_->GetCoverage(entity);
30 }
31
32 bool FramebufferBlendContents::Render(const ContentContext& renderer,
33 const Entity& entity,
34 RenderPass& pass) const {
35 if (!renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
36 return false;
37 }
38
39 using VS = FramebufferBlendScreenPipeline::VertexShader;
40 using FS = FramebufferBlendScreenPipeline::FragmentShader;
41
42 auto& host_buffer = pass.GetTransientsBuffer();
43
44 auto src_snapshot = child_contents_->RenderToSnapshot(
45 renderer, // renderer
46 entity, // entity
47 Rect::MakeSize(pass.GetRenderTargetSize()), // coverage_limit
48 std::nullopt, // sampler_descriptor
49 true, // msaa_enabled
50 "FramebufferBlendContents Snapshot"); // label
51
52 if (!src_snapshot.has_value()) {
53 return true;
54 }
55 auto coverage = src_snapshot->GetCoverage();
56 if (!coverage.has_value()) {
57 return true;
58 }
59 Rect src_coverage = coverage.value();
60
61 auto size = src_coverage.size;
62 VertexBufferBuilder<VS::PerVertexData> vtx_builder;
63 vtx_builder.AddVertices({
64 {Point(0, 0), Point(0, 0)},
65 {Point(size.width, 0), Point(1, 0)},
66 {Point(size.width, size.height), Point(1, 1)},
67 {Point(0, 0), Point(0, 0)},
68 {Point(size.width, size.height), Point(1, 1)},
69 {Point(0, size.height), Point(0, 1)},
70 });
71 auto vtx_buffer = vtx_builder.CreateVertexBuffer(host_buffer);
72
73 auto options = OptionsFromPass(pass);
74 options.blend_mode = BlendMode::kSource;
75
76 Command cmd;
77 DEBUG_COMMAND_INFO(cmd, "Framebuffer Advanced Blend Filter");
78 cmd.BindVertices(vtx_buffer);
79 cmd.stencil_reference = entity.GetStencilDepth();
80
81 switch (blend_mode_) {
82 case BlendMode::kScreen:
83 cmd.pipeline = renderer.GetFramebufferBlendScreenPipeline(options);
84 break;
85 case BlendMode::kOverlay:
86 cmd.pipeline = renderer.GetFramebufferBlendOverlayPipeline(options);
87 break;
88 case BlendMode::kDarken:
89 cmd.pipeline = renderer.GetFramebufferBlendDarkenPipeline(options);
90 break;
91 case BlendMode::kLighten:
92 cmd.pipeline = renderer.GetFramebufferBlendLightenPipeline(options);
93 break;
94 case BlendMode::kColorDodge:
95 cmd.pipeline = renderer.GetFramebufferBlendColorDodgePipeline(options);
96 break;
97 case BlendMode::kColorBurn:
98 cmd.pipeline = renderer.GetFramebufferBlendColorBurnPipeline(options);
99 break;
100 case BlendMode::kHardLight:
101 cmd.pipeline = renderer.GetFramebufferBlendHardLightPipeline(options);
102 break;
103 case BlendMode::kSoftLight:
104 cmd.pipeline = renderer.GetFramebufferBlendSoftLightPipeline(options);
105 break;
106 case BlendMode::kDifference:
107 cmd.pipeline = renderer.GetFramebufferBlendDifferencePipeline(options);
108 break;
109 case BlendMode::kExclusion:
110 cmd.pipeline = renderer.GetFramebufferBlendExclusionPipeline(options);
111 break;
112 case BlendMode::kMultiply:
113 cmd.pipeline = renderer.GetFramebufferBlendMultiplyPipeline(options);
114 break;
115 case BlendMode::kHue:
116 cmd.pipeline = renderer.GetFramebufferBlendHuePipeline(options);
117 break;
118 case BlendMode::kSaturation:
119 cmd.pipeline = renderer.GetFramebufferBlendSaturationPipeline(options);
120 break;
121 case BlendMode::kColor:
122 cmd.pipeline = renderer.GetFramebufferBlendColorPipeline(options);
123 break;
124 case BlendMode::kLuminosity:
125 cmd.pipeline = renderer.GetFramebufferBlendLuminosityPipeline(options);
126 break;
127 default:
128 return false;
129 }
130
131 VS::FrameInfo frame_info;
132 FS::FragInfo frag_info;
133
134 auto src_sampler_descriptor = src_snapshot->sampler_descriptor;
135 if (!renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
136 // No known devices that support framebuffer fetch but not decal tile mode.
137 return false;
138 }
139 src_sampler_descriptor.width_address_mode = SamplerAddressMode::kDecal;
140 src_sampler_descriptor.height_address_mode = SamplerAddressMode::kDecal;
141 auto src_sampler = renderer.GetContext()->GetSamplerLibrary()->GetSampler(
142 src_sampler_descriptor);
143 FS::BindTextureSamplerSrc(cmd, src_snapshot->texture, src_sampler);
144
145 frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
146 src_snapshot->transform;
147 frame_info.src_y_coord_scale = src_snapshot->texture->GetYCoordScale();
148 VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info));
149
150 frag_info.src_input_alpha = src_snapshot->opacity;
151 FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
152
153 return pass.AddCommand(std::move(cmd));
154 }
155
156 } // namespace impeller
impeller::BlendMode
BlendMode
Definition: color.h:57
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:20
DEBUG_COMMAND_INFO
#define DEBUG_COMMAND_INFO(obj, arg)
Definition: command.h:31
impeller::TRect::size
TSize< Type > size
Definition: rect.h:24
sampler_library.h
impeller::BlendMode::kMultiply
@ kMultiply
impeller::RenderPipelineT::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:91
impeller::BlendMode::kSaturation
@ kSaturation
impeller::BlendMode::kHue
@ kHue
impeller::BlendMode::kDarken
@ kDarken
framebuffer_blend_contents.h
impeller::BlendMode::kColor
@ kColor
impeller::BlendMode::kLuminosity
@ kLuminosity
impeller::FramebufferBlendContents::~FramebufferBlendContents
~FramebufferBlendContents() override
impeller::BlendMode::kOverlay
@ kOverlay
impeller::BlendMode::kColorBurn
@ kColorBurn
impeller::Entity
Definition: entity.h:21
impeller::Point
TPoint< Scalar > Point
Definition: point.h:306
impeller::BlendMode::kLighten
@ kLighten
render_pass.h
impeller::BlendMode::kHardLight
@ kHardLight
impeller::FramebufferBlendContents::FramebufferBlendContents
FramebufferBlendContents()
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:306
impeller::BlendMode::kSoftLight
@ kSoftLight
impeller::FramebufferBlendContents::SetChildContents
void SetChildContents(std::shared_ptr< Contents > child_contents)
Definition: framebuffer_blend_contents.cc:21
impeller::BlendMode::kDifference
@ kDifference
content_context.h
impeller::BlendMode::kExclusion
@ kExclusion
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:52
impeller::FramebufferBlendContents::SetBlendMode
void SetBlendMode(BlendMode blend_mode)
Definition: framebuffer_blend_contents.cc:17
impeller::Matrix::MakeOrthographic
static constexpr Matrix MakeOrthographic(TSize< T > size)
Definition: matrix.h:448
impeller::BlendMode::kColorDodge
@ kColorDodge
impeller::RenderPipelineT::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:90
impeller::BlendMode::kScreen
@ kScreen
impeller
Definition: aiks_context.cc:10
impeller::BlendMode::kSource
@ kSource
impeller::SamplerAddressMode::kDecal
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...