[Impeller] various iOS cleanups. (#166859)
* delete lazy drawable holder which is unused.
* Add some docs/test to PassBindingsCache
* Add StencilRef to PassBindingsCache - mostly to reduce redundant ops
in the debugger.
diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter
index be24712..044200c 100644
--- a/engine/src/flutter/ci/licenses_golden/licenses_flutter
+++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter
@@ -51503,8 +51503,6 @@
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/formats_mtl.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/renderer/backend/metal/gpu_tracer_mtl.h + ../../../flutter/LICENSE
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
@@ -54491,8 +54489,6 @@
FILE: ../../../flutter/impeller/renderer/backend/metal/formats_mtl.mm
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
diff --git a/engine/src/flutter/impeller/renderer/backend/metal/BUILD.gn b/engine/src/flutter/impeller/renderer/backend/metal/BUILD.gn
index f1271c2..ac4a000 100644
--- a/engine/src/flutter/impeller/renderer/backend/metal/BUILD.gn
+++ b/engine/src/flutter/impeller/renderer/backend/metal/BUILD.gn
@@ -26,8 +26,6 @@
"formats_mtl.mm",
"gpu_tracer_mtl.h",
"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",
diff --git a/engine/src/flutter/impeller/renderer/backend/metal/allocator_mtl_unittests.mm b/engine/src/flutter/impeller/renderer/backend/metal/allocator_mtl_unittests.mm
index b490b3a..096c1db 100644
--- a/engine/src/flutter/impeller/renderer/backend/metal/allocator_mtl_unittests.mm
+++ b/engine/src/flutter/impeller/renderer/backend/metal/allocator_mtl_unittests.mm
@@ -10,7 +10,6 @@
#include "impeller/renderer/backend/metal/allocator_mtl.h"
#include "impeller/renderer/backend/metal/context_mtl.h"
#include "impeller/renderer/backend/metal/formats_mtl.h"
-#include "impeller/renderer/backend/metal/lazy_drawable_holder.h"
#include "impeller/renderer/backend/metal/texture_mtl.h"
#include "impeller/renderer/capabilities.h"
diff --git a/engine/src/flutter/impeller/renderer/backend/metal/lazy_drawable_holder.h b/engine/src/flutter/impeller/renderer/backend/metal/lazy_drawable_holder.h
deleted file mode 100644
index c01975b..0000000
--- a/engine/src/flutter/impeller/renderer/backend/metal/lazy_drawable_holder.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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_LAZY_DRAWABLE_HOLDER_H_
-#define FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_LAZY_DRAWABLE_HOLDER_H_
-
-#include <Metal/Metal.h>
-
-#include <future>
-#include "impeller/core/texture_descriptor.h"
-#include "impeller/renderer/backend/metal/texture_mtl.h"
-
-@protocol CAMetalDrawable;
-@class CAMetalLayer;
-
-namespace impeller {
-
-/// @brief Create a deferred drawable from a CAMetalLayer.
-std::shared_future<id<CAMetalDrawable>> GetDrawableDeferred(
- CAMetalLayer* layer);
-
-/// @brief Create a TextureMTL from a deferred drawable.
-///
-/// This function is safe to call multiple times and will only call
-/// nextDrawable once.
-std::shared_ptr<TextureMTL> CreateTextureFromDrawableFuture(
- TextureDescriptor desc,
- const std::shared_future<id<CAMetalDrawable>>& drawble_future);
-
-} // namespace impeller
-
-#endif // FLUTTER_IMPELLER_RENDERER_BACKEND_METAL_LAZY_DRAWABLE_HOLDER_H_
diff --git a/engine/src/flutter/impeller/renderer/backend/metal/lazy_drawable_holder.mm b/engine/src/flutter/impeller/renderer/backend/metal/lazy_drawable_holder.mm
deleted file mode 100644
index b847791..0000000
--- a/engine/src/flutter/impeller/renderer/backend/metal/lazy_drawable_holder.mm
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-#include "impeller/renderer/backend/metal/lazy_drawable_holder.h"
-
-#include <QuartzCore/CAMetalLayer.h>
-#include <future>
-#include <memory>
-
-#include "flutter/fml/trace_event.h"
-#include "impeller/base/validation.h"
-
-namespace impeller {
-
-#pragma GCC diagnostic push
-// Disable the diagnostic for iOS Simulators. Metal without emulation isn't
-// available prior to iOS 13 and that's what the simulator headers say when
-// support for CAMetalLayer begins. CAMetalLayer is available on iOS 8.0 and
-// above which is well below Flutters support level.
-#pragma GCC diagnostic ignored "-Wunguarded-availability-new"
-
-std::shared_future<id<CAMetalDrawable>> GetDrawableDeferred(
- CAMetalLayer* layer) {
- auto future =
- std::async(std::launch::deferred, [layer]() -> id<CAMetalDrawable> {
- id<CAMetalDrawable> current_drawable = nil;
- {
- TRACE_EVENT0("impeller", "WaitForNextDrawable");
- current_drawable = [layer nextDrawable];
- }
- if (!current_drawable) {
- VALIDATION_LOG << "Could not acquire current drawable.";
- return nullptr;
- }
- return current_drawable;
- });
- return std::shared_future<id<CAMetalDrawable>>(std::move(future));
-}
-
-std::shared_ptr<TextureMTL> CreateTextureFromDrawableFuture(
- TextureDescriptor desc,
- const std::shared_future<id<CAMetalDrawable>>& drawble_future) {
- return std::make_shared<TextureMTL>(
- desc, [drawble_future]() { return drawble_future.get().texture; },
- /*wrapped=*/false, /*drawable=*/true);
-}
-
-#pragma GCC diagnostic pop
-
-} // namespace impeller
diff --git a/engine/src/flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.h b/engine/src/flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.h
index 4728bee..960bd77 100644
--- a/engine/src/flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.h
+++ b/engine/src/flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.h
@@ -30,27 +30,57 @@
PassBindingsCacheMTL(PassBindingsCacheMTL&&) = delete;
+ /// @brief Set the command encoder for this pass bindings cache.
+ ///
+ /// The encoder must be set before any state adjusting commands can be called.
void SetEncoder(id<MTLRenderCommandEncoder> encoder);
+ /// @brief Set the render pipeline state for the current encoder.
+ ///
+ /// If this matches the previous render pipeline state, no update
+ /// is performed.
void SetRenderPipelineState(id<MTLRenderPipelineState> pipeline);
+ /// @brief Set the depth and stencil state for the current encoder.
+ ///
+ /// If this matches the previous depth and stencil state, no update
+ /// is performed.
void SetDepthStencilState(id<MTLDepthStencilState> depth_stencil);
+ /// @brief Set the buffer for the given shader stage, binding, and offset.
+ ///
+ /// If the buffer is already bound, only the offset is updated.
bool SetBuffer(ShaderStage stage,
uint64_t index,
uint64_t offset,
id<MTLBuffer> buffer);
+ /// @brief Set the texture for the given stage and binding.
+ ///
+ /// If the same texture is already bound at the index for this stage, no
+ /// state updates are performed.
bool SetTexture(ShaderStage stage, uint64_t index, id<MTLTexture> texture);
+ /// @brief Set the sampler for the given stage and binding.
+ ///
+ /// If the same sampler is already bound at the index for this stage, no
+ /// state updates are performed.
bool SetSampler(ShaderStage stage,
uint64_t index,
id<MTLSamplerState> sampler);
+ /// @brief Set the viewport if the value is different from the current encoder
+ /// state
void SetViewport(const Viewport& viewport);
+ /// @brief Set the encoder scissor rect if the value is different from the
+ /// current encoder state.
void SetScissor(const IRect& scissor);
+ /// @brief Set the encoder's stencil reference if the value is different from
+ /// the current encoder state.
+ void SetStencilRef(uint32_t stencil_ref);
+
private:
struct BufferOffsetPair {
id<MTLBuffer> buffer = nullptr;
@@ -68,6 +98,7 @@
std::map<ShaderStage, SamplerMap> samplers_;
std::optional<Viewport> viewport_;
std::optional<IRect> scissor_;
+ std::optional<uint32_t> stencil_ref_;
};
} // namespace impeller
diff --git a/engine/src/flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.mm
index ab5370a..2029fd6 100644
--- a/engine/src/flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.mm
+++ b/engine/src/flutter/impeller/renderer/backend/metal/pass_bindings_cache_mtl.mm
@@ -149,4 +149,12 @@
scissor_ = scissor;
}
+void PassBindingsCacheMTL::SetStencilRef(uint32_t stencil_ref) {
+ if (stencil_ref_.has_value() && stencil_ref_.value() == stencil_ref) {
+ return;
+ }
+ [encoder_ setStencilReferenceValue:stencil_ref];
+ stencil_ref_ = stencil_ref;
+}
+
} // namespace impeller
diff --git a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm
index fb26a8d..20cc24c 100644
--- a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm
+++ b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm
@@ -264,7 +264,7 @@
// |RenderPass|
void RenderPassMTL::SetStencilReference(uint32_t value) {
- [encoder_ setStencilReferenceValue:value];
+ pass_bindings_.SetStencilRef(value);
}
// |RenderPass|
diff --git a/engine/src/flutter/impeller/renderer/backend/metal/texture_mtl_unittests.mm b/engine/src/flutter/impeller/renderer/backend/metal/texture_mtl_unittests.mm
index 2e263eb..899fbbd 100644
--- a/engine/src/flutter/impeller/renderer/backend/metal/texture_mtl_unittests.mm
+++ b/engine/src/flutter/impeller/renderer/backend/metal/texture_mtl_unittests.mm
@@ -6,7 +6,6 @@
#include "impeller/core/formats.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/renderer/backend/metal/formats_mtl.h"
-#include "impeller/renderer/backend/metal/lazy_drawable_holder.h"
#include "impeller/renderer/backend/metal/texture_mtl.h"
#include "impeller/renderer/capabilities.h"
@@ -18,36 +17,7 @@
namespace impeller {
namespace testing {
-TEST(TextureMTL, CreateFromDrawable) {
- auto device = MTLCreateSystemDefaultDevice();
- auto layer = [[CAMetalLayer alloc] init];
- layer.device = device;
- layer.drawableSize = CGSize{100, 100};
- layer.pixelFormat = ToMTLPixelFormat(PixelFormat::kB8G8R8A8UNormInt);
-
- TextureDescriptor desc;
- desc.size = {100, 100};
- desc.format = PixelFormat::kB8G8R8A8UNormInt;
- auto drawable_future = GetDrawableDeferred(layer);
- auto drawable_texture =
- CreateTextureFromDrawableFuture(desc, drawable_future);
-
- ASSERT_TRUE(drawable_texture->IsValid());
- EXPECT_TRUE(drawable_texture->IsDrawable());
-
- // Spawn a thread and acquire the drawable in the thread.
- auto thread = std::thread([&drawable_texture]() {
- // Force the drawable to be acquired.
- drawable_texture->GetMTLTexture();
- });
- thread.join();
- // Block until drawable is acquired.
- EXPECT_TRUE(drawable_future.get() != nil);
- // Drawable is cached.
- EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
- // Once more for good measure.
- EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
-}
+//
} // namespace testing
} // namespace impeller