1*c8dee2aaSAndroid Build Coastguard Worker/* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlTexture.h" 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h" 11*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/GrTexture.h" 12*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlGpu.h" 13*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/mtl/MtlUtilsPriv.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker#if !__has_feature(objc_arc) 16*c8dee2aaSAndroid Build Coastguard Worker#error This file must be compiled with Arc. Use -fobjc-arc flag 17*c8dee2aaSAndroid Build Coastguard Worker#endif 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_BEGIN 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard WorkerGrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 22*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted budgeted, 23*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 24*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrMtlAttachment> texture, 25*c8dee2aaSAndroid Build Coastguard Worker GrMipmapStatus mipmapStatus, 26*c8dee2aaSAndroid Build Coastguard Worker std::string_view label) 27*c8dee2aaSAndroid Build Coastguard Worker : GrSurface(gpu, dimensions, GrProtected::kNo, label) 28*c8dee2aaSAndroid Build Coastguard Worker , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus, label) 29*c8dee2aaSAndroid Build Coastguard Worker , fTexture(std::move(texture)) { 30*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();) 31*c8dee2aaSAndroid Build Coastguard Worker SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount)); 32*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 33*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead)); 34*c8dee2aaSAndroid Build Coastguard Worker } 35*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!mtlTexture.framebufferOnly); 36*c8dee2aaSAndroid Build Coastguard Worker this->registerWithCache(budgeted); 37*c8dee2aaSAndroid Build Coastguard Worker if (skgpu::MtlFormatIsCompressed(fTexture->mtlFormat())) { 38*c8dee2aaSAndroid Build Coastguard Worker this->setReadOnly(); 39*c8dee2aaSAndroid Build Coastguard Worker } 40*c8dee2aaSAndroid Build Coastguard Worker} 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard WorkerGrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 43*c8dee2aaSAndroid Build Coastguard Worker Wrapped, 44*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 45*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrMtlAttachment> texture, 46*c8dee2aaSAndroid Build Coastguard Worker GrMipmapStatus mipmapStatus, 47*c8dee2aaSAndroid Build Coastguard Worker GrWrapCacheable cacheable, 48*c8dee2aaSAndroid Build Coastguard Worker GrIOType ioType, 49*c8dee2aaSAndroid Build Coastguard Worker std::string_view label) 50*c8dee2aaSAndroid Build Coastguard Worker : GrSurface(gpu, dimensions, GrProtected::kNo, label) 51*c8dee2aaSAndroid Build Coastguard Worker , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus, label) 52*c8dee2aaSAndroid Build Coastguard Worker , fTexture(std::move(texture)) { 53*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();) 54*c8dee2aaSAndroid Build Coastguard Worker SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount)); 55*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 56*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead)); 57*c8dee2aaSAndroid Build Coastguard Worker } 58*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!mtlTexture.framebufferOnly); 59*c8dee2aaSAndroid Build Coastguard Worker if (ioType == kRead_GrIOType) { 60*c8dee2aaSAndroid Build Coastguard Worker this->setReadOnly(); 61*c8dee2aaSAndroid Build Coastguard Worker } 62*c8dee2aaSAndroid Build Coastguard Worker this->registerWithCacheWrapped(cacheable); 63*c8dee2aaSAndroid Build Coastguard Worker} 64*c8dee2aaSAndroid Build Coastguard Worker 65*c8dee2aaSAndroid Build Coastguard WorkerGrMtlTexture::GrMtlTexture(GrMtlGpu* gpu, 66*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 67*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrMtlAttachment> texture, 68*c8dee2aaSAndroid Build Coastguard Worker GrMipmapStatus mipmapStatus, 69*c8dee2aaSAndroid Build Coastguard Worker std::string_view label) 70*c8dee2aaSAndroid Build Coastguard Worker : GrSurface(gpu, dimensions, GrProtected::kNo, label) 71*c8dee2aaSAndroid Build Coastguard Worker , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus, label) 72*c8dee2aaSAndroid Build Coastguard Worker , fTexture(std::move(texture)) { 73*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();) 74*c8dee2aaSAndroid Build Coastguard Worker SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount)); 75*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 76*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead)); 77*c8dee2aaSAndroid Build Coastguard Worker } 78*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!mtlTexture.framebufferOnly); 79*c8dee2aaSAndroid Build Coastguard Worker} 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Workersk_sp<GrMtlTexture> GrMtlTexture::MakeNewTexture(GrMtlGpu* gpu, 82*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted budgeted, 83*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 84*c8dee2aaSAndroid Build Coastguard Worker MTLPixelFormat format, 85*c8dee2aaSAndroid Build Coastguard Worker uint32_t mipLevels, 86*c8dee2aaSAndroid Build Coastguard Worker GrMipmapStatus mipmapStatus, 87*c8dee2aaSAndroid Build Coastguard Worker std::string_view label) { 88*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrMtlAttachment> texture = GrMtlAttachment::MakeTexture( 89*c8dee2aaSAndroid Build Coastguard Worker gpu, dimensions, format, mipLevels, GrRenderable::kNo, /*numSamples=*/1, budgeted); 90*c8dee2aaSAndroid Build Coastguard Worker 91*c8dee2aaSAndroid Build Coastguard Worker if (!texture) { 92*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 93*c8dee2aaSAndroid Build Coastguard Worker } 94*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, dimensions, std::move(texture), 95*c8dee2aaSAndroid Build Coastguard Worker mipmapStatus, label)); 96*c8dee2aaSAndroid Build Coastguard Worker} 97*c8dee2aaSAndroid Build Coastguard Worker 98*c8dee2aaSAndroid Build Coastguard Workersk_sp<GrMtlTexture> GrMtlTexture::MakeWrappedTexture(GrMtlGpu* gpu, 99*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 100*c8dee2aaSAndroid Build Coastguard Worker id<MTLTexture> texture, 101*c8dee2aaSAndroid Build Coastguard Worker GrWrapCacheable cacheable, 102*c8dee2aaSAndroid Build Coastguard Worker GrIOType ioType) { 103*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nil != texture); 104*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 105*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(SkToBool(texture.usage & MTLTextureUsageShaderRead)); 106*c8dee2aaSAndroid Build Coastguard Worker } 107*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrMtlAttachment> attachment = 108*c8dee2aaSAndroid Build Coastguard Worker GrMtlAttachment::MakeWrapped(gpu, dimensions, texture, 109*c8dee2aaSAndroid Build Coastguard Worker GrAttachment::UsageFlags::kTexture, cacheable, 110*c8dee2aaSAndroid Build Coastguard Worker /*label=*/"MtlAttachment_MakeWrapped"); 111*c8dee2aaSAndroid Build Coastguard Worker if (!attachment) { 112*c8dee2aaSAndroid Build Coastguard Worker return nullptr; 113*c8dee2aaSAndroid Build Coastguard Worker } 114*c8dee2aaSAndroid Build Coastguard Worker 115*c8dee2aaSAndroid Build Coastguard Worker GrMipmapStatus mipmapStatus = texture.mipmapLevelCount > 1 ? GrMipmapStatus::kValid 116*c8dee2aaSAndroid Build Coastguard Worker : GrMipmapStatus::kNotAllocated; 117*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<GrMtlTexture>( 118*c8dee2aaSAndroid Build Coastguard Worker new GrMtlTexture(gpu, kWrapped, dimensions, std::move(attachment), mipmapStatus, 119*c8dee2aaSAndroid Build Coastguard Worker cacheable, ioType, /*label=*/"MtlTextureWrappedTexture")); 120*c8dee2aaSAndroid Build Coastguard Worker} 121*c8dee2aaSAndroid Build Coastguard Worker 122*c8dee2aaSAndroid Build Coastguard WorkerGrMtlTexture::~GrMtlTexture() { 123*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(nil == fTexture); 124*c8dee2aaSAndroid Build Coastguard Worker} 125*c8dee2aaSAndroid Build Coastguard Worker 126*c8dee2aaSAndroid Build Coastguard WorkerGrMtlGpu* GrMtlTexture::getMtlGpu() const { 127*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->wasDestroyed()); 128*c8dee2aaSAndroid Build Coastguard Worker return static_cast<GrMtlGpu*>(this->getGpu()); 129*c8dee2aaSAndroid Build Coastguard Worker} 130*c8dee2aaSAndroid Build Coastguard Worker 131*c8dee2aaSAndroid Build Coastguard WorkerGrBackendTexture GrMtlTexture::getBackendTexture() const { 132*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped mipmapped = fTexture->mtlTexture().mipmapLevelCount > 1 133*c8dee2aaSAndroid Build Coastguard Worker ? skgpu::Mipmapped::kYes 134*c8dee2aaSAndroid Build Coastguard Worker : skgpu::Mipmapped::kNo; 135*c8dee2aaSAndroid Build Coastguard Worker GrMtlTextureInfo info; 136*c8dee2aaSAndroid Build Coastguard Worker info.fTexture.reset(GrRetainPtrFromId(fTexture->mtlTexture())); 137*c8dee2aaSAndroid Build Coastguard Worker return GrBackendTextures::MakeMtl(this->width(), this->height(), mipmapped, info); 138*c8dee2aaSAndroid Build Coastguard Worker} 139*c8dee2aaSAndroid Build Coastguard Worker 140*c8dee2aaSAndroid Build Coastguard WorkerGrBackendFormat GrMtlTexture::backendFormat() const { 141*c8dee2aaSAndroid Build Coastguard Worker return GrBackendFormats::MakeMtl(fTexture->mtlFormat()); 142*c8dee2aaSAndroid Build Coastguard Worker} 143*c8dee2aaSAndroid Build Coastguard Worker 144*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlTexture::onSetLabel() { 145*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fTexture); 146*c8dee2aaSAndroid Build Coastguard Worker if (!this->getLabel().empty()) { 147*c8dee2aaSAndroid Build Coastguard Worker NSString* labelStr = @(this->getLabel().c_str()); 148*c8dee2aaSAndroid Build Coastguard Worker fTexture->mtlTexture().label = [@"_Skia_" stringByAppendingString:labelStr]; 149*c8dee2aaSAndroid Build Coastguard Worker } 150*c8dee2aaSAndroid Build Coastguard Worker} 151*c8dee2aaSAndroid Build Coastguard Worker 152*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_END 153