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 fMaxRasterSamples = 0; 55 fMaxWindowRectangles = 0; 56 57 // An default count of 4 was chosen because of the common pattern in Blink of: 58 // isect RR 59 // diff RR 60 // isect convex_poly 61 // isect convex_poly 62 // when drawing rounded div borders. 63 fMaxClipAnalyticFPs = 4; 64 65 fSuppressPrints = options.fSuppressPrints; 66 #if GR_TEST_UTILS 67 fWireframeMode = options.fWireframeMode; 68 #else 69 fWireframeMode = false; 70 #endif 71 fBufferMapThreshold = options.fBufferMapThreshold; 72 fBlacklistCoverageCounting = false; 73 fAvoidStencilBuffers = false; 74 fAvoidWritePixelsFastPath = false; 75 76 fPreferVRAMUseOverFlushes = true; 77 78 // Default to true, allow older versions of OpenGL to disable explicitly 79 fClampToBorderSupport = true; 80 81 fDriverBugWorkarounds = options.fDriverBugWorkarounds; 82 } 83 84 void GrCaps::applyOptionsOverrides(const GrContextOptions& options) { 85 this->onApplyOptionsOverrides(options); 86 if (options.fDisableDriverCorrectnessWorkarounds) { 87 // We always blacklist coverage counting on Vulkan currently. TODO: Either stop doing that 88 // or disambiguate blacklisting from incomplete implementation. 89 // SkASSERT(!fBlacklistCoverageCounting); 90 SkASSERT(!fAvoidStencilBuffers); 91 SkASSERT(!fAdvBlendEqBlacklist); 92 SkASSERT(!fPerformColorClearsAsDraws); 93 SkASSERT(!fPerformStencilClearsAsDraws); 94 // Don't check the partial-clear workaround, since that is a backend limitation, not a 95 // driver workaround (it just so happens the fallbacks are the same). 96 } 97 if (GrContextOptions::Enable::kNo == options.fUseDrawInsteadOfClear) { 98 fPerformColorClearsAsDraws = false; 99 fPerformStencilClearsAsDraws = false; 100 } else if (GrContextOptions::Enable::kYes == options.fUseDrawInsteadOfClear) { 101 fPerformColorClearsAsDraws = true; 102 fPerformStencilClearsAsDraws = true; 103 } 104 105 fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride); 106 fMaxTileSize = fMaxTextureSize; 107 #if GR_TEST_UTILS 108 // If the max tile override is zero, it means we should use the max texture size. 109 if (options.fMaxTileSizeOverride && options.fMaxTileSizeOverride < fMaxTextureSize) { 110 fMaxTileSize = options.fMaxTileSizeOverride; 111 } 112 if (options.fSuppressGeometryShaders) { 113 fShaderCaps->fGeometryShaderSupport = false; 114 } 115 #endif 116 if (fMaxWindowRectangles > GrWindowRectangles::kMaxWindows) { 117 SkDebugf("WARNING: capping window rectangles at %i. HW advertises support for %i.\n", 118 GrWindowRectangles::kMaxWindows, fMaxWindowRectangles); 119 fMaxWindowRectangles = GrWindowRectangles::kMaxWindows; 120 } 121 fAvoidStencilBuffers = options.fAvoidStencilBuffers; 122 123 fDriverBugWorkarounds.applyOverrides(options.fDriverBugWorkarounds); 124 } 125 126 127 #ifdef SK_ENABLE_DUMP_GPU 128 static const char* pixel_config_name(GrPixelConfig config) { 129 switch (config) { 130 case kUnknown_GrPixelConfig: return "Unknown"; 131 case kAlpha_8_GrPixelConfig: return "Alpha8"; 132 case kAlpha_8_as_Alpha_GrPixelConfig: return "Alpha8_asAlpha"; 133 case kAlpha_8_as_Red_GrPixelConfig: return "Alpha8_asRed"; 134 case kGray_8_GrPixelConfig: return "Gray8"; 135 case kGray_8_as_Lum_GrPixelConfig: return "Gray8_asLum"; 136 case kGray_8_as_Red_GrPixelConfig: return "Gray8_asRed"; 137 case kRGB_565_GrPixelConfig: return "RGB565"; 138 case kRGBA_4444_GrPixelConfig: return "RGBA444"; 139 case kRGBA_8888_GrPixelConfig: return "RGBA8888"; 140 case kRGB_888_GrPixelConfig: return "RGB888"; 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 kRGB_ETC1_GrPixelConfig: return "RGBETC1"; 152 } 153 SK_ABORT("Invalid pixel config"); 154 return "<invalid>"; 155 } 156 157 static SkString map_flags_to_string(uint32_t flags) { 158 SkString str; 159 if (GrCaps::kNone_MapFlags == flags) { 160 str = "none"; 161 } else { 162 SkASSERT(GrCaps::kCanMap_MapFlag & flags); 163 SkDEBUGCODE(flags &= ~GrCaps::kCanMap_MapFlag); 164 str = "can_map"; 165 166 if (GrCaps::kSubset_MapFlag & flags) { 167 str.append(" partial"); 168 } else { 169 str.append(" full"); 170 } 171 SkDEBUGCODE(flags &= ~GrCaps::kSubset_MapFlag); 172 } 173 SkASSERT(0 == flags); // Make sure we handled all the flags. 174 return str; 175 } 176 177 void GrCaps::dumpJSON(SkJSONWriter* writer) const { 178 writer->beginObject(); 179 180 writer->appendBool("MIP Map Support", fMipMapSupport); 181 writer->appendBool("NPOT Texture Tile Support", fNPOTTextureTileSupport); 182 writer->appendBool("sRGB Support", fSRGBSupport); 183 writer->appendBool("sRGB Write Control", fSRGBWriteControl); 184 writer->appendBool("Discard Render Target Support", fDiscardRenderTargetSupport); 185 writer->appendBool("Reuse Scratch Textures", fReuseScratchTextures); 186 writer->appendBool("Reuse Scratch Buffers", fReuseScratchBuffers); 187 writer->appendBool("Gpu Tracing Support", fGpuTracingSupport); 188 writer->appendBool("Oversized Stencil Support", fOversizedStencilSupport); 189 writer->appendBool("Texture Barrier Support", fTextureBarrierSupport); 190 writer->appendBool("Sample Locations Support", fSampleLocationsSupport); 191 writer->appendBool("Multisample disable support", fMultisampleDisableSupport); 192 writer->appendBool("Instance Attrib Support", fInstanceAttribSupport); 193 writer->appendBool("Uses Mixed Samples", fUsesMixedSamples); 194 writer->appendBool("Use primitive restart", fUsePrimitiveRestart); 195 writer->appendBool("Prefer client-side dynamic buffers", fPreferClientSideDynamicBuffers); 196 writer->appendBool("Prefer fullscreen clears", fPreferFullscreenClears); 197 writer->appendBool("Must clear buffer memory", fMustClearUploadedBufferData); 198 writer->appendBool("Supports importing AHardwareBuffers", fSupportsAHardwareBufferImages); 199 writer->appendBool("Fence sync support", fFenceSyncSupport); 200 writer->appendBool("Cross context texture support", fCrossContextTextureSupport); 201 writer->appendBool("Half float vertex attribute support", fHalfFloatVertexAttributeSupport); 202 writer->appendBool("Specify GeometryProcessor textures as a dynamic state array", 203 fDynamicStateArrayGeometryProcessorTextureSupport); 204 writer->appendBool("Use draws for partial clears", fPerformPartialClearsAsDraws); 205 writer->appendBool("Use draws for color clears", fPerformColorClearsAsDraws); 206 writer->appendBool("Use draws for stencil clip clears", fPerformStencilClearsAsDraws); 207 writer->appendBool("Clamp-to-border", fClampToBorderSupport); 208 209 writer->appendBool("Blacklist Coverage Counting Path Renderer [workaround]", 210 fBlacklistCoverageCounting); 211 writer->appendBool("Prefer VRAM Use over flushes [workaround]", fPreferVRAMUseOverFlushes); 212 writer->appendBool("Avoid stencil buffers [workaround]", fAvoidStencilBuffers); 213 214 if (this->advancedBlendEquationSupport()) { 215 writer->appendHexU32("Advanced Blend Equation Blacklist", fAdvBlendEqBlacklist); 216 } 217 218 writer->appendS32("Max Vertex Attributes", fMaxVertexAttributes); 219 writer->appendS32("Max Texture Size", fMaxTextureSize); 220 writer->appendS32("Max Render Target Size", fMaxRenderTargetSize); 221 writer->appendS32("Max Preferred Render Target Size", fMaxPreferredRenderTargetSize); 222 writer->appendS32("Max Raster Samples", fMaxRasterSamples); 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