Code: Select all
bin/gn gen out/ios-apple --args='target_os="ios" target_cpu="arm64" ios_use_simulator=false skia_enable_tools=false is_official_build=false is_debug=true is_trivial_abi=false skia_use_metal=true skia_use_expat=false skia_use_system_expat=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false skia_use_system_freetype2=false skia_use_system_harfbuzz=false skia_use_system_icu=false skia_enable_gpu=true skia_enable_skottie=false skia_compile_modules=true extra_cflags=["-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks"] extra_ldflags=["-framework", "CoreFoundation", "-framework", "Metal"]'
Code: Select all
#import
#import
#import
#define SK_GANESH
#define SK_METAL
#import
#import
@interface SkiaViewController : UIViewController
@property (nonatomic, strong) MTKView *mtkView;
@property (nonatomic, strong) id metalDevice;
@property (nonatomic, strong) id metalQueue;
@property (nonatomic, assign) sk_sp grDirectContext;
@property (nonatomic, assign) sk_sp surface;
@end
Code: Select all
#import
#import
#define SK_GANESH
#define SK_METAL
#import "include/gpu/ganesh/GrTypes.h"
#import "include/gpu/ganesh/SkSurfaceGanesh.h"
#import "include/gpu/ganesh/mtl/GrMtlTypes.h"
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import
#import "SkiaViewController.h"
@implementation SkiaViewController
- (void)viewDidLoad {
[super viewDidLoad];
#ifndef SK_GANESH
NSLog(@"SK_GANESH is undefined");
#endif
#ifndef SK_METAL
NSLog(@"SK_METAL is undefined");
#endif
[self setMetalDevice:MTLCreateSystemDefaultDevice()];
[self setMetalQueue:[[self metalDevice] newCommandQueue]];
if(![self metalDevice]) {
NSLog(@"Metal is not supported on this device");
return;
}
if(![self metalQueue]) {
NSLog(@"Failed to create Metal command queue");
return;
}
// Initialize MTKView
self.mtkView = [[MTKView alloc] initWithFrame:self.view.bounds device:self.metalDevice];
self.mtkView.delegate = self;
self.mtkView.enableSetNeedsDisplay = YES;
[self.mtkView setDepthStencilPixelFormat:MTLPixelFormatDepth32Float_Stencil8];
[self.mtkView setColorPixelFormat:MTLPixelFormatBGRA8Unorm];
[self.mtkView setSampleCount:1];
NSLog(@"self.metalDevice.maxBufferLength=%lu", self.metalDevice.maxBufferLength);
self.mtkView.layer.borderWidth = 2.0; // Set border width
self.mtkView.layer.borderColor = [UIColor redColor].CGColor; // Set border color
[self.view addSubview:self.mtkView];
// Initialize Skia with Metal
GrMtlBackendContext backendContext = {};
backendContext.fDevice.retain((__bridge void*)[self metalDevice]); // also tried __bridge_retained
backendContext.fQueue.retain((__bridge void*)[self metalQueue]);
GrContextOptions grContextOptions;
self.grDirectContext = GrDirectContexts::MakeMetal(backendContext, grContextOptions);
if (![self grDirectContext]) {
NSLog(@"Failed to create GrDirectContext");
return;
}
NSLog(@"Created GrDirectContext");
}
#pragma mark - MTKViewDelegate
- (void)drawInMTKView:(nonnull MTKView *)view {
}
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
}
@end
Aber wenn ich eine statische Bibliothek innerhalb desselben Projekts erstelle, verschiebe ViewController in diese statische Bibliothek und verwende die Ansicht Controller aus der statischen Bibliothek in meiner App, ich habe Speicherprobleme in GrDirectContexts::MakeMetal.
Manchmal stürzt es mit einem fehlerhaften Zugriffsfehler ab, manchmal werden einige Zeiger beschädigt nullptr, zum Beispiel in backendContext direkt nach dem Festlegen dieser Werte.
Das Gleiche gilt, wenn ich diese Skia-Initialisierung in eine separate C++-Bibliothek verschiebe (kompiliert von CMake, nicht direkt in Xcode).Ich vermute, dass dies ein Problem mit den intelligenten Zeigern von Skia ist (vielleicht wird beim Verknüpfen mit der statischen Bibliothek etwas entfernt?), aber ich bin nicht mit der Obj-C-Entwicklung und der Interoperabilität mit C++ für iOS vertraut.
UPD. Ich habe es mit einer einfachen C++-Bibliothek getestet, ohne Obj-C-Zeiger an Skia zu übergeben, und kann bestätigen, dass ich genau die gleichen Probleme damit habe – irgendwann a Zeiger innerhalb eines sk_sp wird ungültig (z. B. wenn Skia versucht, ihn freizugeben).
Was könnte hier falsch sein?