• 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/GrMtlGpu.h"
9#include "src/gpu/mtl/GrMtlTextureRenderTarget.h"
10#include "src/gpu/mtl/GrMtlUtil.h"
11
12#if !__has_feature(objc_arc)
13#error This file must be compiled with Arc. Use -fobjc-arc flag
14#endif
15
16GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
17                                                   SkBudgeted budgeted,
18                                                   const GrSurfaceDesc& desc,
19                                                   int sampleCnt,
20                                                   id<MTLTexture> colorTexture,
21                                                   id<MTLTexture> resolveTexture,
22                                                   GrMipMapsStatus mipMapsStatus)
23        : GrSurface(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo)
24        , GrMtlTexture(gpu, desc, resolveTexture, mipMapsStatus)
25        , GrMtlRenderTarget(gpu, desc, sampleCnt, colorTexture, resolveTexture) {
26    this->registerWithCache(budgeted);
27}
28
29GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
30                                                   SkBudgeted budgeted,
31                                                   const GrSurfaceDesc& desc,
32                                                   id<MTLTexture> colorTexture,
33                                                   GrMipMapsStatus mipMapsStatus)
34        : GrSurface(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo)
35        , GrMtlTexture(gpu, desc, colorTexture, mipMapsStatus)
36        , GrMtlRenderTarget(gpu, desc, colorTexture) {
37    this->registerWithCache(budgeted);
38}
39
40GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
41                                                   const GrSurfaceDesc& desc,
42                                                   int sampleCnt,
43                                                   id<MTLTexture> colorTexture,
44                                                   id<MTLTexture> resolveTexture,
45                                                   GrMipMapsStatus mipMapsStatus,
46                                                   GrWrapCacheable cacheable)
47        : GrSurface(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo)
48        , GrMtlTexture(gpu, desc, resolveTexture, mipMapsStatus)
49        , GrMtlRenderTarget(gpu, desc, sampleCnt, colorTexture, resolveTexture) {
50    this->registerWithCacheWrapped(cacheable);
51}
52
53GrMtlTextureRenderTarget::GrMtlTextureRenderTarget(GrMtlGpu* gpu,
54                                                   const GrSurfaceDesc& desc,
55                                                   id<MTLTexture> colorTexture,
56                                                   GrMipMapsStatus mipMapsStatus,
57                                                   GrWrapCacheable cacheable)
58        : GrSurface(gpu, {desc.fWidth, desc.fHeight}, desc.fConfig, GrProtected::kNo)
59        , GrMtlTexture(gpu, desc, colorTexture, mipMapsStatus)
60        , GrMtlRenderTarget(gpu, desc, colorTexture) {
61    this->registerWithCacheWrapped(cacheable);
62}
63
64id<MTLTexture> create_msaa_texture(GrMtlGpu* gpu, const GrSurfaceDesc& desc, int sampleCnt) {
65    MTLPixelFormat format;
66    if (!GrPixelConfigToMTLFormat(desc.fConfig, &format)) {
67        return nullptr;
68    }
69    MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init];
70    texDesc.textureType = MTLTextureType2DMultisample;
71    texDesc.pixelFormat = format;
72    texDesc.width = desc.fWidth;
73    texDesc.height = desc.fHeight;
74    texDesc.depth = 1;
75    texDesc.mipmapLevelCount = 1;
76    texDesc.sampleCount = sampleCnt;
77    texDesc.arrayLength = 1;
78    texDesc.storageMode = MTLStorageModePrivate;
79    texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
80
81    return [gpu->device() newTextureWithDescriptor:texDesc];
82}
83
84sk_sp<GrMtlTextureRenderTarget> GrMtlTextureRenderTarget::MakeNewTextureRenderTarget(
85        GrMtlGpu* gpu,
86        SkBudgeted budgeted,
87        const GrSurfaceDesc& desc,
88        int sampleCnt,
89        MTLTextureDescriptor* texDesc,
90        GrMipMapsStatus mipMapsStatus) {
91    id<MTLTexture> texture = [gpu->device() newTextureWithDescriptor:texDesc];
92    if (!texture) {
93        return nullptr;
94    }
95    SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & texture.usage);
96
97    if (sampleCnt > 1) {
98        id<MTLTexture> colorTexture = create_msaa_texture(gpu, desc, sampleCnt);
99        if (!colorTexture) {
100            return nullptr;
101        }
102        SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & colorTexture.usage);
103        return sk_sp<GrMtlTextureRenderTarget>(new GrMtlTextureRenderTarget(
104                gpu, budgeted, desc, sampleCnt, colorTexture, texture, mipMapsStatus));
105    } else {
106        return sk_sp<GrMtlTextureRenderTarget>(
107                new GrMtlTextureRenderTarget(gpu, budgeted, desc, texture, mipMapsStatus));
108    }
109}
110
111sk_sp<GrMtlTextureRenderTarget> GrMtlTextureRenderTarget::MakeWrappedTextureRenderTarget(
112        GrMtlGpu* gpu,
113        const GrSurfaceDesc& desc,
114        int sampleCnt,
115        id<MTLTexture> texture,
116        GrWrapCacheable cacheable) {
117    SkASSERT(nil != texture);
118    SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & texture.usage);
119    GrMipMapsStatus mipMapsStatus = texture.mipmapLevelCount > 1
120                                            ? GrMipMapsStatus::kDirty
121                                            : GrMipMapsStatus::kNotAllocated;
122    if (sampleCnt > 1) {
123        id<MTLTexture> colorTexture = create_msaa_texture(gpu, desc, sampleCnt);
124        if (!colorTexture) {
125            return nullptr;
126        }
127        SkASSERT((MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget) & colorTexture.usage);
128        return sk_sp<GrMtlTextureRenderTarget>(new GrMtlTextureRenderTarget(
129                gpu, desc, sampleCnt, colorTexture, texture, mipMapsStatus, cacheable));
130    } else {
131        return sk_sp<GrMtlTextureRenderTarget>(
132                new GrMtlTextureRenderTarget(gpu, desc, texture, mipMapsStatus, cacheable));
133    }
134}
135