Skip to content

Commit 53a2189

Browse files
author
jonahwilliams
committed
Use sub-contents
1 parent e83fb61 commit 53a2189

3 files changed

Lines changed: 179 additions & 110 deletions

File tree

impeller/entity/contents/atlas_contents.cc

Lines changed: 119 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -82,97 +82,105 @@ const SamplerDescriptor& AtlasContents::GetSamplerDescriptor() const {
8282
return sampler_descriptor_;
8383
}
8484

85+
const std::vector<Matrix>& AtlasContents::GetTransforms() const {
86+
return transforms_;
87+
}
88+
89+
const std::vector<Rect>& AtlasContents::GetTextureCoordinates() const {
90+
return texture_coords_;
91+
}
92+
93+
const std::vector<Color>& AtlasContents::GetColors() const {
94+
return colors_;
95+
}
96+
8597
bool AtlasContents::Render(const ContentContext& renderer,
8698
const Entity& entity,
8799
RenderPass& pass) const {
88100
if (texture_ == nullptr || blend_mode_ == BlendMode::kClear) {
89101
return true;
90102
}
91103

104+
// Ensure that we use the actual computed bounds and not a cull-rect
105+
// approximation of them.
106+
auto coverage = ComputeBoundingBox();
107+
92108
if (blend_mode_ == BlendMode::kSource || colors_.size() == 0) {
93-
return RenderTexture(renderer, entity, pass, alpha_);
109+
auto child_contents = AtlasTextureContents(*this);
110+
child_contents.SetAlpha(alpha_);
111+
child_contents.SetCoverage(coverage);
112+
return child_contents.Render(renderer, entity, pass);
94113
}
95114
if (blend_mode_ == BlendMode::kDestination) {
96-
return RenderColors(renderer, entity, pass, alpha_);
115+
auto child_contents = AtlasColorContents(*this);
116+
child_contents.SetAlpha(alpha_);
117+
child_contents.SetCoverage(coverage);
118+
return child_contents.Render(renderer, entity, pass);
97119
}
98120

99-
// Ensure that we use the actual computed bounds and not a cull-rect
100-
// approximation of them.
101-
auto coverage = ComputeBoundingBox();
102-
auto size = coverage.size;
103-
104-
// Simple blends.
105-
if (blend_mode_ < BlendMode::kScreen) {
106-
auto subpass_texture = renderer.MakeSubpass(
107-
ISize::Ceil(size),
108-
[&contents = *this, &coverage](const ContentContext& renderer,
109-
RenderPass& pass) -> bool {
110-
Entity sub_entity;
111-
sub_entity.SetBlendMode(BlendMode::kSourceOver);
112-
sub_entity.SetTransformation(
113-
Matrix::MakeTranslation(Vector3(-coverage.origin)));
114-
if (!contents.RenderColors(renderer, sub_entity, pass, 1.0)) {
115-
return false;
116-
}
117-
return contents.RenderTexture(renderer, sub_entity, pass, 1.0, true);
118-
});
119-
auto contents = ColorFilterContents::MakeBlend(
120-
blend_mode_, {FilterInput::Make(subpass_texture)});
121-
contents->SetAlpha(alpha_);
122-
return contents->Render(renderer, entity, pass);
123-
}
121+
auto src_contents = std::make_shared<AtlasTextureContents>(*this);
122+
src_contents->SetCoverage(coverage);
123+
124+
auto dst_contents = std::make_shared<AtlasColorContents>(*this);
125+
dst_contents->SetCoverage(coverage);
124126

125-
auto dst_texture = renderer.MakeSubpass(
126-
ISize::Ceil(size),
127-
[&contents = *this, &coverage](const ContentContext& renderer,
128-
RenderPass& pass) -> bool {
129-
Entity sub_entity;
130-
sub_entity.SetBlendMode(BlendMode::kSourceOver);
131-
sub_entity.SetTransformation(
132-
Matrix::MakeTranslation(Vector3(-coverage.origin)));
133-
return contents.RenderColors(renderer, sub_entity, pass, 1.0);
134-
});
135-
auto src_texture = renderer.MakeSubpass(
136-
ISize::Ceil(size),
137-
[&contents = *this, &coverage](const ContentContext& renderer,
138-
RenderPass& pass) -> bool {
139-
Entity sub_entity;
140-
sub_entity.SetBlendMode(BlendMode::kSourceOver);
141-
sub_entity.SetTransformation(
142-
Matrix::MakeTranslation(Vector3(-coverage.origin)));
143-
return contents.RenderTexture(renderer, sub_entity, pass, 1.0);
144-
});
145-
146-
if (!src_texture || !dst_texture) {
147-
return false;
148-
}
149127
auto contents = ColorFilterContents::MakeBlend(
150128
blend_mode_,
151-
{FilterInput::Make(src_texture), FilterInput::Make(dst_texture)});
129+
{FilterInput::Make(dst_contents), FilterInput::Make(src_contents)});
152130
contents->SetAlpha(alpha_);
153131
return contents->Render(renderer, entity, pass);
154132
}
155133

