Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit af24113

Browse files
committed
[Impeller] Add depth settings to pipeline variant hash.
1 parent 68943af commit af24113

37 files changed

+307
-124
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4040,5 +4040,32 @@ TEST_P(AiksTest, ImageColorSourceEffectTransform) {
40404040
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
40414041
}
40424042

4043+
TEST_P(AiksTest, CorrectClipDepthAssignedToEntities) {
4044+
Canvas canvas; // Depth 1 (base pass)
4045+
canvas.DrawRRect(Rect::MakeLTRB(0, 0, 100, 100), {10, 10}, {}); // Depth 2
4046+
canvas.ClipRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 4
4047+
canvas.SaveLayer({}); // Depth 3
4048+
canvas.DrawRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 4
4049+
4050+
auto picture = canvas.EndRecordingAsPicture();
4051+
std::array<uint32_t, 4> expected = {2, 4, 3, 4};
4052+
std::vector<uint32_t> actual;
4053+
4054+
picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
4055+
if (auto* subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
4056+
actual.push_back(subpass->get()->GetNewClipDepth());
4057+
}
4058+
if (Entity* entity = std::get_if<Entity>(&element)) {
4059+
actual.push_back(entity->GetNewClipDepth());
4060+
}
4061+
return true;
4062+
});
4063+
4064+
ASSERT_EQ(actual.size(), expected.size());
4065+
for (size_t i = 0; i < expected.size(); i++) {
4066+
EXPECT_EQ(actual[i], expected[i]) << "Index: " << i;
4067+
}
4068+
}
4069+
40434070
} // namespace testing
40444071
} // namespace impeller

