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 
11 #include "impeller/entity/entity.h"
12 #include "impeller/entity/texture_fill.frag.h"
13 #include "impeller/entity/texture_fill.vert.h"
16 
17 namespace impeller {
18 
20 
22 
23 std::optional<Rect> AtlasContents::GetCoverage(const Entity& entity) const {
24  if (!geometry_) {
25  return std::nullopt;
26  }
27  return geometry_->ComputeBoundingBox().TransformBounds(entity.GetTransform());
28 }
29 
31  geometry_ = geometry;
32 }
33 
35  alpha_ = alpha;
36 }
37 
39  const Entity& entity,
40  RenderPass& pass) const {
41  if (geometry_->ShouldSkip() || alpha_ <= 0.0) {
42  return true;
43  }
44 
45  auto dst_sampler_descriptor = geometry_->GetSamplerDescriptor();
47  dst_sampler_descriptor.width_address_mode = SamplerAddressMode::kDecal;
48  dst_sampler_descriptor.height_address_mode = SamplerAddressMode::kDecal;
49  }
50  raw_ptr<const Sampler> dst_sampler =
51  renderer.GetContext()->GetSamplerLibrary()->GetSampler(
52  dst_sampler_descriptor);
53 
54  auto& host_buffer = renderer.GetTransientsBuffer();
55  if (!geometry_->ShouldUseBlend()) {
56  using VS = TextureFillVertexShader;
57  using FS = TextureFillFragmentShader;
58 
59  auto dst_sampler_descriptor = geometry_->GetSamplerDescriptor();
60 
61  raw_ptr<const Sampler> dst_sampler =
62  renderer.GetContext()->GetSamplerLibrary()->GetSampler(
63  dst_sampler_descriptor);
64 
65  auto pipeline_options = OptionsFromPassAndEntity(pass, entity);
66  pipeline_options.primitive_type = PrimitiveType::kTriangle;
67  pipeline_options.depth_write_enabled =
68  pipeline_options.blend_mode == BlendMode::kSource;
69 
70  pass.SetPipeline(renderer.GetTexturePipeline(pipeline_options));
71  pass.SetVertexBuffer(geometry_->CreateSimpleVertexBuffer(host_buffer));
72 #ifdef IMPELLER_DEBUG
73  pass.SetCommandLabel("DrawAtlas");
74 #endif // IMPELLER_DEBUG
75 
76  VS::FrameInfo frame_info;
77  frame_info.mvp = entity.GetShaderTransform(pass);
78  frame_info.texture_sampler_y_coord_scale =
79  geometry_->GetAtlas()->GetYCoordScale();
80 
81  VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
82 
83  FS::FragInfo frag_info;
84  frag_info.alpha = alpha_;
85  FS::BindFragInfo(pass, host_buffer.EmplaceUniform((frag_info)));
86  FS::BindTextureSampler(pass, geometry_->GetAtlas(), dst_sampler);
87  return pass.Draw().ok();
88  }
89 
90  BlendMode blend_mode = geometry_->GetBlendMode();
91 
92  if (blend_mode <= BlendMode::kModulate) {
95 
96 #ifdef IMPELLER_DEBUG
97  pass.SetCommandLabel("DrawAtlas Blend");
98 #endif // IMPELLER_DEBUG
99  pass.SetVertexBuffer(geometry_->CreateBlendVertexBuffer(host_buffer));
100  auto inverted_blend_mode =
101  InvertPorterDuffBlend(blend_mode).value_or(BlendMode::kSource);
102  pass.SetPipeline(renderer.GetPorterDuffPipeline(inverted_blend_mode,
103  OptionsFromPass(pass)));
104 
105  FS::FragInfo frag_info;
106  VS::FrameInfo frame_info;
107 
108  FS::BindTextureSamplerDst(pass, geometry_->GetAtlas(), dst_sampler);
109  frame_info.texture_sampler_y_coord_scale =
110  geometry_->GetAtlas()->GetYCoordScale();
111 
112  frag_info.output_alpha = alpha_;
113  frag_info.input_alpha = 1.0;
114 
115  // These values are ignored on platforms that natively support decal.
116  frag_info.tmx = static_cast<int>(Entity::TileMode::kDecal);
117  frag_info.tmy = static_cast<int>(Entity::TileMode::kDecal);
118 
119  FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
120 
121  frame_info.mvp = entity.GetShaderTransform(pass);
122 
123  auto uniform_view = host_buffer.EmplaceUniform(frame_info);
124  VS::BindFrameInfo(pass, uniform_view);
125 
126  return pass.Draw().ok();
127  }
128 
131 
132 #ifdef IMPELLER_DEBUG
133  pass.SetCommandLabel("DrawAtlas Advanced Blend");
134 #endif // IMPELLER_DEBUG
135  pass.SetVertexBuffer(geometry_->CreateBlendVertexBuffer(host_buffer));
136 
138  FS::BindTextureSampler(pass, geometry_->GetAtlas(), dst_sampler);
139 
140  VUS::FrameInfo frame_info;
141  FS::FragInfo frag_info;
142 
143  frame_info.texture_sampler_y_coord_scale =
144  geometry_->GetAtlas()->GetYCoordScale();
145  frame_info.mvp = entity.GetShaderTransform(pass);
146 
147  frag_info.alpha = alpha_;
148  frag_info.blend_mode = static_cast<int>(blend_mode);
149 
150  // These values are ignored on platforms that natively support decal.
151  frag_info.tmx = static_cast<int>(Entity::TileMode::kDecal);
152  frag_info.tmy = static_cast<int>(Entity::TileMode::kDecal);
153 
154  FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
155  VUS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
156 
157  return pass.Draw().ok();
158 }
159 
160 } // namespace impeller
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 VertexBuffer CreateSimpleVertexBuffer(HostBuffer &host_buffer) const =0
virtual Rect ComputeBoundingBox() const =0
virtual bool ShouldUseBlend() const =0
virtual std::shared_ptr< Texture > GetAtlas() const =0
virtual const SamplerDescriptor & GetSamplerDescriptor() const =0
virtual bool ShouldSkip() const =0
virtual VertexBuffer CreateBlendVertexBuffer(HostBuffer &host_buffer) const =0
virtual BlendMode GetBlendMode() const =0
virtual bool SupportsDecalSamplerAddressMode() const =0
Whether the context backend supports SamplerAddressMode::Decal.
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
PipelineRef GetPorterDuffPipeline(BlendMode mode, ContentContextOptions opts) const
const Capabilities & GetDeviceCapabilities() const
PipelineRef GetDrawVerticesUberShader(ContentContextOptions opts) const
PipelineRef GetTexturePipeline(ContentContextOptions opts) const
std::shared_ptr< Context > GetContext() const
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:48
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:44
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:114
A wrapper around a raw ptr that adds additional unopt mode only checks.
Definition: raw_ptr.h:15
float Scalar
Definition: scalar.h:18
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
GlyphAtlasPipeline::VertexShader VS
std::optional< BlendMode > InvertPorterDuffBlend(BlendMode blend_mode)
BlendMode
Definition: color.h:58
GlyphAtlasPipeline::FragmentShader FS
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:34
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19
SamplerAddressMode width_address_mode
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:476