Flutter Impeller
atlas_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 <optional>
6 #include <utility>
7 
13 #include "impeller/entity/entity.h"
17 
18 namespace impeller {
19 
21 
23 
24 void AtlasContents::SetTexture(std::shared_ptr<Texture> texture) {
25  texture_ = std::move(texture);
26 }
27 
28 std::shared_ptr<Texture> AtlasContents::GetTexture() const {
29  return texture_;
30 }
31 
32 void AtlasContents::SetTransforms(std::vector<Matrix> transforms) {
33  transforms_ = std::move(transforms);
34  bounding_box_cache_.reset();
35 }
36 
37 void AtlasContents::SetTextureCoordinates(std::vector<Rect> texture_coords) {
38  texture_coords_ = std::move(texture_coords);
39  bounding_box_cache_.reset();
40 }
41 
42 void AtlasContents::SetColors(std::vector<Color> colors) {
43  colors_ = std::move(colors);
44 }
45 
47  alpha_ = alpha;
48 }
49 
51  blend_mode_ = blend_mode;
52 }
53 
54 void AtlasContents::SetCullRect(std::optional<Rect> cull_rect) {
55  cull_rect_ = cull_rect;
56 }
57 
58 std::optional<Rect> AtlasContents::GetCoverage(const Entity& entity) const {
59  if (cull_rect_.has_value()) {
60  return cull_rect_.value().TransformBounds(entity.GetTransform());
61  }
62  return ComputeBoundingBox().TransformBounds(entity.GetTransform());
63 }
64 
65 Rect AtlasContents::ComputeBoundingBox() const {
66  if (!bounding_box_cache_.has_value()) {
67  Rect bounding_box = {};
68  for (size_t i = 0; i < texture_coords_.size(); i++) {
69  auto matrix = transforms_[i];
70  auto sample_rect = texture_coords_[i];
71  auto bounds =
72  Rect::MakeSize(sample_rect.GetSize()).TransformBounds(matrix);
73  bounding_box = bounds.Union(bounding_box);
74  }
75  bounding_box_cache_ = bounding_box;
76  }
77  return bounding_box_cache_.value();
78 }
79 
81  sampler_descriptor_ = std::move(desc);
82 }
83 
85  return sampler_descriptor_;
86 }
87 
88 const std::vector<Matrix>& AtlasContents::GetTransforms() const {
89  return transforms_;
90 }
91 
92 const std::vector<Rect>& AtlasContents::GetTextureCoordinates() const {
93  return texture_coords_;
94 }
95 
96 const std::vector<Color>& AtlasContents::GetColors() const {
97  return colors_;
98 }
99 
101  const Entity& entity,
102  RenderPass& pass) const {
103  if (texture_ == nullptr || blend_mode_ == BlendMode::kClear ||
104  alpha_ <= 0.0) {
105  return true;
106  }
107 
108  BlendMode blend_mode = blend_mode_;
109  if (colors_.empty()) {
110  blend_mode = BlendMode::kSource;
111  }
112 
113  constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3};
114 
116 
118  vtx_builder.Reserve(texture_coords_.size() * 6);
119  const auto texture_size = texture_->GetSize();
120  auto& host_buffer = renderer.GetTransientsBuffer();
121  bool has_colors = !colors_.empty();
122  for (size_t i = 0; i < texture_coords_.size(); i++) {
123  auto sample_rect = texture_coords_[i];
124  auto matrix = transforms_[i];
125  auto points = sample_rect.GetPoints();
126  auto transformed_points =
127  Rect::MakeSize(sample_rect.GetSize()).GetTransformedPoints(matrix);
128  Color color =
129  has_colors ? colors_[i].Premultiply() : Color::BlackTransparent();
130  for (size_t j = 0; j < 6; j++) {
131  VS::PerVertexData data;
132  data.vertices = transformed_points[indices[j]];
133  data.texture_coords = points[indices[j]] / texture_size;
134  data.color = color;
135  vtx_builder.AppendVertex(data);
136  }
137  }
138 
139  auto dst_sampler_descriptor = sampler_descriptor_;
141  dst_sampler_descriptor.width_address_mode = SamplerAddressMode::kDecal;
142  dst_sampler_descriptor.height_address_mode = SamplerAddressMode::kDecal;
143  }
144  const std::unique_ptr<const Sampler>& dst_sampler =
145  renderer.GetContext()->GetSamplerLibrary()->GetSampler(
146  dst_sampler_descriptor);
147 
148  if (blend_mode <= BlendMode::kModulate) {
150 
151 #ifdef IMPELLER_DEBUG
152  pass.SetCommandLabel(
153  SPrintF("DrawAtlas Blend (%s)", BlendModeToString(blend_mode)));
154 #endif // IMPELLER_DEBUG
155  pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
156  pass.SetPipeline(
158 
159  FS::FragInfo frag_info;
160  VS::FrameInfo frame_info;
161 
162  FS::BindTextureSamplerDst(pass, texture_, dst_sampler);
163  frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
164 
165  frag_info.output_alpha = alpha_;
166  frag_info.input_alpha = 1.0;
167 
168  auto inverted_blend_mode =
169  InvertPorterDuffBlend(blend_mode).value_or(BlendMode::kSource);
170  auto blend_coefficients =
171  kPorterDuffCoefficients[static_cast<int>(inverted_blend_mode)];
172  frag_info.src_coeff = blend_coefficients[0];
173  frag_info.src_coeff_dst_alpha = blend_coefficients[1];
174  frag_info.dst_coeff = blend_coefficients[2];
175  frag_info.dst_coeff_src_alpha = blend_coefficients[3];
176  frag_info.dst_coeff_src_color = blend_coefficients[4];
177  // These values are ignored on platforms that natively support decal.
178  frag_info.tmx = static_cast<int>(Entity::TileMode::kDecal);
179  frag_info.tmy = static_cast<int>(Entity::TileMode::kDecal);
180 
181  FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
182 
183  frame_info.mvp = entity.GetShaderTransform(pass);
184 
185  auto uniform_view = host_buffer.EmplaceUniform(frame_info);
186  VS::BindFrameInfo(pass, uniform_view);
187 
188  return pass.Draw().ok();
189  }
190 
193 
194 #ifdef IMPELLER_DEBUG
195  pass.SetCommandLabel(
196  SPrintF("DrawAtlas Advanced Blend (%s)", BlendModeToString(blend_mode)));
197 #endif // IMPELLER_DEBUG
198  pass.SetVertexBuffer(vtx_builder.CreateVertexBuffer(host_buffer));
199 
201  FS::BindTextureSampler(pass, texture_, dst_sampler);
202 
203  VUS::FrameInfo frame_info;
204  FS::FragInfo frag_info;
205 
206  frame_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
207  frame_info.mvp = entity.GetShaderTransform(pass);
208 
209  frag_info.alpha = alpha_;
210  frag_info.blend_mode = static_cast<int>(blend_mode);
211 
212  // These values are ignored on platforms that natively support decal.
213  frag_info.tmx = static_cast<int>(Entity::TileMode::kDecal);
214  frag_info.tmy = static_cast<int>(Entity::TileMode::kDecal);
215 
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::AtlasContents::SetTextureCoordinates
void SetTextureCoordinates(std::vector< Rect > texture_coords)
Definition: atlas_contents.cc:37
impeller::Entity::GetShaderTransform
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:50
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19
impeller::BlendModeToString
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
impeller::Scalar
float Scalar
Definition: scalar.h:18
texture_contents.h
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:46
entity.h
impeller::AtlasContents::SetSamplerDescriptor
void SetSamplerDescriptor(SamplerDescriptor desc)
Definition: atlas_contents.cc:80
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::Color
Definition: color.h:124
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
impeller::Entity::TileMode::kDecal
@ kDecal
impeller::BlendMode::kSource
@ kSource
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:463
formats.h
impeller::InvertPorterDuffBlend
std::optional< BlendMode > InvertPorterDuffBlend(BlendMode blend_mode)
Definition: blend_filter_contents.cc:31
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::RenderPass::SetCommandLabel
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
Definition: render_pass.cc:97
impeller::BlendMode::kModulate
@ kModulate
impeller::RenderPass::Draw
virtual fml::Status Draw()
Record the currently pending command.
Definition: render_pass.cc:127
impeller::VS
SolidFillVertexShader VS
Definition: stroke_path_geometry.cc:16
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::Entity
Definition: entity.h:20
impeller::AtlasContents::SetBlendMode
void SetBlendMode(BlendMode blend_mode)
Definition: atlas_contents.cc:50
render_pass.h
impeller::AtlasContents::~AtlasContents
~AtlasContents() override
impeller::AtlasContents::Render
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Definition: atlas_contents.cc:100
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::TRect::GetTransformedPoints
constexpr std::array< TPoint< T >, 4 > GetTransformedPoints(const Matrix &transform) const
Definition: rect.h:417
impeller::BlendMode::kClear
@ kClear
impeller::ContentContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: content_context.cc:553
impeller::VertexBufferBuilder
Definition: vertex_buffer_builder.h:21
impeller::AtlasContents::GetTransforms
const std::vector< Matrix > & GetTransforms() const
Definition: atlas_contents.cc:88
impeller::RenderPipelineHandle::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:106
impeller::SamplerDescriptor::width_address_mode
SamplerAddressMode width_address_mode
Definition: sampler_descriptor.h:20
impeller::AtlasContents::GetTextureCoordinates
const std::vector< Rect > & GetTextureCoordinates() const
Definition: atlas_contents.cc:92
impeller::AtlasContents::GetTexture
std::shared_ptr< Texture > GetTexture() const
Definition: atlas_contents.cc:28
impeller::kPorterDuffCoefficients
constexpr std::array< std::array< Scalar, 5 >, 15 > kPorterDuffCoefficients
Definition: blend_filter_contents.h:15
impeller::ContentContext::GetDrawVerticesUberShader
std::shared_ptr< Pipeline< PipelineDescriptor > > GetDrawVerticesUberShader(ContentContextOptions opts) const
Definition: content_context.h:684
impeller::AtlasContents::AtlasContents
AtlasContents()
impeller::AtlasContents::SetColors
void SetColors(std::vector< Color > colors)
Definition: atlas_contents.cc:42
impeller::VertexBufferBuilder::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
Definition: vertex_buffer_builder.h:81
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:33
impeller::AtlasContents::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: atlas_contents.cc:58
atlas_contents.h
content_context.h
impeller::ContentContext::GetDeviceCapabilities
const Capabilities & GetDeviceCapabilities() const
Definition: content_context.cc:557
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:146
impeller::AtlasContents::SetAlpha
void SetAlpha(Scalar alpha)
Definition: atlas_contents.cc:46
impeller::AtlasContents::SetCullRect
void SetCullRect(std::optional< Rect > cull_rect)
Definition: atlas_contents.cc:54
impeller::Color::BlackTransparent
static constexpr Color BlackTransparent()
Definition: color.h:272
impeller::VertexBufferBuilder::AppendVertex
VertexBufferBuilder & AppendVertex(VertexType_ vertex)
Definition: vertex_buffer_builder.h:62
impeller::TRect::Union
constexpr TRect Union(const TRect &o) const
Definition: rect.h:504
color.h
impeller::AtlasContents::SetTexture
void SetTexture(std::shared_ptr< Texture > texture)
Definition: atlas_contents.cc:24
color
DlColor color
Definition: dl_golden_blur_unittests.cc:23
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::AtlasContents::SetTransforms
void SetTransforms(std::vector< Matrix > transforms)
Definition: atlas_contents.cc:32
impeller::VertexBufferBuilder::Reserve
void Reserve(size_t count)
Definition: vertex_buffer_builder.h:45
impeller::Capabilities::SupportsDecalSamplerAddressMode
virtual bool SupportsDecalSamplerAddressMode() const =0
Whether the context backend supports SamplerAddressMode::Decal.
impeller
Definition: aiks_blend_unittests.cc:18
impeller::AtlasContents::GetSamplerDescriptor
const SamplerDescriptor & GetSamplerDescriptor() const
Definition: atlas_contents.cc:84
impeller::ContentContext
Definition: content_context.h:366
impeller::TRect< Scalar >
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:752
impeller::ContentContext::GetPorterDuffBlendPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetPorterDuffBlendPipeline(ContentContextOptions opts) const
Definition: content_context.h:511
vertex_buffer_builder.h
impeller::AtlasContents::GetColors
const std::vector< Color > & GetColors() const
Definition: atlas_contents.cc:96
impeller::SamplerAddressMode::kDecal
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...