xref: /aosp_15_r20/external/skia/src/gpu/ganesh/mtl/GrMtlTexture.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/GrMtlTexture.h"
9
10#include "include/gpu/ganesh/mtl/GrMtlBackendSurface.h"
11#include "src/gpu/ganesh/GrTexture.h"
12#include "src/gpu/ganesh/mtl/GrMtlGpu.h"
13#include "src/gpu/mtl/MtlUtilsPriv.h"
14
15#if !__has_feature(objc_arc)
16#error This file must be compiled with Arc. Use -fobjc-arc flag
17#endif
18
19GR_NORETAIN_BEGIN
20
21GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
22                           skgpu::Budgeted budgeted,
23                           SkISize dimensions,
24                           sk_sp<GrMtlAttachment> texture,
25                           GrMipmapStatus mipmapStatus,
26                           std::string_view label)
27        : GrSurface(gpu, dimensions, GrProtected::kNo, label)
28        , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus, label)
29        , fTexture(std::move(texture)) {
30    SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();)
31    SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount));
32    if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
33        SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead));
34    }
35    SkASSERT(!mtlTexture.framebufferOnly);
36    this->registerWithCache(budgeted);
37    if (skgpu::MtlFormatIsCompressed(fTexture->mtlFormat())) {
38        this->setReadOnly();
39    }
40}
41
42GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
43                           Wrapped,
44                           SkISize dimensions,
45                           sk_sp<GrMtlAttachment> texture,
46                           GrMipmapStatus mipmapStatus,
47                           GrWrapCacheable cacheable,
48                           GrIOType ioType,
49                           std::string_view label)
50        : GrSurface(gpu, dimensions, GrProtected::kNo, label)
51        , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus, label)
52        , fTexture(std::move(texture)) {
53    SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();)
54    SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount));
55    if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
56        SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead));
57    }
58    SkASSERT(!mtlTexture.framebufferOnly);
59    if (ioType == kRead_GrIOType) {
60        this->setReadOnly();
61    }
62    this->registerWithCacheWrapped(cacheable);
63}
64
65GrMtlTexture::GrMtlTexture(GrMtlGpu* gpu,
66                           SkISize dimensions,
67                           sk_sp<GrMtlAttachment> texture,
68                           GrMipmapStatus mipmapStatus,
69                           std::string_view label)
70        : GrSurface(gpu, dimensions, GrProtected::kNo, label)
71        , INHERITED(gpu, dimensions, GrProtected::kNo, GrTextureType::k2D, mipmapStatus, label)
72        , fTexture(std::move(texture)) {
73    SkDEBUGCODE(id<MTLTexture> mtlTexture = fTexture->mtlTexture();)
74    SkASSERT((GrMipmapStatus::kNotAllocated == mipmapStatus) == (1 == mtlTexture.mipmapLevelCount));
75    if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
76        SkASSERT(SkToBool(mtlTexture.usage & MTLTextureUsageShaderRead));
77    }
78    SkASSERT(!mtlTexture.framebufferOnly);
79}
80
81sk_sp<GrMtlTexture> GrMtlTexture::MakeNewTexture(GrMtlGpu* gpu,
82                                                 skgpu::Budgeted budgeted,
83                                                 SkISize dimensions,
84                                                 MTLPixelFormat format,
85                                                 uint32_t mipLevels,
86                                                 GrMipmapStatus mipmapStatus,
87                                                 std::string_view label) {
88    sk_sp<GrMtlAttachment> texture = GrMtlAttachment::MakeTexture(
89            gpu, dimensions, format, mipLevels, GrRenderable::kNo, /*numSamples=*/1, budgeted);
90
91    if (!texture) {
92        return nullptr;
93    }
94    return sk_sp<GrMtlTexture>(new GrMtlTexture(gpu, budgeted, dimensions, std::move(texture),
95                                                mipmapStatus, label));
96}
97
98sk_sp<GrMtlTexture> GrMtlTexture::MakeWrappedTexture(GrMtlGpu* gpu,
99                                                     SkISize dimensions,
100                                                     id<MTLTexture> texture,
101                                                     GrWrapCacheable cacheable,
102                                                     GrIOType ioType) {
103    SkASSERT(nil != texture);
104    if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
105        SkASSERT(SkToBool(texture.usage & MTLTextureUsageShaderRead));
106    }
107    sk_sp<GrMtlAttachment> attachment =
108            GrMtlAttachment::MakeWrapped(gpu, dimensions, texture,
109                                         GrAttachment::UsageFlags::kTexture, cacheable,
110                                         /*label=*/"MtlAttachment_MakeWrapped");
111    if (!attachment) {
112        return nullptr;
113    }
114
115    GrMipmapStatus mipmapStatus = texture.mipmapLevelCount > 1 ? GrMipmapStatus::kValid
116                                                               : GrMipmapStatus::kNotAllocated;
117    return sk_sp<GrMtlTexture>(
118            new GrMtlTexture(gpu, kWrapped, dimensions, std::move(attachment), mipmapStatus,
119                             cacheable, ioType, /*label=*/"MtlTextureWrappedTexture"));
120}
121
122GrMtlTexture::~GrMtlTexture() {
123    SkASSERT(nil == fTexture);
124}
125
126GrMtlGpu* GrMtlTexture::getMtlGpu() const {
127    SkASSERT(!this->wasDestroyed());
128    return static_cast<GrMtlGpu*>(this->getGpu());
129}
130
131GrBackendTexture GrMtlTexture::getBackendTexture() const {
132    skgpu::Mipmapped mipmapped = fTexture->mtlTexture().mipmapLevelCount > 1
133                                         ? skgpu::Mipmapped::kYes
134                                         : skgpu::Mipmapped::kNo;
135    GrMtlTextureInfo info;
136    info.fTexture.reset(GrRetainPtrFromId(fTexture->mtlTexture()));
137    return GrBackendTextures::MakeMtl(this->width(), this->height(), mipmapped, info);
138}
139
140GrBackendFormat GrMtlTexture::backendFormat() const {
141    return GrBackendFormats::MakeMtl(fTexture->mtlFormat());
142}
143
144void GrMtlTexture::onSetLabel() {
145    SkASSERT(fTexture);
146    if (!this->getLabel().empty()) {
147        NSString* labelStr = @(this->getLabel().c_str());
148        fTexture->mtlTexture().label = [@"_Skia_" stringByAppendingString:labelStr];
149    }
150}
151
152GR_NORETAIN_END
153