| 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) {
|
|
|