impeller/aiks/canvas.cc

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ Canvas::~Canvas() = default;
117117
void Canvas::Initialize(std::optional<Rect> cull_rect) {
118118
initial_cull_rect_ = cull_rect;
119119
base_pass_ = std::make_unique<EntityPass>();
120+
base_pass_->SetNewClipDepth(++current_depth_);
120121
current_pass_ = base_pass_.get();
121122
transform_stack_.emplace_back(CanvasStackEntry{.cull_rect = cull_rect});
122123
FML_DCHECK(GetSaveCount() == 1u);
@@ -126,6 +127,7 @@ void Canvas::Initialize(std::optional<Rect> cull_rect) {
126127
void Canvas::Reset() {
127128
base_pass_ = nullptr;
128129
current_pass_ = nullptr;
130+
current_depth_ = 0u;
129131
transform_stack_ = {};
130132
}
131133

@@ -174,6 +176,7 @@ void Canvas::Save(bool create_subpass,
174176
if (create_subpass) {
175177
entry.rendering_mode = Entity::RenderingMode::kSubpass;
176178
auto subpass = std::make_unique<EntityPass>();
179+
subpass->SetNewClipDepth(++current_depth_);
177180
subpass->SetEnableOffscreenCheckerboard(
178181
debug_options.offscreen_texture_checkerboard);
179182
if (backdrop_filter) {
@@ -206,16 +209,16 @@ bool Canvas::Restore() {
206209
if (transform_stack_.size() == 1) {
207210
return false;
208211
}
212+
size_t num_clips = transform_stack_.back().num_clips;
209213
if (transform_stack_.back().rendering_mode ==
210214
Entity::RenderingMode::kSubpass) {
215+
current_pass_->PopClips(num_clips, current_depth_);
211216
current_pass_ = GetCurrentPass().GetSuperpass();
212217
FML_DCHECK(current_pass_);
213218
}
214219

215-
bool contains_clips = transform_stack_.back().contains_clips;
216220
transform_stack_.pop_back();
217-
218-
if (contains_clips) {
221+
if (num_clips > 0) {
219222
RestoreClip();
220223
}
221224

@@ -290,7 +293,7 @@ void Canvas::DrawPath(const Path& path, const Paint& paint) {
290293
entity.SetBlendMode(paint.blend_mode);
291294
entity.SetContents(CreatePathContentsWithFilters(paint, path));
292295

293-
GetCurrentPass().AddEntity(std::move(entity));
296+
AddEntityToCurrentPass(std::move(entity));
294297
}
295298

296299
void Canvas::DrawPaint(const Paint& paint) {
@@ -300,7 +303,7 @@ void Canvas::DrawPaint(const Paint& paint) {
300303
entity.SetBlendMode(paint.blend_mode);
301304
entity.SetContents(CreateCoverContentsWithFilters(paint));
302305

303-
GetCurrentPass().AddEntity(std::move(entity));
306+
AddEntityToCurrentPass(std::move(entity));
304307
}
305308

306309
bool Canvas::AttemptDrawBlurredRRect(const Rect& rect,
@@ -338,7 +341,7 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect,
338341
entity.SetBlendMode(new_paint.blend_mode);
339342
entity.SetContents(new_paint.WithFilters(std::move(contents)));
340343

341-
GetCurrentPass().AddEntity(std::move(entity));
344+
AddEntityToCurrentPass(std::move(entity));
342345

343346
return true;
344347
}
@@ -351,7 +354,7 @@ void Canvas::DrawLine(const Point& p0, const Point& p1, const Paint& paint) {
351354
entity.SetContents(CreateContentsForGeometryWithFilters(
352355
paint, Geometry::MakeLine(p0, p1, paint.stroke_width, paint.stroke_cap)));
353356

354-
GetCurrentPass().AddEntity(std::move(entity));
357+
AddEntityToCurrentPass(std::move(entity));
355358
}
356359

357360
void Canvas::DrawRect(const Rect& rect, const Paint& paint) {
@@ -371,7 +374,7 @@ void Canvas::DrawRect(const Rect& rect, const Paint& paint) {
371374
entity.SetContents(
372375
CreateContentsForGeometryWithFilters(paint, Geometry::MakeRect(rect)));
373376

374-
GetCurrentPass().AddEntity(std::move(entity));
377+
AddEntityToCurrentPass(std::move(entity));
375378
}
376379

377380
void Canvas::DrawOval(const Rect& rect, const Paint& paint) {
@@ -398,7 +401,7 @@ void Canvas::DrawOval(const Rect& rect, const Paint& paint) {
398401
entity.SetContents(
399402
CreateContentsForGeometryWithFilters(paint, Geometry::MakeOval(rect)));
400403

401-
GetCurrentPass().AddEntity(std::move(entity));
404+
AddEntityToCurrentPass(std::move(entity));
402405
}
403406

404407
void Canvas::DrawRRect(const Rect& rect,
@@ -416,7 +419,7 @@ void Canvas::DrawRRect(const Rect& rect,
416419
entity.SetContents(CreateContentsForGeometryWithFilters(
417420
paint, Geometry::MakeRoundRect(rect, corner_radii)));
418421

419-
GetCurrentPass().AddEntity(std::move(entity));
422+
AddEntityToCurrentPass(std::move(entity));
420423
return;
421424
}
422425

@@ -449,7 +452,7 @@ void Canvas::DrawCircle(const Point& center,
449452
entity.SetContents(
450453
CreateContentsForGeometryWithFilters(paint, std::move(geometry)));
451454

452-
GetCurrentPass().AddEntity(std::move(entity));
455+
AddEntityToCurrentPass(std::move(entity));
453456
}
454457

455458
void Canvas::ClipPath(const Path& path, Entity::ClipOperation clip_op) {
@@ -554,10 +557,10 @@ void Canvas::ClipGeometry(const std::shared_ptr<Geometry>& geometry,
554557
entity.SetContents(std::move(contents));
555558
entity.SetClipDepth(GetClipDepth());
556559

557-
GetCurrentPass().AddEntity(std::move(entity));
560+
GetCurrentPass().PushClip(std::move(entity));
558561

559562
++transform_stack_.back().clip_depth;
560-
transform_stack_.back().contains_clips = true;
563+
++transform_stack_.back().num_clips;
561564
}
562565

563566
void Canvas::IntersectCulling(Rect clip_rect) {
@@ -593,7 +596,8 @@ void Canvas::RestoreClip() {
593596
entity.SetContents(std::make_shared<ClipRestoreContents>());
594597
entity.SetClipDepth(GetClipDepth());
595598

596-
GetCurrentPass().AddEntity(std::move(entity));
599+
// TODO(bdero): To be removed when swapping the clip strategy.
600+
AddEntityToCurrentPass(std::move(entity));
597601
}
598602

599603
void Canvas::DrawPoints(std::vector<Point> points,
@@ -613,7 +617,7 @@ void Canvas::DrawPoints(std::vector<Point> points,
613617
Geometry::MakePointField(std::move(points), radius,
614618
/*round=*/point_style == PointStyle::kRound)));
615619

616-
GetCurrentPass().AddEntity(std::move(entity));
620+
AddEntityToCurrentPass(std::move(entity));
617621
}
618622

619623
void Canvas::DrawPicture(const Picture& picture) {
@@ -690,10 +694,16 @@ void Canvas::DrawImageRect(const std::shared_ptr<Image>& image,
690694
entity.SetContents(paint.WithFilters(contents));
691695
entity.SetTransform(GetCurrentTransform());
692696

693-
GetCurrentPass().AddEntity(std::move(entity));
697+
AddEntityToCurrentPass(std::move(entity));
694698
}
695699

696700
Picture Canvas::EndRecordingAsPicture() {
701+
// Assign clip depths to any outstanding clip entities.
702+
while (current_pass_ != nullptr) {
703+
current_pass_->PopAllClips(current_depth_);
704+
current_pass_ = current_pass_->GetSuperpass();
705+
}
706+
697707
Picture picture;
698708
picture.pass = std::move(base_pass_);
699709

@@ -712,6 +722,11 @@ size_t Canvas::GetClipDepth() const {
712722
return transform_stack_.back().clip_depth;
713723
}
714724

725+
void Canvas::AddEntityToCurrentPass(Entity entity) {
726+
entity.SetNewClipDepth(++current_depth_);
727+
GetCurrentPass().AddEntity(std::move(entity));
728+
}
729+
715730
void Canvas::SaveLayer(const Paint& paint,
716731
std::optional<Rect> bounds,
717732
const std::shared_ptr<ImageFilter>& backdrop_filter) {
@@ -768,7 +783,7 @@ void Canvas::DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
768783
entity.SetContents(
769784
paint.WithFilters(paint.WithMaskBlur(std::move(text_contents), true)));
770785

771-
GetCurrentPass().AddEntity(std::move(entity));
786+
AddEntityToCurrentPass(std::move(entity));
772787
}
773788

774789
static bool UseColorSourceContents(
@@ -807,7 +822,7 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
807822
// are vertex coordinates then only if the contents are an image.
808823
if (UseColorSourceContents(vertices, paint)) {
809824
entity.SetContents(CreateContentsForGeometryWithFilters(paint, vertices));
810-
GetCurrentPass().AddEntity(std::move(entity));
825+
AddEntityToCurrentPass(std::move(entity));
811826
return;
812827
}
813828

@@ -845,7 +860,7 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
845860
contents->SetSourceContents(std::move(src_contents));
846861
entity.SetContents(paint.WithFilters(std::move(contents)));
847862

848-
GetCurrentPass().AddEntity(std::move(entity));
863+
AddEntityToCurrentPass(std::move(entity));
849864
}
850865

851866
void Canvas::DrawAtlas(const std::shared_ptr<Image>& atlas,
@@ -876,7 +891,7 @@ void Canvas::DrawAtlas(const std::shared_ptr<Image>& atlas,
876891
entity.SetBlendMode(paint.blend_mode);
877892
entity.SetContents(paint.WithFilters(contents));
878893

879-
GetCurrentPass().AddEntity(std::move(entity));
894+
AddEntityToCurrentPass(std::move(entity));
880895
}
881896

882897
} // namespace impeller

impeller/aiks/canvas.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ struct CanvasStackEntry {
3333
// |cull_rect| is conservative screen-space bounds of the clipped output area
3434
std::optional<Rect> cull_rect;
3535
size_t clip_depth = 0u;
36+
// The number of clips tracked for this canvas stack entry.
37+
size_t num_clips = 0u;
3638
Entity::RenderingMode rendering_mode = Entity::RenderingMode::kDirect;
37-
bool contains_clips = false;
3839
};
3940

4041
enum class PointStyle {
@@ -181,6 +182,7 @@ class Canvas {
181182
private:
182183
std::unique_ptr<EntityPass> base_pass_;
183184
EntityPass* current_pass_ = nullptr;
185+
uint64_t current_depth_ = 0u;
184186
std::deque<CanvasStackEntry> transform_stack_;
185187
std::optional<Rect> initial_cull_rect_;
186188

@@ -192,6 +194,8 @@ class Canvas {
192194

193195
size_t GetClipDepth() const;
194196

197+
void AddEntityToCurrentPass(Entity entity);
198+
195199
void ClipGeometry(const std::shared_ptr<Geometry>& geometry,
196200
Entity::ClipOperation clip_op);
197201

impeller/entity/contents/atlas_contents.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ bool AtlasContents::Render(const ContentContext& renderer,
246246

247247
FS::FragInfo frag_info;
248248
VS::FrameInfo frame_info;
249+
frame_info.depth = entity.GetShaderClipDepth();
249250

250251
auto dst_sampler_descriptor = sampler_descriptor_;
251252
if (renderer.GetDeviceCapabilities().SupportsDecalSamplerAddressMode()) {
@@ -404,6 +405,7 @@ bool AtlasTextureContents::Render(const ContentContext& renderer,
404405
auto& host_buffer = renderer.GetTransientsBuffer();
405406

406407
VS::FrameInfo frame_info;
408+
frame_info.depth = entity.GetShaderClipDepth();
407409
frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform();
408410
frame_info.texture_sampler_y_coord_scale = texture->GetYCoordScale();
409411
frame_info.alpha = alpha_;
@@ -490,6 +492,7 @@ bool AtlasColorContents::Render(const ContentContext& renderer,
490492
auto& host_buffer = renderer.GetTransientsBuffer();
491493

492494
VS::FrameInfo frame_info;
495+
frame_info.depth = entity.GetShaderClipDepth();
493496
frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform();
494497

495498
FS::FragInfo frag_info;

impeller/entity/contents/clip_contents.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,19 @@ bool ClipContents::Render(const ContentContext& renderer,
7979
using VS = ClipPipeline::VertexShader;
8080

8181
VS::FrameInfo info;
82+
info.depth = entity.GetShaderClipDepth();
8283

8384
auto options = OptionsFromPass(pass);
8485
options.blend_mode = BlendMode::kDestination;
8586
pass.SetStencilReference(entity.GetClipDepth());
86-
options.stencil_compare = CompareFunction::kEqual;
87-
options.stencil_operation = StencilOperation::kIncrementClamp;
8887

8988
if (clip_op_ == Entity::ClipOperation::kDifference) {
9089
{
9190
pass.SetCommandLabel("Difference Clip (Increment)");
9291

92+
options.stencil_compare = CompareFunction::kEqual;
93+
options.stencil_operation = StencilOperation::kIncrementClamp;
94+
9395
auto points = Rect::MakeSize(pass.GetRenderTargetSize()).GetPoints();
9496
auto vertices =
9597
VertexBufferBuilder<VS::PerVertexData>{}

impeller/entity/contents/conical_gradient_contents.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
8787
DefaultUniformAlignment());
8888

8989
VS::FrameInfo frame_info;
90+
frame_info.depth = entity.GetShaderClipDepth();
9091
frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform();
9192
frame_info.matrix = GetInverseEffectTransform();
9293

@@ -155,6 +156,7 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
155156
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
156157

157158
VS::FrameInfo frame_info;
159+
frame_info.depth = entity.GetShaderClipDepth();
158160
frame_info.mvp = geometry_result.transform;
159161
frame_info.matrix = GetInverseEffectTransform();
160162

impeller/entity/contents/content_context.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
160160
}
161161
if (maybe_depth.has_value()) {
162162
DepthAttachmentDescriptor depth = maybe_depth.value();
163-
depth.depth_compare = CompareFunction::kAlways;
164-
depth.depth_write_enabled = false;
163+
depth.depth_write_enabled = depth_write_enabled;
164+
depth.depth_compare = depth_compare;
165+
desc.SetDepthStencilAttachmentDescriptor(depth);
165166
}
166167

167168
desc.SetPrimitiveType(primitive_type);

impeller/entity/contents/content_context.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,13 @@ struct PendingCommandBuffers {
288288
struct ContentContextOptions {
289289
SampleCount sample_count = SampleCount::kCount1;
290290
BlendMode blend_mode = BlendMode::kSourceOver;
291+
CompareFunction depth_compare = CompareFunction::kAlways;
291292
CompareFunction stencil_compare = CompareFunction::kEqual;
292293
StencilOperation stencil_operation = StencilOperation::kKeep;
293294
PrimitiveType primitive_type = PrimitiveType::kTriangle;
294295
PixelFormat color_attachment_pixel_format = PixelFormat::kUnknown;
295296
bool has_depth_stencil_attachments = true;
297+
bool depth_write_enabled = false;
296298
bool wireframe = false;
297299
bool is_for_rrect_blur_clear = false;
298300

@@ -301,6 +303,7 @@ struct ContentContextOptions {
301303
static_assert(sizeof(o.sample_count) == 1);
302304
static_assert(sizeof(o.blend_mode) == 1);
303305
static_assert(sizeof(o.sample_count) == 1);
306+
static_assert(sizeof(o.depth_compare) == 1);
304307
static_assert(sizeof(o.stencil_compare) == 1);
305308
static_assert(sizeof(o.stencil_operation) == 1);
306309
static_assert(sizeof(o.primitive_type) == 1);
@@ -309,11 +312,13 @@ struct ContentContextOptions {
309312
return (o.is_for_rrect_blur_clear ? 1llu : 0llu) << 0 |
310313
(o.wireframe ? 1llu : 0llu) << 1 |
311314
(o.has_depth_stencil_attachments ? 1llu : 0llu) << 2 |
315+
(o.depth_write_enabled ? 1llu : 0llu) << 3 |
312316
// enums
313-
static_cast<uint64_t>(o.color_attachment_pixel_format) << 16 |
314-
static_cast<uint64_t>(o.primitive_type) << 24 |
315-
static_cast<uint64_t>(o.stencil_operation) << 32 |
316-
static_cast<uint64_t>(o.stencil_compare) << 40 |
317+
static_cast<uint64_t>(o.color_attachment_pixel_format) << 8 |
318+
static_cast<uint64_t>(o.primitive_type) << 16 |
319+
static_cast<uint64_t>(o.stencil_operation) << 24 |
320+
static_cast<uint64_t>(o.stencil_compare) << 32 |
321+
static_cast<uint64_t>(o.depth_compare) << 40 |
317322
static_cast<uint64_t>(o.blend_mode) << 48 |
318323
static_cast<uint64_t>(o.sample_count) << 56;
319324
}
@@ -324,6 +329,8 @@ struct ContentContextOptions {
324329
const ContentContextOptions& rhs) const {
325330
return lhs.sample_count == rhs.sample_count &&
326331
lhs.blend_mode == rhs.blend_mode &&
332+
lhs.depth_write_enabled == rhs.depth_write_enabled &&
333+
lhs.depth_compare == rhs.depth_compare &&
327334
lhs.stencil_compare == rhs.stencil_compare &&
328335
lhs.stencil_operation == rhs.stencil_operation &&
329336
lhs.primitive_type == rhs.primitive_type &&

0 commit comments

Comments
 (0)