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"
11 #include "impeller/core/formats.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) {
30  break;
33  break;
36  break;
38  if (capabilities.SupportsDecalSamplerAddressMode()) {
40  }
41  return std::nullopt;
42  }
43 }
44 } // namespace
45 
46 //------------------------------------------------------
47 // VerticesSimpleBlendContents
48 
50 
52 
54  std::shared_ptr<VerticesGeometry> geometry) {
55  geometry_ = std::move(geometry);
56 }
57 
59  alpha_ = alpha;
60 }
61 
63  blend_mode_ = blend_mode;
64 }
65 
66 void VerticesSimpleBlendContents::SetTexture(std::shared_ptr<Texture> texture) {
67  texture_ = std::move(texture);
68 }
69 
71  const Entity& entity) const {
72  return geometry_->GetCoverage(entity.GetTransform());
73 }
74 
76  const SamplerDescriptor& descriptor) {
77  descriptor_ = descriptor;
78 }
79 
81  Entity::TileMode tile_mode_y) {
82  tile_mode_x_ = tile_mode_x;
83  tile_mode_y_ = tile_mode_y;
84 }
85 
87  inverse_matrix_ = transform.Invert();
88 }
89 
91  const LazyTexture& lazy_texture) {
92  lazy_texture_ = lazy_texture;
93 }
94 
96  lazy_texture_coverage_ = rect;
97 }
98 
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())
127  dst_sampler_descriptor.height_address_mode =
128  TileModeToAddressMode(tile_mode_y_, renderer.GetDeviceCapabilities())
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) {
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 
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
PipelineRef GetPorterDuffPipeline(BlendMode mode, ContentContextOptions opts) const
std::shared_ptr< Texture > GetEmptyTexture() const
const Capabilities & GetDeviceCapabilities() const
HostBuffer & GetTransientsDataBuffer() const
Retrieve the current host buffer for transient storage of other non-index data.
std::shared_ptr< Context > GetContext() const
PipelineRef GetDrawVerticesUberPipeline(BlendMode blend_mode, ContentContextOptions opts) const
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:44
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:28
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:30
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
Definition: render_pass.cc:127
virtual void SetPipeline(PipelineRef pipeline)
The pipeline to use for this command.
Definition: render_pass.cc:86
virtual fml::Status Draw()
Record the currently pending command.
Definition: render_pass.cc:208
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
Definition: render_pass.cc:97
FragmentShader_ FragmentShader
Definition: pipeline.h:164
void SetSamplerDescriptor(const SamplerDescriptor &descriptor)
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.
void SetBlendMode(BlendMode blend_mode)
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
void SetTileMode(Entity::TileMode tile_mode_x, Entity::TileMode tile_mode_y)
void SetLazyTexture(const LazyTexture &lazy_texture)
std::function< std::shared_ptr< Texture >(const ContentContext &renderer)> LazyTexture
void SetTexture(std::shared_ptr< Texture > texture)
void SetGeometry(std::shared_ptr< VerticesGeometry > geometry)
A wrapper around a raw ptr that adds additional unopt mode only checks.
Definition: raw_ptr.h:15
float Scalar
Definition: scalar.h:19
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
LinePipeline::FragmentShader FS
static std::optional< SamplerAddressMode > TileModeToAddressMode(Entity::TileMode tile_mode, const Capabilities &capabilities)
std::optional< BlendMode > InvertPorterDuffBlend(BlendMode blend_mode)
BlendMode
Definition: color.h:58
LinePipeline::VertexShader VS
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:34
PrimitiveType type
Definition: geometry.h:37
@ kNormal
The geometry has no overlapping triangles.
VertexBuffer vertex_buffer
Definition: geometry.h:38
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
SamplerAddressMode width_address_mode
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:150
#define VALIDATION_LOG
Definition: validation.h:91