[graphite] Add debug guards against reusing dead SkCombinationOptions

Bug: skia:12701
Change-Id: I4209a4741a957a4dc60ad6669fc164a2d5993676
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/545720
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2022-06-03 09:38:16 -04:00 committed by SkCQ
parent c18fb9c8a2
commit 0c8a88526d
3 changed files with 46 additions and 0 deletions

View File

@ -2245,6 +2245,24 @@ void precompile(skgpu::graphite::Context* context) {
context->precompile(builder);
}
#ifdef SK_DEBUG
// TODO: move this to CombinationBuilderTest
builder.reset();
// Check that epochs are updated upon builder reset
{
SkCombinationOption solid_0 = builder.addOption(SkShaderType::kSolidColor);
int optionEpoch = solid_0.epoch();
SkASSERT(optionEpoch == builder.epoch());
builder.reset();
SkASSERT(optionEpoch != builder.epoch());
}
#endif
}
} // anonymous namespace

View File

@ -97,6 +97,7 @@ public:
bool isValid() const { return fDataInArena; }
SkShaderType type() const;
int numChildSlots() const;
SkDEBUGCODE(int epoch() const;)
private:
friend class SkCombinationBuilder; // for ctor
@ -143,6 +144,7 @@ public:
#ifdef SK_DEBUG
void dump() const;
int epoch() const { return fEpoch; }
#endif
private:
@ -167,6 +169,8 @@ private:
// TODO: store the SkBlender-based blenders in the arena
SkTHashSet<uint32_t> fBlendModes;
SkDEBUGCODE(int fEpoch = 0;)
};
#endif // SkCombinationBuilder_DEFINED

View File

@ -113,6 +113,14 @@ public:
SkShaderType type() const { return fType; }
int numSlots() const { return fNumSlots; }
#ifdef SK_DEBUG
int epoch() const { return fEpoch; }
void setEpoch(int epoch) {
SkASSERT(fEpoch == kInvalidEpoch && epoch != kInvalidEpoch);
fEpoch = epoch;
}
#endif
void setSlotsArray(SkSlot* slots) {
SkASSERT(!fSlots);
fSlots = slots;
@ -170,8 +178,11 @@ public:
private:
int numIntrinsicCombinations() const;
SkDEBUGCODE(static constexpr int kInvalidEpoch = -1;)
const SkShaderType fType;
const int fNumSlots;
SkDEBUGCODE(int fEpoch = kInvalidEpoch;)
SkOption* fNext = nullptr;
SkSlot* fSlots = nullptr; // an array of 'fNumSlots' SkSlots
};
@ -304,6 +315,8 @@ SkCombinationOption SkCombinationOption::addChildOption(int childIndex, SkShader
return SkCombinationOption(fBuilder, /*dataInArena=*/nullptr);
}
SkASSERT(fDataInArena->epoch() == fBuilder->fEpoch);
SkOption* child = fBuilder->addOptionInternal(type);
if (child) {
fDataInArena->addOption(childIndex, child);
@ -318,6 +331,8 @@ SkCombinationOption SkCombinationOption::addChildOption(int childIndex, SkShader
return SkCombinationOption(fBuilder, /*dataInArena=*/nullptr);
}
SkASSERT(fDataInArena->epoch() == fBuilder->fEpoch);
SkOption* child = fBuilder->addOptionInternal(type, minNumStops, maxNumStops);
if (child) {
fDataInArena->addOption(childIndex, child);
@ -333,6 +348,8 @@ SkCombinationOption SkCombinationOption::addChildOption(
return SkCombinationOption(fBuilder, /*dataInArena=*/nullptr);
}
SkASSERT(fDataInArena->epoch() == fBuilder->fEpoch);
SkOption* child = fBuilder->addOptionInternal(type, tileModes);
if (child) {
fDataInArena->addOption(childIndex, child);
@ -343,6 +360,7 @@ SkCombinationOption SkCombinationOption::addChildOption(
SkShaderType SkCombinationOption::type() const { return fDataInArena->type(); }
int SkCombinationOption::numChildSlots() const { return fDataInArena->numSlots(); }
SkDEBUGCODE(int SkCombinationOption::epoch() const { return fDataInArena->epoch(); })
//--------------------------------------------------------------------------------------------------
#ifdef SK_GRAPHITE_ENABLED
@ -367,6 +385,11 @@ SkOption* SkCombinationBuilder::allocInArena(Args&&... args) {
return nullptr;
}
SkASSERT(arenaObject->type() == T::kType);
SkASSERT(arenaObject->numSlots() == T::kNumChildSlots);
SkDEBUGCODE(arenaObject->setEpoch(fEpoch));
if (T::kNumChildSlots) {
arenaObject->setSlotsArray(fArena->makeArrayDefault<SkOption::SkSlot>(T::kNumChildSlots));
}
@ -490,6 +513,7 @@ void SkCombinationBuilder::reset() {
fShaderOptions.reset();
fBlendModes.reset();
fArena->reset();
SkDEBUGCODE(++fEpoch;)
}
int SkCombinationBuilder::numCombinations() {