156-
bool AtlasContents::RenderColors(const ContentContext& renderer,
157-
const Entity& entity,
158-
RenderPass& pass,
159-
Scalar alpha) const {
160-
using VS = GeometryColorPipeline::VertexShader;
161-
using FS = GeometryColorPipeline::FragmentShader;
134+
// AtlasTextureContents
135+
// ---------------------------------------------------------
136+
137+
AtlasTextureContents::AtlasTextureContents(const AtlasContents& parent)
138+
: parent_(parent) {}
139+
140+
AtlasTextureContents::~AtlasTextureContents() {}
162141

142+
std::optional<Rect> AtlasTextureContents::GetCoverage(
143+
const Entity& entity) const {
144+
return coverage_.TransformBounds(entity.GetTransformation());
145+
}
146+
147+
void AtlasTextureContents::SetAlpha(Scalar alpha) {
148+
alpha_ = alpha;
149+
}
150+
151+
void AtlasTextureContents::SetCoverage(Rect coverage) {
152+
coverage_ = coverage;
153+
}
154+
155+
bool AtlasTextureContents::Render(const ContentContext& renderer,
156+
const Entity& entity,
157+
RenderPass& pass) const {
158+
using VS = TextureFillVertexShader;
159+
using FS = TextureFillFragmentShader;
160+
161+
auto texture = parent_.GetTexture();
162+
auto texture_coords = parent_.GetTextureCoordinates();
163+
auto transforms = parent_.GetTransforms();
164+
165+
const auto texture_size = texture->GetSize();
163166
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
164-
vertex_builder.Reserve(texture_coords_.size() * 6);
167+
vertex_builder.Reserve(texture_coords.size() * 6);
165168
constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3};
166-
for (size_t i = 0; i < texture_coords_.size(); i++) {
167-
auto sample_rect = texture_coords_[i];
168-
auto matrix = transforms_[i];
169+
constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1};
170+
constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1};
171+
for (size_t i = 0; i < texture_coords.size(); i++) {
172+
auto sample_rect = texture_coords[i];
173+
auto matrix = transforms[i];
169174
auto transformed_points =
170175
Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix);
171176

172177
for (size_t j = 0; j < 6; j++) {
173178
VS::PerVertexData data;
174179
data.position = transformed_points[indices[j]];
175-
data.color = colors_[i].Premultiply();
180+
data.texture_coords =
181+
(sample_rect.origin + Point(sample_rect.size.width * width[j],
182+
sample_rect.size.height * height[j])) /
183+
texture_size;
176184
vertex_builder.AppendVertex(data);
177185
}
178186
}
@@ -182,7 +190,7 @@ bool AtlasContents::RenderColors(const ContentContext& renderer,
182190
}
183191

184192
Command cmd;
185-
cmd.label = "DrawAtlas";
193+
cmd.label = "AtlasTexture";
186194

187195
auto& host_buffer = pass.GetTransientsBuffer();
188196

