| 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
10 namespace impeller {
11
12 FramebufferBlendContents::FramebufferBlendContents() = default;
13
14 FramebufferBlendContents::~FramebufferBlendContents() = default;
15
16 void FramebufferBlendContents::SetBlendMode(BlendMode blend_mode) {
17 blend_mode_ = blend_mode;
18 }
19
20 void FramebufferBlendContents::SetChildContents(
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
38 using VS = FramebufferBlendScreenPipeline::VertexShader;
39 using FS = FramebufferBlendScreenPipeline::FragmentShader;
40
41 auto& host_buffer = renderer.GetTransientsBuffer();
42
43 auto src_snapshot = child_contents_->RenderToSnapshot(
44 renderer, // renderer
45 entity, // entity
46 Rect::MakeSize(pass.GetRenderTargetSize()), // coverage_limit
47 std::nullopt, // sampler_descriptor
48 true, // msaa_enabled
49 /*mip_count=*/1,
50 "FramebufferBlendContents Snapshot"); // label
51
52 if (!src_snapshot.has_value()) {
53 return true;
54 }
55
56 auto size = src_snapshot->texture->GetSize();
57
58 std::array<VS::PerVertexData, 4> vertices = {
59 VS::PerVertexData{Point(0, 0), Point(0, 0)},
60 VS::PerVertexData{Point(size.width, 0), Point(1, 0)},
61 VS::PerVertexData{Point(0, size.height), Point(0, 1)},
62 VS::PerVertexData{Point(size.width, size.height), Point(1, 1)},
63 };
64
65 auto options = OptionsFromPass(pass);
66 options.blend_mode = BlendMode::kSource;
67 options.primitive_type = PrimitiveType::kTriangleStrip;
68
69 pass.SetCommandLabel("Framebuffer Advanced Blend Filter");
70 pass.SetVertexBuffer(
71 CreateVertexBuffer(vertices, renderer.GetTransientsBuffer()));
72
73 switch (blend_mode_) {
74 case BlendMode::kScreen:
75 pass.SetPipeline(renderer.GetFramebufferBlendScreenPipeline(options));
76 break;
77 case BlendMode::kOverlay:
78 pass.SetPipeline(renderer.GetFramebufferBlendOverlayPipeline(options));
79 break;
80 case BlendMode::kDarken:
81 pass.SetPipeline(renderer.GetFramebufferBlendDarkenPipeline(options));
82 break;
83 case BlendMode::kLighten:
84 pass.SetPipeline(renderer.GetFramebufferBlendLightenPipeline(options));
85 break;
86 case BlendMode::kColorDodge:
87 pass.SetPipeline(renderer.GetFramebufferBlendColorDodgePipeline(options));
88 break;
89 case BlendMode::kColorBurn:
90 pass.SetPipeline(renderer.GetFramebufferBlendColorBurnPipeline(options));
91 break;
92 case BlendMode::kHardLight:
93 pass.SetPipeline(renderer.GetFramebufferBlendHardLightPipeline(options));
94 break;
95 case BlendMode::kSoftLight:
96 pass.SetPipeline(renderer.GetFramebufferBlendSoftLightPipeline(options));
97 break;
98 case BlendMode::kDifference:
99 pass.SetPipeline(renderer.GetFramebufferBlendDifferencePipeline(options));
100 break;
101 case BlendMode::kExclusion:
102 pass.SetPipeline(renderer.GetFramebufferBlendExclusionPipeline(options));
103 break;
104 case BlendMode::kMultiply:
105 pass.SetPipeline(renderer.GetFramebufferBlendMultiplyPipeline(options));
106 break;
107 case BlendMode::kHue:
108 pass.SetPipeline(renderer.GetFramebufferBlendHuePipeline(options));
109 break;
110 case BlendMode::kSaturation:
111 pass.SetPipeline(renderer.GetFramebufferBlendSaturationPipeline(options));
112 break;
113 case BlendMode::kColor:
114 pass.SetPipeline(renderer.GetFramebufferBlendColorPipeline(options));
115 break;
116 case BlendMode::kLuminosity:
117 pass.SetPipeline(renderer.GetFramebufferBlendLuminosityPipeline(options));
118 break;
119 default:
120 return false;
121 }
122
123 VS::FrameInfo frame_info;
124 FS::FragInfo frag_info;
125
126 auto src_sampler_descriptor = src_snapshot->sampler_descriptor;
127 if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
128 src_sampler_descriptor.width_address_mode = SamplerAddressMode::kDecal;
129 src_sampler_descriptor.height_address_mode = SamplerAddressMode::kDecal;
130 }
131 const std::unique_ptr<const Sampler>& src_sampler =
132 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
133 src_sampler_descriptor);
134 FS::BindTextureSamplerSrc(pass, src_snapshot->texture, src_sampler);
135
136 frame_info.mvp = Entity::GetShaderTransform(entity.GetShaderClipDepth(), pass,
137 src_snapshot->transform);
138 frame_info.src_y_coord_scale = src_snapshot->texture->GetYCoordScale();
139 VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
140
141 frag_info.src_input_alpha = src_snapshot->opacity;
142 FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
143
144 return pass.Draw().ok();
145 }
146
147 } // namespace impeller
impeller::RenderPipelineHandle::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:107
impeller::Entity::GetShaderTransform
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:51
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19
impeller::BlendMode
BlendMode
Definition: color.h:58
impeller::BlendMode::kLuminosity
@ kLuminosity
impeller::BlendMode::kSource
@ kSource
impeller::BlendMode::kColorDodge
@ kColorDodge
impeller::BlendMode::kDarken
@ kDarken
impeller::BlendMode::kColor
@ kColor
impeller::BlendMode::kOverlay
@ kOverlay
framebuffer_blend_contents.h
impeller::FramebufferBlendContents::~FramebufferBlendContents
~FramebufferBlendContents() override
impeller::BlendMode::kSaturation
@ kSaturation
impeller::BlendMode::kDifference
@ kDifference
impeller::VS
SolidFillVertexShader VS
Definition: stroke_path_geometry.cc:16
impeller::Entity
Definition: entity.h:20
impeller::BlendMode::kLighten
@ kLighten
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::BlendMode::kSoftLight
@ kSoftLight
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
render_pass.h
impeller::BlendMode::kColorBurn
@ kColorBurn
impeller::BlendMode::kHardLight
@ kHardLight
impeller::FramebufferBlendContents::FramebufferBlendContents
FramebufferBlendContents()
impeller::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(std::array< VertexType, size > input, HostBuffer &host_buffer)
Create an index-less vertex buffer from a fixed size array.
Definition: vertex_buffer_builder.h:24
impeller::RenderPipelineHandle::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:106
impeller::FramebufferBlendContents::SetChildContents
void SetChildContents(std::shared_ptr< Contents > child_contents)
Definition: framebuffer_blend_contents.cc:20
impeller::BlendMode::kExclusion
@ kExclusion
content_context.h
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150
impeller::FramebufferBlendContents::SetBlendMode
void SetBlendMode(BlendMode blend_mode)
Definition: framebuffer_blend_contents.cc:16
impeller::BlendMode::kScreen
@ kScreen
impeller::BlendMode::kHue
@ kHue
impeller
Definition: allocation.cc:12
impeller::BlendMode::kMultiply
@ kMultiply
impeller::SamplerAddressMode::kDecal
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...