Make GPU image lazy size calculation thread-safe

We also don't talk to the GrGpuResource if its been assigned,
because other threads may be querying this proxy for its size.

Bug: skia:10286
Change-Id: Ifd4fb8ca796143c7264554b0812910c88e32dcdd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376716
Auto-Submit: Adlai Holler <adlai@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Adlai Holler 2021-02-26 13:16:39 -05:00 committed by Skia Commit-Bot
parent a1e30a3a28
commit ba52c9165d
2 changed files with 6 additions and 11 deletions

View File

@ -56,8 +56,7 @@ GrSurfaceProxy::GrSurfaceProxy(const GrBackendFormat& format,
, fFit(fit)
, fBudgeted(budgeted)
, fUseAllocator(useAllocator)
, fIsProtected(isProtected)
, fGpuMemorySize(kInvalidGpuMemorySize) {
, fIsProtected(isProtected) {
SkASSERT(fFormat.isValid());
SkASSERT(is_valid_non_lazy(dimensions));
}
@ -78,8 +77,7 @@ GrSurfaceProxy::GrSurfaceProxy(LazyInstantiateCallback&& callback,
, fBudgeted(budgeted)
, fUseAllocator(useAllocator)
, fLazyInstantiateCallback(std::move(callback))
, fIsProtected(isProtected)
, fGpuMemorySize(kInvalidGpuMemorySize) {
, fIsProtected(isProtected) {
SkASSERT(fFormat.isValid());
SkASSERT(fLazyInstantiateCallback);
SkASSERT(is_valid_lazy(dimensions, fit));
@ -99,8 +97,7 @@ GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface,
: SkBudgeted::kNo)
, fUseAllocator(useAllocator)
, fUniqueID(fTarget->uniqueID()) // Note: converting from unique resource ID to a proxy ID!
, fIsProtected(fTarget->isProtected() ? GrProtected::kYes : GrProtected::kNo)
, fGpuMemorySize(kInvalidGpuMemorySize) {
, fIsProtected(fTarget->isProtected() ? GrProtected::kYes : GrProtected::kNo) {
SkASSERT(fFormat.isValid());
}
@ -158,6 +155,7 @@ void GrSurfaceProxy::assign(sk_sp<GrSurface> surface) {
}
if (kInvalidGpuMemorySize != this->getRawGpuMemorySize_debugOnly()) {
// TODO(11373): Can this check be exact?
SkASSERT(fTarget->gpuMemorySize() <= this->getRawGpuMemorySize_debugOnly());
}
#endif

View File

@ -276,9 +276,6 @@ public:
*/
size_t gpuMemorySize() const {
SkASSERT(!this->isFullyLazy());
if (fTarget) {
return fTarget->gpuMemorySize();
}
if (kInvalidGpuMemorySize == fGpuMemorySize) {
fGpuMemorySize = this->onUninstantiatedGpuMemorySize();
SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
@ -438,8 +435,8 @@ private:
// This entry is lazily evaluated so, when the proxy wraps a resource, the resource
// will be called but, when the proxy is deferred, it will compute the answer itself.
// If the proxy computes its own answer that answer is checked (in debug mode) in
// the instantiation method.
mutable size_t fGpuMemorySize;
// the instantiation method. The image may be shared between threads, hence atomic.
mutable std::atomic<size_t> fGpuMemorySize{kInvalidGpuMemorySize};
SkDEBUGCODE(SkString fDebugName;)
};