Skip to content

Commit

Permalink
[Impeller] fix subpass collapse pass ending logic (#40057)
Browse files Browse the repository at this point in the history
[Impeller] fix subpass collapse pass ending logic
  • Loading branch information
jonahwilliams committed Mar 3, 2023
1 parent 55b6631 commit f319881
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 35 deletions.
29 changes: 16 additions & 13 deletions impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,13 @@ EntityPass::EntityResult EntityPass::GetEntityForElement(
return EntityPass::EntityResult::Skip();
}

if (subpass->delegate_->CanCollapseIntoParentPass() &&
!subpass->backdrop_filter_proc_.has_value()) {
if (!subpass->backdrop_filter_proc_.has_value() &&
subpass->delegate_->CanCollapseIntoParentPass()) {
// Directly render into the parent target and move on.
if (!subpass->OnRender(renderer, root_pass_size,
pass_context.GetRenderTarget(), position, position,
stencil_depth_floor)) {
pass_depth, stencil_depth_, nullptr,
pass_context.GetRenderPass(pass_depth))) {
return EntityPass::EntityResult::Failure();
}
return EntityPass::EntityResult::Skip();
Expand Down Expand Up @@ -405,20 +406,22 @@ struct StencilLayer {
size_t stencil_depth;
};

bool EntityPass::OnRender(
ContentContext& renderer,
ISize root_pass_size,
const RenderTarget& render_target,
Point position,
Point parent_position,
uint32_t pass_depth,
size_t stencil_depth_floor,
std::shared_ptr<Contents> backdrop_filter_contents) const {
bool EntityPass::OnRender(ContentContext& renderer,
ISize root_pass_size,
const RenderTarget& render_target,
Point position,
Point parent_position,
uint32_t pass_depth,
size_t stencil_depth_floor,
std::shared_ptr<Contents> backdrop_filter_contents,
std::optional<InlinePassContext::RenderPassResult>
collapsed_parent_pass) const {
TRACE_EVENT0("impeller", "EntityPass::OnRender");

auto context = renderer.GetContext();
InlinePassContext pass_context(context, render_target,
reads_from_pass_texture_);
reads_from_pass_texture_,
std::move(collapsed_parent_pass));
if (!pass_context.IsValid()) {
return false;
}
Expand Down
19 changes: 10 additions & 9 deletions impeller/entity/entity_pass.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,16 @@ class EntityPass {
uint32_t pass_depth,
size_t stencil_depth_floor) const;

bool OnRender(
ContentContext& renderer,
ISize root_pass_size,
const RenderTarget& render_target,
Point position,
Point parent_position,
uint32_t pass_depth,
size_t stencil_depth_floor = 0,
std::shared_ptr<Contents> backdrop_filter_contents = nullptr) const;
bool OnRender(ContentContext& renderer,
ISize root_pass_size,
const RenderTarget& render_target,
Point position,
Point parent_position,
uint32_t pass_depth,
size_t stencil_depth_floor = 0,
std::shared_ptr<Contents> backdrop_filter_contents = nullptr,
std::optional<InlinePassContext::RenderPassResult>
collapsed_parent_pass = std::nullopt) const;

std::vector<Element> elements_;

Expand Down
16 changes: 16 additions & 0 deletions impeller/entity/entity_playground.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ EntityPlayground::EntityPlayground() = default;

EntityPlayground::~EntityPlayground() = default;

bool EntityPlayground::OpenPlaygroundHere(EntityPass& entity_pass) {
if (!Playground::is_enabled()) {
return true;
}

ContentContext content_context(GetContext());
if (!content_context.IsValid()) {
return false;
}

auto callback = [&](RenderTarget& render_target) -> bool {
return entity_pass.Render(content_context, render_target);
};
return Playground::OpenPlaygroundHere(callback);
}

bool EntityPlayground::OpenPlaygroundHere(Entity entity) {
if (!Playground::is_enabled()) {
return true;
Expand Down
4 changes: 4 additions & 0 deletions impeller/entity/entity_playground.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "flutter/fml/macros.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/entity_pass.h"

#include "impeller/playground/playground_test.h"

namespace impeller {
Expand All @@ -22,6 +24,8 @@ class EntityPlayground : public PlaygroundTest {

bool OpenPlaygroundHere(Entity entity);

bool OpenPlaygroundHere(EntityPass& entity_pass);

bool OpenPlaygroundHere(EntityPlaygroundCallback callback);

private:
Expand Down
35 changes: 30 additions & 5 deletions impeller/entity/entity_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ TEST_P(EntityTest, CanCreateEntity) {

class TestPassDelegate final : public EntityPassDelegate {
public:
explicit TestPassDelegate(std::optional<Rect> coverage)
: coverage_(coverage) {}
explicit TestPassDelegate(std::optional<Rect> coverage, bool collapse = false)
: coverage_(coverage), collapse_(collapse) {}

// |EntityPassDelegate|
~TestPassDelegate() override = default;
Expand All @@ -74,7 +74,7 @@ class TestPassDelegate final : public EntityPassDelegate {
bool CanElide() override { return false; }

// |EntityPassDelgate|
bool CanCollapseIntoParentPass() override { return false; }
bool CanCollapseIntoParentPass() override { return collapse_; }

// |EntityPassDelgate|
std::shared_ptr<Contents> CreateContentsForSubpassTarget(
Expand All @@ -85,15 +85,19 @@ class TestPassDelegate final : public EntityPassDelegate {

private:
const std::optional<Rect> coverage_;
const bool collapse_;
};

auto CreatePassWithRectPath(Rect rect, std::optional<Rect> bounds_hint) {
auto CreatePassWithRectPath(Rect rect,
std::optional<Rect> bounds_hint,
bool collapse = false) {
auto subpass = std::make_unique<EntityPass>();
Entity entity;
entity.SetContents(SolidColorContents::Make(
PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
subpass->AddEntity(entity);
subpass->SetDelegate(std::make_unique<TestPassDelegate>(bounds_hint));
subpass->SetDelegate(
std::make_unique<TestPassDelegate>(bounds_hint, collapse));
return subpass;
}

Expand Down Expand Up @@ -124,6 +128,27 @@ TEST_P(EntityTest, EntityPassCoverageRespectsDelegateBoundsHint) {
ASSERT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(50, 50, 900, 900));
}

TEST_P(EntityTest, EntityPassCanMergeSubpassIntoParent) {
// Both a red and a blue box should appear if the pass merging has worked
// correctly.

EntityPass pass;
auto subpass = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
Rect::MakeLTRB(50, 50, 150, 150), true);
pass.AddSubpass(std::move(subpass));

Entity entity;
entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
auto contents = std::make_unique<SolidColorContents>();
contents->SetGeometry(Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
contents->SetColor(Color::Blue());
entity.SetContents(std::move(contents));

pass.AddEntity(entity);

ASSERT_TRUE(OpenPlaygroundHere(pass));
}

TEST_P(EntityTest, EntityPassCoverageRespectsCoverageLimit) {
// Rect is drawn entirely in negative area.
auto pass = CreatePassWithRectPath(Rect::MakeLTRB(-200, -200, -100, -100),
Expand Down
19 changes: 14 additions & 5 deletions impeller/entity/inline_pass_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,24 @@

namespace impeller {

InlinePassContext::InlinePassContext(std::shared_ptr<Context> context,
const RenderTarget& render_target,
uint32_t pass_texture_reads)
InlinePassContext::InlinePassContext(
std::shared_ptr<Context> context,
const RenderTarget& render_target,
uint32_t pass_texture_reads,
std::optional<RenderPassResult> collapsed_parent_pass)
: context_(std::move(context)),
render_target_(render_target),
total_pass_reads_(pass_texture_reads) {}
total_pass_reads_(pass_texture_reads),
is_collapsed_(collapsed_parent_pass.has_value()) {
if (collapsed_parent_pass.has_value()) {
pass_ = collapsed_parent_pass.value().pass;
}
}

InlinePassContext::~InlinePassContext() {
EndPass();
if (!is_collapsed_) {
EndPass();
}
}

bool InlinePassContext::IsValid() const {
Expand Down
10 changes: 7 additions & 3 deletions impeller/entity/inline_pass_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ class InlinePassContext {
std::shared_ptr<Texture> backdrop_texture;
};

InlinePassContext(std::shared_ptr<Context> context,
const RenderTarget& render_target,
uint32_t pass_texture_reads);
InlinePassContext(
std::shared_ptr<Context> context,
const RenderTarget& render_target,
uint32_t pass_texture_reads,
std::optional<RenderPassResult> collapsed_parent_pass = std::nullopt);
~InlinePassContext();

bool IsValid() const;
Expand All @@ -38,6 +40,8 @@ class InlinePassContext {
std::shared_ptr<RenderPass> pass_;
uint32_t pass_count_ = 0;
uint32_t total_pass_reads_ = 0;
// Whether this context is collapsed into a parent entity pass.
bool is_collapsed_ = false;

FML_DISALLOW_COPY_AND_ASSIGN(InlinePassContext);
};
Expand Down

0 comments on commit f319881

Please sign in to comment.