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#include "src/gpu/mtl/GrMtlTexture.h" 9 10#include "src/gpu/GrTexturePriv.h" 11#include "src/gpu/mtl/GrMtlGpu.h" 12#include "src/gpu/mtl/GrMtlUtil.h" 13 14#if !__has_feature(objc_arc) 15#error This file must be compiled with Arc. Use -fobjc-arc flag 16#endif 17 18GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 19 SkBudgeted budgeted, 20 const GrSurfaceDesc& desc, 21 id<MTLTexture> texture, 22 GrMipMapsStatus mipMapsStatus) 23 : GrSurface(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo) 24 , INHERITED(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo, 25 GrTextureType::k2D, mipMapsStatus) 26 , fTexture(texture) { 27 SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == texture.mipmapLevelCount)); 28 this->registerWithCache(budgeted); 29} 30 31GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 32 Wrapped, 33 const GrSurfaceDesc& desc, 34 id<MTLTexture> texture, 35 GrMipMapsStatus mipMapsStatus, 36 GrWrapCacheable cacheable, 37 GrIOType ioType) 38 : GrSurface(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo) 39 , INHERITED(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo, 40 GrTextureType::k2D, mipMapsStatus) 41 , fTexture(texture) { 42 SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == texture.mipmapLevelCount)); 43 if (ioType == kRead_GrIOType) { 44 this->setReadOnly(); 45 } 46 this->registerWithCacheWrapped(cacheable); 47} 48 49GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 50 const GrSurfaceDesc& desc, 51 id<MTLTexture> texture, 52 GrMipMapsStatus mipMapsStatus) 53 : GrSurface(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo) 54 , INHERITED(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo, 55 GrTextureType::k2D, mipMapsStatus) 56 , fTexture(texture) { 57 SkASSERT((GrMipMapsStatus::kNotAllocated == mipMapsStatus) == (1 == texture.mipmapLevelCount)); 58} 59 60sk_sp<GrMtlTexture> GrMtlTexture::MakeNewTexture(GrMtlGpu* gpu, SkBudgeted budgeted, 61 const GrSurfaceDesc& desc, 62 MTLTextureDescriptor* texDesc, 63 GrMipMapsStatus mipMapsStatus) { 64 id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:texDesc]; 65 if (!texture) { 66 return nullptr; 67 } 68 SkASSERT(MTLTextureUsageShaderRead & texture.usage); 69 return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, desc, texture, mipMapsStatus)); 70} 71 72sk_sp<GrMtlTexture> GrMtlTexture::MakeWrappedTexture(GrMtlGpu* gpu, 73 const GrSurfaceDesc& desc, 74 id<MTLTexture> texture, 75 GrWrapCacheable cacheable, 76 GrIOType ioType) { 77 SkASSERT(nil != texture); 78 SkASSERT(MTLTextureUsageShaderRead & texture.usage); 79 GrMipMapsStatus mipMapsStatus = texture.mipmapLevelCount > 1 ? GrMipMapsStatus::kValid 80 : GrMipMapsStatus::kNotAllocated; 81 return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, kWrapped, desc, texture, mipMapsStatus, 82 cacheable, ioType)); 83} 84 85GrMtlTexture::~GrMtlTexture() { 86 SkASSERT(nil == fTexture); 87} 88 89GrMtlGpu* GrMtlTexture::getMtlGpu() const { 90 SkASSERT(!this->wasDestroyed()); 91 return static_cast<GrMtlGpu*>(this->getGpu()); 92} 93 94GrBackendTexture GrMtlTexture::getBackendTexture() const { 95 GrMipMapped mipMapped = fTexture.mipmapLevelCount > 1 ? GrMipMapped::kYes 96 : GrMipMapped::kNo; 97 GrMtlTextureInfo info; 98 info.fTexture.reset(GrRetainPtrFromId(fTexture)); 99 return GrBackendTexture(this->width(), this->height(), mipMapped, info); 100} 101 102GrBackendFormat GrMtlTexture::backendFormat() const { 103 return GrBackendFormat::MakeMtl(fTexture.pixelFormat); 104} 105 106