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