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 "GrBackendSurface.h" 10 #include "GrContextOptions.h" 11 #include "GrSurface.h" 12 #include "GrSurfaceProxy.h" 13 #include "GrTypesPriv.h" 14 #include "GrWindowRectangles.h" 15 #include "SkJSONWriter.h" 16 17 GrCaps::GrCaps(const GrContextOptions& options) { 18 fMipMapSupport = false; 19 fNPOTTextureTileSupport = false; 20 fSRGBSupport = false; 21 fSRGBWriteControl = false; 22 fDiscardRenderTargetSupport = false; 23 fReuseScratchTextures = true; 24 fReuseScratchBuffers = true; 25 fGpuTracingSupport = false; 26 fOversizedStencilSupport = false; 27 fTextureBarrierSupport = false; 28 fSampleLocationsSupport = false; 29 fMultisampleDisableSupport = false; 30 fInstanceAttribSupport = false; 31 fUsesMixedSamples = false; 32 fUsePrimitiveRestart = false; 33 fPreferClientSideDynamicBuffers = false; 34 fPreferFullscreenClears = false; 35 fMustClearUploadedBufferData = false; 36 fSupportsAHardwareBufferImages = false; 37 fFenceSyncSupport = false; 38 fCrossContextTextureSupport = false; 39 fHalfFloatVertexAttributeSupport = false; 40 fDynamicStateArrayGeometryProcessorTextureSupport = false; 41 fPerformPartialClearsAsDraws = false; 42 fPerformColorClearsAsDraws = false; 43 fPerformStencilClearsAsDraws = false; 44 45 fBlendEquationSupport = kBasic_BlendEquationSupport; 46 fAdvBlendEqBlacklist = 0; 47 48 fMapBufferFlags = kNone_MapFlags; 49 50 fMaxVertexAttributes = 0; 51 fMaxRenderTargetSize = 1; 52 fMaxPreferredRenderTargetSize = 1; 53 fMaxTextureSize = 1; 54 fMaxWindowRectangles = 0; 55 56 // An default count of 4 was chosen because of the common pattern in Blink of: 57 // isect RR 58 // diff RR 59 // isect convex_poly 60 // isect convex_poly 61 // when drawing rounded div borders. 62 fMaxClipAnalyticFPs = 4; 63 64 fSuppressPrints = options.fSuppressPrints; 65 #if GR_TEST_UTILS 66 fWireframeMode = options.fWireframeMode; 67 #else 68 fWireframeMode = false; 69 #endif 70 fBufferMapThreshold = options.fBufferMapThreshold; 71 fBlacklistCoverageCounting = false; 72 fAvoidStencilBuffers = false; 73 fAvoidWritePixelsFastPath = false; 74 75 fPreferVRAMUseOverFlushes = true; 76 77 // Default to true, allow older versions of OpenGL to disable explicitly 78 fClampToBorderSupport = true; 79 80 fDriverBugWorkarounds = options.fDriverBugWorkarounds; 81 } 82 83 void GrCaps::applyOptionsOverrides(const GrContextOptions& options) { 84 this->onApplyOptionsOverrides(options); 85 if (options.fDisableDriverCorrectnessWorkarounds) { 86 // We always blacklist coverage counting on Vulkan currently. TODO: Either stop doing that 87 // or disambiguate blacklisting from incomplete implementation. 88 // SkASSERT(!fBlacklistCoverageCounting); 89 SkASSERT(!fAvoidStencilBuffers); 90 SkASSERT(!fAdvBlendEqBlacklist); 91 SkASSERT(!fPerformColorClearsAsDraws); 92 SkASSERT(!fPerformStencilClearsAsDraws); 93 // Don't check the partial-clear workaround, since that is a backend limitation, not a 94 // driver workaround (it just so happens the fallbacks are the same). 95 } 96 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfClear) { 97 fPerformColorClearsAsDraws = false; 98 fPerformStencilClearsAsDraws = false; 99 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfClear) { 100 fPerformColorClearsAsDraws = true; 101 fPerformStencilClearsAsDraws = true; 102 } 103 104 fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride); 105 fMaxTileSize = fMaxTextureSize; 106 #if GR_TEST_UTILS 107 // If the max tile override is zero, it means we should use the max texture size. 108 if (options.fMaxTileSizeOverride && options.fMaxTileSizeOverride < fMaxTextureSize) { 109 fMaxTileSize = options.fMaxTileSizeOverride; 110 } 111 if (options.fSuppressGeometryShaders) { 112 fShaderCaps->fGeometryShaderSupport = false; 113 } 114 #endif 115 if (fMaxWindowRectangles > GrWindowRectangles::kMaxWindows) { 116 SkDebugf("WARNING: capping window rectangles at %i. HW advertises support for %i.\n", 117 GrWindowRectangles::kMaxWindows, fMaxWindowRectangles); 118 fMaxWindowRectangles = GrWindowRectangles::kMaxWindows; 119 } 120 fAvoidStencilBuffers = options.fAvoidStencilBuffers; 121 122 fDriverBugWorkarounds.applyOverrides(options.fDriverBugWorkarounds); 123 } 124 125 126 #ifdef SK_ENABLE_DUMP_GPU 127 static const char* pixel_config_name(GrPixelConfig config) { 128 switch (config) { 129 case kUnknown_GrPixelConfig: return "Unknown"; 130 case kAlpha_8_GrPixelConfig: return "Alpha8"; 131 case kAlpha_8_as_Alpha_GrPixelConfig: return "Alpha8_asAlpha"; 132 case kAlpha_8_as_Red_GrPixelConfig: return "Alpha8_asRed"; 133 case kGray_8_GrPixelConfig: return "Gray8"; 134 case kGray_8_as_Lum_GrPixelConfig: return "Gray8_asLum"; 135 case kGray_8_as_Red_GrPixelConfig: return "Gray8_asRed"; 136 case kRGB_565_GrPixelConfig: return "RGB565"; 137 case kRGBA_4444_GrPixelConfig: return "RGBA444"; 138 case kRGBA_8888_GrPixelConfig: return "RGBA8888"; 139 case kRGB_888_GrPixelConfig: return "RGB888"; 140 case kRGB_888X_GrPixelConfig: return "RGB888X"; 141 case kRG_88_GrPixelConfig: return "RG88"; 142 case kBGRA_8888_GrPixelConfig: return "BGRA8888"; 143 case kSRGBA_8888_GrPixelConfig: return "SRGBA8888"; 144 case kSBGRA_8888_GrPixelConfig: return "SBGRA8888"; 145 case kRGBA_1010102_GrPixelConfig: return "RGBA1010102"; 146 case kRGBA_float_GrPixelConfig: return "RGBAFloat"; 147 case kRG_float_GrPixelConfig: return "RGFloat"; 148 case kAlpha_half_GrPixelConfig: return "AlphaHalf"; 149 case kAlpha_half_as_Red_GrPixelConfig: return "AlphaHalf_asRed"; 150 case kRGBA_half_GrPixelConfig: return "RGBAHalf"; 151 case kRGBA_half_Clamped_GrPixelConfig: return "RGBAHalfClamped"; 152 case kRGB_ETC1_GrPixelConfig: return "RGBETC1"; 153 } 154 SK_ABORT("Invalid pixel config"); 155 return "<invalid>"; 156 } 157 158 static SkString map_flags_to_string(uint32_t flags) { 159 SkString str; 160 if (GrCaps::kNone_MapFlags == flags) { 161 str = "none"; 162 } else { 163 SkASSERT(GrCaps::kCanMap_MapFlag & flags); 164 SkDEBUGCODE(flags &= ~GrCaps::kCanMap_MapFlag); 165 str = "can_map"; 166 167 if (GrCaps::kSubset_MapFlag & flags) { 168 str.append(" partial"); 169 } else { 170 str.append(" full"); 171 } 172 SkDEBUGCODE(flags &= ~GrCaps::kSubset_MapFlag); 173 } 174 SkASSERT(0 == flags); // Make sure we handled all the flags. 175 return str; 176 } 177 178 void GrCaps::dumpJSON(SkJSONWriter* writer) const { 179 writer->beginObject(); 180 181 writer->appendBool("MIP Map Support", fMipMapSupport); 182 writer->appendBool("NPOT Texture Tile Support", fNPOTTextureTileSupport); 183 writer->appendBool("sRGB Support", fSRGBSupport); 184 writer->appendBool("sRGB Write Control", fSRGBWriteControl); 185 writer->appendBool("Discard Render Target Support", fDiscardRenderTargetSupport); 186 writer->appendBool("Reuse Scratch Textures", fReuseScratchTextures); 187 writer->appendBool("Reuse Scratch Buffers", fReuseScratchBuffers); 188 writer->appendBool("Gpu Tracing Support", fGpuTracingSupport); 189 writer->appendBool("Oversized Stencil Support", fOversizedStencilSupport); 190 writer->appendBool("Texture Barrier Support", fTextureBarrierSupport); 191 writer->appendBool("Sample Locations Support", fSampleLocationsSupport); 192 writer->appendBool("Multisample disable support", fMultisampleDisableSupport); 193 writer->appendBool("Instance Attrib Support", fInstanceAttribSupport); 194 writer->appendBool("Uses Mixed Samples", fUsesMixedSamples); 195 writer->appendBool("Use primitive restart", fUsePrimitiveRestart); 196 writer->appendBool("Prefer client-side dynamic buffers", fPreferClientSideDynamicBuffers); 197 writer->appendBool("Prefer fullscreen clears", fPreferFullscreenClears); 198 writer->appendBool("Must clear buffer memory", fMustClearUploadedBufferData); 199 writer->appendBool("Supports importing AHardwareBuffers", fSupportsAHardwareBufferImages); 200 writer->appendBool("Fence sync support", fFenceSyncSupport); 201 writer->appendBool("Cross context texture support", fCrossContextTextureSupport); 202 writer->appendBool("Half float vertex attribute support", fHalfFloatVertexAttributeSupport); 203 writer->appendBool("Specify GeometryProcessor textures as a dynamic state array", 204 fDynamicStateArrayGeometryProcessorTextureSupport); 205 writer->appendBool("Use draws for partial clears", fPerformPartialClearsAsDraws); 206 writer->appendBool("Use draws for color clears", fPerformColorClearsAsDraws); 207 writer->appendBool("Use draws for stencil clip clears", fPerformStencilClearsAsDraws); 208 writer->appendBool("Clamp-to-border", fClampToBorderSupport); 209 210 writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]", 211 fBlacklistCoverageCounting); 212 writer->appendBool("Prefer VRAM Use over flushes [workaround]", fPreferVRAMUseOverFlushes); 213 writer->appendBool("Avoid stencil buffers [workaround]", fAvoidStencilBuffers); 214 215 if (this->advancedBlendEquationSupport()) { 216 writer->appendHexU32("Advanced Blend Equation Blacklist", fAdvBlendEqBlacklist); 217 } 218 219 writer->appendS32("Max Vertex Attributes", fMaxVertexAttributes); 220 writer->appendS32("Max Texture Size", fMaxTextureSize); 221 writer->appendS32("Max Render Target Size", fMaxRenderTargetSize); 222 writer->appendS32("Max Preferred Render Target Size", fMaxPreferredRenderTargetSize); 223 writer->appendS32("Max Window Rectangles", fMaxWindowRectangles); 224 writer->appendS32("Max Clip Analytic Fragment Processors", fMaxClipAnalyticFPs); 225 226 static const char* kBlendEquationSupportNames[] = { 227 "Basic", 228 "Advanced", 229 "Advanced Coherent", 230 }; 231 GR_STATIC_ASSERT(0 == kBasic_BlendEquationSupport); 232 GR_STATIC_ASSERT(1 == kAdvanced_BlendEquationSupport); 233 GR_STATIC_ASSERT(2 == kAdvancedCoherent_BlendEquationSupport); 234 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kBlendEquationSupportNames) == kLast_BlendEquationSupport + 1); 235 236 writer->appendString("Blend Equation Support", 237 kBlendEquationSupportNames[fBlendEquationSupport]); 238 writer->appendString("Map Buffer Support", map_flags_to_string(fMapBufferFlags).c_str()); 239 240 SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig)); 241 SkASSERT(!this->isConfigTexturable(kUnknown_GrPixelConfig)); 242 243 writer->beginArray("configs"); 244 245 for (size_t i = 1; i < kGrPixelConfigCnt; ++i) { 246 GrPixelConfig config = static_cast<GrPixelConfig>(i); 247 writer->beginObject(nullptr, false); 248 writer->appendString("name", pixel_config_name(config)); 249 writer->appendS32("max sample count", this->maxRenderTargetSampleCount(config)); 250 writer->appendBool("texturable", this->isConfigTexturable(config)); 251 writer->endObject(); 252 } 253 254 writer->endArray(); 255 256 this->onDumpJSON(writer); 257 258 writer->appendName("shaderCaps"); 259 this->shaderCaps()->dumpJSON(writer); 260 261 writer->endObject(); 262 } 263 #else 264 void GrCaps::dumpJSON(SkJSONWriter* writer) const { } 265 #endif 266 267 bool GrCaps::surfaceSupportsWritePixels(const GrSurface* surface) const { 268 return surface->readOnly() ? false : this->onSurfaceSupportsWritePixels(surface); 269 } 270 271 bool GrCaps::canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 272 const SkIRect& srcRect, const SkIPoint& dstPoint) const { 273 return dst->readOnly() ? false : this->onCanCopySurface(dst, src, srcRect, dstPoint); 274 } 275 276 bool GrCaps::validateSurfaceDesc(const GrSurfaceDesc& desc, GrMipMapped mipped) const { 277 if (!this->isConfigTexturable(desc.fConfig)) { 278 return false; 279 } 280 281 if (GrMipMapped::kYes == mipped && !this->mipMapSupport()) { 282 return false; 283 } 284 285 if (desc.fWidth < 1 || desc.fHeight < 1) { 286 return false; 287 } 288 289 if (SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag)) { 290 if (0 == this->getRenderTargetSampleCount(desc.fSampleCnt, desc.fConfig)) { 291 return false; 292 } 293 int maxRTSize = this->maxRenderTargetSize(); 294 if (desc.fWidth > maxRTSize || desc.fHeight > maxRTSize) { 295 return false; 296 } 297 } else { 298 // We currently do not support multisampled textures 299 if (desc.fSampleCnt > 1) { 300 return false; 301 } 302 int maxSize = this->maxTextureSize(); 303 if (desc.fWidth > maxSize || desc.fHeight > maxSize) { 304 return false; 305 } 306 } 307 308 return true; 309 } 310 311 GrBackendFormat GrCaps::getBackendFormatFromColorType(SkColorType ct) const { 312 return this->getBackendFormatFromGrColorType(SkColorTypeToGrColorType(ct), GrSRGBEncoded::kNo); 313 } 314