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

[Impeller] add async command submission for blit pass. #48040

Merged
merged 3 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ TEST_P(AiksTest, CanRenderColorFilterWithInvertColorsDrawPaint) {
namespace {
bool GenerateMipmap(const std::shared_ptr<Context>& context,
std::shared_ptr<Texture> texture,
std::string label) {
std::string label,
bool async_submit) {
auto buffer = context->CreateCommandBuffer();
if (!buffer) {
return false;
Expand All @@ -174,18 +175,23 @@ bool GenerateMipmap(const std::shared_ptr<Context>& context,
return false;
}
pass->GenerateMipmap(std::move(texture), std::move(label));
if (async_submit) {
return buffer->EncodeAndSubmit(pass, context->GetResourceAllocator());
}

pass->EncodeCommands(context->GetResourceAllocator());
return buffer->SubmitCommands();
}

void CanRenderTiledTexture(AiksTest* aiks_test,
Entity::TileMode tile_mode,
bool async_submit = false,
Matrix local_matrix = {}) {
auto context = aiks_test->GetContext();
ASSERT_TRUE(context);
auto texture = aiks_test->CreateTextureForFixture("table_mountain_nx.png",
/*enable_mipmapping=*/true);
GenerateMipmap(context, texture, "table_mountain_nx");
GenerateMipmap(context, texture, "table_mountain_nx", async_submit);
Canvas canvas;
canvas.Scale(aiks_test->GetContentScale());
canvas.Translate({100.0f, 100.0f, 0});
Expand Down Expand Up @@ -232,6 +238,10 @@ TEST_P(AiksTest, CanRenderTiledTextureClamp) {
CanRenderTiledTexture(this, Entity::TileMode::kClamp);
}

TEST_P(AiksTest, CanRenderTiledTextureClampAsync) {
CanRenderTiledTexture(this, Entity::TileMode::kClamp, /*async_submit=*/true);
}

TEST_P(AiksTest, CanRenderTiledTextureRepeat) {
CanRenderTiledTexture(this, Entity::TileMode::kRepeat);
}
Expand All @@ -245,7 +255,7 @@ TEST_P(AiksTest, CanRenderTiledTextureDecal) {
}

TEST_P(AiksTest, CanRenderTiledTextureClampWithTranslate) {
CanRenderTiledTexture(this, Entity::TileMode::kClamp,
CanRenderTiledTexture(this, Entity::TileMode::kClamp, /*async_submit=*/false,
Matrix::MakeTranslation({172.f, 172.f, 0.f}));
}

Expand Down
5 changes: 0 additions & 5 deletions impeller/aiks/testing/context_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ class CommandBufferMock : public CommandBuffer {

MOCK_METHOD(void, SetLabel, (const std::string& label), (const, override));

MOCK_METHOD(bool,
SubmitCommandsAsync,
(std::shared_ptr<RenderPass> render_pass),
(override));

MOCK_METHOD(std::shared_ptr<RenderPass>,
OnCreateRenderPass,
(RenderTarget render_target),
Expand Down
6 changes: 0 additions & 6 deletions impeller/aiks/testing/context_spy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,6 @@ std::shared_ptr<ContextMock> ContextSpy::MakeContext(
return real_buffer->SetLabel(label);
});

ON_CALL(*spy, SubmitCommandsAsync)
.WillByDefault([real_buffer](
std::shared_ptr<RenderPass> render_pass) {
return real_buffer->SubmitCommandsAsync(std::move(render_pass));
});

ON_CALL(*spy, OnCreateRenderPass)
.WillByDefault(
[real_buffer, shared_this](const RenderTarget& render_target) {
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/content_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ std::shared_ptr<Texture> ContentContext::MakeSubpass(
return nullptr;
}

if (!sub_command_buffer->SubmitCommandsAsync(std::move(sub_renderpass))) {
if (!sub_command_buffer->EncodeAndSubmit(sub_renderpass)) {
return nullptr;
}

Expand Down
10 changes: 3 additions & 7 deletions impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,8 @@ bool EntityPass::Render(ContentContext& renderer,
offscreen_target.GetRenderTarget().GetRenderTargetTexture(),
root_render_target.GetRenderTargetTexture());

if (!blit_pass->EncodeCommands(
renderer.GetContext()->GetResourceAllocator())) {
if (!command_buffer->EncodeAndSubmit(
blit_pass, renderer.GetContext()->GetResourceAllocator())) {
VALIDATION_LOG << "Failed to encode root pass blit command.";
return false;
}
Expand All @@ -399,15 +399,11 @@ bool EntityPass::Render(ContentContext& renderer,
}
}

if (!render_pass->EncodeCommands()) {
if (!command_buffer->EncodeAndSubmit(render_pass)) {
VALIDATION_LOG << "Failed to encode root pass command buffer.";
return false;
}
}
if (!command_buffer->SubmitCommands()) {
VALIDATION_LOG << "Failed to submit root pass command buffer.";
return false;
}

return true;
}
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/inline_pass_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ bool InlinePassContext::EndPass() {
}

if (command_buffer_) {
if (!command_buffer_->SubmitCommandsAsync(std::move(pass_))) {
if (!command_buffer_->EncodeAndSubmit(pass_)) {
VALIDATION_LOG
<< "Failed to encode and submit command buffer while ending "
"render pass.";
Expand Down
7 changes: 6 additions & 1 deletion impeller/renderer/backend/metal/command_buffer_mtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <Metal/Metal.h>

#include "flutter/fml/macros.h"
#include "impeller/core/allocator.h"
#include "impeller/renderer/command_buffer.h"

namespace impeller {
Expand Down Expand Up @@ -37,7 +38,11 @@ class CommandBufferMTL final : public CommandBuffer {
void OnWaitUntilScheduled() override;

// |CommandBuffer|
bool SubmitCommandsAsync(std::shared_ptr<RenderPass> render_pass) override;
bool EncodeAndSubmit(const std::shared_ptr<RenderPass>& render_pass) override;

// |CommandBuffer|
bool EncodeAndSubmit(const std::shared_ptr<BlitPass>& blit_ass,
const std::shared_ptr<Allocator>& allocator) override;

// |CommandBuffer|
std::shared_ptr<RenderPass> OnCreateRenderPass(RenderTarget target) override;
Expand Down
34 changes: 31 additions & 3 deletions impeller/renderer/backend/metal/command_buffer_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ static bool LogMTLCommandBufferErrorIfPresent(id<MTLCommandBuffer> buffer) {
return true;
}

bool CommandBufferMTL::SubmitCommandsAsync(
std::shared_ptr<RenderPass> render_pass) {
TRACE_EVENT0("impeller", "CommandBufferMTL::SubmitCommandsAsync");
bool CommandBufferMTL::EncodeAndSubmit(
const std::shared_ptr<RenderPass>& render_pass) {
TRACE_EVENT0("impeller", "CommandBufferMTL::EncodeAndSubmit");
if (!IsValid() || !render_pass->IsValid()) {
return false;
}
Expand Down Expand Up @@ -239,6 +239,34 @@ static bool LogMTLCommandBufferErrorIfPresent(id<MTLCommandBuffer> buffer) {
return true;
}

bool CommandBufferMTL::EncodeAndSubmit(
const std::shared_ptr<BlitPass>& blit_pass,
const std::shared_ptr<Allocator>& allocator) {
if (!IsValid() || !blit_pass->IsValid()) {
return false;
}
auto context = context_.lock();
if (!context) {
return false;
}
[buffer_ enqueue];
auto buffer = buffer_;
buffer_ = nil;

auto worker_task_runner = ContextMTL::Cast(*context).GetWorkerTaskRunner();
auto task = fml::MakeCopyable(
[blit_pass, buffer, weak_context = context_, allocator]() {
auto context = weak_context.lock();
if (!blit_pass->EncodeCommands(allocator)) {
VALIDATION_LOG << "Failed to encode blit pass.";
return;
}
[buffer commit];
});
worker_task_runner->PostTask(task);
return true;
}

void CommandBufferMTL::OnWaitUntilScheduled() {}

std::shared_ptr<RenderPass> CommandBufferMTL::OnCreateRenderPass(
Expand Down
22 changes: 17 additions & 5 deletions impeller/renderer/command_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ void CommandBuffer::WaitUntilScheduled() {
return OnWaitUntilScheduled();
}

bool CommandBuffer::SubmitCommandsAsync(
std::shared_ptr<RenderPass>
render_pass // NOLINT(performance-unnecessary-value-param)
) {
TRACE_EVENT0("impeller", "CommandBuffer::SubmitCommandsAsync");
bool CommandBuffer::EncodeAndSubmit(
const std::shared_ptr<RenderPass>& render_pass) {
TRACE_EVENT0("impeller", "CommandBuffer::EncodeAndSubmit");
if (!render_pass->IsValid() || !IsValid()) {
return false;
}
Expand All @@ -51,6 +49,20 @@ bool CommandBuffer::SubmitCommandsAsync(
return SubmitCommands(nullptr);
}

bool CommandBuffer::EncodeAndSubmit(
const std::shared_ptr<BlitPass>& blit_pass,
const std::shared_ptr<Allocator>& allocator) {
TRACE_EVENT0("impeller", "CommandBuffer::EncodeAndSubmit");
if (!blit_pass->IsValid() || !IsValid()) {
return false;
}
if (!blit_pass->EncodeCommands(allocator)) {
return false;
}

return SubmitCommands(nullptr);
}

std::shared_ptr<RenderPass> CommandBuffer::CreateRenderPass(
const RenderTarget& render_target) {
auto pass = OnCreateRenderPass(render_target);
Expand Down
16 changes: 14 additions & 2 deletions impeller/renderer/command_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,20 @@ class CommandBuffer {
///
/// A command buffer may only be committed once.
///
[[nodiscard]] virtual bool SubmitCommandsAsync(
std::shared_ptr<RenderPass> render_pass);
[[nodiscard]] virtual bool EncodeAndSubmit(
const std::shared_ptr<RenderPass>& render_pass);

//----------------------------------------------------------------------------
/// @brief Schedule the command encoded by blit passes within this
/// command buffer on the GPU. The enqueing of this buffer is
/// performed immediately but encoding is pushed to a worker
/// thread if possible.
///
/// A command buffer may only be committed once.
///
[[nodiscard]] virtual bool EncodeAndSubmit(
const std::shared_ptr<BlitPass>& blit_pass,
const std::shared_ptr<Allocator>& allocator);

//----------------------------------------------------------------------------
/// @brief Force execution of pending GPU commands.
Expand Down