1

I've compiled Skia for iOS:

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"]'

This is how I'm using it in a View Controller:

#import <MetalKit/MetalKit.h>
#import <Metal/Metal.h>
#import <UIKit/UIKit.h>

#define SK_GANESH
#define SK_METAL

#import <include/gpu/ganesh/GrDirectContext.h>
#import <include/core/SkSurface.h>

@interface SkiaViewController : UIViewController <MTKViewDelegate>

@property (nonatomic, strong) MTKView *mtkView;
@property (nonatomic, strong) id<MTLDevice> metalDevice;
@property (nonatomic, strong) id<MTLCommandQueue> metalQueue;

@property (nonatomic, assign) sk_sp<GrDirectContext> grDirectContext;
@property (nonatomic, assign) sk_sp<SkSurface> surface;
@end
#import <MetalKit/MetalKit.h>
#import <Metal/Metal.h>

#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 <include/gpu/ganesh/GrBackendSurface.h>
#import <include/gpu/ganesh/SkSurfaceGanesh.h>
#import <include/gpu/ganesh/mtl/GrMtlBackendContext.h>
#import <include/gpu/ganesh/mtl/GrMtlBackendSurface.h>
#import <include/gpu/ganesh/mtl/GrMtlDirectContext.h>
#import <include/gpu/ganesh/mtl/SkSurfaceMetal.h>

#import <include/gpu/ganesh/GrDirectContext.h>
#import <include/core/SkSurface.h>
#import <include/core/SkCanvas.h>
#import <include/core/SkColorSpace.h>

#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

In this case it works fine.

But if I create a static library inside the same project, move ViewController into that static library and use view controller from the static library in my app, I'm facing memory issues in GrDirectContexts::MakeMetal.

Sometimes it crashes with bad access error, sometimes some of pointers are becoming nullptr, for example in backendContext right after setting these values.

Same if I move this Skia initialization in a separate C++ library (compiled by CMake, not in Xcode directly).

I guess that this is some issue with Skia's smart pointers (maybe something is stripped when linking with static lib?), but I'm not familiar with Obj-C development and interop with C++ for iOS.

UPD. I've tested with a simple C++ library without passing any Obj-C pointers to Skia, and can confirm that I have exactly the same issues with it — at some point a pointer inside an sk_sp becomes invalid (for example, when Skia tries to free it).

What may be wrong here?

1
  • The way you describe your memory issues, it sounds like out of bounds/trying to access memory you shouldn't access from that point in code. It doesn't turn up as an error immediately, but can have all kinds of effects later on, which is what you're observing. If you can run a suitable sample with address sanitizer, that could reveal where the first invalid access lies. I don't expect static lib to be the cause. Commented Jan 2 at 20:11

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.