| 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
7 #include "impeller/core/formats.h"
8 #include "impeller/entity/contents/atlas_contents.h"
9 #include "impeller/entity/contents/content_context.h"
10 #include "impeller/entity/contents/filters/blend_filter_contents.h"
11 #include "impeller/entity/entity.h"
12 #include "impeller/entity/texture_fill.frag.h"
13 #include "impeller/entity/texture_fill.vert.h"
14 #include "impeller/geometry/color.h"
15 #include "impeller/renderer/render_pass.h"
16
17 namespace impeller {
18
19 AtlasContents::AtlasContents() = default;
20
21 AtlasContents::~AtlasContents() = default;
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
30 void AtlasContents::SetGeometry(AtlasGeometry* geometry) {
31 geometry_ = geometry;
32 }
33
34 void AtlasContents::SetAlpha(Scalar alpha) {
35 alpha_ = alpha;
36 }
37
38 bool AtlasContents::Render(const ContentContext& renderer,
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();
46 if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
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) {
93 using VS = PorterDuffBlendPipeline::VertexShader;
94 using FS = PorterDuffBlendPipeline::FragmentShader;
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(
102 renderer.GetPorterDuffBlendPipeline(OptionsFromPass(pass)));
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
137 using VUS = VerticesUberShader::VertexShader;
138 using FS = VerticesUberShader::FragmentShader;
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
146 pass.SetPipeline(renderer.GetDrawVerticesUberShader(OptionsFromPass(pass)));
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...