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