Switch GrTextureFreedMessages over to using DirectContextIDs
Bug: skia:11728
Change-Id: I514f917577a4166c2834f72fc8c64ab85b259938
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/382879
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 620e18c..078593f 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -23,37 +23,38 @@
#include "src/gpu/SkGr.h"
#include "src/gpu/gl/GrGLTexture.h"
-GrBackendTextureImageGenerator::RefHelper::RefHelper(GrTexture* texture, uint32_t owningContextID,
- std::unique_ptr<GrSemaphore> semaphore)
+GrBackendTextureImageGenerator::RefHelper::RefHelper(
+ GrTexture* texture,
+ GrDirectContext::DirectContextID owningContextID,
+ std::unique_ptr<GrSemaphore> semaphore)
: fOriginalTexture(texture)
, fOwningContextID(owningContextID)
, fBorrowingContextReleaseProc(nullptr)
- , fBorrowingContextID(SK_InvalidGenID)
, fSemaphore(std::move(semaphore)) {}
GrBackendTextureImageGenerator::RefHelper::~RefHelper() {
- SkASSERT(fBorrowingContextID == SK_InvalidUniqueID);
+ SkASSERT(!fBorrowingContextID.isValid());
// Generator has been freed, and no one is borrowing the texture. Notify the original cache
// that it can free the last ref, so it happens on the correct thread.
GrTextureFreedMessage msg { fOriginalTexture, fOwningContextID };
- SkMessageBus<GrTextureFreedMessage, uint32_t>::Post(msg);
+ SkMessageBus<GrTextureFreedMessage, GrDirectContext::DirectContextID>::Post(msg);
}
std::unique_ptr<SkImageGenerator>
GrBackendTextureImageGenerator::Make(sk_sp<GrTexture> texture, GrSurfaceOrigin origin,
std::unique_ptr<GrSemaphore> semaphore, SkColorType colorType,
SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace) {
- GrDirectContext* context = texture->getContext();
+ GrDirectContext* dContext = texture->getContext();
// Attach our texture to this context's resource cache. This ensures that deletion will happen
// in the correct thread/context. This adds the only ref to the texture that will persist from
// this point. That ref will be released when the generator's RefHelper is freed.
- context->priv().getResourceCache()->insertDelayedTextureUnref(texture.get());
+ dContext->priv().getResourceCache()->insertDelayedTextureUnref(texture.get());
GrBackendTexture backendTexture = texture->getBackendTexture();
- if (!context->priv().caps()->areColorTypeAndFormatCompatible(
+ if (!dContext->priv().caps()->areColorTypeAndFormatCompatible(
SkColorTypeToGrColorType(colorType), backendTexture.getBackendFormat())) {
return nullptr;
}
@@ -61,17 +62,17 @@
SkImageInfo info = SkImageInfo::Make(texture->width(), texture->height(), colorType, alphaType,
std::move(colorSpace));
return std::unique_ptr<SkImageGenerator>(new GrBackendTextureImageGenerator(
- info, texture.get(), origin, context->priv().contextID(),
+ info, texture.get(), origin, dContext->directContextID(),
std::move(semaphore), backendTexture));
}
GrBackendTextureImageGenerator::GrBackendTextureImageGenerator(
- const SkImageInfo& info,
- GrTexture* texture,
- GrSurfaceOrigin origin,
- uint32_t owningContextID,
- std::unique_ptr<GrSemaphore> semaphore,
- const GrBackendTexture& backendTex)
+ const SkImageInfo& info,
+ GrTexture* texture,
+ GrSurfaceOrigin origin,
+ GrDirectContext::DirectContextID owningContextID,
+ std::unique_ptr<GrSemaphore> semaphore,
+ const GrBackendTexture& backendTex)
: INHERITED(info)
, fRefHelper(new RefHelper(texture, owningContextID, std::move(semaphore)))
, fBackendTexture(backendTex)
@@ -88,33 +89,42 @@
SkASSERT(refHelper);
refHelper->fBorrowingContextReleaseProc = nullptr;
- refHelper->fBorrowingContextID = SK_InvalidGenID;
+ refHelper->fBorrowingContextID.makeInvalid();
refHelper->unref();
}
GrSurfaceProxyView GrBackendTextureImageGenerator::onGenerateTexture(
- GrRecordingContext* context,
+ GrRecordingContext* rContext,
const SkImageInfo& info,
const SkIPoint& origin,
GrMipmapped mipMapped,
GrImageTexGenPolicy texGenPolicy) {
- SkASSERT(context);
+ SkASSERT(rContext);
- if (context->backend() != fBackendTexture.backend()) {
+ // We currently limit GrBackendTextureImageGenerators to direct contexts since
+ // only Flutter uses them and doesn't use recording/DDL contexts. Ideally, the
+ // cross context texture functionality can be subsumed by the thread-safe cache
+ // working with utility contexts.
+ auto dContext = rContext->asDirectContext();
+ if (!dContext) {
+ return {};
+ }
+
+ if (dContext->backend() != fBackendTexture.backend()) {
return {};
}
if (info.colorType() != this->getInfo().colorType()) {
return {};
}
- auto proxyProvider = context->priv().proxyProvider();
+ auto proxyProvider = dContext->priv().proxyProvider();
fBorrowingMutex.acquire();
sk_sp<GrRefCntedCallback> releaseProcHelper;
- if (SK_InvalidGenID != fRefHelper->fBorrowingContextID) {
- if (fRefHelper->fBorrowingContextID != context->priv().contextID()) {
+ if (fRefHelper->fBorrowingContextID.isValid()) {
+ if (fRefHelper->fBorrowingContextID != dContext->directContextID()) {
fBorrowingMutex.release();
- context->priv().printWarningMessage(
+ rContext->priv().printWarningMessage(
"GrBackendTextureImageGenerator: Trying to use texture on two GrContexts!\n");
return {};
} else {
@@ -131,7 +141,7 @@
GrRefCntedCallback::Make(ReleaseRefHelper_TextureReleaseProc, fRefHelper);
fRefHelper->fBorrowingContextReleaseProc = releaseProcHelper.get();
}
- fRefHelper->fBorrowingContextID = context->priv().contextID();
+ fRefHelper->fBorrowingContextID = dContext->directContextID();
if (!fRefHelper->fBorrowedTextureKey.isValid()) {
static const auto kDomain = GrUniqueKey::GenerateDomain();
GrUniqueKey::Builder builder(&fRefHelper->fBorrowedTextureKey, kDomain, 1);
@@ -139,7 +149,7 @@
}
fBorrowingMutex.release();
- SkASSERT(fRefHelper->fBorrowingContextID == context->priv().contextID());
+ SkASSERT(fRefHelper->fBorrowingContextID == dContext->directContextID());
GrBackendFormat backendFormat = fBackendTexture.getBackendFormat();
SkASSERT(backendFormat.isValid());
@@ -154,7 +164,7 @@
GrMipmapStatus mipmapStatus = fBackendTexture.hasMipmaps()
? GrMipmapStatus::kValid : GrMipmapStatus::kNotAllocated;
- GrSwizzle readSwizzle = context->priv().caps()->getReadSwizzle(backendFormat, grColorType);
+ GrSwizzle readSwizzle = dContext->priv().caps()->getReadSwizzle(backendFormat, grColorType);
// Must make copies of member variables to capture in the lambda since this image generator may
// be deleted before we actually execute the lambda.
@@ -219,7 +229,7 @@
? SkBudgeted::kNo
: SkBudgeted::kYes;
- auto copy = GrSurfaceProxy::Copy(context,
+ auto copy = GrSurfaceProxy::Copy(dContext,
std::move(proxy),
fSurfaceOrigin,
mipMapped,
diff --git a/src/gpu/GrBackendTextureImageGenerator.h b/src/gpu/GrBackendTextureImageGenerator.h
index cea0f40..72bdc96 100644
--- a/src/gpu/GrBackendTextureImageGenerator.h
+++ b/src/gpu/GrBackendTextureImageGenerator.h
@@ -9,7 +9,7 @@
#include "include/core/SkImageGenerator.h"
#include "include/gpu/GrBackendSurface.h"
-#include "include/gpu/GrRecordingContext.h"
+#include "include/gpu/GrDirectContext.h"
#include "include/private/GrResourceKey.h"
#include "include/private/SkMutex.h"
#include "src/gpu/GrTexture.h"
@@ -48,33 +48,38 @@
GrMipmapped mipMapped, GrImageTexGenPolicy) override;
private:
- GrBackendTextureImageGenerator(const SkImageInfo& info, GrTexture*, GrSurfaceOrigin,
- uint32_t owningContextID, std::unique_ptr<GrSemaphore>,
+ GrBackendTextureImageGenerator(const SkImageInfo& info,
+ GrTexture*,
+ GrSurfaceOrigin,
+ GrDirectContext::DirectContextID owningContextID,
+ std::unique_ptr<GrSemaphore>,
const GrBackendTexture&);
static void ReleaseRefHelper_TextureReleaseProc(void* ctx);
class RefHelper : public SkNVRefCnt<RefHelper> {
public:
- RefHelper(GrTexture*, uint32_t owningContextID, std::unique_ptr<GrSemaphore>);
+ RefHelper(GrTexture*,
+ GrDirectContext::DirectContextID owningContextID,
+ std::unique_ptr<GrSemaphore>);
~RefHelper();
- GrTexture* fOriginalTexture;
- uint32_t fOwningContextID;
+ GrTexture* fOriginalTexture;
+ GrDirectContext::DirectContextID fOwningContextID;
// We use this key so that we don't rewrap the GrBackendTexture in a GrTexture for each
// proxy created from this generator for a particular borrowing context.
- GrUniqueKey fBorrowedTextureKey;
+ GrUniqueKey fBorrowedTextureKey;
// There is no ref associated with this pointer. We rely on our atomic bookkeeping with the
// context ID to know when this pointer is valid and safe to use. This is used to make sure
// all uses of the wrapped texture are finished on the borrowing context before we open
// this back up to other contexts. In general a ref to this release proc is owned by all
// proxies and gpu uses of the backend texture.
- GrRefCntedCallback* fBorrowingContextReleaseProc;
- uint32_t fBorrowingContextID;
+ GrRefCntedCallback* fBorrowingContextReleaseProc;
+ GrDirectContext::DirectContextID fBorrowingContextID;
- std::unique_ptr<GrSemaphore> fSemaphore;
+ std::unique_ptr<GrSemaphore> fSemaphore;
};
RefHelper* fRefHelper;
diff --git a/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp
index f04c365..96621c6 100644
--- a/src/gpu/GrDirectContext.cpp
+++ b/src/gpu/GrDirectContext.cpp
@@ -209,7 +209,9 @@
SkASSERT(this->threadSafeCache());
fStrikeCache = std::make_unique<GrStrikeCache>();
- fResourceCache = std::make_unique<GrResourceCache>(this->singleOwner(), this->contextID());
+ fResourceCache = std::make_unique<GrResourceCache>(this->singleOwner(),
+ this->directContextID(),
+ this->contextID());
fResourceCache->setProxyProvider(this->proxyProvider());
fResourceCache->setThreadSafeCache(this->threadSafeCache());
fResourceProvider = std::make_unique<GrResourceProvider>(fGpu.get(), fResourceCache.get(),
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index ac22385..4c5cb85 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -27,7 +27,7 @@
DECLARE_SKMESSAGEBUS_MESSAGE(GrUniqueKeyInvalidatedMessage, uint32_t, true);
-DECLARE_SKMESSAGEBUS_MESSAGE(GrTextureFreedMessage, uint32_t, true);
+DECLARE_SKMESSAGEBUS_MESSAGE(GrTextureFreedMessage, GrDirectContext::DirectContextID, true);
#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(fSingleOwner)
@@ -108,12 +108,16 @@
//////////////////////////////////////////////////////////////////////////////
-GrResourceCache::GrResourceCache(GrSingleOwner* singleOwner, uint32_t contextUniqueID)
- : fInvalidUniqueKeyInbox(contextUniqueID)
- , fFreedTextureInbox(contextUniqueID)
- , fContextUniqueID(contextUniqueID)
+GrResourceCache::GrResourceCache(GrSingleOwner* singleOwner,
+ GrDirectContext::DirectContextID owningContextID,
+ uint32_t familyID)
+ : fInvalidUniqueKeyInbox(familyID)
+ , fFreedTextureInbox(owningContextID)
+ , fOwningContextID(owningContextID)
+ , fContextUniqueID(familyID)
, fSingleOwner(singleOwner) {
- SkASSERT(contextUniqueID != SK_InvalidUniqueID);
+ SkASSERT(owningContextID.isValid());
+ SkASSERT(familyID != SK_InvalidUniqueID);
}
GrResourceCache::~GrResourceCache() {
@@ -679,7 +683,7 @@
SkTArray<GrTextureFreedMessage> msgs;
fFreedTextureInbox.poll(&msgs);
for (int i = 0; i < msgs.count(); ++i) {
- SkASSERT(msgs[i].fOwningUniqueID == fContextUniqueID);
+ SkASSERT(msgs[i].fIntendedRecipient == fOwningContextID);
uint32_t id = msgs[i].fTexture->uniqueID().asUInt();
TextureAwaitingUnref* info = fTexturesAwaitingUnref.find(id);
// If the GrContext was released or abandoned then fTexturesAwaitingUnref should have been
diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
index e1706a3..4a634ad 100644
--- a/src/gpu/GrResourceCache.h
+++ b/src/gpu/GrResourceCache.h
@@ -9,6 +9,7 @@
#define GrResourceCache_DEFINED
#include "include/core/SkRefCnt.h"
+#include "include/gpu/GrDirectContext.h"
#include "include/private/GrResourceKey.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTHash.h"
@@ -30,13 +31,12 @@
struct GrTextureFreedMessage {
GrTexture* fTexture;
- uint32_t fOwningUniqueID;
+ GrDirectContext::DirectContextID fIntendedRecipient;
};
static inline bool SkShouldPostMessageToBus(
- const GrTextureFreedMessage& msg, uint32_t msgBusUniqueID) {
- // The inbox's ID is the unique ID of the owning GrContext.
- return msgBusUniqueID == msg.fOwningUniqueID;
+ const GrTextureFreedMessage& msg, GrDirectContext::DirectContextID potentialRecipient) {
+ return potentialRecipient == msg.fIntendedRecipient;
}
/**
@@ -58,7 +58,9 @@
*/
class GrResourceCache {
public:
- GrResourceCache(GrSingleOwner* owner, uint32_t contextUniqueID);
+ GrResourceCache(GrSingleOwner* owner,
+ GrDirectContext::DirectContextID owningContextID,
+ uint32_t familyID);
~GrResourceCache();
// Default maximum number of bytes of gpu memory of budgeted resources in the cache.
@@ -321,8 +323,10 @@
return res->cacheAccess().accessCacheIndex();
}
+ using TextureFreedMessageBus = SkMessageBus<GrTextureFreedMessage,
+ GrDirectContext::DirectContextID>;
+
typedef SkMessageBus<GrUniqueKeyInvalidatedMessage, uint32_t>::Inbox InvalidUniqueKeyInbox;
- typedef SkMessageBus<GrTextureFreedMessage, uint32_t>::Inbox FreedTextureInbox;
typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> PurgeableQueue;
typedef SkTDArray<GrGpuResource*> ResourceArray;
@@ -362,9 +366,10 @@
int fNumBudgetedResourcesFlushWillMakePurgeable = 0;
InvalidUniqueKeyInbox fInvalidUniqueKeyInbox;
- FreedTextureInbox fFreedTextureInbox;
+ TextureFreedMessageBus::Inbox fFreedTextureInbox;
TexturesAwaitingUnref fTexturesAwaitingUnref;
+ GrDirectContext::DirectContextID fOwningContextID;
uint32_t fContextUniqueID = SK_InvalidUniqueID;
GrSingleOwner* fSingleOwner = nullptr;
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index ecaabbb..0b3ae30 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -259,7 +259,8 @@
// In the future the GrSurface class hierarchy refactoring should eliminate this
// difficulty by removing the virtual inheritance.
if (fTexture) {
- SkMessageBus<GrTextureFreedMessage, uint32_t>::Post({fTexture, fTextureContextID});
+ GrTextureFreedMessage msg { fTexture, fTextureContextID };
+ SkMessageBus<GrTextureFreedMessage, GrDirectContext::DirectContextID>::Post(msg);
}
}
@@ -313,7 +314,7 @@
// our destructor.
auto dContext = fTexture->getContext();
dContext->priv().getResourceCache()->insertDelayedTextureUnref(fTexture);
- fTextureContextID = dContext->priv().contextID();
+ fTextureContextID = dContext->directContextID();
return {std::move(tex), kReleaseCallbackOnInstantiation, kKeySyncMode};
}
@@ -321,7 +322,7 @@
PromiseImageTextureFulfillProc fFulfillProc;
sk_sp<GrRefCntedCallback> fReleaseHelper;
GrTexture* fTexture = nullptr;
- uint32_t fTextureContextID = SK_InvalidUniqueID;
+ GrDirectContext::DirectContextID fTextureContextID;
bool fFulfillProcFailed = false;
} callback(fulfillProc, std::move(releaseHelper));
diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp
index 7e8fc84..c4d2168 100644
--- a/tests/ResourceCacheTest.cpp
+++ b/tests/ResourceCacheTest.cpp
@@ -1561,15 +1561,15 @@
REPORTER_ASSERT(reporter, 0 == (freed[0] + freed[1] + freed[2]));
// Send message to free the first resource
- GrTextureFreedMessage msg1{wrapped[0], dContext->priv().contextID()};
- SkMessageBus<GrTextureFreedMessage, uint32_t>::Post(msg1);
+ GrTextureFreedMessage msg1{wrapped[0], dContext->directContextID()};
+ SkMessageBus<GrTextureFreedMessage, GrDirectContext::DirectContextID>::Post(msg1);
cache->purgeAsNeeded();
REPORTER_ASSERT(reporter, 1 == (freed[0] + freed[1] + freed[2]));
REPORTER_ASSERT(reporter, 1 == freed[0]);
- GrTextureFreedMessage msg2{wrapped[2], dContext->priv().contextID()};
- SkMessageBus<GrTextureFreedMessage, uint32_t>::Post(msg2);
+ GrTextureFreedMessage msg2{wrapped[2], dContext->directContextID()};
+ SkMessageBus<GrTextureFreedMessage, GrDirectContext::DirectContextID>::Post(msg2);
cache->purgeAsNeeded();
REPORTER_ASSERT(reporter, 2 == (freed[0] + freed[1] + freed[2]));
@@ -1606,13 +1606,13 @@
// This simulates a portion of Chrome's context abandonment processing.
// Please see: crbug.com/1011368 and crbug.com/1014993
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceMessagesAfterAbandon, reporter, ctxInfo) {
- auto context = ctxInfo.directContext();
- GrGpu* gpu = context->priv().getGpu();
- GrResourceCache* cache = context->priv().getResourceCache();
+ auto dContext = ctxInfo.directContext();
+ GrGpu* gpu = dContext->priv().getGpu();
+ GrResourceCache* cache = dContext->priv().getResourceCache();
- GrBackendTexture backend = context->createBackendTexture(16, 16,
- SkColorType::kRGBA_8888_SkColorType,
- GrMipmapped::kNo, GrRenderable::kNo);
+ GrBackendTexture backend = dContext->createBackendTexture(16, 16,
+ SkColorType::kRGBA_8888_SkColorType,
+ GrMipmapped::kNo, GrRenderable::kNo);
GrTexture* tex = gpu->wrapBackendTexture(backend,
GrWrapOwnership::kBorrow_GrWrapOwnership,
GrWrapCacheable::kYes,
@@ -1637,18 +1637,18 @@
// We must delete the backend texture before abandoning the context in vulkan. We just do it
// for all the backends for consistency.
- context->deleteBackendTexture(backend);
- context->abandonContext();
+ dContext->deleteBackendTexture(backend);
+ dContext->abandonContext();
REPORTER_ASSERT(reporter, 1 == freed);
// In the past, creating this message could cause an exception due to
// an un-safe downcast from GrTexture to GrGpuResource
- GrTextureFreedMessage msg{tex, context->priv().contextID()};
- SkMessageBus<GrTextureFreedMessage, uint32_t>::Post(msg);
+ GrTextureFreedMessage msg{tex, dContext->directContextID()};
+ SkMessageBus<GrTextureFreedMessage, GrDirectContext::DirectContextID>::Post(msg);
// This doesn't actually do anything but it does trigger us to read messages
- context->purgeUnlockedResources(false);
+ dContext->purgeUnlockedResources(false);
}
////////////////////////////////////////////////////////////////////////////////