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/GrTexture.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 18GR_NORETAIN_BEGIN 19 20GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 21 SkBudgeted budgeted, 22 SkISize dimensions, 23 sk_sp<GrMtlAttachment> texture, 24 GrMipmapStatus mipmapStatus) 25 : GrSurface(gpu, dimensions, GrProtected::kNo) 26 , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus) 27 , fTexture(std::move(texture)) { 28 SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();) 29 SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount)); 30 if (@available(macOS 10.11, iOS 9.0, *)) { 31 SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead)); 32 } 33 SkASSERT(!mtlTexture.framebufferOnly); 34 this->registerWithCache(budgeted); 35 if (GrMtlFormatIsCompressed(fTexture->mtlFormat())) { 36 this->setReadOnly(); 37 } 38} 39 40GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 41 Wrapped, 42 SkISize dimensions, 43 sk_sp<GrMtlAttachment> texture, 44 GrMipmapStatus mipmapStatus, 45 GrWrapCacheable cacheable, 46 GrIOType ioType) 47 : GrSurface(gpu, dimensions, GrProtected::kNo) 48 , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus) 49 , fTexture(std::move(texture)) { 50 SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();) 51 SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount)); 52 if (@available(macOS 10.11, iOS 9.0, *)) { 53 SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead)); 54 } 55 SkASSERT(!mtlTexture.framebufferOnly); 56 if (ioType == kRead_GrIOType) { 57 this->setReadOnly(); 58 } 59 this->registerWithCacheWrapped(cacheable); 60} 61 62GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 63 SkISize dimensions, 64 sk_sp<GrMtlAttachment> texture, 65 GrMipmapStatus mipmapStatus) 66 : GrSurface(gpu, dimensions, GrProtected::kNo) 67 , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus) 68 , fTexture(std::move(texture)) { 69 SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();) 70 SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount)); 71 if (@available(macOS 10.11, iOS 9.0, *)) { 72 SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead)); 73 } 74 SkASSERT(!mtlTexture.framebufferOnly); 75} 76 77sk_sp<GrMtlTexture> GrMtlTexture::MakeNewTexture(GrMtlGpu* gpu, 78 SkBudgeted budgeted, 79 SkISize dimensions, 80 MTLPixelFormat format, 81 uint32_t mipLevels, 82 GrMipmapStatus mipmapStatus) { 83 sk_sp<GrMtlAttachment> texture = GrMtlAttachment::MakeTexture( 84 gpu, dimensions, format, mipLevels, GrRenderable::kNo, /*numSamples=*/1, budgeted); 85 86 if (!texture) { 87 return nullptr; 88 } 89 return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, dimensions, std::move(texture), 90 mipmapStatus)); 91} 92 93sk_sp<GrMtlTexture> GrMtlTexture::MakeWrappedTexture(GrMtlGpu* gpu, 94 SkISize dimensions, 95 id<MTLTexture> texture, 96 GrWrapCacheable cacheable, 97 GrIOType ioType) { 98 SkASSERT(nil != texture); 99 if (@available(macOS 10.11, iOS 9.0, *)) { 100 SkASSERT(SkToBool(texture.usage & MTLTextureUsageShaderRead)); 101 } 102 sk_sp<GrMtlAttachment> attachment = 103 GrMtlAttachment::MakeWrapped(gpu, dimensions, texture, 104 GrAttachment::UsageFlags::kTexture, cacheable); 105 if (!attachment) { 106 return nullptr; 107 } 108 109 GrMipmapStatus mipmapStatus = texture.mipmapLevelCount > 1 ? GrMipmapStatus::kValid 110 : GrMipmapStatus::kNotAllocated; 111 return sk_sp<GrMtlTexture>( 112 new GrMtlTexture(gpu, kWrapped, dimensions, std::move(attachment), mipmapStatus, 113 cacheable, ioType)); 114} 115 116GrMtlTexture::~GrMtlTexture() { 117 SkASSERT(nil == fTexture); 118} 119 120GrMtlGpu* GrMtlTexture::getMtlGpu() const { 121 SkASSERT(!this->wasDestroyed()); 122 return static_cast<GrMtlGpu*>(this->getGpu()); 123} 124 125GrBackendTexture GrMtlTexture::getBackendTexture() const { 126 GrMipmapped mipMapped = fTexture->mtlTexture().mipmapLevelCount > 1 ? GrMipmapped::kYes 127 : GrMipmapped::kNo; 128 GrMtlTextureInfo info; 129 info.fTexture.reset(GrRetainPtrFromId(fTexture->mtlTexture())); 130 return GrBackendTexture(this->width(), this->height(), mipMapped, info); 131} 132 133GrBackendFormat GrMtlTexture::backendFormat() const { 134 return GrBackendFormat::MakeMtl(fTexture->mtlFormat()); 135} 136 137GR_NORETAIN_END 138