1 /*
2 * Copyright 2015 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 #include "GrCaps.h"
9 #include "GrContextOptions.h"
10 #include "GrWindowRectangles.h"
11
pixel_config_name(GrPixelConfig config)12 static const char* pixel_config_name(GrPixelConfig config) {
13 switch (config) {
14 case kUnknown_GrPixelConfig: return "Unknown";
15 case kAlpha_8_GrPixelConfig: return "Alpha8";
16 case kGray_8_GrPixelConfig: return "Gray8";
17 case kRGB_565_GrPixelConfig: return "RGB565";
18 case kRGBA_4444_GrPixelConfig: return "RGBA444";
19 case kRGBA_8888_GrPixelConfig: return "RGBA8888";
20 case kBGRA_8888_GrPixelConfig: return "BGRA8888";
21 case kSRGBA_8888_GrPixelConfig: return "SRGBA8888";
22 case kSBGRA_8888_GrPixelConfig: return "SBGRA8888";
23 case kRGBA_8888_sint_GrPixelConfig: return "RGBA8888_sint";
24 case kETC1_GrPixelConfig: return "ETC1";
25 case kRGBA_float_GrPixelConfig: return "RGBAFloat";
26 case kRG_float_GrPixelConfig: return "RGFloat";
27 case kAlpha_half_GrPixelConfig: return "AlphaHalf";
28 case kRGBA_half_GrPixelConfig: return "RGBAHalf";
29 }
30 SkFAIL("Invalid pixel config");
31 return "<invalid>";
32 }
33
GrCaps(const GrContextOptions & options)34 GrCaps::GrCaps(const GrContextOptions& options) {
35 fMipMapSupport = false;
36 fNPOTTextureTileSupport = false;
37 fSRGBSupport = false;
38 fSRGBWriteControl = false;
39 fTwoSidedStencilSupport = false;
40 fStencilWrapOpsSupport = false;
41 fDiscardRenderTargetSupport = false;
42 fReuseScratchTextures = true;
43 fReuseScratchBuffers = true;
44 fGpuTracingSupport = false;
45 fCompressedTexSubImageSupport = false;
46 fOversizedStencilSupport = false;
47 fTextureBarrierSupport = false;
48 fSampleLocationsSupport = false;
49 fMultisampleDisableSupport = false;
50 fUsesMixedSamples = false;
51 fPreferClientSideDynamicBuffers = false;
52 fFullClearIsFree = false;
53 fMustClearUploadedBufferData = false;
54 fSampleShadingSupport = false;
55 fFenceSyncSupport = false;
56 fCrossContextTextureSupport = false;
57
58 fUseDrawInsteadOfClear = false;
59
60 fInstancedSupport = InstancedSupport::kNone;
61
62 fBlendEquationSupport = kBasic_BlendEquationSupport;
63 fAdvBlendEqBlacklist = 0;
64
65 fMapBufferFlags = kNone_MapFlags;
66
67 fMaxVertexAttributes = 0;
68 fMaxRenderTargetSize = 1;
69 fMaxTextureSize = 1;
70 fMaxColorSampleCount = 0;
71 fMaxStencilSampleCount = 0;
72 fMaxRasterSamples = 0;
73 fMaxWindowRectangles = 0;
74
75 fSuppressPrints = options.fSuppressPrints;
76 fImmediateFlush = options.fImmediateMode;
77 fBufferMapThreshold = options.fBufferMapThreshold;
78 fUseDrawInsteadOfPartialRenderTargetWrite = options.fUseDrawInsteadOfPartialRenderTargetWrite;
79 fUseDrawInsteadOfAllRenderTargetWrites = false;
80 fAvoidInstancedDrawsToFPTargets = false;
81
82 fPreferVRAMUseOverFlushes = true;
83 }
84
applyOptionsOverrides(const GrContextOptions & options)85 void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
86 this->onApplyOptionsOverrides(options);
87 fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride);
88 // If the max tile override is zero, it means we should use the max texture size.
89 if (!options.fMaxTileSizeOverride || options.fMaxTileSizeOverride > fMaxTextureSize) {
90 fMaxTileSize = fMaxTextureSize;
91 } else {
92 fMaxTileSize = options.fMaxTileSizeOverride;
93 }
94 if (fMaxWindowRectangles > GrWindowRectangles::kMaxWindows) {
95 SkDebugf("WARNING: capping window rectangles at %i. HW advertises support for %i.\n",
96 GrWindowRectangles::kMaxWindows, fMaxWindowRectangles);
97 fMaxWindowRectangles = GrWindowRectangles::kMaxWindows;
98 }
99 }
100
map_flags_to_string(uint32_t flags)101 static SkString map_flags_to_string(uint32_t flags) {
102 SkString str;
103 if (GrCaps::kNone_MapFlags == flags) {
104 str = "none";
105 } else {
106 SkASSERT(GrCaps::kCanMap_MapFlag & flags);
107 SkDEBUGCODE(flags &= ~GrCaps::kCanMap_MapFlag);
108 str = "can_map";
109
110 if (GrCaps::kSubset_MapFlag & flags) {
111 str.append(" partial");
112 } else {
113 str.append(" full");
114 }
115 SkDEBUGCODE(flags &= ~GrCaps::kSubset_MapFlag);
116 }
117 SkASSERT(0 == flags); // Make sure we handled all the flags.
118 return str;
119 }
120
dump() const121 SkString GrCaps::dump() const {
122 SkString r;
123 static const char* gNY[] = {"NO", "YES"};
124 r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]);
125 r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
126 r.appendf("sRGB Support : %s\n", gNY[fSRGBSupport]);
127 r.appendf("sRGB Write Control : %s\n", gNY[fSRGBWriteControl]);
128 r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
129 r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
130 r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]);
131 r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]);
132 r.appendf("Reuse Scratch Buffers : %s\n", gNY[fReuseScratchBuffers]);
133 r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]);
134 r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]);
135 r.appendf("Oversized Stencil Support : %s\n", gNY[fOversizedStencilSupport]);
136 r.appendf("Texture Barrier Support : %s\n", gNY[fTextureBarrierSupport]);
137 r.appendf("Sample Locations Support : %s\n", gNY[fSampleLocationsSupport]);
138 r.appendf("Multisample disable support : %s\n", gNY[fMultisampleDisableSupport]);
139 r.appendf("Uses Mixed Samples : %s\n", gNY[fUsesMixedSamples]);
140 r.appendf("Prefer client-side dynamic buffers : %s\n", gNY[fPreferClientSideDynamicBuffers]);
141 r.appendf("Full screen clear is free : %s\n", gNY[fFullClearIsFree]);
142 r.appendf("Must clear buffer memory : %s\n", gNY[fMustClearUploadedBufferData]);
143 r.appendf("Sample shading support : %s\n", gNY[fSampleShadingSupport]);
144 r.appendf("Fence sync support : %s\n", gNY[fFenceSyncSupport]);
145 r.appendf("Cross context texture support : %s\n", gNY[fCrossContextTextureSupport]);
146
147 r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]);
148 r.appendf("Draw Instead of TexSubImage [workaround] : %s\n",
149 gNY[fUseDrawInsteadOfPartialRenderTargetWrite]);
150 r.appendf("Prefer VRAM Use over flushes [workaround] : %s\n", gNY[fPreferVRAMUseOverFlushes]);
151
152 if (this->advancedBlendEquationSupport()) {
153 r.appendf("Advanced Blend Equation Blacklist : 0x%x\n", fAdvBlendEqBlacklist);
154 }
155
156 r.appendf("Max Vertex Attributes : %d\n", fMaxVertexAttributes);
157 r.appendf("Max Texture Size : %d\n", fMaxTextureSize);
158 r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
159 r.appendf("Max Color Sample Count : %d\n", fMaxColorSampleCount);
160 r.appendf("Max Stencil Sample Count : %d\n", fMaxStencilSampleCount);
161 r.appendf("Max Raster Samples : %d\n", fMaxRasterSamples);
162 r.appendf("Max Window Rectangles : %d\n", fMaxWindowRectangles);
163
164 static const char* kInstancedSupportNames[] = {
165 "None",
166 "Basic",
167 "Multisampled",
168 "Mixed Sampled",
169 };
170 GR_STATIC_ASSERT(0 == (int)InstancedSupport::kNone);
171 GR_STATIC_ASSERT(1 == (int)InstancedSupport::kBasic);
172 GR_STATIC_ASSERT(2 == (int)InstancedSupport::kMultisampled);
173 GR_STATIC_ASSERT(3 == (int)InstancedSupport::kMixedSampled);
174 GR_STATIC_ASSERT(4 == SK_ARRAY_COUNT(kInstancedSupportNames));
175
176 r.appendf("Instanced Support : %s\n",
177 kInstancedSupportNames[(int)fInstancedSupport]);
178
179 static const char* kBlendEquationSupportNames[] = {
180 "Basic",
181 "Advanced",
182 "Advanced Coherent",
183 };
184 GR_STATIC_ASSERT(0 == kBasic_BlendEquationSupport);
185 GR_STATIC_ASSERT(1 == kAdvanced_BlendEquationSupport);
186 GR_STATIC_ASSERT(2 == kAdvancedCoherent_BlendEquationSupport);
187 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kBlendEquationSupportNames) == kLast_BlendEquationSupport + 1);
188
189 r.appendf("Blend Equation Support : %s\n",
190 kBlendEquationSupportNames[fBlendEquationSupport]);
191 r.appendf("Map Buffer Support : %s\n",
192 map_flags_to_string(fMapBufferFlags).c_str());
193
194 SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, false));
195 SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, true));
196
197 for (size_t i = 1; i < kGrPixelConfigCnt; ++i) {
198 GrPixelConfig config = static_cast<GrPixelConfig>(i);
199 r.appendf("%s is renderable: %s, with MSAA: %s\n",
200 pixel_config_name(config),
201 gNY[this->isConfigRenderable(config, false)],
202 gNY[this->isConfigRenderable(config, true)]);
203 }
204
205 SkASSERT(!this->isConfigTexturable(kUnknown_GrPixelConfig));
206
207 for (size_t i = 1; i < kGrPixelConfigCnt; ++i) {
208 GrPixelConfig config = static_cast<GrPixelConfig>(i);
209 r.appendf("%s is uploadable to a texture: %s\n",
210 pixel_config_name(config),
211 gNY[this->isConfigTexturable(config)]);
212 }
213
214 return r;
215 }
216