• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright 2021 Google LLC
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/graphite/mtl/MtlTexture.h"
9
10#include "include/gpu/MutableTextureState.h"
11#include "include/gpu/graphite/mtl/MtlGraphiteTypes.h"
12#include "include/private/gpu/graphite/MtlGraphiteTypesPriv.h"
13#include "src/core/SkMipmap.h"
14#include "src/gpu/graphite/mtl/MtlCaps.h"
15#include "src/gpu/graphite/mtl/MtlSharedContext.h"
16#include "src/gpu/mtl/MtlUtilsPriv.h"
17
18namespace skgpu::graphite {
19
20sk_cfp<id<MTLTexture>> MtlTexture::MakeMtlTexture(const MtlSharedContext* sharedContext,
21                                                  SkISize dimensions,
22                                                  const TextureInfo& info) {
23    const Caps* caps = sharedContext->caps();
24    if (dimensions.width() > caps->maxTextureSize() ||
25        dimensions.height() > caps->maxTextureSize()) {
26        return nullptr;
27    }
28
29    const MtlTextureSpec& mtlSpec = info.mtlTextureSpec();
30    SkASSERT(!mtlSpec.fFramebufferOnly);
31
32    if (mtlSpec.fUsage & MTLTextureUsageShaderRead && !caps->isTexturable(info)) {
33        return nullptr;
34    }
35
36    if (mtlSpec.fUsage & MTLTextureUsageRenderTarget &&
37        !(caps->isRenderable(info) || MtlFormatIsDepthOrStencil((MTLPixelFormat)mtlSpec.fFormat))) {
38        return nullptr;
39    }
40
41    if (mtlSpec.fUsage & MTLTextureUsageShaderWrite && !caps->isStorage(info)) {
42        return nullptr;
43    }
44
45    int numMipLevels = 1;
46    if (info.mipmapped() == Mipmapped::kYes) {
47        numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
48    }
49
50    sk_cfp<MTLTextureDescriptor*> desc([[MTLTextureDescriptor alloc] init]);
51    (*desc).textureType = (info.numSamples() > 1) ? MTLTextureType2DMultisample : MTLTextureType2D;
52    (*desc).pixelFormat = (MTLPixelFormat)mtlSpec.fFormat;
53    (*desc).width = dimensions.width();
54    (*desc).height = dimensions.height();
55    (*desc).depth = 1;
56    (*desc).mipmapLevelCount = numMipLevels;
57    (*desc).sampleCount = info.numSamples();
58    (*desc).arrayLength = 1;
59    (*desc).usage = mtlSpec.fUsage;
60    (*desc).storageMode = (MTLStorageMode)mtlSpec.fStorageMode;
61
62    sk_cfp<id<MTLTexture>> texture([sharedContext->device() newTextureWithDescriptor:desc.get()]);
63    return texture;
64}
65
66MtlTexture::MtlTexture(const MtlSharedContext* sharedContext,
67                       SkISize dimensions,
68                       const TextureInfo& info,
69                       sk_cfp<id<MTLTexture>> texture,
70                       Ownership ownership,
71                       skgpu::Budgeted budgeted)
72        : Texture(sharedContext,
73                  dimensions,
74                  info,
75                  /*mutableState=*/nullptr,
76                  ownership,
77                  budgeted)
78        , fTexture(std::move(texture)) {}
79
80sk_sp<Texture> MtlTexture::Make(const MtlSharedContext* sharedContext,
81                                SkISize dimensions,
82                                const TextureInfo& info,
83                                skgpu::Budgeted budgeted) {
84    sk_cfp<id<MTLTexture>> texture = MakeMtlTexture(sharedContext, dimensions, info);
85    if (!texture) {
86        return nullptr;
87    }
88    return sk_sp<Texture>(new MtlTexture(sharedContext,
89                                         dimensions,
90                                         info,
91                                         std::move(texture),
92                                         Ownership::kOwned,
93                                         budgeted));
94}
95
96sk_sp<Texture> MtlTexture::MakeWrapped(const MtlSharedContext* sharedContext,
97                                       SkISize dimensions,
98                                       const TextureInfo& info,
99                                       sk_cfp<id<MTLTexture>> texture) {
100    return sk_sp<Texture>(new MtlTexture(sharedContext,
101                                         dimensions,
102                                         info,
103                                         std::move(texture),
104                                         Ownership::kWrapped,
105                                         skgpu::Budgeted::kNo));
106}
107
108void MtlTexture::freeGpuData() {
109    fTexture.reset();
110}
111
112
113void MtlTexture::setBackendLabel(char const* label) {
114    SkASSERT(label);
115#ifdef SK_ENABLE_MTL_DEBUG_INFO
116    NSString* labelStr = @(label);
117    this->mtlTexture().label = labelStr;
118#endif
119}
120
121} // namespace skgpu::graphite
122
123