Flutter Engine
The Flutter Engine
MtlSampler.mm
Go to the documentation of this file.
1/*
2 * Copyright 2022 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
9
13
14namespace skgpu::graphite {
15
16MtlSampler::MtlSampler(const MtlSharedContext* sharedContext,
17 sk_cfp<id<MTLSamplerState>> samplerState)
18 : Sampler(sharedContext)
19 , fSamplerState(std::move(samplerState)) {}
20
21static inline MTLSamplerAddressMode tile_mode_to_mtl_sampler_address(SkTileMode tileMode,
22 const Caps& caps) {
23 switch (tileMode) {
25 return MTLSamplerAddressModeClampToEdge;
27 return MTLSamplerAddressModeRepeat;
29 return MTLSamplerAddressModeMirrorRepeat;
31 // For this tilemode, we should have checked that clamp-to-border support exists.
32 // If it doesn't we should have fallen back to a shader instead.
33 // TODO: for textures with alpha, we could use ClampToZero if there's no
34 // ClampToBorderColor as they'll clamp to (0,0,0,0).
35 // Unfortunately textures without alpha end up clamping to (0,0,0,1).
36 if (@available(macOS 10.12, iOS 14.0, tvOS 14.0, *)) {
38 return MTLSamplerAddressModeClampToBorderColor;
39 } else {
40 SkASSERT(false);
41 return MTLSamplerAddressModeClampToZero;
42 }
43 }
45}
46
48 const SkSamplingOptions& samplingOptions,
49 SkTileMode xTileMode,
50 SkTileMode yTileMode) {
51 sk_cfp<MTLSamplerDescriptor*> desc([[MTLSamplerDescriptor alloc] init]);
52
53 MTLSamplerMinMagFilter minMagFilter = [&] {
54 switch (samplingOptions.filter) {
55 case SkFilterMode::kNearest: return MTLSamplerMinMagFilterNearest;
56 case SkFilterMode::kLinear: return MTLSamplerMinMagFilterLinear;
57 }
59 }();
60
61 MTLSamplerMipFilter mipFilter = [&] {
62 switch (samplingOptions.mipmap) {
63 case SkMipmapMode::kNone: return MTLSamplerMipFilterNotMipmapped;
64 case SkMipmapMode::kNearest: return MTLSamplerMipFilterNearest;
65 case SkMipmapMode::kLinear: return MTLSamplerMipFilterLinear;
66 }
68 }();
69
70 (*desc).rAddressMode = MTLSamplerAddressModeClampToEdge;
71 (*desc).sAddressMode = tile_mode_to_mtl_sampler_address(xTileMode, sharedContext->mtlCaps());
72 (*desc).tAddressMode = tile_mode_to_mtl_sampler_address(yTileMode, sharedContext->mtlCaps());
73 (*desc).magFilter = minMagFilter;
74 (*desc).minFilter = minMagFilter;
75 (*desc).mipFilter = mipFilter;
76 (*desc).lodMinClamp = 0.0f;
77 (*desc).lodMaxClamp = FLT_MAX; // default value according to docs.
78 (*desc).maxAnisotropy = 1; // TODO: if we start using aniso, need to add to key
79 (*desc).normalizedCoordinates = true;
80 if (@available(macOS 10.11, iOS 9.0, tvOS 9.0, *)) {
81 (*desc).compareFunction = MTLCompareFunctionNever;
82 }
83#ifdef SK_ENABLE_MTL_DEBUG_INFO
84 NSString* tileModeLabels[] = {
85 @"Clamp",
86 @"Repeat",
87 @"Mirror",
88 @"Decal"
89 };
90 NSString* minMagFilterLabels[] = {
91 @"Nearest",
92 @"Linear"
93 };
94 NSString* mipFilterLabels[] = {
95 @"MipNone",
96 @"MipNearest",
97 @"MipLinear"
98 };
99
100 (*desc).label = [NSString stringWithFormat:@"X%@Y%@%@%@",
101 tileModeLabels[(int)xTileMode],
102 tileModeLabels[(int)yTileMode],
103 minMagFilterLabels[(int)samplingOptions.filter],
104 mipFilterLabels[(int)samplingOptions.mipmap]];
105#endif
106
107 sk_cfp<id<MTLSamplerState>> sampler(
108 [sharedContext->device() newSamplerStateWithDescriptor:desc.get()]);
109 if (!sampler) {
110 return nullptr;
111 }
112 return sk_sp<MtlSampler>(new MtlSampler(sharedContext, std::move(sampler)));
113}
114
115void MtlSampler::freeGpuData() {
116 fSamplerState.reset();
117}
118
119} // namespace skgpu::graphite
120
#define SkUNREACHABLE
Definition: SkAssert.h:135
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkTileMode
Definition: SkTileMode.h:13
bool clampToBorderSupport() const
Definition: Caps.h:224
const MtlCaps & mtlCaps() const
id< MTLDevice > device() const
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
static bool init()
std::function< ProfileSample(void)> Sampler
Sampler is run during SamplingProfiler::SampleRepeatedly. Each platform should implement its version ...
static MTLSamplerAddressMode tile_mode_to_mtl_sampler_address(SkTileMode tileMode, const Caps &caps)
Definition: MtlSampler.mm:21
Definition: ref_ptr.h:256
const SkFilterMode filter
const SkMipmapMode mipmap