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