Change PromiseImage API to take GrContextThreadSafeProxy
This detaches PromiseImages from any specific context, just to
a certain family.
Next up is to remove the tileSpecificSKP code from the DDLTileHelper.
Currently we have this janky PromiseImageDummy GrImageContext that
we make for each promise image. It's not ideal but it'll tide us over.
Bug: skia:10286
Change-Id: I12ab0bb7df9360a08af594da80de9df14cc2a44f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/372516
Commit-Queue: Adlai Holler <adlai@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp
index 98d72a9..f124b8f 100644
--- a/src/core/SkDeferredDisplayListRecorder.cpp
+++ b/src/core/SkDeferredDisplayListRecorder.cpp
@@ -246,7 +246,10 @@
PromiseImageTextureFulfillProc textureFulfillProc,
PromiseImageTextureReleaseProc textureReleaseProc,
PromiseImageTextureContext textureContext) {
- return SkImage_Gpu::MakePromiseTexture(fContext.get(),
+ if (!fContext) {
+ return nullptr;
+ }
+ return SkImage_Gpu::MakePromiseTexture(fContext->threadSafeProxy(),
backendFormat,
{width, height},
mipMapped,
@@ -265,7 +268,10 @@
PromiseImageTextureFulfillProc textureFulfillProc,
PromiseImageTextureReleaseProc textureReleaseProc,
PromiseImageTextureContext textureContexts[]) {
- return SkImage_GpuYUVA::MakePromiseYUVATexture(fContext.get(),
+ if (!fContext) {
+ return nullptr;
+ }
+ return SkImage_GpuYUVA::MakePromiseYUVATexture(fContext->threadSafeProxy(),
yuvaBackendTextureInfo,
std::move(imageColorSpace),
textureFulfillProc,
diff --git a/src/gpu/GrImageContext.cpp b/src/gpu/GrImageContext.cpp
index c5c1abf..c0df261 100644
--- a/src/gpu/GrImageContext.cpp
+++ b/src/gpu/GrImageContext.cpp
@@ -30,6 +30,10 @@
return fThreadSafeProxy->priv().abandoned();
}
+sk_sp<GrImageContext> GrImageContext::MakeForPromiseImage(sk_sp<GrContextThreadSafeProxy> tsp) {
+ return sk_sp<GrImageContext>(new GrImageContext(std::move(tsp)));
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<const GrCaps> GrImageContextPriv::refCaps() const {
return fContext->refCaps();
diff --git a/src/gpu/GrImageContextPriv.h b/src/gpu/GrImageContextPriv.h
index f681003..ca2b6ba 100644
--- a/src/gpu/GrImageContextPriv.h
+++ b/src/gpu/GrImageContextPriv.h
@@ -10,6 +10,8 @@
#include "include/private/GrImageContext.h"
+#include "include/gpu/GrContextThreadSafeProxy.h"
+
/** Class that exposes methods on GrImageContext that are only intended for use internal to Skia.
This class is purely a privileged window into GrImageContext. It should never have
additional data members or virtual methods. */
@@ -30,6 +32,10 @@
bool abandoned() const { return fContext->abandoned(); }
+ static sk_sp<GrImageContext> MakeForPromiseImage(sk_sp<GrContextThreadSafeProxy> tsp) {
+ return GrImageContext::MakeForPromiseImage(std::move(tsp));
+ }
+
/** This is only useful for debug purposes */
SkDEBUGCODE(GrSingleOwner* singleOwner() const { return fContext->singleOwner(); } )
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 8ec7265..8e4bc2a 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -20,6 +20,7 @@
#include "src/core/SkMipmap.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/GrCaps.h"
+#include "src/gpu/GrContextThreadSafeProxyPriv.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrImageContextPriv.h"
#include "src/gpu/GrRenderTarget.h"
@@ -666,6 +667,41 @@
std::move(rt), UseAllocator::kNo, GrRenderTargetProxy::WrapsVkSecondaryCB::kYes));
}
+sk_sp<GrTextureProxy> GrProxyProvider::CreatePromiseProxy(GrContextThreadSafeProxy* threadSafeProxy,
+ LazyInstantiateCallback&& callback,
+ const GrBackendFormat& format,
+ SkISize dimensions,
+ GrMipmapped mipMapped) {
+ if (threadSafeProxy->priv().abandoned()) {
+ return nullptr;
+ }
+ SkASSERT((dimensions.fWidth <= 0 && dimensions.fHeight <= 0) ||
+ (dimensions.fWidth > 0 && dimensions.fHeight > 0));
+
+ if (dimensions.fWidth > threadSafeProxy->priv().caps()->maxTextureSize() ||
+ dimensions.fHeight > threadSafeProxy->priv().caps()->maxTextureSize()) {
+ return nullptr;
+ }
+ // Ganesh assumes that, when wrapping a mipmapped backend texture from a client, that its
+ // mipmaps are fully fleshed out.
+ GrMipmapStatus mipmapStatus = (GrMipmapped::kYes == mipMapped) ? GrMipmapStatus::kValid
+ : GrMipmapStatus::kNotAllocated;
+
+ // We pass kReadOnly here since we should treat content of the client's texture as immutable.
+ // The promise API provides no way for the client to indicate that the texture is protected.
+ return sk_sp<GrTextureProxy>(new GrTextureProxy(std::move(callback),
+ format,
+ dimensions,
+ mipMapped,
+ mipmapStatus,
+ SkBackingFit::kExact,
+ SkBudgeted::kNo,
+ GrProtected::kNo,
+ GrInternalSurfaceFlags::kReadOnly,
+ GrSurfaceProxy::UseAllocator::kYes,
+ GrDDLProvider::kYes));
+}
+
sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
const GrBackendFormat& format,
SkISize dimensions,
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 415305a..5ea0e8e 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -151,6 +151,16 @@
};
/**
+ * Similar to createLazyProxy below, except narrowed to the use case of shared promise images
+ * i.e. static so it doesn't have access to mutable state. Used by MakePromiseImageLazyProxy().
+ */
+ static sk_sp<GrTextureProxy> CreatePromiseProxy(GrContextThreadSafeProxy*,
+ LazyInstantiateCallback&&,
+ const GrBackendFormat&,
+ SkISize dimensions,
+ GrMipmapped);
+
+ /**
* Creates a texture proxy that will be instantiated by a user-supplied callback during flush.
* The width and height must either both be greater than 0 or both less than or equal to zero. A
* non-positive value is a signal that the width height are currently unknown. The texture will
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index da7df04..02beb61 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -25,6 +25,7 @@
#include "src/gpu/GrBitmapTextureMaker.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrColorSpaceXform.h"
+#include "src/gpu/GrContextThreadSafeProxyPriv.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrDrawingManager.h"
#include "src/gpu/GrGpu.h"
@@ -373,7 +374,7 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
-sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrRecordingContext* context,
+sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(sk_sp<GrContextThreadSafeProxy> threadSafeProxy,
const GrBackendFormat& backendFormat,
SkISize dimensions,
GrMipmapped mipMapped,
@@ -393,7 +394,7 @@
return nullptr;
}
- if (!context) {
+ if (!threadSafeProxy) {
return nullptr;
}
@@ -401,18 +402,19 @@
return nullptr;
}
- GrColorType grColorType = SkColorTypeAndFormatToGrColorType(context->priv().caps(),
+ GrColorType grColorType = SkColorTypeAndFormatToGrColorType(threadSafeProxy->priv().caps(),
colorType,
backendFormat);
if (GrColorType::kUnknown == grColorType) {
return nullptr;
}
- if (!context->priv().caps()->areColorTypeAndFormatCompatible(grColorType, backendFormat)) {
+ if (!threadSafeProxy->priv().caps()->areColorTypeAndFormatCompatible(grColorType,
+ backendFormat)) {
return nullptr;
}
- auto proxy = MakePromiseImageLazyProxy(context,
+ auto proxy = MakePromiseImageLazyProxy(threadSafeProxy.get(),
dimensions,
backendFormat,
mipMapped,
@@ -421,10 +423,11 @@
if (!proxy) {
return nullptr;
}
- GrSwizzle swizzle = context->priv().caps()->getReadSwizzle(backendFormat, grColorType);
+ GrSwizzle swizzle = threadSafeProxy->priv().caps()->getReadSwizzle(backendFormat, grColorType);
GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
- return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID,
- std::move(view), colorType, alphaType, std::move(colorSpace));
+ sk_sp<GrImageContext> ctx(GrImageContextPriv::MakeForPromiseImage(std::move(threadSafeProxy)));
+ return sk_make_sp<SkImage_Gpu>(std::move(ctx), kNeedNewImageUniqueID, std::move(view),
+ colorType, alphaType, std::move(colorSpace));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index 3115349..f78afd0 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -78,8 +78,9 @@
/**
* This is the implementation of SkDeferredDisplayListRecorder::makePromiseImage.
+ * TODO: Make this public, and remove the SkDDLRecorder entry point.
*/
- static sk_sp<SkImage> MakePromiseTexture(GrRecordingContext*,
+ static sk_sp<SkImage> MakePromiseTexture(sk_sp<GrContextThreadSafeProxy>,
const GrBackendFormat& backendFormat,
SkISize dimensions,
GrMipmapped mipMapped,
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index 6f42a490..d11a617 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -204,13 +204,13 @@
}
sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
- GrRecordingContext* context,
+ GrContextThreadSafeProxy* tsp,
SkISize dimensions,
GrBackendFormat backendFormat,
GrMipmapped mipMapped,
PromiseImageTextureFulfillProc fulfillProc,
sk_sp<GrRefCntedCallback> releaseHelper) {
- SkASSERT(context);
+ SkASSERT(tsp);
SkASSERT(!dimensions.isEmpty());
SkASSERT(releaseHelper);
@@ -361,17 +361,6 @@
bool fFulfillProcFailed = false;
} callback(fulfillProc, std::move(releaseHelper));
- GrProxyProvider* proxyProvider = context->priv().proxyProvider();
-
- // Ganesh assumes that, when wrapping a mipmapped backend texture from a client, that its
- // mipmaps are fully fleshed out.
- GrMipmapStatus mipmapStatus = (GrMipmapped::kYes == mipMapped) ? GrMipmapStatus::kValid
- : GrMipmapStatus::kNotAllocated;
-
- // We pass kReadOnly here since we should treat content of the client's texture as immutable.
- // The promise API provides no way for the client to indicated that the texture is protected.
- return proxyProvider->createLazyProxy(std::move(callback), backendFormat, dimensions, mipMapped,
- mipmapStatus, GrInternalSurfaceFlags::kReadOnly,
- SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo,
- GrSurfaceProxy::UseAllocator::kYes);
+ return GrProxyProvider::CreatePromiseProxy(tsp, std::move(callback), backendFormat, dimensions,
+ mipMapped);
}
diff --git a/src/image/SkImage_GpuBase.h b/src/image/SkImage_GpuBase.h
index d55c29d..57a9644 100644
--- a/src/image/SkImage_GpuBase.h
+++ b/src/image/SkImage_GpuBase.h
@@ -61,7 +61,7 @@
// if not null, immediately if this function fails. Othwerwise, it is installed in the
// proxy along with the TextureFulfillProc and TextureReleaseProc. PromiseDoneProc must not
// be null.
- static sk_sp<GrTextureProxy> MakePromiseImageLazyProxy(GrRecordingContext*,
+ static sk_sp<GrTextureProxy> MakePromiseImageLazyProxy(GrContextThreadSafeProxy*,
SkISize dimensions,
GrBackendFormat,
GrMipmapped,
diff --git a/src/image/SkImage_GpuYUVA.cpp b/src/image/SkImage_GpuYUVA.cpp
index ffabc64..fc45302 100644
--- a/src/image/SkImage_GpuYUVA.cpp
+++ b/src/image/SkImage_GpuYUVA.cpp
@@ -380,7 +380,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkImage> SkImage_GpuYUVA::MakePromiseYUVATexture(
- GrRecordingContext* context,
+ sk_sp<GrContextThreadSafeProxy> threadSafeProxy,
const GrYUVABackendTextureInfo& yuvaBackendTextureInfo,
sk_sp<SkColorSpace> imageColorSpace,
PromiseImageTextureFulfillProc textureFulfillProc,
@@ -401,7 +401,7 @@
releaseHelpers[i] = GrRefCntedCallback::Make(textureReleaseProc, textureContexts[i]);
}
- if (!context) {
+ if (!threadSafeProxy) {
return nullptr;
}
@@ -416,7 +416,7 @@
// Make a lazy proxy for each plane and wrap in a view.
sk_sp<GrSurfaceProxy> proxies[4];
for (int i = 0; i < n; ++i) {
- proxies[i] = MakePromiseImageLazyProxy(context,
+ proxies[i] = MakePromiseImageLazyProxy(threadSafeProxy.get(),
planeDimensions[i],
yuvaBackendTextureInfo.planeFormat(i),
GrMipmapped::kNo,
@@ -430,7 +430,8 @@
proxies,
yuvaBackendTextureInfo.textureOrigin());
SkASSERT(yuvaTextureProxies.isValid());
- return sk_make_sp<SkImage_GpuYUVA>(sk_ref_sp(context),
+ sk_sp<GrImageContext> ctx(GrImageContextPriv::MakeForPromiseImage(std::move(threadSafeProxy)));
+ return sk_make_sp<SkImage_GpuYUVA>(std::move(ctx),
kNeedNewImageUniqueID,
std::move(yuvaTextureProxies),
std::move(imageColorSpace));
diff --git a/src/image/SkImage_GpuYUVA.h b/src/image/SkImage_GpuYUVA.h
index ccdbffe..3e461f3 100644
--- a/src/image/SkImage_GpuYUVA.h
+++ b/src/image/SkImage_GpuYUVA.h
@@ -65,8 +65,9 @@
/**
* This is the implementation of SkDeferredDisplayListRecorder::makeYUVAPromiseTexture.
+ * TODO: Make this public, and remove the SkDDLRecorder entry point.
*/
- static sk_sp<SkImage> MakePromiseYUVATexture(GrRecordingContext*,
+ static sk_sp<SkImage> MakePromiseYUVATexture(sk_sp<GrContextThreadSafeProxy>,
const GrYUVABackendTextureInfo&,
sk_sp<SkColorSpace> imageColorSpace,
PromiseImageTextureFulfillProc textureFulfillProc,