Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
17
18namespace impeller {
19
21
23
24void AtlasContents::SetTexture(std::shared_ptr<Texture> texture) {
25 texture_ = std::move(texture);
26}
27
28std::shared_ptr<Texture> AtlasContents::GetTexture() const {
29 return texture_;
30}
31
32void AtlasContents::SetTransforms(std::vector<Matrix> transforms) {
33 transforms_ = std::move(transforms);
34 bounding_box_cache_.reset();
35}
36
37void AtlasContents::SetTextureCoordinates(std::vector<Rect> texture_coords) {
38 texture_coords_ = std::move(texture_coords);
39 bounding_box_cache_.reset();
40}
41
42void 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
54void AtlasContents::SetCullRect(std::optional<Rect> cull_rect) {
55 cull_rect_ = cull_rect;
56}
57
58std::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
65Rect 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
88const std::vector<Matrix>& AtlasContents::GetTransforms() const {
89 return transforms_;
90}
91
92const std::vector<Rect>& AtlasContents::GetTextureCoordinates() const {
93 return texture_coords_;
94}
95
96const 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_;
140 if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
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(
157 renderer.GetPorterDuffBlendPipeline(OptionsFromPass(pass)));
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
200 pass.SetPipeline(renderer.GetDrawVerticesUberShader(OptionsFromPass(pass)));
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
static const int points[]
SkColor4f color
bool ok() const
Definition status.h:71
const SamplerDescriptor & GetSamplerDescriptor() const
const std::vector< Rect > & GetTextureCoordinates() const
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
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 SetTransforms(std::vector< Matrix > transforms)
const std::vector< Color > & GetColors() const
void SetAlpha(Scalar alpha)
void SetTexture(std::shared_ptr< Texture > texture)
void SetSamplerDescriptor(SamplerDescriptor desc)
void SetBlendMode(BlendMode blend_mode)
void SetCullRect(std::optional< Rect > cull_rect)
const std::vector< Matrix > & GetTransforms() const
void SetColors(std::vector< Color > colors)
std::shared_ptr< Texture > GetTexture() const
void SetTextureCoordinates(std::vector< Rect > texture_coords)
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition entity.cc:50
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition entity.cc:46
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition render_pass.h:33
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
virtual void SetPipeline(const std::shared_ptr< Pipeline< PipelineDescriptor > > &pipeline)
The pipeline to use for this command.
virtual fml::Status Draw()
Record the currently pending command.
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
FragmentShader_ FragmentShader
Definition pipeline.h:106
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
VertexBufferBuilder & AppendVertex(VertexType_ vertex)
FlTexture * texture
float Scalar
Definition scalar.h:18
SolidFillVertexShader VS
const char * BlendModeToString(BlendMode blend_mode)
Definition color.cc:47
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
std::string SPrintF(const char *format,...)
Definition strings.cc:12
constexpr std::array< std::array< Scalar, 5 >, 15 > kPorterDuffCoefficients
std::optional< BlendMode > InvertPorterDuffBlend(BlendMode blend_mode)
BlendMode
Definition color.h:59
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition contents.cc:20
static constexpr Color BlackTransparent()
Definition color.h:262
SamplerAddressMode width_address_mode
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition rect.h:440
constexpr std::array< TPoint< T >, 4 > GetTransformedPoints(const Matrix &transform) const
Definition rect.h:394
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:146