Remove ARC from tools lib.
Trying this in baby steps to manage leaks better.
Change-Id: Id8597ba236c752bcbf1c7ec94f6c1021e636d547
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/372556
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Adlai Holler <adlai@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 792e832..f62fe24 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1781,8 +1781,6 @@
libs +=
[ "${fuchsia_sdk_path}/arch/${target_cpu}/sysroot/lib/libzircon.so" ]
}
-
- cflags_objcc = [ "-fobjc-arc" ]
} # test_lib("gpu_tool_utils")
test_lib("flags") {
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 738f1b3..4f7ca64 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -6,6 +6,9 @@
Milestone 90
------------
+ * Renamed use of sk_cf_obj in external Metal types to sk_cfp.
+ https://review.skia.org/372556
+
* GrDirectContext::ComputeImageSize() is removed. Use SkImage::textureSize() instead.
https://review.skia.org/368621
https://review.skia.org/369317
diff --git a/include/gpu/mtl/GrMtlBackendContext.h b/include/gpu/mtl/GrMtlBackendContext.h
index ca49bf2..0d88f47 100644
--- a/include/gpu/mtl/GrMtlBackendContext.h
+++ b/include/gpu/mtl/GrMtlBackendContext.h
@@ -13,9 +13,9 @@
// The BackendContext contains all of the base Metal objects needed by the GrMtlGpu. The assumption
// is that the client will set these up and pass them to the GrMtlGpu constructor.
struct SK_API GrMtlBackendContext {
- sk_cf_obj<GrMTLHandle> fDevice;
- sk_cf_obj<GrMTLHandle> fQueue;
- sk_cf_obj<GrMTLHandle> fBinaryArchive;
+ sk_cfp<GrMTLHandle> fDevice;
+ sk_cfp<GrMTLHandle> fQueue;
+ sk_cfp<GrMTLHandle> fBinaryArchive;
};
#endif
diff --git a/include/gpu/mtl/GrMtlTypes.h b/include/gpu/mtl/GrMtlTypes.h
index e772245..2f4bdfd 100644
--- a/include/gpu/mtl/GrMtlTypes.h
+++ b/include/gpu/mtl/GrMtlTypes.h
@@ -59,7 +59,7 @@
public:
GrMtlTextureInfo() {}
- sk_cf_obj<const void*> fTexture;
+ sk_cfp<const void*> fTexture;
bool operator==(const GrMtlTextureInfo& that) const {
return fTexture == that.fTexture;
diff --git a/include/ports/SkCFObject.h b/include/ports/SkCFObject.h
index ac156da..13546d0 100644
--- a/include/ports/SkCFObject.h
+++ b/include/ports/SkCFObject.h
@@ -30,50 +30,50 @@
}
}
-template <typename T> class sk_cf_obj {
+template <typename T> class sk_cfp {
public:
using element_type = T;
- constexpr sk_cf_obj() {}
- constexpr sk_cf_obj(std::nullptr_t) {}
+ constexpr sk_cfp() {}
+ constexpr sk_cfp(std::nullptr_t) {}
/**
* Shares the underlying object by calling CFRetain(), so that both the argument and the newly
- * created sk_cf_obj both have a reference to it.
+ * created sk_cfp both have a reference to it.
*/
- sk_cf_obj(const sk_cf_obj<T>& that) : fObject(SkCFSafeRetain(that.get())) {}
+ sk_cfp(const sk_cfp<T>& that) : fObject(SkCFSafeRetain(that.get())) {}
/**
- * Move the underlying object from the argument to the newly created sk_cf_obj. Afterwards only
- * the new sk_cf_obj will have a reference to the object, and the argument will point to null.
+ * Move the underlying object from the argument to the newly created sk_cfp. Afterwards only
+ * the new sk_cfp will have a reference to the object, and the argument will point to null.
* No call to CFRetain() or CFRelease() will be made.
*/
- sk_cf_obj(sk_cf_obj<T>&& that) : fObject(that.release()) {}
+ sk_cfp(sk_cfp<T>&& that) : fObject(that.release()) {}
/**
- * Adopt the bare object into the newly created sk_cf_obj.
+ * Adopt the bare object into the newly created sk_cfp.
* No call to CFRetain() or CFRelease() will be made.
*/
- explicit sk_cf_obj(T obj) {
+ explicit sk_cfp(T obj) {
fObject = obj;
}
/**
* Calls CFRelease() on the underlying object pointer.
*/
- ~sk_cf_obj() {
+ ~sk_cfp() {
SkCFSafeRelease(fObject);
SkDEBUGCODE(fObject = nil);
}
- sk_cf_obj<T>& operator=(std::nullptr_t) { this->reset(); return *this; }
+ sk_cfp<T>& operator=(std::nullptr_t) { this->reset(); return *this; }
/**
* Shares the underlying object referenced by the argument by calling CFRetain() on it. If this
- * sk_cf_obj previously had a reference to an object (i.e. not null) it will call CFRelease()
+ * sk_cfp previously had a reference to an object (i.e. not null) it will call CFRelease()
* on that object.
*/
- sk_cf_obj<T>& operator=(const sk_cf_obj<T>& that) {
+ sk_cfp<T>& operator=(const sk_cfp<T>& that) {
if (this != &that) {
this->reset(SkCFSafeRetain(that.get()));
}
@@ -81,11 +81,11 @@
}
/**
- * Move the underlying object from the argument to the sk_cf_obj. If the sk_cf_obj
+ * Move the underlying object from the argument to the sk_cfp. If the sk_cfp
* previously held a reference to another object, CFRelease() will be called on that object.
* No call to CFRetain() will be made.
*/
- sk_cf_obj<T>& operator=(sk_cf_obj<T>&& that) {
+ sk_cfp<T>& operator=(sk_cfp<T>&& that) {
this->reset(that.release());
return *this;
}
@@ -112,7 +112,7 @@
}
/**
- * Shares the new object by calling CFRetain() on it. If this sk_cf_obj previously had a
+ * Shares the new object by calling CFRetain() on it. If this sk_cfp previously had a
* reference to an object (i.e. not null) it will call CFRelease() on that object.
*/
void retain(T object) {
@@ -136,40 +136,40 @@
T fObject = nil;
};
-template <typename T> inline bool operator==(const sk_cf_obj<T>& a,
- const sk_cf_obj<T>& b) {
+template <typename T> inline bool operator==(const sk_cfp<T>& a,
+ const sk_cfp<T>& b) {
return a.get() == b.get();
}
-template <typename T> inline bool operator==(const sk_cf_obj<T>& a,
+template <typename T> inline bool operator==(const sk_cfp<T>& a,
std::nullptr_t) {
return !a;
}
template <typename T> inline bool operator==(std::nullptr_t,
- const sk_cf_obj<T>& b) {
+ const sk_cfp<T>& b) {
return !b;
}
-template <typename T> inline bool operator!=(const sk_cf_obj<T>& a,
- const sk_cf_obj<T>& b) {
+template <typename T> inline bool operator!=(const sk_cfp<T>& a,
+ const sk_cfp<T>& b) {
return a.get() != b.get();
}
-template <typename T> inline bool operator!=(const sk_cf_obj<T>& a,
+template <typename T> inline bool operator!=(const sk_cfp<T>& a,
std::nullptr_t) {
return static_cast<bool>(a);
}
template <typename T> inline bool operator!=(std::nullptr_t,
- const sk_cf_obj<T>& b) {
+ const sk_cfp<T>& b) {
return static_cast<bool>(b);
}
/*
- * Returns a sk_cf_obj wrapping the provided object AND calls retain on it (if not null).
+ * Returns a sk_cfp wrapping the provided object AND calls retain on it (if not null).
*
- * This is different than the semantics of the constructor for sk_cf_obj, which just wraps the
+ * This is different than the semantics of the constructor for sk_cfp, which just wraps the
* object, effectively "adopting" it.
*/
-template <typename T> sk_cf_obj<T> sk_ret_cf_obj(T obj) {
- return sk_cf_obj<T>(SkCFSafeRetain(obj));
+template <typename T> sk_cfp<T> sk_ret_cfp(T obj) {
+ return sk_cfp<T>(SkCFSafeRetain(obj));
}
#endif // SK_BUILD_FOR_MAC || SK_BUILD_FOR_IOS
diff --git a/src/gpu/mtl/GrMtlUtil.h b/src/gpu/mtl/GrMtlUtil.h
index 78f166b..017c6d5 100644
--- a/src/gpu/mtl/GrMtlUtil.h
+++ b/src/gpu/mtl/GrMtlUtil.h
@@ -14,10 +14,6 @@
#include "include/private/GrTypesPriv.h"
#include "src/sksl/ir/SkSLProgram.h"
-#if !__has_feature(objc_arc)
-#error This file must be compiled with Arc. Use -fobjc-arc flag
-#endif
-
#if defined(SK_BUILD_FOR_MAC)
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 101400
#error Must use at least 10.14 SDK to build Metal backend for MacOS
@@ -35,14 +31,23 @@
* Returns a id<MTLTexture> to the MTLTexture pointed at by the const void*.
*/
SK_ALWAYS_INLINE id<MTLTexture> GrGetMTLTexture(const void* mtlTexture) {
+#if __has_feature(objc_arc)
return (__bridge id<MTLTexture>)mtlTexture;
+#else
+ // ARC will retain when bridging from a CoreFoundation to an ObjC object
+ return (id<MTLTexture>) CFRetain(mtlTexture);
+#endif
}
/**
* Returns a const void* to whatever the id object is pointing to.
*/
SK_ALWAYS_INLINE const void* GrGetPtrFromId(id idObject) {
+#if __has_feature(objc_arc)
return (__bridge const void*)idObject;
+#else
+ return (const void*)idObject;
+#endif
}
/**
@@ -50,7 +55,7 @@
* Will call CFRetain on the object.
*/
SK_ALWAYS_INLINE const void* GrRetainPtrFromId(id idObject) {
- return (__bridge_retained const void*)idObject;
+ return CFBridgingRetain(idObject);
}
enum class GrMtlErrorCode {
diff --git a/src/ports/SkOSFile_ios.h b/src/ports/SkOSFile_ios.h
index 2e2367e..67e7e7b 100644
--- a/src/ports/SkOSFile_ios.h
+++ b/src/ports/SkOSFile_ios.h
@@ -21,15 +21,15 @@
// Get a reference to the file's URL
// Use this to normalize the path
- sk_cf_obj<CFURLRef> pathURL(CFURLCreateFromFileSystemRepresentation(/*allocator=*/nullptr,
- (const UInt8*)path,
- strlen(path),
- /*isDirectory=*/false));
- sk_cf_obj<CFStringRef> pathRef(CFURLCopyFileSystemPath(pathURL.get(), kCFURLPOSIXPathStyle));
+ sk_cfp<CFURLRef> pathURL(CFURLCreateFromFileSystemRepresentation(/*allocator=*/nullptr,
+ (const UInt8*)path,
+ strlen(path),
+ /*isDirectory=*/false));
+ sk_cfp<CFStringRef> pathRef(CFURLCopyFileSystemPath(pathURL.get(), kCFURLPOSIXPathStyle));
// We use "data" as our subdirectory to match {{bundle_resources_dir}}/data in GN
// Unfortunately "resources" is not a valid top-level name in iOS, so we push it one level down
- sk_cf_obj<CFURLRef> fileURL(CFBundleCopyResourceURL(mainBundle, pathRef.get(),
- /*resourceType=*/nullptr, CFSTR("data")));
+ sk_cfp<CFURLRef> fileURL(CFBundleCopyResourceURL(mainBundle, pathRef.get(),
+ /*resourceType=*/nullptr, CFSTR("data")));
if (!fileURL) {
return false;
}
@@ -38,7 +38,7 @@
}
// Convert the URL reference into a string reference
- sk_cf_obj<CFStringRef> filePath(CFURLCopyFileSystemPath(fileURL.get(), kCFURLPOSIXPathStyle));
+ sk_cfp<CFStringRef> filePath(CFURLCopyFileSystemPath(fileURL.get(), kCFURLPOSIXPathStyle));
// Get the system encoding method
CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
diff --git a/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm b/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm
index eff6bd0..db334aa 100644
--- a/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm
+++ b/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm
@@ -10,6 +10,8 @@
#import <OpenGLES/EAGL.h>
#include <dlfcn.h>
+#include "include/ports/SkCFObject.h"
+
#define EAGLCTX ((EAGLContext*)(fEAGLContext))
namespace {
@@ -32,30 +34,29 @@
std::function<void()> onPlatformGetAutoContextRestore() const override;
GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
- EAGLContext* fEAGLContext;
+ sk_cfp<EAGLContext*> fEAGLContext;
void* fGLLibrary;
};
IOSGLTestContext::IOSGLTestContext(IOSGLTestContext* shareContext)
- : fEAGLContext(NULL)
- , fGLLibrary(RTLD_DEFAULT) {
+ : fGLLibrary(RTLD_DEFAULT) {
if (shareContext) {
- EAGLContext* iosShareContext = shareContext->fEAGLContext;
- fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
- sharegroup:[iosShareContext sharegroup]];
- if (fEAGLContext == nil) {
- fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
- sharegroup:[iosShareContext sharegroup]];
+ EAGLContext* iosShareContext = shareContext->fEAGLContext.get();
+ fEAGLContext.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
+ sharegroup:[iosShareContext sharegroup]]);
+ if (!fEAGLContext) {
+ fEAGLContext.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2
+ sharegroup:[iosShareContext sharegroup]]);
}
} else {
- fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
- if (fEAGLContext == nil) {
- fEAGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+ fEAGLContext.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]);
+ if (!fEAGLContext) {
+ fEAGLContext.reset([[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]);
}
}
SkScopeExit restorer(context_restorer());
- [EAGLContext setCurrentContext:fEAGLContext];
+ [EAGLContext setCurrentContext:fEAGLContext.get()];
sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface());
if (NULL == gl.get()) {
@@ -83,11 +84,11 @@
void IOSGLTestContext::destroyGLContext() {
if (fEAGLContext) {
- if ([EAGLContext currentContext] == fEAGLContext) {
+ if ([EAGLContext currentContext] == fEAGLContext.get()) {
// This will ensure that the context is immediately deleted.
[EAGLContext setCurrentContext:nil];
}
- fEAGLContext = nil;
+ fEAGLContext.reset();
}
if (nullptr != fGLLibrary) {
dlclose(fGLLibrary);
@@ -101,13 +102,13 @@
}
void IOSGLTestContext::onPlatformMakeCurrent() const {
- if (![EAGLContext setCurrentContext:fEAGLContext]) {
+ if (![EAGLContext setCurrentContext:fEAGLContext.get()]) {
SkDebugf("Could not set the context.\n");
}
}
std::function<void()> IOSGLTestContext::onPlatformGetAutoContextRestore() const {
- if ([EAGLContext currentContext] == fEAGLContext) {
+ if ([EAGLContext currentContext] == fEAGLContext.get()) {
return nullptr;
}
return context_restorer();
diff --git a/tools/gpu/mtl/MtlTestContext.mm b/tools/gpu/mtl/MtlTestContext.mm
index 9580fd3..4e4b12c 100644
--- a/tools/gpu/mtl/MtlTestContext.mm
+++ b/tools/gpu/mtl/MtlTestContext.mm
@@ -25,29 +25,29 @@
MtlTestContextImpl* sharedContextImpl = (MtlTestContextImpl*) sharedContext;
backendContext = sharedContextImpl->getMtlBackendContext();
} else {
- id<MTLDevice> device;
+ sk_cfp<id<MTLDevice>> device;
#ifdef SK_BUILD_FOR_MAC
- NSArray<id <MTLDevice>>* availableDevices = MTLCopyAllDevices();
+ sk_cfp<NSArray<id <MTLDevice>>*> availableDevices(MTLCopyAllDevices());
// Choose the non-integrated CPU if available
- for (id<MTLDevice> dev in availableDevices) {
+ for (id<MTLDevice> dev in availableDevices.get()) {
if (!dev.isLowPower) {
- device = dev;
+ device.retain(dev);
break;
}
if (dev.isRemovable) {
- device = dev;
+ device.retain(dev);
break;
}
}
if (!device) {
- device = MTLCreateSystemDefaultDevice();
+ device.reset(MTLCreateSystemDefaultDevice());
}
#else
- device = MTLCreateSystemDefaultDevice();
+ device.reset(MTLCreateSystemDefaultDevice());
#endif
- backendContext.fDevice.retain((__bridge GrMTLHandle)device);
- id<MTLCommandQueue> queue = [device newCommandQueue];
- backendContext.fQueue.retain((__bridge GrMTLHandle)queue);
+ backendContext.fDevice.retain((GrMTLHandle)device.get());
+ sk_cfp<id<MTLCommandQueue>> queue([*device newCommandQueue]);
+ backendContext.fQueue.retain((GrMTLHandle)queue.get());
}
return new MtlTestContextImpl(backendContext);
diff --git a/tools/sk_app/MetalWindowContext.h b/tools/sk_app/MetalWindowContext.h
index c0b9d92..e8c8392 100644
--- a/tools/sk_app/MetalWindowContext.h
+++ b/tools/sk_app/MetalWindowContext.h
@@ -9,6 +9,7 @@
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurface.h"
+#include "include/ports/SkCFObject.h"
#include "tools/sk_app/WindowContext.h"
@@ -45,12 +46,13 @@
virtual void onDestroyContext() = 0;
bool fValid;
- id<MTLDevice> fDevice;
- id<MTLCommandQueue> fQueue;
+ sk_cfp<id<MTLDevice>> fDevice;
+ sk_cfp<id<MTLCommandQueue>> fQueue;
CAMetalLayer* fMetalLayer;
GrMTLHandle fDrawableHandle;
#if GR_METAL_SDK_VERSION >= 230
- id<MTLBinaryArchive> fPipelineArchive SK_API_AVAILABLE(macos(11.0), ios(14.0));
+ // wrapping this in sk_cfp throws up an availability warning, so we'll track lifetime manually
+ id<MTLBinaryArchive> fPipelineArchive SK_API_AVAILABLE(macos(11.0), ios(14.0));
#endif
};
diff --git a/tools/sk_app/MetalWindowContext.mm b/tools/sk_app/MetalWindowContext.mm
index 4bfa688..5b62381 100644
--- a/tools/sk_app/MetalWindowContext.mm
+++ b/tools/sk_app/MetalWindowContext.mm
@@ -24,8 +24,8 @@
MetalWindowContext::MetalWindowContext(const DisplayParams& params)
: WindowContext(params)
- , fValid(false) {
-
+ , fValid(false)
+ , fDrawableHandle(nil) {
fDisplayParams.fMSAASampleCount = GrNextPow2(fDisplayParams.fMSAASampleCount);
}
@@ -39,12 +39,12 @@
void MetalWindowContext::initializeContext() {
SkASSERT(!fContext);
- fDevice = MTLCreateSystemDefaultDevice();
- fQueue = [fDevice newCommandQueue];
+ fDevice.reset(MTLCreateSystemDefaultDevice());
+ fQueue.reset([*fDevice newCommandQueue]);
if (fDisplayParams.fMSAASampleCount > 1) {
if (@available(macOS 10.11, iOS 9.0, *)) {
- if (![fDevice supportsTextureSampleCount:fDisplayParams.fMSAASampleCount]) {
+ if (![*fDevice supportsTextureSampleCount:fDisplayParams.fMSAASampleCount]) {
return;
}
} else {
@@ -59,20 +59,19 @@
#if GR_METAL_SDK_VERSION >= 230
if (fDisplayParams.fEnableBinaryArchive) {
if (@available(macOS 11.0, iOS 14.0, *)) {
- MTLBinaryArchiveDescriptor* desc = [MTLBinaryArchiveDescriptor new];
- desc.url = CacheURL(); // try to load
+ sk_cfp<MTLBinaryArchiveDescriptor*> desc([MTLBinaryArchiveDescriptor new]);
+ (*desc).url = CacheURL(); // try to load
NSError* error;
- fPipelineArchive = [fDevice newBinaryArchiveWithDescriptor:desc error:&error];
+ fPipelineArchive = [*fDevice newBinaryArchiveWithDescriptor:*desc error:&error];
if (!fPipelineArchive) {
- desc.url = nil; // create new
+ (*desc).url = nil; // create new
NSError* error;
- fPipelineArchive = [fDevice newBinaryArchiveWithDescriptor:desc error:&error];
+ fPipelineArchive = [*fDevice newBinaryArchiveWithDescriptor:*desc error:&error];
if (!fPipelineArchive) {
SkDebugf("Error creating MTLBinaryArchive:\n%s\n",
error.debugDescription.UTF8String);
}
}
- [desc release];
}
} else {
if (@available(macOS 11.0, iOS 14.0, *)) {
@@ -82,8 +81,8 @@
#endif
GrMtlBackendContext backendContext = {};
- backendContext.fDevice.retain((__bridge GrMTLHandle)fDevice);
- backendContext.fQueue.retain((__bridge GrMTLHandle)fQueue);
+ backendContext.fDevice.retain((GrMTLHandle)fDevice.get());
+ backendContext.fQueue.retain((GrMTLHandle)fQueue.get());
#if GR_METAL_SDK_VERSION >= 230
if (@available(macOS 11.0, iOS 14.0, *)) {
backendContext.fBinaryArchive.retain((__bridge GrMTLHandle)fPipelineArchive);
@@ -114,8 +113,8 @@
[fPipelineArchive release];
}
#endif
- [fQueue release];
- [fDevice release];
+ fQueue.reset();
+ fDevice.reset();
}
sk_sp<SkSurface> MetalWindowContext::getBackbufferSurface() {
@@ -156,7 +155,7 @@
void MetalWindowContext::swapBuffers() {
id<CAMetalDrawable> currentDrawable = (id<CAMetalDrawable>)fDrawableHandle;
- id<MTLCommandBuffer> commandBuffer = [fQueue commandBuffer];
+ id<MTLCommandBuffer> commandBuffer([*fQueue commandBuffer]);
commandBuffer.label = @"Present";
[commandBuffer presentDrawable:currentDrawable];
diff --git a/tools/sk_app/ios/MetalWindowContext_ios.mm b/tools/sk_app/ios/MetalWindowContext_ios.mm
index b8cee03..ec525c2 100644
--- a/tools/sk_app/ios/MetalWindowContext_ios.mm
+++ b/tools/sk_app/ios/MetalWindowContext_ios.mm
@@ -71,7 +71,7 @@
[fViewController.view addSubview:fMetalView];
fMetalLayer = (CAMetalLayer*)fMetalView.layer;
- fMetalLayer.device = fDevice;
+ fMetalLayer.device = fDevice.get();
fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
fMetalLayer.drawableSize = frameRect.size;
fMetalLayer.frame = frameRect;
diff --git a/tools/sk_app/mac/MetalWindowContext_mac.mm b/tools/sk_app/mac/MetalWindowContext_mac.mm
index 305da2b..5bea857 100644
--- a/tools/sk_app/mac/MetalWindowContext_mac.mm
+++ b/tools/sk_app/mac/MetalWindowContext_mac.mm
@@ -52,7 +52,7 @@
SkASSERT(nil != fMainView);
fMetalLayer = [CAMetalLayer layer];
- fMetalLayer.device = fDevice;
+ fMetalLayer.device = fDevice.get();
fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
// resize ignores the passed values and uses the fMainView directly.