ccpr: Don't use the GrContext id for the path cache id

Currently this is probably safe, but somebody could easily make a
change in the future that adds another path cache to the context and
accidentally introduces tricky bugs.

TBR=brianosman@google.com

Bug: chromium:897510
Bug: chromium:897413
Bug: chromium:897245
Bug: chromium:897507
Change-Id: I6bc40ac671058f78eb290dd775612d99008d32e7
Reviewed-on: https://skia-review.googlesource.com/c/164700
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
Chris Dalton 2018-10-23 15:56:22 -06:00 committed by Skia Commit-Bot
parent c96740729a
commit 8429c79302
9 changed files with 35 additions and 19 deletions

View File

@ -37,8 +37,7 @@ GrPathRendererChain::GrPathRendererChain(GrContext* context, const Options& opti
if (options.fGpuPathRenderers & GpuPathRenderers::kCoverageCounting) {
using AllowCaching = GrCoverageCountingPathRenderer::AllowCaching;
if (auto ccpr = GrCoverageCountingPathRenderer::CreateIfSupported(
caps, AllowCaching(options.fAllowPathMaskCaching),
context->uniqueID())) {
caps, AllowCaching(options.fAllowPathMaskCaching))) {
fCoverageCountingPathRenderer = ccpr.get();
context->contextPriv().addOnFlushCallbackObject(fCoverageCountingPathRenderer);
fChain.push_back(std::move(ccpr));

View File

@ -166,10 +166,11 @@ const GrUniqueKey& GrCCAtlas::getOrAssignUniqueKey(GrOnFlushResourceProvider* on
return fUniqueKey;
}
sk_sp<GrCCAtlas::CachedAtlasInfo> GrCCAtlas::refOrMakeCachedAtlasInfo() {
sk_sp<GrCCAtlas::CachedAtlasInfo> GrCCAtlas::refOrMakeCachedAtlasInfo(uint32_t contextUniqueID) {
if (!fCachedAtlasInfo) {
fCachedAtlasInfo = sk_make_sp<CachedAtlasInfo>();
fCachedAtlasInfo = sk_make_sp<CachedAtlasInfo>(contextUniqueID);
}
SkASSERT(fCachedAtlasInfo->fContextUniqueID == contextUniqueID);
return fCachedAtlasInfo;
}

View File

@ -74,11 +74,13 @@ public:
// potentially be reused (i.e., those which still represent an extant path). When the percentage
// of useful pixels drops below 50%, the entire texture is purged from the resource cache.
struct CachedAtlasInfo : public GrNonAtomicRef<CachedAtlasInfo> {
CachedAtlasInfo(uint32_t contextUniqueID) : fContextUniqueID(contextUniqueID) {}
const uint32_t fContextUniqueID;
int fNumPathPixels = 0;
int fNumInvalidatedPathPixels = 0;
bool fIsPurgedFromResourceCache = false;
};
sk_sp<CachedAtlasInfo> refOrMakeCachedAtlasInfo();
sk_sp<CachedAtlasInfo> refOrMakeCachedAtlasInfo(uint32_t contextUniqueID);
// Instantiates our texture proxy for the atlas and returns a pre-cleared GrRenderTargetContext
// that the caller may use to render the content. After this call, it is no longer valid to call

View File

@ -345,8 +345,9 @@ void GrCCDrawPathsOp::setupResources(GrOnFlushResourceProvider* onFlushRP,
SkIVector newOffset;
GrCCAtlas* atlas =
resources->copyPathToCachedAtlas(*cacheEntry, doEvenOddFill, &newOffset);
cacheEntry->updateToCachedAtlas(atlas->getOrAssignUniqueKey(onFlushRP), newOffset,
atlas->refOrMakeCachedAtlasInfo());
cacheEntry->updateToCachedAtlas(
atlas->getOrAssignUniqueKey(onFlushRP), newOffset,
atlas->refOrMakeCachedAtlasInfo(onFlushRP->contextUniqueID()));
this->recordInstance(atlas->textureProxy(), resources->nextPathInstanceIdx());
resources->appendDrawPathInstance().set(*cacheEntry, draw.fCachedMaskShift,
draw.fColor);

View File

@ -12,6 +12,16 @@
DECLARE_SKMESSAGEBUS_MESSAGE(sk_sp<GrCCPathCacheEntry>);
static inline uint32_t next_path_cache_id() {
static std::atomic<uint32_t> gNextID(1);
for (;;) {
uint32_t id = gNextID.fetch_add(+1, std::memory_order_acquire);
if (SK_InvalidUniqueID != id) {
return id;
}
}
}
static inline bool SkShouldPostMessageToBus(
const sk_sp<GrCCPathCacheEntry>& entry, uint32_t msgBusUniqueID) {
return entry->pathCacheUniqueID() == msgBusUniqueID;
@ -20,6 +30,7 @@ static inline bool SkShouldPostMessageToBus(
// The maximum number of cache entries we allow in our own cache.
static constexpr int kMaxCacheCount = 1 << 16;
GrCCPathCache::MaskTransform::MaskTransform(const SkMatrix& m, SkIVector* shift)
: fMatrix2x2{m.getScaleX(), m.getSkewX(), m.getSkewY(), m.getScaleY()} {
SkASSERT(!m.hasPerspective());
@ -128,6 +139,11 @@ inline uint32_t GrCCPathCache::HashNode::Hash(HashKey key) {
return GrResourceKeyHash(&key.fData[1], key.fData[0]);
}
GrCCPathCache::GrCCPathCache()
: fInvalidatedEntriesInbox(next_path_cache_id()) {
}
#ifdef SK_DEBUG
GrCCPathCache::~GrCCPathCache() {
// Ensure the hash table and LRU list are still coherent.
@ -248,9 +264,8 @@ void GrCCPathCacheEntry::invalidateAtlas() {
fCachedAtlasInfo->fNumInvalidatedPathPixels >= fCachedAtlasInfo->fNumPathPixels / 2) {
// Too many invalidated pixels: purge the atlas texture from the resource cache.
// The GrContext and CCPR path cache both share the same unique ID.
uint32_t contextUniqueID = fPathCacheUniqueID;
SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(
GrUniqueKeyInvalidatedMessage(fAtlasKey, contextUniqueID));
GrUniqueKeyInvalidatedMessage(fAtlasKey, fCachedAtlasInfo->fContextUniqueID));
fCachedAtlasInfo->fIsPurgedFromResourceCache = true;
}
}

View File

@ -24,7 +24,7 @@ class GrShape;
*/
class GrCCPathCache {
public:
GrCCPathCache(uint32_t contextUniqueID) : fInvalidatedEntriesInbox(contextUniqueID) {}
GrCCPathCache();
SkDEBUGCODE(~GrCCPathCache();)
// Stores the components of a transformation that affect a path mask (i.e. everything but

View File

@ -30,16 +30,15 @@ bool GrCoverageCountingPathRenderer::IsSupported(const GrCaps& caps) {
}
sk_sp<GrCoverageCountingPathRenderer> GrCoverageCountingPathRenderer::CreateIfSupported(
const GrCaps& caps, AllowCaching allowCaching, uint32_t contextUniqueID) {
const GrCaps& caps, AllowCaching allowCaching) {
return sk_sp<GrCoverageCountingPathRenderer>((IsSupported(caps))
? new GrCoverageCountingPathRenderer(allowCaching, contextUniqueID)
? new GrCoverageCountingPathRenderer(allowCaching)
: nullptr);
}
GrCoverageCountingPathRenderer::GrCoverageCountingPathRenderer(AllowCaching allowCaching,
uint32_t contextUniqueID) {
GrCoverageCountingPathRenderer::GrCoverageCountingPathRenderer(AllowCaching allowCaching) {
if (AllowCaching::kYes == allowCaching) {
fPathCache = skstd::make_unique<GrCCPathCache>(contextUniqueID);
fPathCache = skstd::make_unique<GrCCPathCache>();
}
}

View File

@ -34,8 +34,7 @@ public:
kYes = true
};
static sk_sp<GrCoverageCountingPathRenderer> CreateIfSupported(const GrCaps&, AllowCaching,
uint32_t contextUniqueID);
static sk_sp<GrCoverageCountingPathRenderer> CreateIfSupported(const GrCaps&, AllowCaching);
using PendingPathsMap = std::map<uint32_t, sk_sp<GrCCPerOpListPaths>>;
@ -83,7 +82,7 @@ public:
float* inflationRadius = nullptr);
private:
GrCoverageCountingPathRenderer(AllowCaching, uint32_t contextUniqueID);
GrCoverageCountingPathRenderer(AllowCaching);
// GrPathRenderer overrides.
StencilSupport onGetStencilSupport(const GrShape&) const override {

View File

@ -12,7 +12,7 @@ bool GrCoverageCountingPathRenderer::IsSupported(const GrCaps& caps) {
}
sk_sp<GrCoverageCountingPathRenderer> GrCoverageCountingPathRenderer::CreateIfSupported(
const GrCaps& caps, AllowCaching allowCaching, uint32_t contextUniqueID) {
const GrCaps& caps, AllowCaching allowCaching) {
return nullptr;
}