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