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