aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Timothy Liang <timliang@google.com>2018-07-02 16:03:28 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-07-02 20:57:57 +0000
commite886e80e8b204460a78dabf5c671b7f4146d71f7 (patch)
treebec7b602ec3855000e8d64fe8e3e6025ca7578d1
parent389abd50fe74c54a11430f5457d2278cda391132 (diff)
implemented wrapped backend texture/rendertarget/textureRT for Metal gpu backend
Bug: skia: Change-Id: I5d84f9f4340023301bf119731d0b544649be7ab0 Reviewed-on: https://skia-review.googlesource.com/137892 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Timothy Liang <timliang@google.com>
-rw-r--r--src/gpu/mtl/GrMtlGpu.h16
-rw-r--r--src/gpu/mtl/GrMtlGpu.mm106
-rw-r--r--src/gpu/mtl/GrMtlRenderTarget.h19
-rw-r--r--src/gpu/mtl/GrMtlRenderTarget.mm49
-rw-r--r--src/gpu/mtl/GrMtlTexture.h8
-rw-r--r--src/gpu/mtl/GrMtlTexture.mm37
-rw-r--r--src/gpu/mtl/GrMtlTextureRenderTarget.h2
-rw-r--r--src/gpu/mtl/GrMtlTextureRenderTarget.mm23
-rw-r--r--src/gpu/mtl/GrMtlUtil.h5
-rw-r--r--src/gpu/mtl/GrMtlUtil.mm4
10 files changed, 197 insertions, 72 deletions
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index b230ef73d7..22fc733217 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -73,24 +73,16 @@ private:
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
const GrMipLevel texels[], int mipLevelCount) override;
- sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) override {
- return nullptr;
- }
+ sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) override;
sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
int sampleCnt,
- GrWrapOwnership) override {
- return nullptr;
- }
+ GrWrapOwnership) override;
- sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override {
- return nullptr;
- }
+ sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&) override;
sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&,
- int sampleCnt) override {
- return nullptr;
- }
+ int sampleCnt) override;
GrBuffer* onCreateBuffer(size_t, GrBufferType, GrAccessPattern, const void*) override {
return nullptr;
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index 149e56220e..42b0739548 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -8,6 +8,8 @@
#include "GrMtlGpu.h"
#include "GrMtlTexture.h"
+#include "GrMtlTextureRenderTarget.h"
+#include "GrMtlUtil.h"
#if !__has_feature(objc_arc)
#error This file must be compiled with Arc. Use -fobjc-arc flag
@@ -115,18 +117,11 @@ sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted
}
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
- if (renderTarget) {
- // Current we don't have render target support
- return nullptr;
- }
sk_sp<GrMtlTexture> tex;
if (renderTarget) {
- // Enable once we have render target support
-#if 0
tex = GrMtlTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted,
- desc, mipLevels);
-#endif
+ desc, mipLevels);
} else {
tex = GrMtlTexture::CreateNewTexture(this, budgeted, desc, mipLevels);
}
@@ -144,3 +139,98 @@ sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted
}
return tex;
}
+
+static id<MTLTexture> get_texture_from_backend(const GrBackendTexture& backendTex,
+ GrWrapOwnership ownership) {
+ GrMtlTextureInfo textureInfo;
+ if (!backendTex.getMtlTextureInfo(&textureInfo)) {
+ return nil;
+ }
+ return GrGetMTLTexture(textureInfo.fTexture, ownership);
+}
+
+static id<MTLTexture> get_texture_from_backend(const GrBackendRenderTarget& backendRT) {
+ GrMtlTextureInfo textureInfo;
+ if (!backendRT.getMtlTextureInfo(&textureInfo)) {
+ return nil;
+ }
+ return GrGetMTLTexture(textureInfo.fTexture, GrWrapOwnership::kBorrow_GrWrapOwnership);
+}
+
+static inline void init_surface_desc(GrSurfaceDesc* surfaceDesc, id<MTLTexture> mtlTexture,
+ bool isRenderTarget, GrPixelConfig config) {
+ if (isRenderTarget) {
+ SkASSERT(MTLTextureUsageRenderTarget & mtlTexture.usage);
+ }
+ surfaceDesc->fFlags = isRenderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
+ surfaceDesc->fWidth = mtlTexture.width;
+ surfaceDesc->fHeight = mtlTexture.height;
+ surfaceDesc->fConfig = config;
+ surfaceDesc->fSampleCnt = 1;
+}
+
+sk_sp<GrTexture> GrMtlGpu::onWrapBackendTexture(const GrBackendTexture& backendTex,
+ GrWrapOwnership ownership) {
+ id<MTLTexture> mtlTexture = get_texture_from_backend(backendTex, ownership);
+ if (!mtlTexture) {
+ return nullptr;
+ }
+
+ GrSurfaceDesc surfDesc;
+ init_surface_desc(&surfDesc, mtlTexture, false, backendTex.config());
+
+ return GrMtlTexture::MakeWrappedTexture(this, surfDesc, mtlTexture);
+}
+
+sk_sp<GrTexture> GrMtlGpu::onWrapRenderableBackendTexture(const GrBackendTexture& backendTex,
+ int sampleCnt,
+ GrWrapOwnership ownership) {
+ id<MTLTexture> mtlTexture = get_texture_from_backend(backendTex, ownership);
+ if (!mtlTexture) {
+ return nullptr;
+ }
+
+ GrSurfaceDesc surfDesc;
+ init_surface_desc(&surfDesc, mtlTexture, true, backendTex.config());
+ surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, surfDesc.fConfig);
+ if (!surfDesc.fSampleCnt) {
+ return nullptr;
+ }
+
+ return GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(this, surfDesc, mtlTexture);
+}
+
+sk_sp<GrRenderTarget> GrMtlGpu::onWrapBackendRenderTarget(const GrBackendRenderTarget& backendRT) {
+ // TODO: Revisit this when the Metal backend is completed. It may support MSAA render targets.
+ if (backendRT.sampleCnt() > 1) {
+ return nullptr;
+ }
+ id<MTLTexture> mtlTexture = get_texture_from_backend(backendRT);
+ if (!mtlTexture) {
+ return nullptr;
+ }
+
+ GrSurfaceDesc surfDesc;
+ init_surface_desc(&surfDesc, mtlTexture, true, backendRT.config());
+
+ return GrMtlRenderTarget::MakeWrappedRenderTarget(this, surfDesc, mtlTexture);
+}
+
+sk_sp<GrRenderTarget> GrMtlGpu::onWrapBackendTextureAsRenderTarget(
+ const GrBackendTexture& backendTex, int sampleCnt) {
+ id<MTLTexture> mtlTexture = get_texture_from_backend(backendTex,
+ GrWrapOwnership::kBorrow_GrWrapOwnership);
+ if (!mtlTexture) {
+ return nullptr;
+ }
+
+ GrSurfaceDesc surfDesc;
+ init_surface_desc(&surfDesc, mtlTexture, true, backendTex.config());
+ surfDesc.fSampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, surfDesc.fConfig);
+ if (!surfDesc.fSampleCnt) {
+ return nullptr;
+ }
+
+ return GrMtlRenderTarget::MakeWrappedRenderTarget(this, surfDesc, mtlTexture);
+}
+
diff --git a/src/gpu/mtl/GrMtlRenderTarget.h b/src/gpu/mtl/GrMtlRenderTarget.h
index c0f0cf57e1..02b0a61a0d 100644
--- a/src/gpu/mtl/GrMtlRenderTarget.h
+++ b/src/gpu/mtl/GrMtlRenderTarget.h
@@ -18,10 +18,9 @@ class GrMtlGpu;
class GrMtlRenderTarget: public GrRenderTarget {
public:
- static sk_sp<GrMtlRenderTarget> CreateNewRenderTarget(GrMtlGpu*, const GrSurfaceDesc&,
- SkBudgeted);
-
- static sk_sp<GrMtlRenderTarget> MakeWrappedRenderTarget(GrMtlGpu*, const GrSurfaceDesc&);
+ static sk_sp<GrMtlRenderTarget> MakeWrappedRenderTarget(GrMtlGpu*,
+ const GrSurfaceDesc&,
+ id<MTLTexture>);
~GrMtlRenderTarget() override;
@@ -40,9 +39,7 @@ public:
return true;
}
- GrBackendRenderTarget getBackendRenderTarget() const override {
- return GrBackendRenderTarget(); // invalid
- }
+ GrBackendRenderTarget getBackendRenderTarget() const override;
protected:
GrMtlRenderTarget(GrMtlGpu* gpu,
@@ -62,6 +59,8 @@ protected:
// This accounts for the texture's memory and any MSAA renderbuffer's memory.
size_t onGpuMemorySize() const override {
int numColorSamples = this->numColorSamples();
+ // TODO: When used as render targets certain formats may actually have a larger size than
+ // the base format size. Check to make sure we are reporting the correct value here.
// The plus 1 is to account for the resolve texture or if not using msaa the RT itself
if (numColorSamples > 1) {
++numColorSamples;
@@ -75,19 +74,19 @@ protected:
private:
GrMtlRenderTarget(GrMtlGpu* gpu,
- const GrSurfaceDesc& desc,
SkBudgeted,
+ const GrSurfaceDesc& desc,
id<MTLTexture> renderTexture,
id<MTLTexture> resolveTexture);
GrMtlRenderTarget(GrMtlGpu* gpu,
- const GrSurfaceDesc& desc,
SkBudgeted,
+ const GrSurfaceDesc& desc,
id<MTLTexture> renderTexture);
static sk_sp<GrMtlRenderTarget> Make(GrMtlGpu*,
- const GrSurfaceDesc&,
SkBudgeted,
+ const GrSurfaceDesc&,
id<MTLTexture> renderTexture,
bool isWrapped);
diff --git a/src/gpu/mtl/GrMtlRenderTarget.mm b/src/gpu/mtl/GrMtlRenderTarget.mm
index 32d612861e..2bf4ae2e18 100644
--- a/src/gpu/mtl/GrMtlRenderTarget.mm
+++ b/src/gpu/mtl/GrMtlRenderTarget.mm
@@ -11,8 +11,8 @@
#include "GrMtlUtil.h"
GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
- const GrSurfaceDesc& desc,
SkBudgeted budgeted,
+ const GrSurfaceDesc& desc,
id<MTLTexture> renderTexture)
: GrSurface(gpu, desc)
, GrRenderTarget(gpu, desc)
@@ -32,37 +32,14 @@ GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
SkASSERT(1 == desc.fSampleCnt);
}
-sk_sp<GrMtlRenderTarget> GrMtlRenderTarget::CreateNewRenderTarget(GrMtlGpu* gpu,
- const GrSurfaceDesc& desc,
- SkBudgeted budgeted) {
- MTLPixelFormat format;
- if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) {
- return nullptr;
- }
-
- if (desc.fSampleCnt) {
- return nullptr;
- }
-
- MTLTextureDescriptor* descriptor = [[MTLTextureDescriptor alloc] init];
- descriptor.textureType = MTLTextureType2D;
- descriptor.pixelFormat = format;
- descriptor.width = desc.fWidth;
- descriptor.height = desc.fHeight;
- descriptor.depth = 1;
- descriptor.mipmapLevelCount = 1;
- descriptor.sampleCount = 1;
- descriptor.arrayLength = 1;
- // descriptor.resourceOptions This looks to be set by setting cpuCacheMode and storageModes
- descriptor.cpuCacheMode = MTLCPUCacheModeWriteCombined;
- // RenderTargets never need to be mapped so their storage mode is set to private
- descriptor.storageMode = MTLStorageModePrivate;
-
- descriptor.usage = MTLTextureUsageRenderTarget;
-
- id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:descriptor];
-
- return sk_sp<GrMtlRenderTarget>(new GrMtlRenderTarget(gpu, desc, budgeted, texture));
+sk_sp<GrMtlRenderTarget>
+GrMtlRenderTarget::MakeWrappedRenderTarget(GrMtlGpu* gpu, const GrSurfaceDesc& desc,
+ id<MTLTexture> renderTexture) {
+ SkASSERT(nil != renderTexture);
+ SkASSERT(1 == renderTexture.mipmapLevelCount);
+ SkASSERT(MTLTextureUsageRenderTarget & renderTexture.usage);
+ return sk_sp<GrMtlRenderTarget>(new GrMtlRenderTarget(gpu, SkBudgeted::kNo,
+ desc, renderTexture));
}
GrMtlRenderTarget::~GrMtlRenderTarget() {
@@ -70,6 +47,13 @@ GrMtlRenderTarget::~GrMtlRenderTarget() {
SkASSERT(nil == fResolveTexture);
}
+
+GrBackendRenderTarget GrMtlRenderTarget::getBackendRenderTarget() const {
+ GrMtlTextureInfo info;
+ info.fTexture = GrGetPtrFromId(fRenderTexture);
+ return GrBackendRenderTarget(this->width(), this->height(), fRenderTexture.sampleCount, info);
+}
+
GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const {
SkASSERT(!this->wasDestroyed());
return static_cast<GrMtlGpu*>(this->getGpu());
@@ -90,4 +74,3 @@ bool GrMtlRenderTarget::completeStencilAttachment() {
return true;
}
-
diff --git a/src/gpu/mtl/GrMtlTexture.h b/src/gpu/mtl/GrMtlTexture.h
index 57a7ee5d71..99fb27d6a5 100644
--- a/src/gpu/mtl/GrMtlTexture.h
+++ b/src/gpu/mtl/GrMtlTexture.h
@@ -20,7 +20,7 @@ public:
const GrSurfaceDesc&, int mipLevels);
static sk_sp<GrMtlTexture> MakeWrappedTexture(GrMtlGpu*, const GrSurfaceDesc&,
- GrWrapOwnership);
+ id<MTLTexture>);
~GrMtlTexture() override;
@@ -57,8 +57,10 @@ protected:
private:
enum Wrapped { kWrapped };
- GrMtlTexture(GrMtlGpu*, SkBudgeted, const GrSurfaceDesc&, id<MTLTexture>, GrMipMapsStatus);
- // GrMtlTexture(GrMtlGpu*, Wrapped, const GrSurfaceDesc&, GrMtlImage::Wrapped wrapped);
+ GrMtlTexture(GrMtlGpu*, SkBudgeted, const GrSurfaceDesc&, id<MTLTexture>,
+ GrMipMapsStatus);
+
+ GrMtlTexture(GrMtlGpu*, Wrapped, const GrSurfaceDesc&, id<MTLTexture>, GrMipMapsStatus);
id<MTLTexture> fTexture;
diff --git a/src/gpu/mtl/GrMtlTexture.mm b/src/gpu/mtl/GrMtlTexture.mm
index 90bfcb38fb..87ee28b206 100644
--- a/src/gpu/mtl/GrMtlTexture.mm
+++ b/src/gpu/mtl/GrMtlTexture.mm
@@ -30,6 +30,19 @@ GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
}
GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
+ Wrapped,
+ const GrSurfaceDesc& desc,
+ id<MTLTexture> texture,
+ GrMipMapsStatus mipMapsStatus)
+ : GrSurface(gpu, desc)
+ , INHERITED(gpu, desc, kTexture2DSampler_GrSLType, highest_filter_mode(desc.fConfig),
+ mipMapsStatus)
+ , fTexture(texture) {
+ SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == texture.mipmapLevelCount));
+ this->registerWithCacheWrapped();
+}
+
+GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
const GrSurfaceDesc& desc,
id<MTLTexture> texture,
GrMipMapsStatus mipMapsStatus)
@@ -47,6 +60,11 @@ sk_sp<GrMtlTexture> GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted bud
return nullptr;
}
+ if (desc.fSampleCnt > 1) {
+ SkASSERT(false); // Currently we don't support msaa
+ return nullptr;
+ }
+
MTLTextureDescriptor* descriptor = [[MTLTextureDescriptor alloc] init];
descriptor.textureType = MTLTextureType2D;
descriptor.pixelFormat = format;
@@ -58,7 +76,7 @@ sk_sp<GrMtlTexture> GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted bud
descriptor.arrayLength = 1;
// descriptor.resourceOptions This looks to be set by setting cpuCacheMode and storageModes
descriptor.cpuCacheMode = MTLCPUCacheModeWriteCombined;
- // Shared is not available on MacOS. Is there a reason to want managed to allow mapping?
+ // Make all textures have private gpu only access. We can use transfer buffers to copy to them.
descriptor.storageMode = MTLStorageModePrivate;
descriptor.usage = MTLTextureUsageShaderRead;
@@ -70,6 +88,16 @@ sk_sp<GrMtlTexture> GrMtlTexture::CreateNewTexture(GrMtlGpu* gpu, SkBudgeted bud
return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, desc, texture, mipMapsStatus));
}
+sk_sp<GrMtlTexture> GrMtlTexture::MakeWrappedTexture(GrMtlGpu* gpu,
+ const GrSurfaceDesc& desc,
+ id<MTLTexture> texture) {
+ SkASSERT(nil != texture);
+ SkASSERT(MTLTextureUsageShaderRead & texture.usage);
+ GrMipMapsStatus mipMapsStatus = texture.mipmapLevelCount > 1 ? GrMipMapsStatus::kValid
+ : GrMipMapsStatus::kNotAllocated;
+ return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, kWrapped, desc, texture, mipMapsStatus));
+}
+
GrMtlTexture::~GrMtlTexture() {
SkASSERT(nil == fTexture);
}
@@ -80,5 +108,10 @@ GrMtlGpu* GrMtlTexture::getMtlGpu() const {
}
GrBackendTexture GrMtlTexture::getBackendTexture() const {
- return GrBackendTexture(); // invalid
+ GrMipMapped mipMapped = fTexture.mipmapLevelCount > 1 ? GrMipMapped::kYes
+ : GrMipMapped::kNo;
+ GrMtlTextureInfo info;
+ info.fTexture = GrGetPtrFromId(fTexture);
+ return GrBackendTexture(this->width(), this->height(), mipMapped, info);
}
+
diff --git a/src/gpu/mtl/GrMtlTextureRenderTarget.h b/src/gpu/mtl/GrMtlTextureRenderTarget.h
index 5137dd0736..74b682a9ec 100644
--- a/src/gpu/mtl/GrMtlTextureRenderTarget.h
+++ b/src/gpu/mtl/GrMtlTextureRenderTarget.h
@@ -20,7 +20,7 @@ public:
static sk_sp<GrMtlTextureRenderTarget> MakeWrappedTextureRenderTarget(GrMtlGpu*,
const GrSurfaceDesc&,
- GrWrapOwnership);
+ id<MTLTexture>);
protected:
void onAbandon() override {
diff --git a/src/gpu/mtl/GrMtlTextureRenderTarget.mm b/src/gpu/mtl/GrMtlTextureRenderTarget.mm
index 99d1c9e358..c1b36dea83 100644
--- a/src/gpu/mtl/GrMtlTextureRenderTarget.mm
+++ b/src/gpu/mtl/GrMtlTextureRenderTarget.mm
@@ -20,6 +20,16 @@ GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
this->registerWithCache(budgeted);
}
+GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
+ const GrSurfaceDesc& desc,
+ id<MTLTexture> renderTexture,
+ GrMipMapsStatus mipMapsStatus)
+ : GrSurface(gpu, desc)
+ , GrMtlTexture(gpu, desc, renderTexture, mipMapsStatus)
+ , GrMtlRenderTarget(gpu, desc, renderTexture) {
+ this->registerWithCacheWrapped();
+}
+
sk_sp<GrMtlTextureRenderTarget>
GrMtlTextureRenderTarget::Make(GrMtlGpu* gpu,
const GrSurfaceDesc& desc,
@@ -41,7 +51,10 @@ GrMtlTextureRenderTarget::Make(GrMtlGpu* gpu,
renderTexture,
mipMapsStatus));
} else {
- return nullptr; // Currently don't support wrapped TextureRenderTargets
+ return sk_sp<GrMtlTextureRenderTarget>(new GrMtlTextureRenderTarget(gpu,
+ desc,
+ renderTexture,
+ mipMapsStatus));
}
}
@@ -80,6 +93,10 @@ GrMtlTextureRenderTarget::CreateNewTextureRenderTarget(GrMtlGpu* gpu,
sk_sp<GrMtlTextureRenderTarget>
GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(GrMtlGpu* gpu,
const GrSurfaceDesc& desc,
- GrWrapOwnership wrapOwnership) {
- return nullptr;
+ id<MTLTexture> texture) {
+
+ SkASSERT(nil != texture);
+ SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & texture.usage);
+ return Make(gpu, desc, texture, texture.mipmapLevelCount, SkBudgeted::kNo, true);
}
+
diff --git a/src/gpu/mtl/GrMtlUtil.h b/src/gpu/mtl/GrMtlUtil.h
index 656b65cd6d..932ebec2b5 100644
--- a/src/gpu/mtl/GrMtlUtil.h
+++ b/src/gpu/mtl/GrMtlUtil.h
@@ -29,4 +29,9 @@ GrPixelConfig GrMTLFormatToPixelConfig(MTLPixelFormat format);
*/
id<MTLTexture> GrGetMTLTexture(const void* mtlTexture, GrWrapOwnership);
+/**
+ * Returns a const void* to whatever the id object is pointing to. Always uses __bridge.
+ */
+const void* GrGetPtrFromId(id idObject);
+
#endif
diff --git a/src/gpu/mtl/GrMtlUtil.mm b/src/gpu/mtl/GrMtlUtil.mm
index 3bd3b280a5..c9766597e8 100644
--- a/src/gpu/mtl/GrMtlUtil.mm
+++ b/src/gpu/mtl/GrMtlUtil.mm
@@ -122,3 +122,7 @@ id<MTLTexture> GrGetMTLTexture(const void* mtlTexture, GrWrapOwnership wrapOwner
}
}
+const void* GrGetPtrFromId(id idObject) {
+ return (__bridge const void*)idObject;
+}
+