/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "GrCaps.h" #include "GrContextOptions.h" #include "GrWindowRectangles.h" GrCaps::GrCaps(const GrContextOptions& options) { fMipMapSupport = false; fNPOTTextureTileSupport = false; fSRGBSupport = false; fSRGBWriteControl = false; fTwoSidedStencilSupport = false; fStencilWrapOpsSupport = false; fDiscardRenderTargetSupport = false; fReuseScratchTextures = true; fReuseScratchBuffers = true; fGpuTracingSupport = false; fCompressedTexSubImageSupport = false; fOversizedStencilSupport = false; fTextureBarrierSupport = false; fSampleLocationsSupport = false; fMultisampleDisableSupport = false; fUsesMixedSamples = false; fPreferClientSideDynamicBuffers = false; fFullClearIsFree = false; fMustClearUploadedBufferData = false; fSampleShadingSupport = false; fFenceSyncSupport = false; fUseDrawInsteadOfClear = false; fInstancedSupport = InstancedSupport::kNone; fBlendEquationSupport = kBasic_BlendEquationSupport; fAdvBlendEqBlacklist = 0; fMapBufferFlags = kNone_MapFlags; fMaxVertexAttributes = 0; fMaxRenderTargetSize = 1; fMaxTextureSize = 1; fMaxColorSampleCount = 0; fMaxStencilSampleCount = 0; fMaxRasterSamples = 0; fMaxWindowRectangles = 0; fSuppressPrints = options.fSuppressPrints; fImmediateFlush = options.fImmediateMode; fBufferMapThreshold = options.fBufferMapThreshold; fUseDrawInsteadOfPartialRenderTargetWrite = options.fUseDrawInsteadOfPartialRenderTargetWrite; fUseDrawInsteadOfAllRenderTargetWrites = false; fAvoidInstancedDrawsToFPTargets = false; fPreferVRAMUseOverFlushes = true; } void GrCaps::applyOptionsOverrides(const GrContextOptions& options) { this->onApplyOptionsOverrides(options); fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride); // If the max tile override is zero, it means we should use the max texture size. if (!options.fMaxTileSizeOverride || options.fMaxTileSizeOverride > fMaxTextureSize) { fMaxTileSize = fMaxTextureSize; } else { fMaxTileSize = options.fMaxTileSizeOverride; } if (fMaxWindowRectangles > GrWindowRectangles::kMaxWindows) { SkDebugf("WARNING: capping window rectangles at %i. HW advertises support for %i.\n", GrWindowRectangles::kMaxWindows, fMaxWindowRectangles); fMaxWindowRectangles = GrWindowRectangles::kMaxWindows; } } static SkString map_flags_to_string(uint32_t flags) { SkString str; if (GrCaps::kNone_MapFlags == flags) { str = "none"; } else { SkASSERT(GrCaps::kCanMap_MapFlag & flags); SkDEBUGCODE(flags &= ~GrCaps::kCanMap_MapFlag); str = "can_map"; if (GrCaps::kSubset_MapFlag & flags) { str.append(" partial"); } else { str.append(" full"); } SkDEBUGCODE(flags &= ~GrCaps::kSubset_MapFlag); } SkASSERT(0 == flags); // Make sure we handled all the flags. return str; } SkString GrCaps::dump() const { SkString r; static const char* gNY[] = {"NO", "YES"}; r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]); r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]); r.appendf("sRGB Support : %s\n", gNY[fSRGBSupport]); r.appendf("sRGB Write Control : %s\n", gNY[fSRGBWriteControl]); r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]); r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]); r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]); r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]); r.appendf("Reuse Scratch Buffers : %s\n", gNY[fReuseScratchBuffers]); r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]); r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]); r.appendf("Oversized Stencil Support : %s\n", gNY[fOversizedStencilSupport]); r.appendf("Texture Barrier Support : %s\n", gNY[fTextureBarrierSupport]); r.appendf("Sample Locations Support : %s\n", gNY[fSampleLocationsSupport]); r.appendf("Multisample disable support : %s\n", gNY[fMultisampleDisableSupport]); r.appendf("Uses Mixed Samples : %s\n", gNY[fUsesMixedSamples]); r.appendf("Prefer client-side dynamic buffers : %s\n", gNY[fPreferClientSideDynamicBuffers]); r.appendf("Full screen clear is free : %s\n", gNY[fFullClearIsFree]); r.appendf("Must clear buffer memory : %s\n", gNY[fMustClearUploadedBufferData]); r.appendf("Sample shading support : %s\n", gNY[fSampleShadingSupport]); r.appendf("Fence sync support : %s\n", gNY[fFenceSyncSupport]); r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]); r.appendf("Draw Instead of TexSubImage [workaround] : %s\n", gNY[fUseDrawInsteadOfPartialRenderTargetWrite]); r.appendf("Prefer VRAM Use over flushes [workaround] : %s\n", gNY[fPreferVRAMUseOverFlushes]); if (this->advancedBlendEquationSupport()) { r.appendf("Advanced Blend Equation Blacklist : 0x%x\n", fAdvBlendEqBlacklist); } r.appendf("Max Vertex Attributes : %d\n", fMaxVertexAttributes); r.appendf("Max Texture Size : %d\n", fMaxTextureSize); r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize); r.appendf("Max Color Sample Count : %d\n", fMaxColorSampleCount); r.appendf("Max Stencil Sample Count : %d\n", fMaxStencilSampleCount); r.appendf("Max Raster Samples : %d\n", fMaxRasterSamples); r.appendf("Max Window Rectangles : %d\n", fMaxWindowRectangles); static const char* kInstancedSupportNames[] = { "None", "Basic", "Multisampled", "Mixed Sampled", }; GR_STATIC_ASSERT(0 == (int)InstancedSupport::kNone); GR_STATIC_ASSERT(1 == (int)InstancedSupport::kBasic); GR_STATIC_ASSERT(2 == (int)InstancedSupport::kMultisampled); GR_STATIC_ASSERT(3 == (int)InstancedSupport::kMixedSampled); GR_STATIC_ASSERT(4 == SK_ARRAY_COUNT(kInstancedSupportNames)); r.appendf("Instanced Support : %s\n", kInstancedSupportNames[(int)fInstancedSupport]); static const char* kBlendEquationSupportNames[] = { "Basic", "Advanced", "Advanced Coherent", }; GR_STATIC_ASSERT(0 == kBasic_BlendEquationSupport); GR_STATIC_ASSERT(1 == kAdvanced_BlendEquationSupport); GR_STATIC_ASSERT(2 == kAdvancedCoherent_BlendEquationSupport); GR_STATIC_ASSERT(SK_ARRAY_COUNT(kBlendEquationSupportNames) == kLast_BlendEquationSupport + 1); r.appendf("Blend Equation Support : %s\n", kBlendEquationSupportNames[fBlendEquationSupport]); r.appendf("Map Buffer Support : %s\n", map_flags_to_string(fMapBufferFlags).c_str()); static const char* kConfigNames[] = { "Unknown", // kUnknown_GrPixelConfig "Alpha8", // kAlpha_8_GrPixelConfig, "Gray8", // kGray_8_GrPixelConfig, "RGB565", // kRGB_565_GrPixelConfig, "RGBA444", // kRGBA_4444_GrPixelConfig, "RGBA8888", // kRGBA_8888_GrPixelConfig, "BGRA8888", // kBGRA_8888_GrPixelConfig, "SRGBA8888", // kSRGBA_8888_GrPixelConfig, "SBGRA8888", // kSBGRA_8888_GrPixelConfig, "RGBA8888_sint", // kRGBA_8888_sint_GrPixelConfig, "ETC1", // kETC1_GrPixelConfig, "LATC", // kLATC_GrPixelConfig, "R11EAC", // kR11_EAC_GrPixelConfig, "ASTC12x12", // kASTC_12x12_GrPixelConfig, "RGBAFloat", // kRGBA_float_GrPixelConfig "AlphaHalf", // kAlpha_half_GrPixelConfig "RGBAHalf", // kRGBA_half_GrPixelConfig }; GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig); GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig); GR_STATIC_ASSERT(2 == kGray_8_GrPixelConfig); GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig); GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig); GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig); GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig); GR_STATIC_ASSERT(7 == kSRGBA_8888_GrPixelConfig); GR_STATIC_ASSERT(8 == kSBGRA_8888_GrPixelConfig); GR_STATIC_ASSERT(9 == kRGBA_8888_sint_GrPixelConfig); GR_STATIC_ASSERT(10 == kETC1_GrPixelConfig); GR_STATIC_ASSERT(11 == kLATC_GrPixelConfig); GR_STATIC_ASSERT(12 == kR11_EAC_GrPixelConfig); GR_STATIC_ASSERT(13 == kASTC_12x12_GrPixelConfig); GR_STATIC_ASSERT(14 == kRGBA_float_GrPixelConfig); GR_STATIC_ASSERT(15 == kAlpha_half_GrPixelConfig); GR_STATIC_ASSERT(16 == kRGBA_half_GrPixelConfig); GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt); SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, false)); SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, true)); for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) { GrPixelConfig config = static_cast(i); r.appendf("%s is renderable: %s, with MSAA: %s\n", kConfigNames[i], gNY[this->isConfigRenderable(config, false)], gNY[this->isConfigRenderable(config, true)]); } SkASSERT(!this->isConfigTexturable(kUnknown_GrPixelConfig)); for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) { GrPixelConfig config = static_cast(i); r.appendf("%s is uploadable to a texture: %s\n", kConfigNames[i], gNY[this->isConfigTexturable(config)]); } return r; }