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  const std::unique_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  const std::unique_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(
98  SPrintF("DrawAtlas Blend (%s)", BlendModeToString(blend_mode)));
99 #endif // IMPELLER_DEBUG
100  pass.SetVertexBuffer(geometry_->CreateBlendVertexBuffer(host_buffer));
101  pass.SetPipeline(
103 
104  FS::FragInfo frag_info;
105  VS::FrameInfo frame_info;
106 
107  FS::BindTextureSamplerDst(pass, geometry_->GetAtlas(), dst_sampler);
108  frame_info.texture_sampler_y_coord_scale =
109  geometry_->GetAtlas()->GetYCoordScale();
110 
111  frag_info.output_alpha = alpha_;
112  frag_info.input_alpha = 1.0;
113 
114  auto inverted_blend_mode =
115  InvertPorterDuffBlend(blend_mode).value_or(BlendMode::kSource);
116  auto blend_coefficients =
117  kPorterDuffCoefficients[static_cast<int>(inverted_blend_mode)];
118  frag_info.src_coeff = blend_coefficients[0];
119  frag_info.src_coeff_dst_alpha = blend_coefficients[1];
120  frag_info.dst_coeff = blend_coefficients[2];
121  frag_info.dst_coeff_src_alpha = blend_coefficients[3];
122  frag_info.dst_coeff_src_color = blend_coefficients[4];
123  // These values are ignored on platforms that natively support decal.
124  frag_info.tmx = static_cast<int>(Entity::TileMode::kDecal);
125  frag_info.tmy = static_cast<int>(Entity::TileMode::kDecal);
126 
127  FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
128 
129  frame_info.mvp = entity.GetShaderTransform(pass);
130 
131  auto uniform_view = host_buffer.EmplaceUniform(frame_info);
132  VS::BindFrameInfo(pass, uniform_view);
133 
134  return pass.Draw().ok();
135  }
136 
139 
140 #ifdef IMPELLER_DEBUG
141  pass.SetCommandLabel(
142  SPrintF("DrawAtlas Advanced Blend (%s)", BlendModeToString(blend_mode)));
143 #endif // IMPELLER_DEBUG
144  pass.SetVertexBuffer(geometry_->CreateBlendVertexBuffer(host_buffer));
145 
147  FS::BindTextureSampler(pass, geometry_->GetAtlas(), dst_sampler);
148 
149  VUS::FrameInfo frame_info;
150  FS::FragInfo frag_info;
151 
152  frame_info.texture_sampler_y_coord_scale =
153  geometry_->GetAtlas()->GetYCoordScale();
154  frame_info.mvp = entity.GetShaderTransform(pass);
155 
156  frag_info.alpha = alpha_;
157  frag_info.blend_mode = static_cast<int>(blend_mode);
158 
159  // These values are ignored on platforms that natively support decal.
160  frag_info.tmx = static_cast<int>(Entity::TileMode::kDecal);
161  frag_info.tmy = static_cast<int>(Entity::TileMode::kDecal);
162 
163  FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
164  VUS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
165 
166  return pass.Draw().ok();
167 }
168 
169 } // namespace impeller
impeller::ContentContext::GetTexturePipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetTexturePipeline(ContentContextOptions opts) const
Definition: content_context.h:438
impeller::RenderPipelineHandle::FragmentShader
FragmentShader_ FragmentShader
Definition: pipeline.h:107
impeller::Entity::GetShaderTransform
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:51
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19
impeller::AtlasGeometry::ShouldUseBlend
virtual bool ShouldUseBlend() const =0
impeller::BlendModeToString
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:47
entity.h
impeller::BlendMode
BlendMode
Definition: color.h:58
impeller::AtlasGeometry::GetBlendMode
virtual BlendMode GetBlendMode() const =0
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:466
impeller::InvertPorterDuffBlend
std::optional< BlendMode > InvertPorterDuffBlend(BlendMode blend_mode)
Definition: blend_filter_contents.cc:33
formats.h
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::AtlasGeometry::GetSamplerDescriptor
virtual const SamplerDescriptor & GetSamplerDescriptor() const =0
impeller::RenderPass::SetCommandLabel
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
Definition: render_pass.cc:97
impeller::AtlasGeometry::ShouldSkip
virtual bool ShouldSkip() const =0
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::PrimitiveType::kTriangle
@ kTriangle
impeller::Entity
Definition: entity.h:20
impeller::OptionsFromPassAndEntity
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:34
impeller::AtlasGeometry
Definition: atlas_contents.h:19
impeller::AtlasGeometry::GetAtlas
virtual std::shared_ptr< Texture > GetAtlas() const =0
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:38
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::AtlasGeometry::CreateSimpleVertexBuffer
virtual VertexBuffer CreateSimpleVertexBuffer(HostBuffer &host_buffer) const =0
impeller::ContentContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: content_context.cc:550
impeller::RenderPipelineHandle::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:106
impeller::SamplerDescriptor::width_address_mode
SamplerAddressMode width_address_mode
Definition: sampler_descriptor.h:20
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:685
impeller::AtlasContents::AtlasContents
AtlasContents()
impeller::AtlasGeometry::ComputeBoundingBox
virtual Rect ComputeBoundingBox() const =0
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:23
atlas_contents.h
impeller::AtlasContents::SetGeometry
void SetGeometry(AtlasGeometry *geometry)
Definition: atlas_contents.cc:30
content_context.h
impeller::ContentContext::GetDeviceCapabilities
const Capabilities & GetDeviceCapabilities() const
Definition: content_context.cc:554
impeller::AtlasGeometry::CreateBlendVertexBuffer
virtual VertexBuffer CreateBlendVertexBuffer(HostBuffer &host_buffer) const =0
impeller::AtlasContents::SetAlpha
void SetAlpha(Scalar alpha)
Definition: atlas_contents.cc:34
color.h
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::Capabilities::SupportsDecalSamplerAddressMode
virtual bool SupportsDecalSamplerAddressMode() const =0
Whether the context backend supports SamplerAddressMode::Decal.
impeller
Definition: allocation.cc:12
impeller::ContentContext
Definition: content_context.h:366
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:753
impeller::ContentContext::GetPorterDuffBlendPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetPorterDuffBlendPipeline(ContentContextOptions opts) const
Definition: content_context.h:507
impeller::SamplerAddressMode::kDecal
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...