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