xref: /aosp_15_r20/external/skia/src/gpu/ganesh/mtl/GrMtlAttachment.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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