diff --git a/BUILD.gn b/BUILD.gn index 792e832308..f62fe2437b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1781,8 +1781,6 @@ if (skia_enable_tools) { 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 738f1b311c..4f7ca64396 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -6,6 +6,9 @@ This file includes a list of high level updates for each milestone release. 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 ca49bf23a5..0d88f479ac 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 fDevice; - sk_cf_obj fQueue; - sk_cf_obj fBinaryArchive; + sk_cfp fDevice; + sk_cfp fQueue; + sk_cfp fBinaryArchive; }; #endif diff --git a/include/gpu/mtl/GrMtlTypes.h b/include/gpu/mtl/GrMtlTypes.h index e772245637..2f4bdfd375 100644 --- a/include/gpu/mtl/GrMtlTypes.h +++ b/include/gpu/mtl/GrMtlTypes.h @@ -59,7 +59,7 @@ struct GrMtlTextureInfo { public: GrMtlTextureInfo() {} - sk_cf_obj fTexture; + sk_cfp fTexture; bool operator==(const GrMtlTextureInfo& that) const { return fTexture == that.fTexture; diff --git a/include/ports/SkCFObject.h b/include/ports/SkCFObject.h index ac156da04a..13546d0a4c 100644 --- a/include/ports/SkCFObject.h +++ b/include/ports/SkCFObject.h @@ -30,50 +30,50 @@ template static inline void SkCFSafeRelease(T obj) { } } -template class sk_cf_obj { +template 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& that) : fObject(SkCFSafeRetain(that.get())) {} + sk_cfp(const sk_cfp& 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&& that) : fObject(that.release()) {} + sk_cfp(sk_cfp&& 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& operator=(std::nullptr_t) { this->reset(); return *this; } + sk_cfp& 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& operator=(const sk_cf_obj& that) { + sk_cfp& operator=(const sk_cfp& that) { if (this != &that) { this->reset(SkCFSafeRetain(that.get())); } @@ -81,11 +81,11 @@ public: } /** - * 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& operator=(sk_cf_obj&& that) { + sk_cfp& operator=(sk_cfp&& that) { this->reset(that.release()); return *this; } @@ -112,7 +112,7 @@ public: } /** - * 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 @@ private: T fObject = nil; }; -template inline bool operator==(const sk_cf_obj& a, - const sk_cf_obj& b) { +template inline bool operator==(const sk_cfp& a, + const sk_cfp& b) { return a.get() == b.get(); } -template inline bool operator==(const sk_cf_obj& a, +template inline bool operator==(const sk_cfp& a, std::nullptr_t) { return !a; } template inline bool operator==(std::nullptr_t, - const sk_cf_obj& b) { + const sk_cfp& b) { return !b; } -template inline bool operator!=(const sk_cf_obj& a, - const sk_cf_obj& b) { +template inline bool operator!=(const sk_cfp& a, + const sk_cfp& b) { return a.get() != b.get(); } -template inline bool operator!=(const sk_cf_obj& a, +template inline bool operator!=(const sk_cfp& a, std::nullptr_t) { return static_cast(a); } template inline bool operator!=(std::nullptr_t, - const sk_cf_obj& b) { + const sk_cfp& b) { return static_cast(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 sk_cf_obj sk_ret_cf_obj(T obj) { - return sk_cf_obj(SkCFSafeRetain(obj)); +template sk_cfp sk_ret_cfp(T obj) { + return sk_cfp(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 78f166b69b..017c6d559c 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 @@ class GrSurface; * Returns a id to the MTLTexture pointed at by the const void*. */ SK_ALWAYS_INLINE id GrGetMTLTexture(const void* mtlTexture) { +#if __has_feature(objc_arc) return (__bridge id)mtlTexture; +#else + // ARC will retain when bridging from a CoreFoundation to an ObjC object + return (id) 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 @@ SK_ALWAYS_INLINE const void* GrGetPtrFromId(id idObject) { * 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 2e2367ebae..67e7e7b959 100644 --- a/src/ports/SkOSFile_ios.h +++ b/src/ports/SkOSFile_ios.h @@ -21,15 +21,15 @@ static bool ios_get_path_in_bundle(const char path[], SkString* result) { // Get a reference to the file's URL // Use this to normalize the path - sk_cf_obj pathURL(CFURLCreateFromFileSystemRepresentation(/*allocator=*/nullptr, - (const UInt8*)path, - strlen(path), - /*isDirectory=*/false)); - sk_cf_obj pathRef(CFURLCopyFileSystemPath(pathURL.get(), kCFURLPOSIXPathStyle)); + sk_cfp pathURL(CFURLCreateFromFileSystemRepresentation(/*allocator=*/nullptr, + (const UInt8*)path, + strlen(path), + /*isDirectory=*/false)); + sk_cfp 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 fileURL(CFBundleCopyResourceURL(mainBundle, pathRef.get(), - /*resourceType=*/nullptr, CFSTR("data"))); + sk_cfp fileURL(CFBundleCopyResourceURL(mainBundle, pathRef.get(), + /*resourceType=*/nullptr, CFSTR("data"))); if (!fileURL) { return false; } @@ -38,7 +38,7 @@ static bool ios_get_path_in_bundle(const char path[], SkString* result) { } // Convert the URL reference into a string reference - sk_cf_obj filePath(CFURLCopyFileSystemPath(fileURL.get(), kCFURLPOSIXPathStyle)); + sk_cfp 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 eff6bd0a97..db334aa3cc 100644 --- a/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm +++ b/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm @@ -10,6 +10,8 @@ #import #include +#include "include/ports/SkCFObject.h" + #define EAGLCTX ((EAGLContext*)(fEAGLContext)) namespace { @@ -32,30 +34,29 @@ private: std::function onPlatformGetAutoContextRestore() const override; GrGLFuncPtr onPlatformGetProcAddress(const char*) const override; - EAGLContext* fEAGLContext; + sk_cfp 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 gl(GrGLCreateNativeInterface()); if (NULL == gl.get()) { @@ -83,11 +84,11 @@ IOSGLTestContext::~IOSGLTestContext() { 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::onPlatformMakeNotCurrent() const { } void IOSGLTestContext::onPlatformMakeCurrent() const { - if (![EAGLContext setCurrentContext:fEAGLContext]) { + if (![EAGLContext setCurrentContext:fEAGLContext.get()]) { SkDebugf("Could not set the context.\n"); } } std::function 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 9580fd3f02..4e4b12c2f5 100644 --- a/tools/gpu/mtl/MtlTestContext.mm +++ b/tools/gpu/mtl/MtlTestContext.mm @@ -25,29 +25,29 @@ public: MtlTestContextImpl* sharedContextImpl = (MtlTestContextImpl*) sharedContext; backendContext = sharedContextImpl->getMtlBackendContext(); } else { - id device; + sk_cfp> device; #ifdef SK_BUILD_FOR_MAC - NSArray>* availableDevices = MTLCopyAllDevices(); + sk_cfp>*> availableDevices(MTLCopyAllDevices()); // Choose the non-integrated CPU if available - for (id dev in availableDevices) { + for (id 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 queue = [device newCommandQueue]; - backendContext.fQueue.retain((__bridge GrMTLHandle)queue); + backendContext.fDevice.retain((GrMTLHandle)device.get()); + sk_cfp> 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 c0b9d92030..e8c8392a15 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 @@ protected: virtual void onDestroyContext() = 0; bool fValid; - id fDevice; - id fQueue; + sk_cfp> fDevice; + sk_cfp> fQueue; CAMetalLayer* fMetalLayer; GrMTLHandle fDrawableHandle; #if GR_METAL_SDK_VERSION >= 230 - id 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 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 4bfa68883f..5b623811ed 100644 --- a/tools/sk_app/MetalWindowContext.mm +++ b/tools/sk_app/MetalWindowContext.mm @@ -24,8 +24,8 @@ namespace sk_app { MetalWindowContext::MetalWindowContext(const DisplayParams& params) : WindowContext(params) - , fValid(false) { - + , fValid(false) + , fDrawableHandle(nil) { fDisplayParams.fMSAASampleCount = GrNextPow2(fDisplayParams.fMSAASampleCount); } @@ -39,12 +39,12 @@ NSURL* MetalWindowContext::CacheURL() { 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 @@ void MetalWindowContext::initializeContext() { #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 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 @@ void MetalWindowContext::initializeContext() { #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 @@ void MetalWindowContext::destroyContext() { [fPipelineArchive release]; } #endif - [fQueue release]; - [fDevice release]; + fQueue.reset(); + fDevice.reset(); } sk_sp MetalWindowContext::getBackbufferSurface() { @@ -156,7 +155,7 @@ sk_sp MetalWindowContext::getBackbufferSurface() { void MetalWindowContext::swapBuffers() { id currentDrawable = (id)fDrawableHandle; - id commandBuffer = [fQueue commandBuffer]; + id 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 b8cee033b0..ec525c2552 100644 --- a/tools/sk_app/ios/MetalWindowContext_ios.mm +++ b/tools/sk_app/ios/MetalWindowContext_ios.mm @@ -71,7 +71,7 @@ bool MetalWindowContext_ios::onInitializeContext() { [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 305da2bdf6..5bea8578fa 100644 --- a/tools/sk_app/mac/MetalWindowContext_mac.mm +++ b/tools/sk_app/mac/MetalWindowContext_mac.mm @@ -52,7 +52,7 @@ bool MetalWindowContext_mac::onInitializeContext() { 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.