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
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
174private:
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