@@ -191,45 +199,65 @@ bool AtlasContents::RenderColors(const ContentContext& renderer,
191199
entity.GetTransformation();
192200

193201
FS::FragInfo frag_info;
194-
frag_info.alpha = alpha;
202+
frag_info.texture_sampler_y_coord_scale = texture->GetYCoordScale();
203+
frag_info.alpha = alpha_;
195204

196-
auto opts = OptionsFromPassAndEntity(pass, entity);
197-
opts.blend_mode = BlendMode::kSourceOver;
198-
cmd.pipeline = renderer.GetGeometryColorPipeline(opts);
205+
auto options = OptionsFromPassAndEntity(pass, entity);
206+
cmd.pipeline = renderer.GetTexturePipeline(options);
199207
cmd.stencil_reference = entity.GetStencilDepth();
200208
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
201209
VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info));
202210
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
211+
FS::BindTextureSampler(cmd, texture,
212+
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
213+
parent_.GetSamplerDescriptor()));
203214
return pass.AddCommand(std::move(cmd));
204215
}
205216

206-
bool AtlasContents::RenderTexture(const ContentContext& renderer,
207-
const Entity& entity,
208-
RenderPass& pass,
209-
Scalar alpha,
210-
bool apply_blend) const {
211-
using VS = TextureFillVertexShader;
212-
using FS = TextureFillFragmentShader;
217+
// AtlasColorContents
218+
// ---------------------------------------------------------
219+
220+
AtlasColorContents::AtlasColorContents(const AtlasContents& parent)
221+
: parent_(parent) {}
222+
223+
AtlasColorContents::~AtlasColorContents() {}
224+
225+
std::optional<Rect> AtlasColorContents::GetCoverage(
226+
const Entity& entity) const {
227+
return coverage_.TransformBounds(entity.GetTransformation());
228+
}
229+
230+
void AtlasColorContents::SetAlpha(Scalar alpha) {
231+
alpha_ = alpha;
232+
}
233+
234+
void AtlasColorContents::SetCoverage(Rect coverage) {
235+
coverage_ = coverage;
236+
}
237+
238+
bool AtlasColorContents::Render(const ContentContext& renderer,
239+
const Entity& entity,
240+
RenderPass& pass) const {
241+
using VS = GeometryColorPipeline::VertexShader;
242+
using FS = GeometryColorPipeline::FragmentShader;
243+
244+
auto texture_coords = parent_.GetTextureCoordinates();
245+
auto transforms = parent_.GetTransforms();
246+
auto colors = parent_.GetColors();
213247

214-
const auto texture_size = texture_->GetSize();
215248
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
216-
vertex_builder.Reserve(texture_coords_.size() * 6);
249+
vertex_builder.Reserve(texture_coords.size() * 6);
217250
constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3};
218-
constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1};
219-
constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1};
220-
for (size_t i = 0; i < texture_coords_.size(); i++) {
221-
auto sample_rect = texture_coords_[i];
222-
auto matrix = transforms_[i];
251+
for (size_t i = 0; i < texture_coords.size(); i++) {
252+
auto sample_rect = texture_coords[i];
253+
auto matrix = transforms[i];
223254
auto transformed_points =
224255
Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix);
225256

226257
for (size_t j = 0; j < 6; j++) {
227258
VS::PerVertexData data;
228259
data.position = transformed_points[indices[j]];
229-
data.texture_coords =
230-
(sample_rect.origin + Point(sample_rect.size.width * width[j],
231-
sample_rect.size.height * height[j])) /
232-
texture_size;
260+
data.color = colors[i].Premultiply();
233261
vertex_builder.AppendVertex(data);
234262
}
235263
}
@@ -239,7 +267,7 @@ bool AtlasContents::RenderTexture(const ContentContext& renderer,
239267
}
240268

241269
Command cmd;
242-
cmd.label = "DrawAtlas";
270+
cmd.label = "AtlasColors";
243271

244272
auto& host_buffer = pass.GetTransientsBuffer();
245273

