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