xref: /aosp_15_r20/external/skia/src/gpu/ganesh/mtl/GrMtlRenderTarget.mm (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1/*
2 * Copyright 2017 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/GrMtlRenderTarget.h"
9
10#include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h"
11#include "src/gpu/ganesh/GrDirectContextPriv.h"
12#include "src/gpu/ganesh/GrResourceProvider.h"
13#include "src/gpu/ganesh/mtl/GrMtlFramebuffer.h"
14#include "src/gpu/ganesh/mtl/GrMtlGpu.h"
15#include "src/gpu/ganesh/mtl/GrMtlUtil.h"
16
17#if !__has_feature(objc_arc)
18#error This file must be compiled with Arc. Use -fobjc-arc flag
19#endif
20
21GR_NORETAIN_BEGIN
22
23// Called for wrapped non-texture render targets.
24GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
25                                     SkISize dimensions,
26                                     sk_sp<GrMtlAttachment> colorAttachment,
27                                     sk_sp<GrMtlAttachment> resolveAttachment,
28                                     Wrapped,
29                                     std::string_view label)
30        : GrSurface(gpu, dimensions, GrProtected::kNo, label)
31        , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(), GrProtected::kNo, label)
32        , fColorAttachment(std::move(colorAttachment))
33        , fResolveAttachment(std::move(resolveAttachment)) {
34    this->registerWithCacheWrapped(GrWrapCacheable::kNo);
35}
36
37// Called by subclass constructors.
38GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
39                                     SkISize dimensions,
40                                     sk_sp<GrMtlAttachment> colorAttachment,
41                                     sk_sp<GrMtlAttachment> resolveAttachment,
42                                     std::string_view label)
43        : GrSurface(gpu, dimensions, GrProtected::kNo, label)
44        , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(), GrProtected::kNo, label)
45        , fColorAttachment(std::move(colorAttachment))
46        , fResolveAttachment(std::move(resolveAttachment)) {
47}
48
49sk_sp<GrMtlRenderTarget> GrMtlRenderTarget::MakeWrappedRenderTarget(GrMtlGpu* gpu,
50                                                                    SkISize dimensions,
51                                                                    int sampleCnt,
52                                                                    id<MTLTexture> texture) {
53    SkASSERT(nil != texture);
54    SkASSERT(1 == texture.mipmapLevelCount);
55    if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
56        SkASSERT(MTLTextureUsageRenderTarget & texture.usage);
57    }
58
59    sk_sp<GrMtlAttachment> textureAttachment =
60            GrMtlAttachment::MakeWrapped(gpu, dimensions, texture,
61                                         GrAttachment::UsageFlags::kColorAttachment,
62                                         GrWrapCacheable::kNo,
63                                         /*label=*/"MtlAttachment_TextureAttachment");
64
65    GrMtlRenderTarget* mtlRT;
66    if (sampleCnt > 1) {
67        if ([texture sampleCount] == 1) {
68            MTLPixelFormat format = texture.pixelFormat;
69            if (!gpu->mtlCaps().isFormatRenderable(format, sampleCnt)) {
70                return nullptr;
71            }
72            auto rp = gpu->getContext()->priv().resourceProvider();
73            sk_sp<GrAttachment> msaaAttachment =
74                    rp->makeMSAAAttachment(dimensions,
75                                           GrBackendFormats::MakeMtl(format),
76                                           sampleCnt,
77                                           GrProtected::kNo,
78                                           GrMemoryless::kNo);
79            if (!msaaAttachment) {
80                return nullptr;
81            }
82            sk_sp<GrMtlAttachment> colorAttachment =
83                    sk_sp<GrMtlAttachment>(static_cast<GrMtlAttachment*>(msaaAttachment.release()));
84            mtlRT = new GrMtlRenderTarget(
85                    gpu, dimensions, std::move(colorAttachment), std::move(textureAttachment),
86                    kWrapped, /*label=*/"MakeWrappedRenderTargetWithOneTextureSampleCount");
87            mtlRT->setRequiresManualMSAAResolve();
88        } else {
89            SkASSERT(sampleCnt == static_cast<int>([texture sampleCount]));
90            mtlRT = new GrMtlRenderTarget(gpu, dimensions, std::move(textureAttachment), nil,
91                                          kWrapped,
92                                          /*label=*/"MakeWrappedRenderTargetWithManySampleCount");
93        }
94    } else {
95        mtlRT = new GrMtlRenderTarget(gpu, dimensions, std::move(textureAttachment), nil,
96                                      kWrapped,
97                                      /*label=*/"MakeWrappedRenderTargetWithOneOrLessSampleCount");
98    }
99
100    return sk_sp<GrMtlRenderTarget>(mtlRT);
101}
102
103GrMtlRenderTarget::~GrMtlRenderTarget() {
104    SkASSERT(nil == fColorAttachment);
105    SkASSERT(nil == fResolveAttachment);
106}
107
108GrBackendRenderTarget GrMtlRenderTarget::getBackendRenderTarget() const {
109    GrMtlTextureInfo info;
110    info.fTexture.reset(GrRetainPtrFromId(fColorAttachment->mtlTexture()));
111    return GrBackendRenderTargets::MakeMtl(this->width(), this->height(), info);
112}
113
114GrBackendFormat GrMtlRenderTarget::backendFormat() const {
115    return GrBackendFormats::MakeMtl(fColorAttachment->mtlFormat());
116}
117
118static int renderpass_features_to_index(bool hasResolve, bool hasStencil) {
119    int index = 0;
120    if (hasResolve) {
121        index += 1;
122    }
123    if (hasStencil) {
124        index += 2;
125    }
126    return index;
127}
128
129const GrMtlFramebuffer* GrMtlRenderTarget::getFramebuffer(bool withResolve,
130                                                          bool withStencil) {
131    int cacheIndex =
132            renderpass_features_to_index(withResolve, withStencil);
133    SkASSERT(cacheIndex < GrMtlRenderTarget::kNumCachedFramebuffers);
134
135    if (fCachedFramebuffers[cacheIndex]) {
136        return fCachedFramebuffers[cacheIndex].get();
137    }
138
139    GrMtlAttachment* resolve = withResolve ? this->resolveAttachment() : nullptr;
140    GrMtlAttachment* colorAttachment = this->colorAttachment();
141
142    // Stencil attachment view is stored in the base RT stencil attachment
143    GrMtlAttachment* stencil =
144            withStencil ? static_cast<GrMtlAttachment*>(this->getStencilAttachment())
145                        : nullptr;
146    fCachedFramebuffers[cacheIndex] =
147            GrMtlFramebuffer::Make(colorAttachment, resolve, stencil);
148    return fCachedFramebuffers[cacheIndex].get();
149}
150
151GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const {
152    SkASSERT(!this->wasDestroyed());
153    return static_cast<GrMtlGpu*>(this->getGpu());
154}
155
156void GrMtlRenderTarget::onAbandon() {
157    fColorAttachment = nil;
158    fResolveAttachment = nil;
159    INHERITED::onAbandon();
160}
161
162void GrMtlRenderTarget::onRelease() {
163    fColorAttachment = nil;
164    fResolveAttachment = nil;
165    INHERITED::onRelease();
166}
167
168bool GrMtlRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) {
169    SkASSERT(useMSAASurface == (this->numSamples() > 1));
170    return true;
171}
172
173void GrMtlRenderTarget::onSetLabel() {
174    SkASSERT(fColorAttachment);
175    if (!this->getLabel().empty()) {
176        NSString* labelStr = @(this->getLabel().c_str());
177        if (fResolveAttachment) {
178            fColorAttachment->mtlTexture().label =
179                    [@"_Skia_MSAA_" stringByAppendingString:labelStr];
180            fResolveAttachment->mtlTexture().label =
181                    [@"_Skia_Resolve_" stringByAppendingString:labelStr];
182        } else {
183            fColorAttachment->mtlTexture().label = [@"_Skia_" stringByAppendingString:labelStr];
184        }
185    }
186}
187
188GR_NORETAIN_END
189