1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrMtlTexture_DEFINED 9 #define GrMtlTexture_DEFINED 10 11 #include "GrTexture.h" 12 13 #import <Metal/Metal.h> 14 15 class GrMtlGpu; 16 17 class GrMtlTexture : public GrTexture { 18 public: 19 static sk_sp<GrMtlTexture> CreateNewTexture(GrMtlGpu*, SkBudgeted budgeted, 20 const GrSurfaceDesc&, 21 MTLTextureDescriptor*, 22 GrMipMapsStatus); 23 24 static sk_sp<GrMtlTexture> MakeWrappedTexture(GrMtlGpu*, const GrSurfaceDesc&, id<MTLTexture>, 25 GrWrapCacheable, GrIOType); 26 27 ~GrMtlTexture() override; 28 mtlTexture()29 id<MTLTexture> mtlTexture() const { return fTexture; } 30 31 GrBackendTexture getBackendTexture() const override; 32 33 GrBackendFormat backendFormat() const override; 34 textureParamsModified()35 void textureParamsModified() override {} 36 37 bool reallocForMipmap(GrMtlGpu* gpu, uint32_t mipLevels); 38 setRelease(sk_sp<GrReleaseProcHelper> releaseHelper)39 void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) override { 40 // Since all MTLResources are inherently ref counted, we can call the Release proc when we 41 // delete the GrMtlTexture without worry of the MTLTexture getting deleted before it is done 42 // on the GPU. 43 fReleaseHelper = std::move(releaseHelper); 44 } 45 setIdleProc(IdleProc proc,void * context)46 void setIdleProc(IdleProc proc, void* context) override { 47 fIdleProc = proc; 48 fIdleProcContext = context; 49 } idleContext()50 void* idleContext() const override { return fIdleProcContext; } 51 52 protected: 53 GrMtlTexture(GrMtlGpu*, const GrSurfaceDesc&, id<MTLTexture>, GrMipMapsStatus); 54 55 GrMtlGpu* getMtlGpu() const; 56 onAbandon()57 void onAbandon() override { 58 this->invokeReleaseProc(); 59 fTexture = nil; 60 } onRelease()61 void onRelease() override { 62 this->invokeReleaseProc(); 63 fTexture = nil; 64 } 65 onStealBackendTexture(GrBackendTexture *,SkImage::BackendTextureReleaseProc *)66 bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) override { 67 return false; 68 } 69 70 private: 71 enum Wrapped { kWrapped }; 72 invokeReleaseProc()73 void invokeReleaseProc() { 74 // Depending on the ref count of fReleaseHelper this may or may not actually trigger the 75 // ReleaseProc to be called. 76 fReleaseHelper.reset(); 77 } 78 removedLastRefOrPendingIO()79 void removedLastRefOrPendingIO() override { 80 if (fIdleProc) { 81 fIdleProc(fIdleProcContext); 82 fIdleProc = nullptr; 83 fIdleProcContext = nullptr; 84 } 85 } 86 87 GrMtlTexture(GrMtlGpu*, SkBudgeted, const GrSurfaceDesc&, id<MTLTexture>, 88 GrMipMapsStatus); 89 90 GrMtlTexture(GrMtlGpu*, Wrapped, const GrSurfaceDesc&, id<MTLTexture>, GrMipMapsStatus, 91 GrWrapCacheable, GrIOType); 92 93 id<MTLTexture> fTexture; 94 sk_sp<GrReleaseProcHelper> fReleaseHelper; 95 IdleProc* fIdleProc = nullptr; 96 void* fIdleProcContext = nullptr; 97 98 typedef GrTexture INHERITED; 99 }; 100 101 #endif 102