Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
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
13#include "impeller/entity/texture_fill.frag.h"
14#include "impeller/entity/texture_fill.vert.h"
17
18namespace impeller {
19
21 std::shared_ptr<Texture> texture,
22 const Rect& source,
23 const Rect& destination,
24 const Color& color,
25 BlendMode blend_mode,
26 const SamplerDescriptor& desc,
27 bool use_strict_src_rect)
28 : texture_(std::move(texture)),
29 source_(source),
30 destination_(destination),
31 color_(color),
32 blend_mode_(blend_mode),
33 desc_(desc),
34 use_strict_src_rect_(use_strict_src_rect) {}
35
37
39 return true;
40}
41
43 return false;
44}
45
47 HostBuffer& data_host_buffer) const {
48 using VS = TextureFillVertexShader;
49 constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3};
50
51 BufferView buffer_view = data_host_buffer.Emplace(
52 sizeof(VS::PerVertexData) * 6, alignof(VS::PerVertexData),
53 [&](uint8_t* raw_data) {
54 VS::PerVertexData* data =
55 reinterpret_cast<VS::PerVertexData*>(raw_data);
56 int offset = 0;
57 std::array<TPoint<float>, 4> destination_points =
58 destination_.GetPoints();
59 std::array<TPoint<float>, 4> texture_coords =
60 Rect::MakeSize(texture_->GetSize()).Project(source_).GetPoints();
61 for (size_t j = 0; j < 6; j++) {
62 data[offset].position = destination_points[indices[j]];
63 data[offset].texture_coords = texture_coords[indices[j]];
64 offset++;
65 }
66 });
67
68 return VertexBuffer{
69 .vertex_buffer = buffer_view,
70 .index_buffer = {},
71 .vertex_count = 6,
72 .index_type = IndexType::kNone,
73 };
74}
75
77 HostBuffer& data_host_buffer) const {
78 using VS = PorterDuffBlendVertexShader;
79 constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3};
80
81 BufferView buffer_view = data_host_buffer.Emplace(
82 sizeof(VS::PerVertexData) * 6, alignof(VS::PerVertexData),
83 [&](uint8_t* raw_data) {
84 VS::PerVertexData* data =
85 reinterpret_cast<VS::PerVertexData*>(raw_data);
86 int offset = 0;
87 std::array<TPoint<float>, 4> texture_coords =
88 Rect::MakeSize(texture_->GetSize()).Project(source_).GetPoints();
89 std::array<TPoint<float>, 4> destination_points =
90 destination_.GetPoints();
91 for (size_t j = 0; j < 6; j++) {
92 data[offset].vertices = destination_points[indices[j]];
93 data[offset].texture_coords = texture_coords[indices[j]];
94 data[offset].color = color_.Premultiply();
95 offset++;
96 }
97 });
98
99 return VertexBuffer{
100 .vertex_buffer = buffer_view,
101 .index_buffer = {},
102 .vertex_count = 6,
103 .index_type = IndexType::kNone,
104 };
105}
106
108 return destination_;
109}
110
111const std::shared_ptr<Texture>& DrawImageRectAtlasGeometry::GetAtlas() const {
112 return texture_;
113}
114
116 const {
117 return desc_;
118}
119
121 return blend_mode_;
122}
123
125 return false;
126}
127
129 if (use_strict_src_rect_) {
130 // For a strict source rect, shrink the texture coordinate range by half a
131 // texel to ensure that linear filtering does not sample anything outside
132 // the source rect bounds.
133 return Rect::MakeSize(texture_->GetSize()).Project(source_.Expand(-0.5));
134 }
135 return std::nullopt;
136}
137
138////
139
141
143
144std::optional<Rect> AtlasContents::GetCoverage(const Entity& entity) const {
145 if (!geometry_) {
146 return std::nullopt;
147 }
148 return geometry_->ComputeBoundingBox().TransformBounds(entity.GetTransform());
149}
150
152 geometry_ = geometry;
153}
154
156 alpha_ = alpha;
157}
158
160 const Entity& entity,
161 RenderPass& pass) const {
162 if (geometry_->ShouldSkip() || alpha_ <= 0.0) {
163 return true;
164 }
165
166 const SamplerDescriptor& dst_sampler_descriptor =
167 geometry_->GetSamplerDescriptor();
168 raw_ptr<const Sampler> dst_sampler =
169 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
170 dst_sampler_descriptor);
171
172 auto& data_host_buffer = renderer.GetTransientsDataBuffer();
173 if (!geometry_->ShouldUseBlend()) {
174 using VS = TextureFillVertexShader;
175 using FS = TextureFillFragmentShader;
176
177 raw_ptr<const Sampler> dst_sampler =
178 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
179 dst_sampler_descriptor);
180
181 auto pipeline_options = OptionsFromPassAndEntity(pass, entity);
182 pipeline_options.primitive_type = PrimitiveType::kTriangle;
183 pipeline_options.depth_write_enabled =
184 pipeline_options.blend_mode == BlendMode::kSrc;
185
186 pass.SetPipeline(renderer.GetTexturePipeline(pipeline_options));
187 pass.SetVertexBuffer(geometry_->CreateSimpleVertexBuffer(data_host_buffer));
188#ifdef IMPELLER_DEBUG
189 pass.SetCommandLabel("DrawAtlas");
190#endif // IMPELLER_DEBUG
191
192 VS::FrameInfo frame_info;
193 frame_info.mvp = entity.GetShaderTransform(pass);
194
195 VS::BindFrameInfo(pass, data_host_buffer.EmplaceUniform(frame_info));
196
197 FS::FragInfo frag_info;
198 frag_info.alpha = alpha_;
199 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform((frag_info)));
200 FS::BindTextureSampler(pass, geometry_->GetAtlas(), dst_sampler);
201 return pass.Draw().ok();
202 }
203
204 BlendMode blend_mode = geometry_->GetBlendMode();
205
206 if (blend_mode <= BlendMode::kModulate) {
207 using VS = PorterDuffBlendPipeline::VertexShader;
208 using FS = PorterDuffBlendPipeline::FragmentShader;
209
210#ifdef IMPELLER_DEBUG
211 pass.SetCommandLabel("DrawAtlas Blend");
212#endif // IMPELLER_DEBUG
213 pass.SetVertexBuffer(geometry_->CreateBlendVertexBuffer(data_host_buffer));
214 BlendMode inverted_blend_mode =
215 geometry_->ShouldInvertBlendMode()
216 ? (InvertPorterDuffBlend(blend_mode).value_or(BlendMode::kSrc))
217 : blend_mode;
219 inverted_blend_mode, OptionsFromPassAndEntity(pass, entity)));
220
221 FS::FragInfo frag_info;
222 VS::FrameInfo frame_info;
223
224 FS::BindTextureSamplerDst(pass, geometry_->GetAtlas(), dst_sampler);
225
226 frag_info.input_alpha_output_alpha_tmx_tmy =
227 Vector4(1.0, alpha_, static_cast<int>(Entity::TileMode::kDecal),
228 static_cast<int>(Entity::TileMode::kDecal));
229 if (auto rect = geometry_->GetStrictSrcRect(); rect.has_value()) {
230 Rect src_rect = rect.value();
231 frag_info.source_rect =
232 Vector4(src_rect.GetX(), src_rect.GetY(), src_rect.GetRight(),
233 src_rect.GetBottom());
234 frag_info.use_strict_source_rect = 1.0;
235 } else {
236 frag_info.use_strict_source_rect = 0.0;
237 }
238
239 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
240
241 frame_info.mvp = entity.GetShaderTransform(pass);
242
243 auto uniform_view = data_host_buffer.EmplaceUniform(frame_info);
244 VS::BindFrameInfo(pass, uniform_view);
245
246 return pass.Draw().ok();
247 }
248
249 using VUS = VerticesUber1Shader::VertexShader;
250 using FS = VerticesUber1Shader::FragmentShader;
251
252#ifdef IMPELLER_DEBUG
253 pass.SetCommandLabel("DrawAtlas Advanced Blend");
254#endif // IMPELLER_DEBUG
255 pass.SetVertexBuffer(geometry_->CreateBlendVertexBuffer(data_host_buffer));
256
258 blend_mode, OptionsFromPassAndEntity(pass, entity)));
259 FS::BindTextureSampler(pass, geometry_->GetAtlas(), dst_sampler);
260
261 VUS::FrameInfo frame_info;
262 FS::FragInfo frag_info;
263
264 frame_info.mvp = entity.GetShaderTransform(pass);
265
266 frag_info.alpha = alpha_;
267 frag_info.blend_mode = static_cast<int>(blend_mode);
268
269 // These values are ignored on platforms that natively support decal.
270 frag_info.tmx = static_cast<int>(Entity::TileMode::kDecal);
271 frag_info.tmy = static_cast<int>(Entity::TileMode::kDecal);
272
273 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
274 VUS::BindFrameInfo(pass, data_host_buffer.EmplaceUniform(frame_info));
275
276 return pass.Draw().ok();
277}
278
279///////////////
280
282
284
286 const Entity& entity) const {
287 if (!geometry_) {
288 return std::nullopt;
289 }
290 return geometry_->ComputeBoundingBox().TransformBounds(entity.GetTransform());
291}
292
294 geometry_ = geometry;
295}
296
298 alpha_ = alpha;
299}
300
302 matrix_ = matrix;
303}
304
306 const Entity& entity,
307 RenderPass& pass) const {
308 if (geometry_->ShouldSkip() || alpha_ <= 0.0) {
309 return true;
310 }
311
312 const SamplerDescriptor& dst_sampler_descriptor =
313 geometry_->GetSamplerDescriptor();
314
315 raw_ptr<const Sampler> dst_sampler =
316 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
317 dst_sampler_descriptor);
318
319 auto& data_host_buffer = renderer.GetTransientsDataBuffer();
320
321 using VS = ColorMatrixColorFilterPipeline::VertexShader;
322 using FS = ColorMatrixColorFilterPipeline::FragmentShader;
323
324#ifdef IMPELLER_DEBUG
325 pass.SetCommandLabel("Atlas ColorFilter");
326#endif // IMPELLER_DEBUG
327 pass.SetVertexBuffer(geometry_->CreateSimpleVertexBuffer(data_host_buffer));
328 pass.SetPipeline(
330
331 FS::FragInfo frag_info;
332 VS::FrameInfo frame_info;
333
334 FS::BindInputTexture(pass, geometry_->GetAtlas(), dst_sampler);
335
336 frag_info.input_alpha = 1;
337 frag_info.output_alpha = alpha_;
338 const float* matrix = matrix_.array;
339 frag_info.color_v = Vector4(matrix[4], matrix[9], matrix[14], matrix[19]);
340 frag_info.color_m = Matrix(matrix[0], matrix[5], matrix[10], matrix[15], //
341 matrix[1], matrix[6], matrix[11], matrix[16], //
342 matrix[2], matrix[7], matrix[12], matrix[17], //
343 matrix[3], matrix[8], matrix[13], matrix[18] //
344 );
345
346 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
347
348 frame_info.mvp = entity.GetShaderTransform(pass);
349
350 auto uniform_view = data_host_buffer.EmplaceUniform(frame_info);
351 VS::BindFrameInfo(pass, uniform_view);
352
353 return pass.Draw().ok();
354}
355
356} // namespace impeller
bool ok() const
Definition status.h:71
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
void SetGeometry(AtlasGeometry *geometry)
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 SetAlpha(Scalar alpha)
virtual const SamplerDescriptor & GetSamplerDescriptor() const =0
virtual VertexBuffer CreateSimpleVertexBuffer(HostBuffer &host_buffer) const =0
virtual Rect ComputeBoundingBox() const =0
virtual const std::shared_ptr< Texture > & GetAtlas() const =0
virtual bool ShouldInvertBlendMode() const
virtual bool ShouldUseBlend() const =0
virtual bool ShouldSkip() const =0
virtual VertexBuffer CreateBlendVertexBuffer(HostBuffer &host_buffer) const =0
virtual BlendMode GetBlendMode() const =0
virtual std::optional< Rect > GetStrictSrcRect() const
The source rect of the draw in texture coordinates if a strict source rect should be applied,...
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 SetGeometry(AtlasGeometry *geometry)
void SetMatrix(ColorMatrix matrix)
bool Render(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
HostBuffer & GetTransientsDataBuffer() const
Retrieve the current host buffer for transient storage of other non-index data.
PipelineRef GetPorterDuffPipeline(BlendMode mode, ContentContextOptions opts) const
PipelineRef GetTexturePipeline(ContentContextOptions opts) const
PipelineRef GetColorMatrixColorFilterPipeline(ContentContextOptions opts) const
std::shared_ptr< Context > GetContext() const
PipelineRef GetDrawVerticesUberPipeline(BlendMode blend_mode, ContentContextOptions opts) const
DrawImageRectAtlasGeometry(std::shared_ptr< Texture > texture, const Rect &source, const Rect &destination, const Color &color, BlendMode blend_mode, const SamplerDescriptor &desc, bool use_strict_src_rect=false)
const SamplerDescriptor & GetSamplerDescriptor() const override
std::optional< Rect > GetStrictSrcRect() const override
The source rect of the draw in texture coordinates if a strict source rect should be applied,...
BlendMode GetBlendMode() const override
bool ShouldInvertBlendMode() const override
VertexBuffer CreateBlendVertexBuffer(HostBuffer &host_buffer) const override
VertexBuffer CreateSimpleVertexBuffer(HostBuffer &host_buffer) const override
const std::shared_ptr< Texture > & GetAtlas() const override
Matrix GetShaderTransform(const RenderPass &pass) const
Definition entity.cc:50
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition entity.cc:46
BufferView Emplace(const BufferType &buffer, size_t alignment=0)
Emplace non-uniform data (like contiguous vertices) onto the host buffer.
Definition host_buffer.h:92
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.
virtual void SetPipeline(PipelineRef 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.
A wrapper around a raw ptr that adds additional unopt mode only checks.
Definition raw_ptr.h:15
std::optional< PipelineDescriptor > desc_
FlTexture * texture
float Scalar
Definition scalar.h:19
@ kNone
Does not use the index buffer.
LinePipeline::FragmentShader FS
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
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition contents.cc:19
Definition ref_ptr.h:261
constexpr Color Premultiply() const
Definition color.h:212
Scalar array[20]
Definition color.h:118
A 4x4 matrix using column-major storage.
Definition matrix.h:37
constexpr auto GetBottom() const
Definition rect.h:391
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition rect.h:371
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition rect.h:506
constexpr std::array< TPoint< T >, 4 > GetPoints() const
Get the points that represent the 4 corners of this rectangle in a Z order that is compatible with tr...
Definition rect.h:448
constexpr TRect< T > Project(TRect< T > source) const
Returns a new rectangle that represents the projection of the source rectangle onto this rectangle....
Definition rect.h:703
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition rect.h:367
constexpr auto GetRight() const
Definition rect.h:389
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:150
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
Definition rect.h:652