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 | #ifndef GrMockCaps_DEFINED |
9 | #define GrMockCaps_DEFINED |
10 | |
11 | #include "include/gpu/mock/GrMockTypes.h" |
12 | #include "src/gpu/GrCaps.h" |
13 | #include "src/gpu/SkGr.h" |
14 | |
15 | class GrMockCaps : public GrCaps { |
16 | public: |
17 | GrMockCaps(const GrContextOptions& contextOptions, const GrMockOptions& options) |
18 | : INHERITED(contextOptions), fOptions(options) { |
19 | fMipMapSupport = options.fMipMapSupport; |
20 | fDrawInstancedSupport = options.fDrawInstancedSupport; |
21 | fHalfFloatVertexAttributeSupport = options.fHalfFloatVertexAttributeSupport; |
22 | fMapBufferFlags = options.fMapBufferFlags; |
23 | fBufferMapThreshold = SK_MaxS32; // Overridable in GrContextOptions. |
24 | fMaxTextureSize = options.fMaxTextureSize; |
25 | fMaxRenderTargetSize = std::min(options.fMaxRenderTargetSize, fMaxTextureSize); |
26 | fMaxPreferredRenderTargetSize = fMaxRenderTargetSize; |
27 | fMaxVertexAttributes = options.fMaxVertexAttributes; |
28 | fSampleLocationsSupport = true; |
29 | |
30 | fShaderCaps.reset(new GrShaderCaps(contextOptions)); |
31 | fShaderCaps->fGeometryShaderSupport = options.fGeometryShaderSupport; |
32 | fShaderCaps->fIntegerSupport = options.fIntegerSupport; |
33 | fShaderCaps->fFlatInterpolationSupport = options.fFlatInterpolationSupport; |
34 | fShaderCaps->fMaxFragmentSamplers = options.fMaxFragmentSamplers; |
35 | fShaderCaps->fShaderDerivativeSupport = options.fShaderDerivativeSupport; |
36 | fShaderCaps->fDualSourceBlendingSupport = options.fDualSourceBlendingSupport; |
37 | fShaderCaps->fSampleMaskSupport = true; |
38 | |
39 | this->finishInitialization(contextOptions); |
40 | } |
41 | |
42 | bool isFormatSRGB(const GrBackendFormat& format) const override { |
43 | SkImage::CompressionType compression = format.asMockCompressionType(); |
44 | if (compression != SkImage::CompressionType::kNone) { |
45 | return false; |
46 | } |
47 | |
48 | auto ct = format.asMockColorType(); |
49 | return GrGetColorTypeDesc(ct).encoding() == GrColorTypeEncoding::kSRGBUnorm; |
50 | } |
51 | |
52 | SkImage::CompressionType compressionType(const GrBackendFormat& format) const override { |
53 | return format.asMockCompressionType(); |
54 | } |
55 | |
56 | bool isFormatTexturable(const GrBackendFormat& format) const override { |
57 | SkImage::CompressionType compression = format.asMockCompressionType(); |
58 | if (compression != SkImage::CompressionType::kNone) { |
59 | return fOptions.fCompressedOptions[(int)compression].fTexturable; |
60 | } |
61 | |
62 | auto index = static_cast<int>(format.asMockColorType()); |
63 | return fOptions.fConfigOptions[index].fTexturable; |
64 | } |
65 | |
66 | bool isFormatCopyable(const GrBackendFormat& format) const override { |
67 | return false; |
68 | } |
69 | |
70 | bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, |
71 | int sampleCount = 1) const override { |
72 | // Currently we don't allow RGB_888X to be renderable because we don't have a way to |
73 | // handle blends that reference dst alpha when the values in the dst alpha channel are |
74 | // uninitialized. |
75 | if (ct == GrColorType::kRGB_888x) { |
76 | return false; |
77 | } |
78 | return this->isFormatRenderable(format, sampleCount); |
79 | } |
80 | |
81 | bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override { |
82 | if (format.asMockCompressionType() != SkImage::CompressionType::kNone) { |
83 | return false; // compressed formats are never renderable |
84 | } |
85 | |
86 | return sampleCount <= this->maxRenderTargetSampleCount(format.asMockColorType()); |
87 | } |
88 | |
89 | int getRenderTargetSampleCount(int requestCount, GrColorType ct) const { |
90 | requestCount = std::max(requestCount, 1); |
91 | |
92 | switch (fOptions.fConfigOptions[(int)ct].fRenderability) { |
93 | case GrMockOptions::ConfigOptions::Renderability::kNo: |
94 | return 0; |
95 | case GrMockOptions::ConfigOptions::Renderability::kNonMSAA: |
96 | return requestCount > 1 ? 0 : 1; |
97 | case GrMockOptions::ConfigOptions::Renderability::kMSAA: |
98 | return requestCount > kMaxSampleCnt ? 0 : GrNextPow2(requestCount); |
99 | } |
100 | return 0; |
101 | } |
102 | |
103 | int getRenderTargetSampleCount(int requestCount, |
104 | const GrBackendFormat& format) const override { |
105 | SkImage::CompressionType compression = format.asMockCompressionType(); |
106 | if (compression != SkImage::CompressionType::kNone) { |
107 | return 0; // no compressed format is renderable |
108 | } |
109 | |
110 | return this->getRenderTargetSampleCount(requestCount, format.asMockColorType()); |
111 | } |
112 | |
113 | int maxRenderTargetSampleCount(GrColorType ct) const { |
114 | switch (fOptions.fConfigOptions[(int)ct].fRenderability) { |
115 | case GrMockOptions::ConfigOptions::Renderability::kNo: |
116 | return 0; |
117 | case GrMockOptions::ConfigOptions::Renderability::kNonMSAA: |
118 | return 1; |
119 | case GrMockOptions::ConfigOptions::Renderability::kMSAA: |
120 | return kMaxSampleCnt; |
121 | } |
122 | return 0; |
123 | } |
124 | |
125 | int maxRenderTargetSampleCount(const GrBackendFormat& format) const override { |
126 | SkImage::CompressionType compression = format.asMockCompressionType(); |
127 | if (compression != SkImage::CompressionType::kNone) { |
128 | return 0; // no compressed format is renderable |
129 | } |
130 | |
131 | return this->maxRenderTargetSampleCount(format.asMockColorType()); |
132 | } |
133 | |
134 | size_t bytesPerPixel(const GrBackendFormat& format) const override { |
135 | SkImage::CompressionType compression = format.asMockCompressionType(); |
136 | if (compression != SkImage::CompressionType::kNone) { |
137 | return 0; |
138 | } |
139 | |
140 | return GrColorTypeBytesPerPixel(format.asMockColorType()); |
141 | } |
142 | |
143 | SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, |
144 | const GrBackendFormat& surfaceFormat, |
145 | GrColorType srcColorType) const override { |
146 | return {surfaceColorType, 1}; |
147 | } |
148 | |
149 | SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override { |
150 | return SurfaceReadPixelsSupport::kSupported; |
151 | } |
152 | |
153 | GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override { |
154 | return {}; |
155 | } |
156 | |
157 | GrSwizzle getReadSwizzle(const GrBackendFormat& format, GrColorType ct) const override { |
158 | SkASSERT(this->areColorTypeAndFormatCompatible(ct, format)); |
159 | return GrSwizzle("rgba" ); |
160 | } |
161 | GrSwizzle getWriteSwizzle(const GrBackendFormat& format, GrColorType ct) const override { |
162 | SkASSERT(this->areColorTypeAndFormatCompatible(ct, format)); |
163 | return GrSwizzle("rgba" ); |
164 | } |
165 | |
166 | uint64_t computeFormatKey(const GrBackendFormat&) const override; |
167 | |
168 | GrProgramDesc makeDesc(const GrRenderTarget*, const GrProgramInfo&) const override; |
169 | |
170 | #if GR_TEST_UTILS |
171 | std::vector<GrCaps::TestFormatColorTypeCombination> getTestingCombinations() const override; |
172 | #endif |
173 | |
174 | private: |
175 | bool onSurfaceSupportsWritePixels(const GrSurface*) const override { return true; } |
176 | bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, |
177 | const SkIRect& srcRect, const SkIPoint& dstPoint) const override { |
178 | return true; |
179 | } |
180 | GrBackendFormat onGetDefaultBackendFormat(GrColorType ct) const override { |
181 | return GrBackendFormat::MakeMock(ct, SkImage::CompressionType::kNone); |
182 | } |
183 | |
184 | bool onAreColorTypeAndFormatCompatible(GrColorType ct, |
185 | const GrBackendFormat& format) const override { |
186 | if (ct == GrColorType::kUnknown) { |
187 | return false; |
188 | } |
189 | |
190 | SkImage::CompressionType compression = format.asMockCompressionType(); |
191 | if (compression == SkImage::CompressionType::kETC2_RGB8_UNORM || |
192 | compression == SkImage::CompressionType::kBC1_RGB8_UNORM) { |
193 | return ct == GrColorType::kRGB_888x; // TODO: this may be too restrictive |
194 | } |
195 | if (compression == SkImage::CompressionType::kBC1_RGBA8_UNORM) { |
196 | return ct == GrColorType::kRGBA_8888; |
197 | } |
198 | |
199 | return ct == format.asMockColorType(); |
200 | } |
201 | |
202 | SupportedRead onSupportedReadPixelsColorType(GrColorType srcColorType, const GrBackendFormat&, |
203 | GrColorType) const override { |
204 | return SupportedRead{srcColorType, 1}; |
205 | } |
206 | |
207 | static const int kMaxSampleCnt = 16; |
208 | |
209 | GrMockOptions fOptions; |
210 | typedef GrCaps INHERITED; |
211 | }; |
212 | |
213 | #endif |
214 | |