| Flutter Impeller |

vertices_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 "vertices_contents.h"
6
7 #include "fml/logging.h"
8 #include "impeller/base/validation.h"
9 #include "impeller/core/formats.h"
10 #include "impeller/entity/contents/content_context.h"
11 #include "impeller/entity/contents/contents.h"
12 #include "impeller/entity/contents/filters/blend_filter_contents.h"
13 #include "impeller/entity/geometry/geometry.h"
14 #include "impeller/entity/geometry/vertices_geometry.h"
15 #include "impeller/geometry/color.h"
16 #include "impeller/renderer/render_pass.h"
17
18 namespace impeller {
19
20 namespace {
21 static std::optional<SamplerAddressMode> TileModeToAddressMode(
22 Entity::TileMode tile_mode,
23 const Capabilities& capabilities) {
24 switch (tile_mode) {
25 case Entity::TileMode::kClamp:
26 return SamplerAddressMode::kClampToEdge;
27 break;
28 case Entity::TileMode::kMirror:
29 return SamplerAddressMode::kMirror;
30 break;
31 case Entity::TileMode::kRepeat:
32 return SamplerAddressMode::kRepeat;
33 break;
34 case Entity::TileMode::kDecal:
35 if (capabilities.SupportsDecalSamplerAddressMode()) {
36 return SamplerAddressMode::kDecal;
37 }
38 return std::nullopt;
39 }
40 }
41 } // namespace
42
43 //------------------------------------------------------
44 // VerticesSimpleBlendContents
45
46 VerticesSimpleBlendContents::VerticesSimpleBlendContents() {}
47
48 VerticesSimpleBlendContents::~VerticesSimpleBlendContents() {}
49
50 void VerticesSimpleBlendContents::SetGeometry(
51 std::shared_ptr<VerticesGeometry> geometry) {
52 geometry_ = std::move(geometry);
53 }
54
55 void VerticesSimpleBlendContents::SetAlpha(Scalar alpha) {
56 alpha_ = alpha;
57 }
58
59 void VerticesSimpleBlendContents::SetBlendMode(BlendMode blend_mode) {
60 blend_mode_ = blend_mode;
61 }
62
63 void VerticesSimpleBlendContents::SetTexture(std::shared_ptr<Texture> texture) {
64 texture_ = std::move(texture);
65 }
66
67 std::optional<Rect> VerticesSimpleBlendContents::GetCoverage(
68 const Entity& entity) const {
69 return geometry_->GetCoverage(entity.GetTransform());
70 }
71
72 void VerticesSimpleBlendContents::SetSamplerDescriptor(
73 SamplerDescriptor descriptor) {
74 descriptor_ = std::move(descriptor);
75 }
76
77 void VerticesSimpleBlendContents::SetTileMode(Entity::TileMode tile_mode_x,
78 Entity::TileMode tile_mode_y) {
79 tile_mode_x_ = tile_mode_x;
80 tile_mode_y_ = tile_mode_y;
81 }
82
83 void VerticesSimpleBlendContents::SetEffectTransform(Matrix transform) {
84 inverse_matrix_ = transform.Invert();
85 }
86
87 void VerticesSimpleBlendContents::SetLazyTexture(
88 const LazyTexture& lazy_texture) {
89 lazy_texture_ = lazy_texture;
90 }
91
92 void VerticesSimpleBlendContents::SetLazyTextureCoverage(Rect rect) {
93 lazy_texture_coverage_ = rect;
94 }
95
96 bool VerticesSimpleBlendContents::Render(const ContentContext& renderer,
97 const Entity& entity,
98 RenderPass& pass) const {
99 FML_DCHECK(texture_ || lazy_texture_ ||
100 blend_mode_ == BlendMode::kDestination);
101 BlendMode blend_mode = blend_mode_;
102 if (!geometry_->HasVertexColors()) {
103 blend_mode = BlendMode::kSource;
104 }
105
106 std::shared_ptr<Texture> texture;
107 if (blend_mode != BlendMode::kDestination) {
108 if (!texture_) {
109 texture = lazy_texture_(renderer);
110 } else {
111 texture = texture_;
112 }
113 } else {
114 texture = renderer.GetEmptyTexture();
115 }
116 if (!texture) {
117 VALIDATION_LOG << "Missing texture for VerticesSimpleBlendContents";
118 return false;
119 }
120
121 auto dst_sampler_descriptor = descriptor_;
122 dst_sampler_descriptor.width_address_mode =
123 TileModeToAddressMode(tile_mode_x_, renderer.GetDeviceCapabilities())
124 .value_or(SamplerAddressMode::kClampToEdge);
125 dst_sampler_descriptor.height_address_mode =
126 TileModeToAddressMode(tile_mode_y_, renderer.GetDeviceCapabilities())
127 .value_or(SamplerAddressMode::kClampToEdge);
128
129 const std::unique_ptr<const Sampler>& dst_sampler =
130 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
131 dst_sampler_descriptor);
132
133 GeometryResult geometry_result = geometry_->GetPositionUVColorBuffer(
134 lazy_texture_coverage_.has_value() ? lazy_texture_coverage_.value()
135 : Rect::MakeSize(texture->GetSize()),
136 inverse_matrix_, renderer, entity, pass);
137 if (geometry_result.vertex_buffer.vertex_count == 0) {
138 return true;
139 }
140 FML_DCHECK(geometry_result.mode == GeometryResult::Mode::kNormal);
141
142 if (blend_mode <= Entity::kLastPipelineBlendMode) {
143 using VS = PorterDuffBlendPipeline::VertexShader;
144 using FS = PorterDuffBlendPipeline::FragmentShader;
145
146 #ifdef IMPELLER_DEBUG
147 pass.SetCommandLabel(SPrintF("DrawVertices Porterduff Blend (%s)",
148 BlendModeToString(blend_mode)));
149 #endif // IMPELLER_DEBUG
150 pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer));
151
152 auto options = OptionsFromPassAndEntity(pass, entity);
153 options.primitive_type = geometry_result.type;
154 pass.SetPipeline(renderer.GetPorterDuffBlendPipeline(options));
155
156 FS::BindTextureSamplerDst(pass, texture, dst_sampler);
157
158 VS::FrameInfo frame_info;
159 FS::FragInfo frag_info;
160
161 frame_info.texture_sampler_y_coord_scale = texture->GetYCoordScale();
162 frame_info.mvp = geometry_result.transform;
163
164 frag_info.output_alpha = alpha_;
165 frag_info.input_alpha = 1.0;
166
167 auto inverted_blend_mode =
168 InvertPorterDuffBlend(blend_mode).value_or(BlendMode::kSource);
169 auto blend_coefficients =
170 kPorterDuffCoefficients[static_cast<int>(inverted_blend_mode)];
171 frag_info.src_coeff = blend_coefficients[0];
172 frag_info.src_coeff_dst_alpha = blend_coefficients[1];
173 frag_info.dst_coeff = blend_coefficients[2];
174 frag_info.dst_coeff_src_alpha = blend_coefficients[3];
175 frag_info.dst_coeff_src_color = blend_coefficients[4];
176
177 // These values are ignored if the platform supports native decal mode.
178 frag_info.tmx = static_cast<int>(tile_mode_x_);
179 frag_info.tmy = static_cast<int>(tile_mode_y_);
180
181 auto& host_buffer = renderer.GetTransientsBuffer();
182 FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
183 VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
184
185 return pass.Draw().ok();
186 }
187
188 using VS = VerticesUberShader::VertexShader;
189 using FS = VerticesUberShader::FragmentShader;
190
191 #ifdef IMPELLER_DEBUG
192 pass.SetCommandLabel(SPrintF("DrawVertices Advanced Blend (%s)",
193 BlendModeToString(blend_mode)));
194 #endif // IMPELLER_DEBUG
195 pass.SetVertexBuffer(std::move(geometry_result.vertex_buffer));
196
197 auto options = OptionsFromPassAndEntity(pass, entity);
198 options.primitive_type = geometry_result.type;
199 pass.SetPipeline(renderer.GetDrawVerticesUberShader(options));
200
201 FS::BindTextureSampler(pass, texture, dst_sampler);
202
203 VS::FrameInfo frame_info;
204 FS::FragInfo frag_info;
205
206 frame_info.texture_sampler_y_coord_scale = texture->GetYCoordScale();
207 frame_info.mvp = geometry_result.transform;
208 frag_info.alpha = alpha_;
209 frag_info.blend_mode = static_cast<int>(blend_mode);
210
211 // These values are ignored if the platform supports native decal mode.
212 frag_info.tmx = static_cast<int>(tile_mode_x_);
213 frag_info.tmy = static_cast<int>(tile_mode_y_);
214
215 auto& host_buffer = renderer.GetTransientsBuffer();
216 FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
217 VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
218
219 return pass.Draw().ok();
220 }
221
222 } // namespace impeller
impeller::RenderPipelineHandle::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:107
impeller::GeometryResult::Mode::kNormal
@ kNormal
The geometry has no overlapping triangles.
impeller::Entity::TileMode::kClamp
@ kClamp
impeller::Entity::kLastPipelineBlendMode
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:22
impeller::BlendModeToString
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
contents.h
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::VerticesSimpleBlendContents::SetEffectTransform
void SetEffectTransform(Matrix transform)
Definition: vertices_contents.cc:83
geometry.h
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:47
impeller::VerticesSimpleBlendContents::GetCoverage
std::optional< Rect > GetCoverage(const Entity &entity) const override
Get the area of the render pass that will be affected when this contents is rendered.
Definition: vertices_contents.cc:67
impeller::BlendMode
BlendMode
Definition: color.h:58
impeller::Entity::TileMode::kDecal
@ kDecal
impeller::BlendMode::kSource
@ kSource
impeller::BlendMode::kDestination
@ kDestination
impeller::InvertPorterDuffBlend
std::optional< BlendMode > InvertPorterDuffBlend(BlendMode blend_mode)
Definition: blend_filter_contents.cc:33
formats.h
impeller::RenderPass::SetVertexBuffer
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
Definition: render_pass.cc:123
impeller::VerticesSimpleBlendContents::SetAlpha
void SetAlpha(Scalar alpha)
Definition: vertices_contents.cc:55
impeller::SamplerAddressMode::kClampToEdge
@ kClampToEdge
impeller::VerticesSimpleBlendContents::Render
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Definition: vertices_contents.cc:96
impeller::VertexBuffer::vertex_count
size_t vertex_count
Definition: vertex_buffer.h:23
impeller::Entity::TileMode::kRepeat
@ kRepeat
impeller::VerticesSimpleBlendContents::SetLazyTextureCoverage
void SetLazyTextureCoverage(Rect rect)
Definition: vertices_contents.cc:92
validation.h
impeller::RenderPass::SetCommandLabel
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
Definition: render_pass.cc:97
impeller::VerticesSimpleBlendContents::SetTexture
void SetTexture(std::shared_ptr< Texture > texture)
Definition: vertices_contents.cc:63
impeller::ContentContext::GetEmptyTexture
std::shared_ptr< Texture > GetEmptyTexture() const
Definition: content_context.cc:474
impeller::Entity::TileMode::kMirror
@ kMirror
impeller::RenderPass::Draw
virtual fml::Status Draw()
Record the currently pending command.
Definition: render_pass.cc:127
vertices_contents.h
impeller::VS
SolidFillVertexShader VS
Definition: stroke_path_geometry.cc:16
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::Entity
Definition: entity.h:20
impeller::OptionsFromPassAndEntity
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:34
render_pass.h
impeller::VerticesSimpleBlendContents::LazyTexture
std::function< std::shared_ptr< Texture >(const ContentContext &renderer)> LazyTexture
Definition: vertices_contents.h:27
impeller::GeometryResult::type
PrimitiveType type
Definition: geometry.h:42
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:213
impeller::VerticesSimpleBlendContents::SetLazyTexture
void SetLazyTexture(const LazyTexture &lazy_texture)
Definition: vertices_contents.cc:87
impeller::ContentContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: content_context.cc:550
impeller::RenderPipelineHandle::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:106
impeller::SamplerDescriptor::width_address_mode
SamplerAddressMode width_address_mode
Definition: sampler_descriptor.h:20
impeller::kPorterDuffCoefficients
constexpr std::array< std::array< Scalar, 5 >, 15 > kPorterDuffCoefficients
Definition: blend_filter_contents.h:15
impeller::GeometryResult
Definition: geometry.h:26
impeller::ContentContext::GetDrawVerticesUberShader
std::shared_ptr< Pipeline< PipelineDescriptor > > GetDrawVerticesUberShader(ContentContextOptions opts) const
Definition: content_context.h:685
impeller::VerticesSimpleBlendContents::SetGeometry
void SetGeometry(std::shared_ptr< VerticesGeometry > geometry)
Definition: vertices_contents.cc:50
impeller::Entity::TileMode
TileMode
Definition: entity.h:42
vertices_geometry.h
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:33
impeller::VerticesSimpleBlendContents::VerticesSimpleBlendContents
VerticesSimpleBlendContents()
Definition: vertices_contents.cc:46
impeller::GeometryResult::transform
Matrix transform
Definition: geometry.h:44
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
content_context.h
impeller::ContentContext::GetDeviceCapabilities
const Capabilities & GetDeviceCapabilities() const
Definition: content_context.cc:554
impeller::VerticesSimpleBlendContents::SetTileMode
void SetTileMode(Entity::TileMode tile_mode_x, Entity::TileMode tile_mode_y)
Definition: vertices_contents.cc:77
impeller::SamplerAddressMode::kMirror
@ kMirror
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150
color.h
impeller::VerticesSimpleBlendContents::SetBlendMode
void SetBlendMode(BlendMode blend_mode)
Definition: vertices_contents.cc:59
impeller::VerticesSimpleBlendContents::~VerticesSimpleBlendContents
~VerticesSimpleBlendContents() override
Definition: vertices_contents.cc:48
blend_filter_contents.h
impeller::RenderPass::SetPipeline
virtual void SetPipeline(const std::shared_ptr< Pipeline< PipelineDescriptor >> &pipeline)
The pipeline to use for this command.
Definition: render_pass.cc:92
impeller::TileModeToAddressMode
static std::optional< SamplerAddressMode > TileModeToAddressMode(Entity::TileMode tile_mode, const Capabilities &capabilities)
Definition: tiled_texture_contents.cc:15
impeller::GeometryResult::vertex_buffer
VertexBuffer vertex_buffer
Definition: geometry.h:43
impeller
Definition: allocation.cc:12
impeller::ContentContext
Definition: content_context.h:366
impeller::TRect< Scalar >
impeller::GeometryResult::mode
Mode mode
Definition: geometry.h:45
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::VerticesSimpleBlendContents::SetSamplerDescriptor
void SetSamplerDescriptor(SamplerDescriptor descriptor)
Definition: vertices_contents.cc:72
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:753
impeller::ContentContext::GetPorterDuffBlendPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetPorterDuffBlendPipeline(ContentContextOptions opts) const
Definition: content_context.h:507
impeller::SamplerAddressMode::kRepeat
@ kRepeat
impeller::SamplerAddressMode::kDecal
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...