Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
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
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -5401,6 +5401,8 @@ ORIGIN: ../../../flutter/impeller/renderer/backend/metal/gpu_tracer_mtl.h + ../.
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/gpu_tracer_mtl.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/lazy_drawable_holder.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/lazy_drawable_holder.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/pipeline_library_mtl.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/pipeline_library_mtl.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/pipeline_mtl.h + ../../../flutter/LICENSE
Expand Down Expand Up @@ -8243,6 +8245,8 @@ FILE: ../../../flutter/impeller/renderer/backend/metal/gpu_tracer_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/gpu_tracer_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/lazy_drawable_holder.h
FILE: ../../../flutter/impeller/renderer/backend/metal/lazy_drawable_holder.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/pipeline_library_mtl.h
FILE: ../../../flutter/impeller/renderer/backend/metal/pipeline_library_mtl.mm
FILE: ../../../flutter/impeller/renderer/backend/metal/pipeline_mtl.h
Expand Down
4 changes: 4 additions & 0 deletions impeller/entity/contents/checkerboard_contents_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ TEST_P(EntityTest, RendersWithoutError) {
ASSERT_TRUE(recording_pass->GetCommands().empty());
ASSERT_TRUE(contents->Render(*content_context, entity, *recording_pass));
ASSERT_FALSE(recording_pass->GetCommands().empty());

if (GetParam() == PlaygroundBackend::kMetal) {
recording_pass->EncodeCommands();
}
}
#endif // IMPELLER_DEBUG

Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/test/recording_render_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void RecordingRenderPass::OnSetLabel(std::string label) {

// |RenderPass|
bool RecordingRenderPass::OnEncodeCommands(const Context& context) const {
return true;
return delegate_->EncodeCommands();
}

// |RenderPass|
Expand Down
4 changes: 4 additions & 0 deletions impeller/entity/contents/tiled_texture_contents_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ TEST_P(EntityTest, TiledTextureContentsRendersWithCorrectPipeline) {
ASSERT_EQ(commands.size(), 1u);
ASSERT_STREQ(commands[0].pipeline->GetDescriptor().GetLabel().c_str(),
"TextureFill Pipeline V#1");

if (GetParam() == PlaygroundBackend::kMetal) {
recording_pass->EncodeCommands();
}
}

// GL_OES_EGL_image_external isn't supported on MacOS hosts.
Expand Down
4 changes: 4 additions & 0 deletions impeller/entity/contents/vertices_contents_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ TEST_P(EntityTest, RendersDstPerColorWithAlpha) {

ASSERT_TRUE(frag_uniforms);
ASSERT_EQ(frag_uniforms->alpha, 0.5);

if (GetParam() == PlaygroundBackend::kMetal) {
recording_pass->EncodeCommands();
}
}

} // namespace testing
Expand Down
2 changes: 2 additions & 0 deletions impeller/renderer/backend/metal/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ impeller_component("metal") {
"gpu_tracer_mtl.mm",
"lazy_drawable_holder.h",
"lazy_drawable_holder.mm",
"pass_bindings_cache_mtl.h",
"pass_bindings_cache_mtl.mm",
"pipeline_library_mtl.h",
"pipeline_library_mtl.mm",
"pipeline_mtl.h",
Expand Down
7 changes: 0 additions & 7 deletions impeller/renderer/backend/metal/command_buffer_mtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ class CommandBufferMTL final : public CommandBuffer {
// |CommandBuffer|
void OnWaitUntilScheduled() override;

// |CommandBuffer|
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
85 changes: 0 additions & 85 deletions impeller/renderer/backend/metal/command_buffer_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include "flutter/fml/make_copyable.h"
#include "flutter/fml/synchronization/semaphore.h"
#include "flutter/fml/trace_event.h"

#include "impeller/renderer/backend/metal/blit_pass_mtl.h"
#include "impeller/renderer/backend/metal/compute_pass_mtl.h"
Expand Down Expand Up @@ -183,90 +182,6 @@ static bool LogMTLCommandBufferErrorIfPresent(id<MTLCommandBuffer> buffer) {
return true;
}

bool CommandBufferMTL::EncodeAndSubmit(
const std::shared_ptr<RenderPass>& render_pass) {
TRACE_EVENT0("impeller", "CommandBufferMTL::EncodeAndSubmit");
if (!IsValid() || !render_pass->IsValid()) {
return false;
}
auto context = context_.lock();
if (!context) {
return false;
}
[buffer_ enqueue];
auto buffer = buffer_;
buffer_ = nil;

#ifdef IMPELLER_DEBUG
ContextMTL::Cast(*context).GetGPUTracer()->RecordCmdBuffer(buffer);
#endif // IMPELLER_DEBUG

auto worker_task_runner = ContextMTL::Cast(*context).GetWorkerTaskRunner();
auto mtl_render_pass = static_cast<RenderPassMTL*>(render_pass.get());

// Render command encoder creation has been observed to exceed the stack size
// limit for worker threads, and therefore is intentionally constructed on the
// raster thread.
auto render_command_encoder =
[buffer renderCommandEncoderWithDescriptor:mtl_render_pass->desc_];
if (!render_command_encoder) {
return false;
}

auto task = fml::MakeCopyable(
[render_pass, buffer, render_command_encoder, weak_context = context_]() {
auto context = weak_context.lock();
if (!context) {
[render_command_encoder endEncoding];
return;
}

auto mtl_render_pass = static_cast<RenderPassMTL*>(render_pass.get());
if (!mtl_render_pass->label_.empty()) {
[render_command_encoder setLabel:@(mtl_render_pass->label_.c_str())];
}

auto result = mtl_render_pass->EncodeCommands(
context->GetResourceAllocator(), render_command_encoder);
[render_command_encoder endEncoding];
if (result) {
[buffer commit];
} else {
VALIDATION_LOG << "Failed to encode command buffer";
}
});
worker_task_runner->PostTask(task);
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
3 changes: 0 additions & 3 deletions impeller/renderer/backend/metal/context_mtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ class ContextMTL final : public Context,

id<MTLCommandBuffer> CreateMTLCommandBuffer(const std::string& label) const;

const std::shared_ptr<fml::ConcurrentTaskRunner> GetWorkerTaskRunner() const;

std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch() const;

#ifdef IMPELLER_DEBUG
Expand Down Expand Up @@ -122,7 +120,6 @@ class ContextMTL final : public Context,
std::shared_ptr<SamplerLibrary> sampler_library_;
std::shared_ptr<AllocatorMTL> resource_allocator_;
std::shared_ptr<const Capabilities> device_capabilities_;
std::shared_ptr<fml::ConcurrentMessageLoop> raster_message_loop_;
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch_;
#ifdef IMPELLER_DEBUG
std::shared_ptr<GPUTracerMTL> gpu_tracer_;
Expand Down
28 changes: 1 addition & 27 deletions impeller/renderer/backend/metal/context_mtl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include "impeller/renderer/backend/metal/context_mtl.h"

#include <Foundation/Foundation.h>
#include <memory>

#include "flutter/fml/concurrent_message_loop.h"
Expand Down Expand Up @@ -88,24 +87,6 @@ static bool DeviceSupportsComputeSubgroups(id<MTLDevice> device) {
sync_switch_observer_.reset(new SyncSwitchObserver(*this));
is_gpu_disabled_sync_switch_->AddObserver(sync_switch_observer_.get());

// Worker task runner.
{
raster_message_loop_ = fml::ConcurrentMessageLoop::Create(
std::min(4u, std::thread::hardware_concurrency()));
raster_message_loop_->PostTaskToAllWorkers([]() {
// See https://github.com/flutter/flutter/issues/65752
// Intentionally opt out of QoS for raster task workloads.
[[NSThread currentThread] setThreadPriority:1.0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get rid of the corresponding Foundation.h header import above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

sched_param param;
int policy;
pthread_t thread = pthread_self();
if (!pthread_getschedparam(thread, &policy, &param)) {
param.sched_priority = 50;
pthread_setschedparam(thread, policy, &param);
}
});
}

// Setup the shader library.
{
if (shader_libraries == nil) {
Expand Down Expand Up @@ -330,21 +311,14 @@ new ContextMTL(device, command_queue,
}

// |Context|
void ContextMTL::Shutdown() {
raster_message_loop_.reset();
}
void ContextMTL::Shutdown() {}

#ifdef IMPELLER_DEBUG
std::shared_ptr<GPUTracerMTL> ContextMTL::GetGPUTracer() const {
return gpu_tracer_;
}
#endif // IMPELLER_DEBUG

const std::shared_ptr<fml::ConcurrentTaskRunner>
ContextMTL::GetWorkerTaskRunner() const {
return raster_message_loop_->GetTaskRunner();
}

std::shared_ptr<const fml::SyncSwitch> ContextMTL::GetIsGpuDisabledSyncSwitch()
const {
return is_gpu_disabled_sync_switch_;
Expand Down
75 changes: 75 additions & 0 deletions impeller/renderer/backend/metal/pass_bindings_cache_mtl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_PASS_BINDINGS_CACHE_MTL_H_
#define FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_PASS_BINDINGS_CACHE_MTL_H_

#include <Metal/Metal.h>

#include "impeller/renderer/render_pass.h"
#include "impeller/renderer/render_target.h"

namespace impeller {

//-----------------------------------------------------------------------------
/// @brief Ensures that bindings on the pass are not redundantly set or
/// updated. Avoids making the driver do additional checks and makes
/// the frame insights during profiling and instrumentation not
/// complain about the same.
///
/// There should be no change to rendering if this caching was
/// absent.
///
struct PassBindingsCacheMTL {
explicit PassBindingsCacheMTL() {}

~PassBindingsCacheMTL() = default;

PassBindingsCacheMTL(const PassBindingsCacheMTL&) = delete;

PassBindingsCacheMTL(PassBindingsCacheMTL&&) = delete;

void SetEncoder(id<MTLRenderCommandEncoder> encoder);

void SetRenderPipelineState(id<MTLRenderPipelineState> pipeline);

void SetDepthStencilState(id<MTLDepthStencilState> depth_stencil);

bool SetBuffer(ShaderStage stage,
uint64_t index,
uint64_t offset,
id<MTLBuffer> buffer);

bool SetTexture(ShaderStage stage, uint64_t index, id<MTLTexture> texture);

bool SetSampler(ShaderStage stage,
uint64_t index,
id<MTLSamplerState> sampler);

void SetViewport(const Viewport& viewport);

void SetScissor(const IRect& scissor);

private:
struct BufferOffsetPair {
id<MTLBuffer> buffer = nullptr;
size_t offset = 0u;
};
using BufferMap = std::map<uint64_t, BufferOffsetPair>;
using TextureMap = std::map<uint64_t, id<MTLTexture>>;
using SamplerMap = std::map<uint64_t, id<MTLSamplerState>>;

id<MTLRenderCommandEncoder> encoder_;
id<MTLRenderPipelineState> pipeline_ = nullptr;
id<MTLDepthStencilState> depth_stencil_ = nullptr;
std::map<ShaderStage, BufferMap> buffers_;
std::map<ShaderStage, TextureMap> textures_;
std::map<ShaderStage, SamplerMap> samplers_;
std::optional<Viewport> viewport_;
std::optional<IRect> scissor_;
};

} // namespace impeller

#endif // FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_PASS_BINDINGS_CACHE_MTL_H_
Loading