Index: src/gpu/GrCaps.cpp |
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp |
index c544d6ef772fa979ba2bb01e402c54ba7e217c82..417f7b4e7917248d07b2d29cff3ed9dcf097a58e 100644 |
--- a/src/gpu/GrCaps.cpp |
+++ b/src/gpu/GrCaps.cpp |
@@ -80,7 +80,7 @@ void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) { |
/////////////////////////////////////////////////////////////////////////////// |
-GrCaps::GrCaps(const GrContextOptions& options) { |
+GrCaps::GrCaps(const GrContextOptions& options) : fMultisampleSpecsAllocator(1) { |
fMipMapSupport = false; |
fNPOTTextureTileSupport = false; |
fTwoSidedStencilSupport = false; |
@@ -132,6 +132,68 @@ void GrCaps::applyOptionsOverrides(const GrContextOptions& options) { |
this->onApplyOptionsOverrides(options); |
} |
+inline static uint8_t multisample_specs_id(uint8_t numSamples, GrSurfaceOrigin origin, |
+ const GrCaps& caps) { |
+ if (!caps.sampleLocationsSupport()) { |
+ return numSamples; |
+ } |
+ |
+ SkASSERT(numSamples < 128); |
+ SkASSERT(kTopLeft_GrSurfaceOrigin == origin || kBottomLeft_GrSurfaceOrigin == origin); |
+ return (numSamples << 1) | (origin - 1); |
+ |
+ GR_STATIC_ASSERT(1 == kTopLeft_GrSurfaceOrigin); |
+ GR_STATIC_ASSERT(2 == kBottomLeft_GrSurfaceOrigin); |
+} |
+ |
+const GrCaps::MultisampleSpecs& |
+GrCaps::getMultisampleSpecs(const GrSurfaceDesc& desc, |
+ const QueryMultisampleFunctor& queryMultisample) const { |
+ uint8_t surfDescKey = multisample_specs_id(desc.fSampleCnt, desc.fOrigin, *this); |
+ if (fMultisampleSpecsMap.count() > surfDescKey && fMultisampleSpecsMap[surfDescKey]) { |
+#if !defined(SK_DEBUG) |
+ // In debug mode we query the multisample info every time and verify the caching is correct. |
+ return *fMultisampleSpecsMap[surfDescKey]; |
+#endif |
+ } |
+ int effectiveSampleCnt; |
+ SkAutoTDeleteArray<SkPoint> locations(nullptr); |
+ queryMultisample(&effectiveSampleCnt, &locations); |
+ SkASSERT(effectiveSampleCnt && effectiveSampleCnt >= desc.fSampleCnt); |
+ uint8_t effectiveKey = multisample_specs_id(effectiveSampleCnt, desc.fOrigin, *this); |
+ if (fMultisampleSpecsMap.count() > effectiveKey && fMultisampleSpecsMap[effectiveKey]) { |
+ const MultisampleSpecs& specs = *fMultisampleSpecsMap[effectiveKey]; |
+ SkASSERT(effectiveKey == specs.fUniqueID); |
+ SkASSERT(effectiveSampleCnt == specs.fEffectiveSampleCnt); |
+ SkASSERT(!this->sampleLocationsSupport() || !memcmp(locations.get(), |
+ specs.fSampleLocations.get(), |
+ effectiveSampleCnt * sizeof(SkPoint))); |
+ SkASSERT(surfDescKey <= effectiveKey); |
+ SkASSERT(!fMultisampleSpecsMap[surfDescKey] || fMultisampleSpecsMap[surfDescKey] == &specs); |
+ fMultisampleSpecsMap[surfDescKey] = &specs; |
+ return specs; |
+ } |
+ const MultisampleSpecs& specs = *new (&fMultisampleSpecsAllocator) |
+ MultisampleSpecs{effectiveKey, effectiveSampleCnt, locations.detach()}; |
+ if (fMultisampleSpecsMap.count() <= effectiveKey) { |
+ int n = 1 + effectiveKey - fMultisampleSpecsMap.count(); |
+ fMultisampleSpecsMap.push_back_n(n, (const MultisampleSpecs*) nullptr); |
+ } |
+ fMultisampleSpecsMap[effectiveKey] = &specs; |
+ if (effectiveSampleCnt != desc.fSampleCnt) { |
+ SkASSERT(surfDescKey < effectiveKey); |
+ fMultisampleSpecsMap[surfDescKey] = &specs; |
+ } |
+ return specs; |
+} |
+ |
+const GrCaps::MultisampleSpecs& GrCaps::getMultisampleSpecs(uint8_t uniqueID) const { |
+ SkASSERT(fMultisampleSpecsMap.count() > uniqueID && fMultisampleSpecsMap[uniqueID]); |
+ const MultisampleSpecs& specs = *fMultisampleSpecsMap[uniqueID]; |
+ SkASSERT(specs.fUniqueID == uniqueID); |
+ return specs; |
+} |
+ |
static SkString map_flags_to_string(uint32_t flags) { |
SkString str; |
if (GrCaps::kNone_MapFlags == flags) { |