• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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