• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/mtl/GrMtlRenderTarget.h"
9
10#include "src/gpu/GrDirectContextPriv.h"
11#include "src/gpu/GrResourceProvider.h"
12#include "src/gpu/mtl/GrMtlFramebuffer.h"
13#include "src/gpu/mtl/GrMtlGpu.h"
14#include "src/gpu/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
22// Called for wrapped non-texture render targets.
23GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
24                                     SkISize dimensions,
25                                     sk_sp<GrMtlAttachment> colorAttachment,
26                                     sk_sp<GrMtlAttachment> resolveAttachment,
27                                     Wrapped)
28        : GrSurface(gpu, dimensions, GrProtected::kNo)
29        , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(), GrProtected::kNo)
30        , fColorAttachment(std::move(colorAttachment))
31        , fResolveAttachment(std::move(resolveAttachment)) {
32    this->registerWithCacheWrapped(GrWrapCacheable::kNo);
33}
34
35// Called by subclass constructors.
36GrMtlRenderTarget::GrMtlRenderTarget(GrMtlGpu* gpu,
37                                     SkISize dimensions,
38                                     sk_sp<GrMtlAttachment> colorAttachment,
39                                     sk_sp<GrMtlAttachment> resolveAttachment)
40        : GrSurface(gpu, dimensions, GrProtected::kNo)
41        , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(), GrProtected::kNo)
42        , fColorAttachment(std::move(colorAttachment))
43        , fResolveAttachment(std::move(resolveAttachment)) {
44}
45
46sk_sp<GrMtlRenderTarget> GrMtlRenderTarget::MakeWrappedRenderTarget(GrMtlGpu* gpu,
47                                                                    SkISize dimensions,
48                                                                    int sampleCnt,
49                                                                    id<MTLTexture> texture) {
50    SkASSERT(nil != texture);
51    SkASSERT(1 == texture.mipmapLevelCount);
52    if (@available(macOS 10.11, iOS 9.0, *)) {
53        SkASSERT(MTLTextureUsageRenderTarget & texture.usage);
54    }
55
56    sk_sp<GrMtlAttachment> textureAttachment =
57            GrMtlAttachment::MakeWrapped(gpu, dimensions, texture,
58                                         GrAttachment::UsageFlags::kColorAttachment,
59                                         GrWrapCacheable::kNo);
60
61    GrMtlRenderTarget* mtlRT;
62    if (sampleCnt > 1) {
63        if ([texture sampleCount] == 1) {
64            MTLPixelFormat format = texture.pixelFormat;
65            if (!gpu->mtlCaps().isFormatRenderable(format, sampleCnt)) {
66                return nullptr;
67            }
68            auto rp = gpu->getContext()->priv().resourceProvider();
69            sk_sp<GrAttachment> msaaAttachment = rp->makeMSAAAttachment(
70                    dimensions, GrBackendFormat::MakeMtl(format), sampleCnt, GrProtected::kNo,
71                    GrMemoryless::kNo);
72            if (!msaaAttachment) {
73                return nullptr;
74            }
75            sk_sp<GrMtlAttachment> colorAttachment =
76                    sk_sp<GrMtlAttachment>(static_cast<GrMtlAttachment*>(msaaAttachment.release()));
77            mtlRT = new GrMtlRenderTarget(
78                    gpu, dimensions, std::move(colorAttachment), std::move(textureAttachment),
79                    kWrapped);
80            mtlRT->setRequiresManualMSAAResolve();
81        } else {
82            SkASSERT(sampleCnt == static_cast<int>([texture sampleCount]));
83            mtlRT = new GrMtlRenderTarget(gpu, dimensions, std::move(textureAttachment), nil,
84                                          kWrapped);
85        }
86    } else {
87        mtlRT = new GrMtlRenderTarget(gpu, dimensions, std::move(textureAttachment), nil,
88                                      kWrapped);
89    }
90
91    return sk_sp<GrMtlRenderTarget>(mtlRT);
92}
93
94GrMtlRenderTarget::~GrMtlRenderTarget() {
95    SkASSERT(nil == fColorAttachment);
96    SkASSERT(nil == fResolveAttachment);
97}
98
99GrBackendRenderTarget GrMtlRenderTarget::getBackendRenderTarget() const {
100    GrMtlTextureInfo info;
101    info.fTexture.reset(GrRetainPtrFromId(fColorAttachment->mtlTexture()));
102    return GrBackendRenderTarget(this->width(), this->height(), info);
103}
104
105GrBackendFormat GrMtlRenderTarget::backendFormat() const {
106    return GrBackendFormat::MakeMtl(fColorAttachment->mtlFormat());
107}
108
109static int renderpass_features_to_index(bool hasResolve, bool hasStencil) {
110    int index = 0;
111    if (hasResolve) {
112        index += 1;
113    }
114    if (hasStencil) {
115        index += 2;
116    }
117    return index;
118}
119
120const GrMtlFramebuffer* GrMtlRenderTarget::getFramebuffer(bool withResolve,
121                                                          bool withStencil) {
122    int cacheIndex =
123            renderpass_features_to_index(withResolve, withStencil);
124    SkASSERT(cacheIndex < GrMtlRenderTarget::kNumCachedFramebuffers);
125
126    if (fCachedFramebuffers[cacheIndex]) {
127        return fCachedFramebuffers[cacheIndex].get();
128    }
129
130    GrMtlAttachment* resolve = withResolve ? this->resolveAttachment() : nullptr;
131    GrMtlAttachment* colorAttachment = this->colorAttachment();
132
133    // Stencil attachment view is stored in the base RT stencil attachment
134    GrMtlAttachment* stencil =
135            withStencil ? static_cast<GrMtlAttachment*>(this->getStencilAttachment())
136                        : nullptr;
137    fCachedFramebuffers[cacheIndex] =
138            GrMtlFramebuffer::Make(colorAttachment, resolve, stencil);
139    return fCachedFramebuffers[cacheIndex].get();
140}
141
142GrMtlGpu* GrMtlRenderTarget::getMtlGpu() const {
143    SkASSERT(!this->wasDestroyed());
144    return static_cast<GrMtlGpu*>(this->getGpu());
145}
146
147void GrMtlRenderTarget::onAbandon() {
148    fColorAttachment = nil;
149    fResolveAttachment = nil;
150    INHERITED::onAbandon();
151}
152
153void GrMtlRenderTarget::onRelease() {
154    fColorAttachment = nil;
155    fResolveAttachment = nil;
156    INHERITED::onRelease();
157}
158
159bool GrMtlRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) {
160    SkASSERT(useMSAASurface == (this->numSamples() > 1));
161    return true;
162}
163
164GR_NORETAIN_END
165