1*c8dee2aaSAndroid Build Coastguard Worker/* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2018 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/GrMtlAttachment.h" 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/GpuTypes.h" 11*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/ganesh/GrBackendSurface.h" 12*c8dee2aaSAndroid Build Coastguard Worker#include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h" 13*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlGpu.h" 14*c8dee2aaSAndroid Build Coastguard Worker#include "src/gpu/ganesh/mtl/GrMtlUtil.h" 15*c8dee2aaSAndroid Build Coastguard Worker 16*c8dee2aaSAndroid Build Coastguard Worker#if !__has_feature(objc_arc) 17*c8dee2aaSAndroid Build Coastguard Worker#error This file must be compiled with Arc. Use -fobjc-arc flag 18*c8dee2aaSAndroid Build Coastguard Worker#endif 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_BEGIN 21*c8dee2aaSAndroid Build Coastguard Worker 22*c8dee2aaSAndroid Build Coastguard WorkerGrMtlAttachment::GrMtlAttachment(GrMtlGpu* gpu, 23*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 24*c8dee2aaSAndroid Build Coastguard Worker UsageFlags supportedUsages, 25*c8dee2aaSAndroid Build Coastguard Worker id<MTLTexture> texture, 26*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted budgeted, 27*c8dee2aaSAndroid Build Coastguard Worker std::string_view label) 28*c8dee2aaSAndroid Build Coastguard Worker : GrAttachment( 29*c8dee2aaSAndroid Build Coastguard Worker gpu, 30*c8dee2aaSAndroid Build Coastguard Worker dimensions, 31*c8dee2aaSAndroid Build Coastguard Worker supportedUsages, 32*c8dee2aaSAndroid Build Coastguard Worker texture.sampleCount, 33*c8dee2aaSAndroid Build Coastguard Worker texture.mipmapLevelCount > 1 ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo, 34*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo, 35*c8dee2aaSAndroid Build Coastguard Worker label) 36*c8dee2aaSAndroid Build Coastguard Worker , fTexture(texture) { 37*c8dee2aaSAndroid Build Coastguard Worker this->registerWithCache(budgeted); 38*c8dee2aaSAndroid Build Coastguard Worker} 39*c8dee2aaSAndroid Build Coastguard Worker 40*c8dee2aaSAndroid Build Coastguard WorkerGrMtlAttachment::GrMtlAttachment(GrMtlGpu* gpu, 41*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 42*c8dee2aaSAndroid Build Coastguard Worker UsageFlags supportedUsages, 43*c8dee2aaSAndroid Build Coastguard Worker id<MTLTexture> texture, 44*c8dee2aaSAndroid Build Coastguard Worker GrWrapCacheable cacheable, 45*c8dee2aaSAndroid Build Coastguard Worker std::string_view label) 46*c8dee2aaSAndroid Build Coastguard Worker : GrAttachment( 47*c8dee2aaSAndroid Build Coastguard Worker gpu, 48*c8dee2aaSAndroid Build Coastguard Worker dimensions, 49*c8dee2aaSAndroid Build Coastguard Worker supportedUsages, 50*c8dee2aaSAndroid Build Coastguard Worker texture.sampleCount, 51*c8dee2aaSAndroid Build Coastguard Worker texture.mipmapLevelCount > 1 ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo, 52*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo, 53*c8dee2aaSAndroid Build Coastguard Worker label) 54*c8dee2aaSAndroid Build Coastguard Worker , fTexture(texture) { 55*c8dee2aaSAndroid Build Coastguard Worker this->registerWithCacheWrapped(cacheable); 56*c8dee2aaSAndroid Build Coastguard Worker} 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Workersk_sp<GrMtlAttachment> GrMtlAttachment::MakeStencil(GrMtlGpu* gpu, 59*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 60*c8dee2aaSAndroid Build Coastguard Worker int sampleCnt, 61*c8dee2aaSAndroid Build Coastguard Worker MTLPixelFormat format) { 62*c8dee2aaSAndroid Build Coastguard Worker int textureUsage = 0; 63*c8dee2aaSAndroid Build Coastguard Worker int storageMode = 0; 64*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 65*c8dee2aaSAndroid Build Coastguard Worker textureUsage = MTLTextureUsageRenderTarget; 66*c8dee2aaSAndroid Build Coastguard Worker storageMode = MTLStorageModePrivate; 67*c8dee2aaSAndroid Build Coastguard Worker } 68*c8dee2aaSAndroid Build Coastguard Worker return GrMtlAttachment::Make(gpu, dimensions, UsageFlags::kStencilAttachment, sampleCnt, format, 69*c8dee2aaSAndroid Build Coastguard Worker /*mipLevels=*/1, textureUsage, storageMode, skgpu::Budgeted::kYes); 70*c8dee2aaSAndroid Build Coastguard Worker} 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Workersk_sp<GrMtlAttachment> GrMtlAttachment::MakeMSAA(GrMtlGpu* gpu, 73*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 74*c8dee2aaSAndroid Build Coastguard Worker int sampleCnt, 75*c8dee2aaSAndroid Build Coastguard Worker MTLPixelFormat format) { 76*c8dee2aaSAndroid Build Coastguard Worker int textureUsage = 0; 77*c8dee2aaSAndroid Build Coastguard Worker int storageMode = 0; 78*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 79*c8dee2aaSAndroid Build Coastguard Worker textureUsage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget; 80*c8dee2aaSAndroid Build Coastguard Worker storageMode = MTLStorageModePrivate; 81*c8dee2aaSAndroid Build Coastguard Worker } 82*c8dee2aaSAndroid Build Coastguard Worker return GrMtlAttachment::Make(gpu, dimensions, UsageFlags::kColorAttachment, sampleCnt, format, 83*c8dee2aaSAndroid Build Coastguard Worker /*mipLevels=*/1, textureUsage, storageMode, skgpu::Budgeted::kYes); 84*c8dee2aaSAndroid Build Coastguard Worker} 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Workersk_sp<GrMtlAttachment> GrMtlAttachment::MakeTexture(GrMtlGpu* gpu, 87*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 88*c8dee2aaSAndroid Build Coastguard Worker MTLPixelFormat format, 89*c8dee2aaSAndroid Build Coastguard Worker uint32_t mipLevels, 90*c8dee2aaSAndroid Build Coastguard Worker GrRenderable renderable, 91*c8dee2aaSAndroid Build Coastguard Worker int numSamples, 92*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted budgeted) { 93*c8dee2aaSAndroid Build Coastguard Worker int textureUsage = 0; 94*c8dee2aaSAndroid Build Coastguard Worker int storageMode = 0; 95*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 96*c8dee2aaSAndroid Build Coastguard Worker textureUsage = MTLTextureUsageShaderRead; 97*c8dee2aaSAndroid Build Coastguard Worker storageMode = MTLStorageModePrivate; 98*c8dee2aaSAndroid Build Coastguard Worker } 99*c8dee2aaSAndroid Build Coastguard Worker UsageFlags usageFlags = UsageFlags::kTexture; 100*c8dee2aaSAndroid Build Coastguard Worker if (renderable == GrRenderable::kYes) { 101*c8dee2aaSAndroid Build Coastguard Worker usageFlags |= UsageFlags::kColorAttachment; 102*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 103*c8dee2aaSAndroid Build Coastguard Worker textureUsage |= MTLTextureUsageRenderTarget; 104*c8dee2aaSAndroid Build Coastguard Worker } 105*c8dee2aaSAndroid Build Coastguard Worker } 106*c8dee2aaSAndroid Build Coastguard Worker 107*c8dee2aaSAndroid Build Coastguard Worker return GrMtlAttachment::Make(gpu, dimensions, usageFlags, numSamples, format, mipLevels, 108*c8dee2aaSAndroid Build Coastguard Worker textureUsage, storageMode, budgeted); 109*c8dee2aaSAndroid Build Coastguard Worker} 110*c8dee2aaSAndroid Build Coastguard Worker 111*c8dee2aaSAndroid Build Coastguard Workersk_sp<GrMtlAttachment> GrMtlAttachment::Make(GrMtlGpu* gpu, 112*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 113*c8dee2aaSAndroid Build Coastguard Worker UsageFlags attachmentUsages, 114*c8dee2aaSAndroid Build Coastguard Worker int sampleCnt, 115*c8dee2aaSAndroid Build Coastguard Worker MTLPixelFormat format, 116*c8dee2aaSAndroid Build Coastguard Worker uint32_t mipLevels, 117*c8dee2aaSAndroid Build Coastguard Worker int mtlTextureUsage, 118*c8dee2aaSAndroid Build Coastguard Worker int mtlStorageMode, 119*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted budgeted) { 120*c8dee2aaSAndroid Build Coastguard Worker auto desc = [[MTLTextureDescriptor alloc] init]; 121*c8dee2aaSAndroid Build Coastguard Worker desc.textureType = (sampleCnt > 1) ? MTLTextureType2DMultisample : MTLTextureType2D; 122*c8dee2aaSAndroid Build Coastguard Worker desc.pixelFormat = format; 123*c8dee2aaSAndroid Build Coastguard Worker desc.width = dimensions.width(); 124*c8dee2aaSAndroid Build Coastguard Worker desc.height = dimensions.height(); 125*c8dee2aaSAndroid Build Coastguard Worker desc.depth = 1; 126*c8dee2aaSAndroid Build Coastguard Worker desc.mipmapLevelCount = mipLevels; 127*c8dee2aaSAndroid Build Coastguard Worker desc.sampleCount = sampleCnt; 128*c8dee2aaSAndroid Build Coastguard Worker desc.arrayLength = 1; 129*c8dee2aaSAndroid Build Coastguard Worker if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) { 130*c8dee2aaSAndroid Build Coastguard Worker desc.usage = mtlTextureUsage; 131*c8dee2aaSAndroid Build Coastguard Worker desc.storageMode = (MTLStorageMode)mtlStorageMode; 132*c8dee2aaSAndroid Build Coastguard Worker } 133*c8dee2aaSAndroid Build Coastguard Worker id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:desc]; 134*c8dee2aaSAndroid Build Coastguard Worker#ifdef SK_ENABLE_MTL_DEBUG_INFO 135*c8dee2aaSAndroid Build Coastguard Worker if (attachmentUsages == UsageFlags::kStencilAttachment) { 136*c8dee2aaSAndroid Build Coastguard Worker texture.label = @"Stencil"; 137*c8dee2aaSAndroid Build Coastguard Worker } else if (SkToBool(attachmentUsages & UsageFlags::kColorAttachment)) { 138*c8dee2aaSAndroid Build Coastguard Worker if (sampleCnt > 1) { 139*c8dee2aaSAndroid Build Coastguard Worker if (SkToBool(attachmentUsages & UsageFlags::kTexture)) { 140*c8dee2aaSAndroid Build Coastguard Worker texture.label = @"MSAA TextureRenderTarget"; 141*c8dee2aaSAndroid Build Coastguard Worker } else { 142*c8dee2aaSAndroid Build Coastguard Worker texture.label = @"MSAA RenderTarget"; 143*c8dee2aaSAndroid Build Coastguard Worker } 144*c8dee2aaSAndroid Build Coastguard Worker } else { 145*c8dee2aaSAndroid Build Coastguard Worker if (SkToBool(attachmentUsages & UsageFlags::kTexture)) { 146*c8dee2aaSAndroid Build Coastguard Worker texture.label = @"TextureRenderTarget"; 147*c8dee2aaSAndroid Build Coastguard Worker } else { 148*c8dee2aaSAndroid Build Coastguard Worker texture.label = @"RenderTarget"; 149*c8dee2aaSAndroid Build Coastguard Worker } 150*c8dee2aaSAndroid Build Coastguard Worker } 151*c8dee2aaSAndroid Build Coastguard Worker } else { 152*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(attachmentUsages == UsageFlags::kTexture); 153*c8dee2aaSAndroid Build Coastguard Worker texture.label = @"Texture"; 154*c8dee2aaSAndroid Build Coastguard Worker } 155*c8dee2aaSAndroid Build Coastguard Worker#endif 156*c8dee2aaSAndroid Build Coastguard Worker 157*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<GrMtlAttachment>(new GrMtlAttachment(gpu, dimensions, attachmentUsages, 158*c8dee2aaSAndroid Build Coastguard Worker texture, budgeted, 159*c8dee2aaSAndroid Build Coastguard Worker /*label=*/"MakeMtlAttachment")); 160*c8dee2aaSAndroid Build Coastguard Worker} 161*c8dee2aaSAndroid Build Coastguard Worker 162*c8dee2aaSAndroid Build Coastguard Workersk_sp<GrMtlAttachment> GrMtlAttachment::MakeWrapped( 163*c8dee2aaSAndroid Build Coastguard Worker GrMtlGpu* gpu, 164*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions, 165*c8dee2aaSAndroid Build Coastguard Worker id<MTLTexture> texture, 166*c8dee2aaSAndroid Build Coastguard Worker UsageFlags attachmentUsages, 167*c8dee2aaSAndroid Build Coastguard Worker GrWrapCacheable cacheable, 168*c8dee2aaSAndroid Build Coastguard Worker std::string_view label) { 169*c8dee2aaSAndroid Build Coastguard Worker 170*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<GrMtlAttachment>(new GrMtlAttachment(gpu, dimensions, attachmentUsages, texture, 171*c8dee2aaSAndroid Build Coastguard Worker cacheable, label)); 172*c8dee2aaSAndroid Build Coastguard Worker} 173*c8dee2aaSAndroid Build Coastguard Worker 174*c8dee2aaSAndroid Build Coastguard WorkerGrMtlAttachment::~GrMtlAttachment() { 175*c8dee2aaSAndroid Build Coastguard Worker // should have been released or abandoned first 176*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!fTexture); 177*c8dee2aaSAndroid Build Coastguard Worker} 178*c8dee2aaSAndroid Build Coastguard Worker 179*c8dee2aaSAndroid Build Coastguard WorkerGrBackendFormat GrMtlAttachment::backendFormat() const { 180*c8dee2aaSAndroid Build Coastguard Worker return GrBackendFormats::MakeMtl(SkToU32(fTexture.pixelFormat)); 181*c8dee2aaSAndroid Build Coastguard Worker} 182*c8dee2aaSAndroid Build Coastguard Worker 183*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlAttachment::onRelease() { 184*c8dee2aaSAndroid Build Coastguard Worker fTexture = nil; 185*c8dee2aaSAndroid Build Coastguard Worker GrAttachment::onRelease(); 186*c8dee2aaSAndroid Build Coastguard Worker} 187*c8dee2aaSAndroid Build Coastguard Worker 188*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlAttachment::onAbandon() { 189*c8dee2aaSAndroid Build Coastguard Worker fTexture = nil; 190*c8dee2aaSAndroid Build Coastguard Worker GrAttachment::onAbandon(); 191*c8dee2aaSAndroid Build Coastguard Worker} 192*c8dee2aaSAndroid Build Coastguard Worker 193*c8dee2aaSAndroid Build Coastguard WorkerGrMtlGpu* GrMtlAttachment::getMtlGpu() const { 194*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->wasDestroyed()); 195*c8dee2aaSAndroid Build Coastguard Worker return static_cast<GrMtlGpu*>(this->getGpu()); 196*c8dee2aaSAndroid Build Coastguard Worker} 197*c8dee2aaSAndroid Build Coastguard Worker 198*c8dee2aaSAndroid Build Coastguard Workervoid GrMtlAttachment::onSetLabel() { 199*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fTexture); 200*c8dee2aaSAndroid Build Coastguard Worker if (!this->getLabel().empty()) { 201*c8dee2aaSAndroid Build Coastguard Worker NSString* labelStr = @(this->getLabel().c_str()); 202*c8dee2aaSAndroid Build Coastguard Worker fTexture.label = [@"_Skia_" stringByAppendingString:labelStr]; 203*c8dee2aaSAndroid Build Coastguard Worker } 204*c8dee2aaSAndroid Build Coastguard Worker} 205*c8dee2aaSAndroid Build Coastguard WorkerGR_NORETAIN_END 206