/src/skia/src/gpu/graphite/Caps.cpp
Line | Count | Source (jump to first uncovered line) |
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/Caps.h" |
9 | | |
10 | | #include "include/core/SkCapabilities.h" |
11 | | #include "include/core/SkPaint.h" |
12 | | #include "include/core/SkTextureCompressionType.h" |
13 | | #include "include/gpu/ShaderErrorHandler.h" |
14 | | #include "include/gpu/graphite/ContextOptions.h" |
15 | | #include "include/gpu/graphite/TextureInfo.h" |
16 | | #include "src/core/SkBlenderBase.h" |
17 | | #include "src/gpu/graphite/GraphiteResourceKey.h" |
18 | | #include "src/gpu/graphite/ResourceTypes.h" |
19 | | #include "src/sksl/SkSLUtil.h" |
20 | | |
21 | | namespace skgpu::graphite { |
22 | | |
23 | | Caps::Caps() |
24 | | : fShaderCaps(std::make_unique<SkSL::ShaderCaps>()) |
25 | 0 | , fCapabilities(new SkCapabilities()) {} |
26 | | |
27 | 0 | Caps::~Caps() {} |
28 | | |
29 | 0 | void Caps::finishInitialization(const ContextOptions& options) { |
30 | 0 | fCapabilities->initSkCaps(fShaderCaps.get()); |
31 | |
|
32 | 0 | fDefaultMSAASamples = options.fInternalMultisampleCount; |
33 | |
|
34 | 0 | if (options.fShaderErrorHandler) { |
35 | 0 | fShaderErrorHandler = options.fShaderErrorHandler; |
36 | 0 | } else { |
37 | 0 | fShaderErrorHandler = DefaultShaderErrorHandler(); |
38 | 0 | } |
39 | |
|
40 | 0 | #if defined(GPU_TEST_UTILS) |
41 | 0 | if (options.fOptionsPriv) { |
42 | 0 | fMaxTextureSize = std::min(fMaxTextureSize, options.fOptionsPriv->fMaxTextureSizeOverride); |
43 | 0 | fMaxTextureAtlasSize = options.fOptionsPriv->fMaxTextureAtlasSize; |
44 | 0 | fRequestedPathRendererStrategy = options.fOptionsPriv->fPathRendererStrategy; |
45 | 0 | } |
46 | 0 | #endif |
47 | 0 | fGlyphCacheTextureMaximumBytes = options.fGlyphCacheTextureMaximumBytes; |
48 | 0 | fMinDistanceFieldFontSize = options.fMinDistanceFieldFontSize; |
49 | 0 | fGlyphsAsPathsFontSize = options.fGlyphsAsPathsFontSize; |
50 | 0 | fMaxPathAtlasTextureSize = options.fMaxPathAtlasTextureSize; |
51 | 0 | fAllowMultipleAtlasTextures = options.fAllowMultipleAtlasTextures; |
52 | 0 | fSupportBilerpFromGlyphAtlas = options.fSupportBilerpFromGlyphAtlas; |
53 | 0 | if (options.fDisableCachedGlyphUploads) { |
54 | 0 | fRequireOrderedRecordings = true; |
55 | 0 | } |
56 | 0 | fSetBackendLabels = options.fSetBackendLabels; |
57 | 0 | } |
58 | | |
59 | 0 | sk_sp<SkCapabilities> Caps::capabilities() const { return fCapabilities; } |
60 | | |
61 | | SkISize Caps::getDepthAttachmentDimensions(const TextureInfo& textureInfo, |
62 | 0 | const SkISize colorAttachmentDimensions) const { |
63 | 0 | return colorAttachmentDimensions; |
64 | 0 | } |
65 | | |
66 | 0 | bool Caps::isTexturable(const TextureInfo& info) const { |
67 | 0 | if (info.numSamples() > 1) { |
68 | 0 | return false; |
69 | 0 | } |
70 | 0 | return this->onIsTexturable(info); |
71 | 0 | } |
72 | | |
73 | 0 | GraphiteResourceKey Caps::makeSamplerKey(const SamplerDesc& samplerDesc) const { |
74 | 0 | GraphiteResourceKey samplerKey; |
75 | 0 | static const ResourceType kType = GraphiteResourceKey::GenerateResourceType(); |
76 | 0 | GraphiteResourceKey::Builder builder(&samplerKey, kType, /*data32Count=*/1, Shareable::kYes); |
77 | | |
78 | | // The default impl. of this method adds no additional backend information to the key. |
79 | 0 | builder[0] = samplerDesc.desc(); |
80 | |
|
81 | 0 | builder.finish(); |
82 | 0 | return samplerKey; |
83 | 0 | } |
84 | | |
85 | 0 | bool Caps::areColorTypeAndTextureInfoCompatible(SkColorType ct, const TextureInfo& info) const { |
86 | | // TODO: add SkTextureCompressionType handling |
87 | | // (can be handled by setting up the colorTypeInfo instead?) |
88 | |
|
89 | 0 | return SkToBool(this->getColorTypeInfo(ct, info)); |
90 | 0 | } |
91 | | |
92 | 0 | static inline SkColorType color_type_fallback(SkColorType ct) { |
93 | 0 | switch (ct) { |
94 | | // kRGBA_8888 is our default fallback for many color types that may not have renderable |
95 | | // backend formats. |
96 | 0 | case kAlpha_8_SkColorType: |
97 | 0 | case kRGB_565_SkColorType: |
98 | 0 | case kARGB_4444_SkColorType: |
99 | 0 | case kBGRA_8888_SkColorType: |
100 | 0 | case kRGBA_1010102_SkColorType: |
101 | 0 | case kBGRA_1010102_SkColorType: |
102 | 0 | case kRGBA_F16_SkColorType: |
103 | 0 | case kRGBA_F16Norm_SkColorType: |
104 | 0 | return kRGBA_8888_SkColorType; |
105 | 0 | case kA16_float_SkColorType: |
106 | 0 | return kRGBA_F16_SkColorType; |
107 | 0 | case kGray_8_SkColorType: |
108 | 0 | case kRGB_F16F16F16x_SkColorType: |
109 | 0 | case kRGB_101010x_SkColorType: |
110 | 0 | return kRGB_888x_SkColorType; |
111 | 0 | default: |
112 | 0 | return kUnknown_SkColorType; |
113 | 0 | } |
114 | 0 | } |
115 | | |
116 | 0 | SkColorType Caps::getRenderableColorType(SkColorType ct) const { |
117 | 0 | do { |
118 | 0 | auto texInfo = this->getDefaultSampledTextureInfo(ct, |
119 | 0 | Mipmapped::kNo, |
120 | 0 | Protected::kNo, |
121 | 0 | Renderable::kYes); |
122 | | // We continue to the fallback color type if there is no default renderable format |
123 | 0 | if (texInfo.isValid() && this->isRenderable(texInfo)) { |
124 | 0 | return ct; |
125 | 0 | } |
126 | 0 | ct = color_type_fallback(ct); |
127 | 0 | } while (ct != kUnknown_SkColorType); |
128 | 0 | return kUnknown_SkColorType; |
129 | 0 | } |
130 | | |
131 | 0 | skgpu::Swizzle Caps::getReadSwizzle(SkColorType ct, const TextureInfo& info) const { |
132 | | // TODO: add SkTextureCompressionType handling |
133 | | // (can be handled by setting up the colorTypeInfo instead?) |
134 | |
|
135 | 0 | auto colorTypeInfo = this->getColorTypeInfo(ct, info); |
136 | 0 | if (!colorTypeInfo) { |
137 | 0 | SkDEBUGFAILF("Illegal color type (%d) and format combination.", static_cast<int>(ct)); |
138 | 0 | return {}; |
139 | 0 | } |
140 | | |
141 | 0 | return colorTypeInfo->fReadSwizzle; |
142 | 0 | } Unexecuted instantiation: skgpu::graphite::Caps::getReadSwizzle(SkColorType, skgpu::graphite::TextureInfo const&) const Unexecuted instantiation: skgpu::graphite::Caps::getReadSwizzle(SkColorType, skgpu::graphite::TextureInfo const&) const |
143 | | |
144 | 0 | skgpu::Swizzle Caps::getWriteSwizzle(SkColorType ct, const TextureInfo& info) const { |
145 | 0 | auto colorTypeInfo = this->getColorTypeInfo(ct, info); |
146 | 0 | if (!colorTypeInfo) { |
147 | 0 | SkDEBUGFAILF("Illegal color type (%d) and format combination.", static_cast<int>(ct)); |
148 | 0 | return {}; |
149 | 0 | } |
150 | | |
151 | 0 | return colorTypeInfo->fWriteSwizzle; |
152 | 0 | } Unexecuted instantiation: skgpu::graphite::Caps::getWriteSwizzle(SkColorType, skgpu::graphite::TextureInfo const&) const Unexecuted instantiation: skgpu::graphite::Caps::getWriteSwizzle(SkColorType, skgpu::graphite::TextureInfo const&) const |
153 | | |
154 | 0 | DstReadRequirement Caps::getDstReadRequirement() const { |
155 | | // TODO(b/238757201): Currently this only supports dst reads by FB fetch and texture copy. |
156 | 0 | if (this->shaderCaps()->fFBFetchSupport) { |
157 | 0 | return DstReadRequirement::kFramebufferFetch; |
158 | 0 | } else { |
159 | 0 | return DstReadRequirement::kTextureCopy; |
160 | 0 | } |
161 | 0 | } |
162 | | |
163 | 0 | sktext::gpu::SubRunControl Caps::getSubRunControl(bool useSDFTForSmallText) const { |
164 | 0 | #if !defined(SK_DISABLE_SDF_TEXT) |
165 | 0 | return sktext::gpu::SubRunControl{ |
166 | 0 | this->shaderCaps()->supportsDistanceFieldText(), |
167 | 0 | useSDFTForSmallText, |
168 | 0 | true, /*ableToUsePerspectiveSDFT*/ |
169 | 0 | this->minDistanceFieldFontSize(), |
170 | 0 | this->glyphsAsPathsFontSize(), |
171 | 0 | true /*forcePathAA*/}; |
172 | | #else |
173 | | return sktext::gpu::SubRunControl{/*forcePathAA=*/true}; |
174 | | #endif |
175 | 0 | } |
176 | | |
177 | | } // namespace skgpu::graphite |