TestMetalContext: Use ARC-managed Metal types (flutter/engine#56717)

Previously, we could not include any Objective-C types in test_metal_context.h, since that file was transitively included in pure C++ translation units. All users have been refactored into backend-specific files, and all Metal-related files are Objective-C++ files.

We now use Metal types directly in the header, without the workarounds.

Issue: https://github.com/flutter/flutter/issues/158998
Issue: https://github.com/flutter/flutter/issues/137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
Chris Bracken 2024-11-19 14:50:10 -08:00 committed by GitHub
parent ccef3ff9c3
commit 1a60defc96
3 changed files with 17 additions and 20 deletions

View File

@ -19,8 +19,9 @@ EmbedderTestContextMetal::EmbedderTestContextMetal(std::string assets_path)
renderer_config_.type = FlutterRendererType::kMetal; renderer_config_.type = FlutterRendererType::kMetal;
renderer_config_.metal = { renderer_config_.metal = {
.struct_size = sizeof(FlutterMetalRendererConfig), .struct_size = sizeof(FlutterMetalRendererConfig),
.device = metal_context_->GetMetalDevice(), .device = (__bridge FlutterMetalDeviceHandle)metal_context_->GetMetalDevice(),
.present_command_queue = metal_context_->GetMetalCommandQueue(), .present_command_queue =
(__bridge FlutterMetalCommandQueueHandle)metal_context_->GetMetalCommandQueue(),
.get_next_drawable_callback = .get_next_drawable_callback =
[](void* user_data, const FlutterFrameInfo* frame_info) { [](void* user_data, const FlutterFrameInfo* frame_info) {
return reinterpret_cast<EmbedderTestContextMetal*>(user_data)->GetNextDrawable( return reinterpret_cast<EmbedderTestContextMetal*>(user_data)->GetNextDrawable(

View File

@ -9,6 +9,8 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <Metal/Metal.h>
#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" #include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
#include "third_party/skia/include/ports/SkCFObject.h" #include "third_party/skia/include/ports/SkCFObject.h"
@ -27,9 +29,9 @@ class TestMetalContext {
~TestMetalContext(); ~TestMetalContext();
void* GetMetalDevice() const; id<MTLDevice> GetMetalDevice() const;
void* GetMetalCommandQueue() const; id<MTLCommandQueue> GetMetalCommandQueue() const;
sk_sp<GrDirectContext> GetSkiaContext() const; sk_sp<GrDirectContext> GetSkiaContext() const;
@ -41,7 +43,8 @@ class TestMetalContext {
TextureInfo GetTextureInfo(int64_t texture_id); TextureInfo GetTextureInfo(int64_t texture_id);
private: private:
std::unique_ptr<MetalObjCFields> metal_; id<MTLDevice> device_;
id<MTLCommandQueue> command_queue_;
sk_sp<GrDirectContext> skia_context_; sk_sp<GrDirectContext> skia_context_;
std::mutex textures_mutex_; std::mutex textures_mutex_;
int64_t texture_id_ctr_ = 1; // guarded by textures_mutex int64_t texture_id_ctr_ = 1; // guarded by textures_mutex

View File

@ -17,12 +17,6 @@ static_assert(__has_feature(objc_arc), "ARC must be enabled.");
namespace flutter::testing { namespace flutter::testing {
// TOOD(cbracken): https://github.com/flutter/flutter/issues/157942
struct MetalObjCFields {
id<MTLDevice> device;
id<MTLCommandQueue> command_queue;
};
TestMetalContext::TestMetalContext() { TestMetalContext::TestMetalContext() {
id<MTLDevice> device = MTLCreateSystemDefaultDevice(); id<MTLDevice> device = MTLCreateSystemDefaultDevice();
if (!device) { if (!device) {
@ -48,22 +42,21 @@ TestMetalContext::TestMetalContext() {
FML_LOG(ERROR) << "Could not create the GrDirectContext from the Metal Device " FML_LOG(ERROR) << "Could not create the GrDirectContext from the Metal Device "
"and command queue."; "and command queue.";
} }
device_ = device;
metal_ = std::make_unique<MetalObjCFields>(MetalObjCFields{device, command_queue}); command_queue_ = command_queue;
} }
TestMetalContext::~TestMetalContext() { TestMetalContext::~TestMetalContext() {
std::scoped_lock lock(textures_mutex_); std::scoped_lock lock(textures_mutex_);
textures_.clear(); textures_.clear();
metal_.reset();
} }
void* TestMetalContext::GetMetalDevice() const { id<MTLDevice> TestMetalContext::GetMetalDevice() const {
return metal_ ? (__bridge void*)metal_->device : nil; return device_;
} }
void* TestMetalContext::GetMetalCommandQueue() const { id<MTLCommandQueue> TestMetalContext::GetMetalCommandQueue() const {
return metal_ ? (__bridge void*)metal_->command_queue : nil; return command_queue_;
} }
sk_sp<GrDirectContext> TestMetalContext::GetSkiaContext() const { sk_sp<GrDirectContext> TestMetalContext::GetSkiaContext() const {
@ -88,12 +81,12 @@ TestMetalContext::TextureInfo TestMetalContext::CreateMetalTexture(const SkISize
return {.texture_id = -1, .texture = nullptr}; return {.texture_id = -1, .texture = nullptr};
} }
if (!metal_) { if (!device_) {
FML_CHECK(false) << "Invalid Metal device."; FML_CHECK(false) << "Invalid Metal device.";
return {.texture_id = -1, .texture = nullptr}; return {.texture_id = -1, .texture = nullptr};
} }
id<MTLTexture> texture = [metal_->device newTextureWithDescriptor:texture_descriptor]; id<MTLTexture> texture = [device_ newTextureWithDescriptor:texture_descriptor];
if (!texture) { if (!texture) {
FML_CHECK(false) << "Could not create texture from texture descriptor."; FML_CHECK(false) << "Could not create texture from texture descriptor.";
return {.texture_id = -1, .texture = nullptr}; return {.texture_id = -1, .texture = nullptr};