-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] allocate the impeller onscreen texture from the render target cache. #55943
Changes from all commits
d1800ba
ff7bc16
b6053b7
a6b6b32
302ca9b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,8 @@ EntityPassTarget::EntityPassTarget(const RenderTarget& render_target, | |
| supports_read_from_resolve_(supports_read_from_resolve), | ||
| supports_implicit_msaa_(supports_implicit_msaa) {} | ||
|
|
||
| std::shared_ptr<Texture> EntityPassTarget::Flip(Allocator& allocator) { | ||
| std::shared_ptr<Texture> EntityPassTarget::Flip( | ||
| const ContentContext& renderer) { | ||
| auto color0 = target_.GetColorAttachments().find(0)->second; | ||
| if (!color0.resolve_texture) { | ||
| VALIDATION_LOG << "EntityPassTarget Flip should never be called for a " | ||
|
|
@@ -40,7 +41,9 @@ std::shared_ptr<Texture> EntityPassTarget::Flip(Allocator& allocator) { | |
| // The second texture is allocated lazily to avoid unused allocations. | ||
| TextureDescriptor new_descriptor = | ||
| color0.resolve_texture->GetTextureDescriptor(); | ||
| secondary_color_texture_ = allocator.CreateTexture(new_descriptor); | ||
| RenderTarget target = renderer.GetRenderTargetCache()->CreateOffscreenMSAA( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When we "flip" the backdrop texture, do the new allocation from the render target cache. Technically this creates some unused transients too but :shrug. While we still only create a maximum of two backdrop textures per frame, this change ensures we recycle them across frames and avoid continual re-allocation
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there be a branch here if we aren't using MSAA?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above, we'll never use this on a non-MSAA target. |
||
| *renderer.GetContext(), new_descriptor.size, 1); | ||
| secondary_color_texture_ = target.GetRenderTargetTexture(); | ||
|
|
||
| if (!secondary_color_texture_) { | ||
| return nullptr; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,8 +38,8 @@ TEST_P(EntityPassTargetTest, SwapWithMSAATexture) { | |
| auto msaa_tex = color0.texture; | ||
| auto resolve_tex = color0.resolve_texture; | ||
|
|
||
| entity_pass_target.Flip( | ||
| *content_context->GetContext()->GetResourceAllocator()); | ||
| FML_DCHECK(content_context); | ||
| entity_pass_target.Flip(*content_context); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, DCHECK for nullptr.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
|
||
| color0 = entity_pass_target.GetRenderTarget() | ||
| .GetColorAttachments() | ||
|
|
@@ -98,8 +98,8 @@ TEST_P(EntityPassTargetTest, SwapWithMSAAImplicitResolve) { | |
|
|
||
| ASSERT_EQ(msaa_tex, resolve_tex); | ||
|
|
||
| entity_pass_target.Flip( | ||
| *content_context->GetContext()->GetResourceAllocator()); | ||
| FML_DCHECK(content_context); | ||
| entity_pass_target.Flip(*content_context); | ||
|
|
||
| color0 = entity_pass_target.GetRenderTarget() | ||
| .GetColorAttachments() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,34 +7,22 @@ | |
| #include <utility> | ||
|
|
||
| #include "flutter/fml/status.h" | ||
| #include "impeller/base/allocation.h" | ||
| #include "impeller/base/validation.h" | ||
| #include "impeller/core/formats.h" | ||
| #include "impeller/entity/contents/content_context.h" | ||
| #include "impeller/entity/entity_pass_target.h" | ||
| #include "impeller/renderer/command_buffer.h" | ||
| #include "impeller/renderer/render_pass.h" | ||
| #include "impeller/renderer/texture_mipmap.h" | ||
|
|
||
| namespace impeller { | ||
|
|
||
| InlinePassContext::InlinePassContext( | ||
| const ContentContext& renderer, | ||
| EntityPassTarget& pass_target, | ||
| uint32_t entity_count, | ||
| std::optional<RenderPassResult> collapsed_parent_pass) | ||
| : renderer_(renderer), | ||
| pass_target_(pass_target), | ||
| entity_count_(entity_count), | ||
| is_collapsed_(collapsed_parent_pass.has_value()) { | ||
| if (collapsed_parent_pass.has_value()) { | ||
| pass_ = collapsed_parent_pass.value().pass; | ||
| } | ||
| } | ||
| InlinePassContext::InlinePassContext(const ContentContext& renderer, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. entity_count, collapsed_parent_pass, is_collapsed_ are all unused |
||
| EntityPassTarget& pass_target) | ||
| : renderer_(renderer), pass_target_(pass_target) {} | ||
|
|
||
| InlinePassContext::~InlinePassContext() { | ||
| if (!is_collapsed_) { | ||
| EndPass(); | ||
| } | ||
| EndPass(); | ||
| } | ||
|
|
||
| bool InlinePassContext::IsValid() const { | ||
|
|
@@ -90,10 +78,9 @@ EntityPassTarget& InlinePassContext::GetPassTarget() const { | |
| return pass_target_; | ||
| } | ||
|
|
||
| InlinePassContext::RenderPassResult InlinePassContext::GetRenderPass( | ||
| uint32_t pass_depth) { | ||
| const std::shared_ptr<RenderPass>& InlinePassContext::GetRenderPass() { | ||
| if (IsActive()) { | ||
| return {.pass = pass_}; | ||
| return pass_; | ||
| } | ||
|
|
||
| /// Create a new render pass if one isn't active. This path will run the first | ||
|
|
@@ -103,30 +90,25 @@ InlinePassContext::RenderPassResult InlinePassContext::GetRenderPass( | |
| command_buffer_ = renderer_.GetContext()->CreateCommandBuffer(); | ||
| if (!command_buffer_) { | ||
| VALIDATION_LOG << "Could not create command buffer."; | ||
| return {}; | ||
| return pass_; | ||
| } | ||
|
|
||
| if (pass_target_.GetRenderTarget().GetColorAttachments().empty()) { | ||
| VALIDATION_LOG << "Color attachment unexpectedly missing from the " | ||
| "EntityPass render target."; | ||
| return {}; | ||
| return pass_; | ||
| } | ||
|
|
||
| command_buffer_->SetLabel("EntityPass Command Buffer"); | ||
|
|
||
| RenderPassResult result; | ||
| { | ||
| // If the pass target has a resolve texture, then we're using MSAA. | ||
| bool is_msaa = pass_target_.GetRenderTarget() | ||
| .GetColorAttachments() | ||
| .find(0) | ||
| ->second.resolve_texture != nullptr; | ||
| if (pass_count_ > 0 && is_msaa) { | ||
| result.backdrop_texture = | ||
| pass_target_.Flip(*renderer_.GetContext()->GetResourceAllocator()); | ||
| if (!result.backdrop_texture) { | ||
| VALIDATION_LOG << "Could not flip the EntityPass render target."; | ||
| } | ||
| pass_target_.Flip(renderer_); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -152,7 +134,7 @@ InlinePassContext::RenderPassResult InlinePassContext::GetRenderPass( | |
| if (!depth.has_value()) { | ||
| VALIDATION_LOG << "Depth attachment unexpectedly missing from the " | ||
| "EntityPass render target."; | ||
| return {}; | ||
| return pass_; | ||
| } | ||
| depth->load_action = LoadAction::kClear; | ||
| depth->store_action = StoreAction::kDontCare; | ||
|
|
@@ -162,7 +144,7 @@ InlinePassContext::RenderPassResult InlinePassContext::GetRenderPass( | |
| if (!depth.has_value() || !stencil.has_value()) { | ||
| VALIDATION_LOG << "Stencil/Depth attachment unexpectedly missing from the " | ||
| "EntityPass render target."; | ||
| return {}; | ||
| return pass_; | ||
| } | ||
| stencil->load_action = LoadAction::kClear; | ||
| stencil->store_action = StoreAction::kDontCare; | ||
|
|
@@ -175,26 +157,12 @@ InlinePassContext::RenderPassResult InlinePassContext::GetRenderPass( | |
| pass_ = command_buffer_->CreateRenderPass(pass_target_.GetRenderTarget()); | ||
| if (!pass_) { | ||
| VALIDATION_LOG << "Could not create render pass."; | ||
| return {}; | ||
| return pass_; | ||
| } | ||
| // Commands are fairly large (500B) objects, so re-allocation of the command | ||
| // buffer while encoding can add a surprising amount of overhead. We make a | ||
| // conservative npot estimate to avoid this case. | ||
| pass_->ReserveCommands(Allocation::NextPowerOfTwoSize(entity_count_)); | ||
| pass_->SetLabel("EntityPass Render Pass"); | ||
|
|
||
| result.pass = pass_; | ||
| result.just_created = true; | ||
|
|
||
| if (!renderer_.GetContext()->GetCapabilities()->SupportsReadFromResolve() && | ||
| result.backdrop_texture == | ||
| result.pass->GetRenderTarget().GetRenderTargetTexture()) { | ||
| VALIDATION_LOG << "EntityPass backdrop restore configuration is not valid " | ||
| "for the current graphics backend."; | ||
| } | ||
|
|
||
| ++pass_count_; | ||
| return result; | ||
| return pass_; | ||
| } | ||
|
|
||
| uint32_t InlinePassContext::GetPassCount() const { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,17 +16,8 @@ namespace impeller { | |
|
|
||
| class InlinePassContext { | ||
| public: | ||
| struct RenderPassResult { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. None of these are used anymore |
||
| bool just_created = false; | ||
| std::shared_ptr<RenderPass> pass; | ||
| std::shared_ptr<Texture> backdrop_texture; | ||
| }; | ||
|
|
||
| InlinePassContext( | ||
| const ContentContext& renderer, | ||
| EntityPassTarget& pass_target, | ||
| uint32_t entity_count, | ||
| std::optional<RenderPassResult> collapsed_parent_pass = std::nullopt); | ||
| InlinePassContext(const ContentContext& renderer, | ||
| EntityPassTarget& pass_target); | ||
|
|
||
| ~InlinePassContext(); | ||
|
|
||
|
|
@@ -42,18 +33,14 @@ class InlinePassContext { | |
|
|
||
| uint32_t GetPassCount() const; | ||
|
|
||
| RenderPassResult GetRenderPass(uint32_t pass_depth); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just straight up dead code regardless of your change? No need to change this PR but for future PRs it would be easier if refactoring and functional changes are split into 2 different prs =)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I get it. Though I didn't intend to do a large refactoring, I realized all this was dead when I started changing it. |
||
| const std::shared_ptr<RenderPass>& GetRenderPass(); | ||
|
|
||
| private: | ||
| const ContentContext& renderer_; | ||
| EntityPassTarget& pass_target_; | ||
| std::shared_ptr<CommandBuffer> command_buffer_; | ||
| std::shared_ptr<RenderPass> pass_; | ||
| uint32_t pass_count_ = 0; | ||
| uint32_t entity_count_ = 0; | ||
|
|
||
| // Whether this context is collapsed into a parent entity pass. | ||
| bool is_collapsed_ = false; | ||
|
|
||
| InlinePassContext(const InlinePassContext&) = delete; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a FML_DCHECK that we can dereference this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its null checked on the previous line?