Change GrCFResource to sk_cf_obj and move to include/ports.
This makes GrCFResource a template class with similar semantics to sk_sp. Change-Id: I9ae9988dac6b39477b16d65591ef6fff44903c36 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/218376 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
parent
40d9c5162f
commit
8429422986
@ -9,8 +9,7 @@
|
||||
#define GrMtlTypes_DEFINED
|
||||
|
||||
#include "include/gpu/GrTypes.h"
|
||||
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#include "include/ports/SkCFObject.h"
|
||||
|
||||
/**
|
||||
* Declares typedefs for Metal types used in Ganesh cpp code
|
||||
@ -19,72 +18,6 @@ typedef unsigned int GrMTLPixelFormat;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Wrapper class for managing lifetime of CoreFoundation objects. It will call
|
||||
* CFRetain and CFRelease appropriately on creation, assignment, and deletion.
|
||||
*/
|
||||
class GrCFResource {
|
||||
public:
|
||||
GrCFResource() : fCFObject(nullptr) {}
|
||||
explicit GrCFResource(const void* resource) {
|
||||
fCFObject = resource;
|
||||
if (fCFObject) {
|
||||
CFRetain(fCFObject);
|
||||
}
|
||||
}
|
||||
GrCFResource(const GrCFResource& that) {
|
||||
fCFObject = that.fCFObject;
|
||||
if (fCFObject) {
|
||||
CFRetain(fCFObject);
|
||||
}
|
||||
}
|
||||
~GrCFResource() {
|
||||
if (fCFObject) {
|
||||
CFRelease(fCFObject);
|
||||
}
|
||||
fCFObject = nullptr;
|
||||
}
|
||||
|
||||
GrCFResource& operator=(const void* resource) {
|
||||
this->assign(resource);
|
||||
return *this;
|
||||
}
|
||||
GrCFResource& operator=(const GrCFResource& that) {
|
||||
this->assign(that.fCFObject);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const void* get() const { return fCFObject; }
|
||||
|
||||
/* Explicitly retains ownership of the object rather than transferring it.
|
||||
* For translating from other shared_ptr/unique_ptr classes that wish to
|
||||
* maintain their own ownership.
|
||||
*/
|
||||
void retain(const void* resource) {
|
||||
this->assign(resource);
|
||||
}
|
||||
|
||||
bool operator==(const GrCFResource& that) const {
|
||||
return this->fCFObject == that.fCFObject;
|
||||
}
|
||||
bool operator!=(const GrCFResource& that) const {
|
||||
return this->fCFObject != that.fCFObject;
|
||||
}
|
||||
|
||||
private:
|
||||
void assign(const void* resource) {
|
||||
if (resource) {
|
||||
CFRetain(resource);
|
||||
}
|
||||
if (fCFObject) {
|
||||
CFRelease(fCFObject);
|
||||
}
|
||||
fCFObject = resource;
|
||||
}
|
||||
|
||||
const void* fCFObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* Types for interacting with Metal resources created externally to Skia.
|
||||
* This is used by GrBackendObjects.
|
||||
@ -93,7 +26,7 @@ struct GrMtlTextureInfo {
|
||||
public:
|
||||
GrMtlTextureInfo() {}
|
||||
|
||||
GrCFResource fTexture;
|
||||
sk_cf_obj<const void*> fTexture;
|
||||
|
||||
bool operator==(const GrMtlTextureInfo& that) const {
|
||||
return fTexture == that.fTexture;
|
||||
|
138
include/ports/SkCFObject.h
Normal file
138
include/ports/SkCFObject.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkCFObject_DEFINED
|
||||
#define SkCFObject_DEFINED
|
||||
|
||||
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
|
||||
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
/**
|
||||
* Wrapper class for managing lifetime of CoreFoundation objects. It will call
|
||||
* CFRetain and CFRelease appropriately on creation, assignment, and deletion.
|
||||
* Based on sk_sp<>.
|
||||
*/
|
||||
template <typename T> static inline T SkCFSafeRetain(T obj) {
|
||||
if (obj) {
|
||||
CFRetain(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
template <typename T> static inline void SkCFSafeRelease(T obj) {
|
||||
if (obj) {
|
||||
CFRelease(obj);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> class sk_cf_obj {
|
||||
public:
|
||||
using element_type = T;
|
||||
|
||||
constexpr sk_cf_obj() : fObject(nullptr) {}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
sk_cf_obj(const sk_cf_obj<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.
|
||||
* No call to CFRetain() or CFRelease() will be made.
|
||||
*/
|
||||
sk_cf_obj(sk_cf_obj<T>&& that) : fObject(that.release()) {}
|
||||
|
||||
/**
|
||||
* Adopt the bare object into the newly created sk_cf_obj.
|
||||
* No call to CFRetain() or CFRelease() will be made.
|
||||
*/
|
||||
explicit sk_cf_obj(T obj) {
|
||||
fObject = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls CFRelease() on the underlying object pointer.
|
||||
*/
|
||||
~sk_cf_obj() {
|
||||
SkCFSafeRelease(fObject);
|
||||
SkDEBUGCODE(fObject = nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
* on that object.
|
||||
*/
|
||||
sk_cf_obj<T>& operator=(const sk_cf_obj<T>& that) {
|
||||
if (this != &that) {
|
||||
this->reset(SkCFSafeRetain(that.get()));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the underlying object from the argument to the sk_cf_obj. If the sk_cf_obj
|
||||
* 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) {
|
||||
this->reset(that.release());
|
||||
return *this;
|
||||
}
|
||||
|
||||
T get() const { return fObject; }
|
||||
|
||||
/**
|
||||
* Adopt the new object, and call CFRelease() on any previously held object (if not null).
|
||||
* No call to CFRetain() will be made.
|
||||
*/
|
||||
void reset(T object = nullptr) {
|
||||
T oldObject = fObject;
|
||||
fObject = object;
|
||||
SkCFSafeRelease(oldObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shares the new object 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() on that object.
|
||||
*/
|
||||
void retain(T object) {
|
||||
if (this->fObject != object) {
|
||||
this->reset(SkCFSafeRetain(object));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the original object, and set the internal object to nullptr.
|
||||
* The caller must assume ownership of the object, and manage its reference count directly.
|
||||
* No call to CFRelease() will be made.
|
||||
*/
|
||||
T SK_WARN_UNUSED_RESULT release() {
|
||||
T obj = fObject;
|
||||
fObject = nullptr;
|
||||
return obj;
|
||||
}
|
||||
|
||||
private:
|
||||
T fObject;
|
||||
};
|
||||
|
||||
template <typename T> inline bool operator==(const sk_cf_obj<T>& a,
|
||||
const sk_cf_obj<T>& b) {
|
||||
return a.get() == b.get();
|
||||
}
|
||||
|
||||
template <typename T> inline bool operator!=(const sk_cf_obj<T>& a,
|
||||
const sk_cf_obj<T>& b) {
|
||||
return a.get() != b.get();
|
||||
}
|
||||
|
||||
#endif // SK_BUILD_FOR_MAC || SK_BUILD_FOR_IOS
|
||||
#endif // SkCFOBject_DEFINED
|
@ -690,7 +690,7 @@ bool GrMtlGpu::createTestingOnlyMtlTextureInfo(GrPixelConfig config, MTLPixelFor
|
||||
[cmdBuffer waitUntilCompleted];
|
||||
transferBuffer = nil;
|
||||
|
||||
info->fTexture = GrGetPtrFromId(testTexture);
|
||||
info->fTexture.reset(GrRetainPtrFromId(testTexture));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ GrMtlRenderTarget::~GrMtlRenderTarget() {
|
||||
|
||||
GrBackendRenderTarget GrMtlRenderTarget::getBackendRenderTarget() const {
|
||||
GrMtlTextureInfo info;
|
||||
info.fTexture = GrGetPtrFromId(fRenderTexture);
|
||||
info.fTexture.reset(GrRetainPtrFromId(fRenderTexture));
|
||||
return GrBackendRenderTarget(this->width(), this->height(), fRenderTexture.sampleCount, info);
|
||||
}
|
||||
|
||||
|
@ -98,7 +98,7 @@ GrBackendTexture GrMtlTexture::getBackendTexture() const {
|
||||
GrMipMapped mipMapped = fTexture.mipmapLevelCount > 1 ? GrMipMapped::kYes
|
||||
: GrMipMapped::kNo;
|
||||
GrMtlTextureInfo info;
|
||||
info.fTexture = GrGetPtrFromId(fTexture);
|
||||
info.fTexture.reset(GrRetainPtrFromId(fTexture));
|
||||
return GrBackendTexture(this->width(), this->height(), mipMapped, info);
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,15 @@ SK_ALWAYS_INLINE const void* GrGetPtrFromId(id idObject) {
|
||||
return (__bridge const void*)idObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a const void* to whatever the id object is pointing to.
|
||||
* Will call CFRetain on the object.
|
||||
*/
|
||||
SK_ALWAYS_INLINE const void* GrRetainPtrFromId(id idObject) {
|
||||
return (__bridge_retained const void*)idObject;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a MTLTextureDescriptor which describes the MTLTexture. Useful when creating a duplicate
|
||||
* MTLTexture without the same storage allocation.
|
||||
|
@ -84,7 +84,7 @@ sk_sp<SkSurface> MetalWindowContext::getBackbufferSurface() {
|
||||
fCurrentDrawable = [fMetalLayer nextDrawable];
|
||||
|
||||
GrMtlTextureInfo fbInfo;
|
||||
fbInfo.fTexture = fCurrentDrawable.texture;
|
||||
fbInfo.fTexture.reset(CFRetain((__bridge const void*)(fCurrentDrawable.texture)));
|
||||
|
||||
GrBackendRenderTarget backendRT(fWidth,
|
||||
fHeight,
|
||||
|
Loading…
Reference in New Issue
Block a user