@@ -248,21 +276,15 @@ bool AtlasContents::RenderTexture(const ContentContext& renderer,
248276
entity.GetTransformation();
249277

250278
FS::FragInfo frag_info;
251-
frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale();
252-
frag_info.alpha = alpha;
279+
frag_info.alpha = alpha_;
253280

254-
auto options = OptionsFromPassAndEntity(pass, entity);
255-
if (apply_blend) {
256-
options.blend_mode = blend_mode_;
257-
}
258-
cmd.pipeline = renderer.GetTexturePipeline(options);
281+
auto opts = OptionsFromPassAndEntity(pass, entity);
282+
opts.blend_mode = BlendMode::kSourceOver;
283+
cmd.pipeline = renderer.GetGeometryColorPipeline(opts);
259284
cmd.stencil_reference = entity.GetStencilDepth();
260285
cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer));
261286
VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info));
262287
FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info));
263-
FS::BindTextureSampler(cmd, texture_,
264-
renderer.GetContext()->GetSamplerLibrary()->GetSampler(
265-
sampler_descriptor_));
266288
return pass.AddCommand(std::move(cmd));
267289
}
268290

impeller/entity/contents/atlas_contents.h

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ class AtlasContents final : public Contents {
4141

4242
const SamplerDescriptor& GetSamplerDescriptor() const;
4343

44+
const std::vector<Matrix>& GetTransforms() const;
45+
46+
const std::vector<Rect>& GetTextureCoordinates() const;
47+
48+
const std::vector<Color>& GetColors() const;
49+
4450
// |Contents|
4551
std::optional<Rect> GetCoverage(const Entity& entity) const override;
4652

@@ -50,17 +56,6 @@ class AtlasContents final : public Contents {
5056
RenderPass& pass) const override;
5157

5258
private:
53-
bool RenderTexture(const ContentContext& renderer,
54-
const Entity& entity,
55-
RenderPass& pass,
56-
Scalar alpha,
57-
bool apply_blend = false) const;
58-
59-
bool RenderColors(const ContentContext& renderer,
60-
const Entity& entity,
61-
RenderPass& pass,
62-
Scalar alpha) const;
63-
6459
Rect ComputeBoundingBox() const;
6560

6661
std::shared_ptr<Texture> texture_;
@@ -75,4 +70,56 @@ class AtlasContents final : public Contents {
7570
FML_DISALLOW_COPY_AND_ASSIGN(AtlasContents);
7671
};
7772

73+
class AtlasTextureContents final : public Contents {
74+
public:
75+
explicit AtlasTextureContents(const AtlasContents& parent);
76+
77+
~AtlasTextureContents() override;
78+
79+
// |Contents|
80+
std::optional<Rect> GetCoverage(const Entity& entity) const override;
81+
82+
// |Contents|
83+
bool Render(const ContentContext& renderer,
84+
const Entity& entity,
85+
RenderPass& pass) const override;
86+
87+
void SetAlpha(Scalar alpha);
88+
89+
void SetCoverage(Rect coverage);
90+
91+
private:
92+
const AtlasContents& parent_;
93+
Scalar alpha_ = 1.0;
94+
Rect coverage_;
95+
96+
FML_DISALLOW_COPY_AND_ASSIGN(AtlasTextureContents);
97+
};
98+
99+
class AtlasColorContents final : public Contents {
100+
public:
101+
explicit AtlasColorContents(const AtlasContents& parent);
102+
103+
~AtlasColorContents() override;
104+
105+
// |Contents|
106+
std::optional<Rect> GetCoverage(const Entity& entity) const override;
107+
108+
// |Contents|
109+
bool Render(const ContentContext& renderer,
110+
const Entity& entity,
111+
RenderPass& pass) const override;
112+
113+
void SetAlpha(Scalar alpha);
114+
115+
void SetCoverage(Rect coverage);
116+
117+
private:
118+
const AtlasContents& parent_;
119+
Scalar alpha_ = 1.0;
120+
Rect coverage_;
121+
122+
FML_DISALLOW_COPY_AND_ASSIGN(AtlasColorContents);
123+
};
124+
78125
} // namespace impeller

0 commit comments

Comments
 (0)