Remove color type from promise image proxy callback.
The color type used to influence the GrPixelConfig and the swizzles used with the proxy and its GrTextures. So we had to create a new proxy if the same API texture was used to fulfill a promise image of a different color type. That has all been removed or lifted out of proxies and into views. So now it is fine to reuse the same proxy/GrTexture with a different color type. Also remove unit test that checked required a new GrTexture be made if a different color type was used. Bug: skia:10078 Change-Id: Ib74c419b5d54d382ea95720af7026640e35013f0 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/281056 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
27801a82e4
commit
c3ce54a8a7
@ -508,7 +508,7 @@ sk_sp<SkImage> SkImage_Gpu::MakePromiseTexture(GrContext* context,
|
||||
}
|
||||
|
||||
callDone.clear();
|
||||
auto proxy = MakePromiseImageLazyProxy(context, width, height, grColorType, backendFormat,
|
||||
auto proxy = MakePromiseImageLazyProxy(context, width, height, backendFormat,
|
||||
mipMapped, textureFulfillProc, textureReleaseProc,
|
||||
textureDoneProc, textureContext, version);
|
||||
if (!proxy) {
|
||||
|
@ -355,7 +355,7 @@ bool SkImage_GpuBase::RenderYUVAToRGBA(GrContext* ctx, GrRenderTargetContext* re
|
||||
}
|
||||
|
||||
sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
|
||||
GrContext* context, int width, int height, GrColorType colorType,
|
||||
GrContext* context, int width, int height,
|
||||
GrBackendFormat backendFormat, GrMipMapped mipMapped,
|
||||
PromiseImageTextureFulfillProc fulfillProc, PromiseImageTextureReleaseProc releaseProc,
|
||||
PromiseImageTextureDoneProc doneProc, PromiseImageTextureContext textureContext,
|
||||
@ -363,7 +363,6 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
|
||||
SkASSERT(context);
|
||||
SkASSERT(width > 0 && height > 0);
|
||||
SkASSERT(doneProc);
|
||||
SkASSERT(colorType != GrColorType::kUnknown);
|
||||
|
||||
if (!fulfillProc || !releaseProc) {
|
||||
doneProc(textureContext);
|
||||
@ -398,11 +397,9 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
|
||||
PromiseImageTextureReleaseProc releaseProc,
|
||||
PromiseImageTextureDoneProc doneProc,
|
||||
PromiseImageTextureContext context,
|
||||
GrColorType colorType,
|
||||
PromiseImageApiVersion version)
|
||||
: fFulfillProc(fulfillProc)
|
||||
, fReleaseProc(releaseProc)
|
||||
, fColorType(colorType)
|
||||
, fVersion(version) {
|
||||
fDoneCallback = sk_make_sp<GrRefCntedCallback>(doneProc, context);
|
||||
}
|
||||
@ -447,7 +444,7 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
|
||||
// Fulfill once. So return our cached result.
|
||||
if (fTexture) {
|
||||
return {sk_ref_sp(fTexture), kReleaseCallbackOnInstantiation, kKeySyncMode};
|
||||
} else if (fColorType == GrColorType::kUnknown) {
|
||||
} else if (fFulfillProcFailed) {
|
||||
// We've already called fulfill and it failed. Our contract says that we should only
|
||||
// call each callback once.
|
||||
return {};
|
||||
@ -459,8 +456,7 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
|
||||
// the return from fulfill was invalid or we fail for some other reason.
|
||||
auto releaseCallback = sk_make_sp<GrRefCntedCallback>(fReleaseProc, textureContext);
|
||||
if (!promiseTexture) {
|
||||
// This records that we have failed.
|
||||
fColorType = GrColorType::kUnknown;
|
||||
fFulfillProcFailed = true;
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -472,9 +468,8 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
|
||||
sk_sp<GrTexture> tex;
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey key;
|
||||
GrUniqueKey::Builder builder(&key, kDomain, 2, "promise");
|
||||
GrUniqueKey::Builder builder(&key, kDomain, 1, "promise");
|
||||
builder[0] = promiseTexture->uniqueID();
|
||||
builder[1] = (uint32_t)fColorType;
|
||||
builder.finish();
|
||||
// A texture with this key may already exist from a different instance of this lazy
|
||||
// callback. This could happen if the client fulfills a promise image with a texture
|
||||
@ -514,9 +509,9 @@ sk_sp<GrTextureProxy> SkImage_GpuBase::MakePromiseImageLazyProxy(
|
||||
sk_sp<GrRefCntedCallback> fDoneCallback;
|
||||
GrTexture* fTexture = nullptr;
|
||||
uint32_t fTextureContextID = SK_InvalidUniqueID;
|
||||
GrColorType fColorType;
|
||||
PromiseImageApiVersion fVersion;
|
||||
} callback(fulfillProc, releaseProc, doneProc, textureContext, colorType, version);
|
||||
bool fFulfillProcFailed = false;
|
||||
} callback(fulfillProc, releaseProc, doneProc, textureContext, version);
|
||||
|
||||
GrProxyProvider* proxyProvider = context->priv().proxyProvider();
|
||||
|
||||
|
@ -79,7 +79,7 @@ protected:
|
||||
// proxy along with the TextureFulfillProc and TextureReleaseProc. PromiseDoneProc must not
|
||||
// be null.
|
||||
static sk_sp<GrTextureProxy> MakePromiseImageLazyProxy(
|
||||
GrContext*, int width, int height, GrColorType, GrBackendFormat, GrMipMapped,
|
||||
GrContext*, int width, int height, GrBackendFormat, GrMipMapped,
|
||||
PromiseImageTextureFulfillProc, PromiseImageTextureReleaseProc,
|
||||
PromiseImageTextureDoneProc, PromiseImageTextureContext, PromiseImageApiVersion);
|
||||
|
||||
|
@ -381,7 +381,7 @@ sk_sp<SkImage> SkImage_GpuYUVA::MakePromiseYUVATexture(
|
||||
}
|
||||
|
||||
auto proxy = MakePromiseImageLazyProxy(
|
||||
context, yuvaSizes[texIdx].width(), yuvaSizes[texIdx].height(), colorType,
|
||||
context, yuvaSizes[texIdx].width(), yuvaSizes[texIdx].height(),
|
||||
yuvaFormats[texIdx], GrMipMapped::kNo, textureFulfillProc, textureReleaseProc,
|
||||
promiseDoneProc, textureContexts[texIdx], version);
|
||||
++proxiesCreated;
|
||||
|
@ -232,97 +232,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTest, reporter, ctxInfo) {
|
||||
ctx->deleteBackendTexture(backendTex);
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTextureReuseDifferentConfig, reporter, ctxInfo) {
|
||||
// Try making two promise SkImages backed by the same texture but with different uses/views.
|
||||
// This will only be testable on backends where a single texture format (8bit red unorm) can
|
||||
// be used for both alpha and gray image color types.
|
||||
|
||||
const int kWidth = 10;
|
||||
const int kHeight = 10;
|
||||
|
||||
GrContext* ctx = ctxInfo.grContext();
|
||||
GrGpu* gpu = ctx->priv().getGpu();
|
||||
|
||||
GrBackendFormat gray8Format = ctx->defaultBackendFormat(kGray_8_SkColorType,
|
||||
GrRenderable::kNo);
|
||||
GrBackendFormat alpha8Format = ctx->defaultBackendFormat(kAlpha_8_SkColorType,
|
||||
GrRenderable::kNo);
|
||||
if (gray8Format != alpha8Format) {
|
||||
// kGray_8 and kAlpha_8 won't share the same backend texture
|
||||
return;
|
||||
}
|
||||
|
||||
GrBackendTexture grayBackendTex = ctx->createBackendTexture(
|
||||
kWidth, kHeight, gray8Format,
|
||||
SkColors::kTransparent, GrMipMapped::kNo, GrRenderable::kNo, GrProtected::kNo);
|
||||
REPORTER_ASSERT(reporter, grayBackendTex.isValid());
|
||||
|
||||
SkImageInfo info =
|
||||
SkImageInfo::Make(kWidth, kHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
|
||||
PromiseTextureChecker promiseChecker(grayBackendTex, reporter, true);
|
||||
|
||||
sk_sp<SkImage> alphaImg(SkImage_Gpu::MakePromiseTexture(
|
||||
ctx, alpha8Format, kWidth, kHeight, GrMipMapped::kNo,
|
||||
kTopLeft_GrSurfaceOrigin, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr,
|
||||
PromiseTextureChecker::Fulfill, PromiseTextureChecker::Release,
|
||||
PromiseTextureChecker::Done, &promiseChecker,
|
||||
SkDeferredDisplayListRecorder::PromiseImageApiVersion::kNew));
|
||||
REPORTER_ASSERT(reporter, alphaImg);
|
||||
|
||||
sk_sp<SkImage> grayImg(SkImage_Gpu::MakePromiseTexture(
|
||||
ctx, gray8Format, kWidth, kHeight, GrMipMapped::kNo,
|
||||
kBottomLeft_GrSurfaceOrigin, kGray_8_SkColorType, kOpaque_SkAlphaType, nullptr,
|
||||
PromiseTextureChecker::Fulfill, PromiseTextureChecker::Release,
|
||||
PromiseTextureChecker::Done, &promiseChecker,
|
||||
SkDeferredDisplayListRecorder::PromiseImageApiVersion::kNew));
|
||||
REPORTER_ASSERT(reporter, grayImg);
|
||||
|
||||
canvas->drawImage(alphaImg, 0, 0);
|
||||
canvas->drawImage(grayImg, 1, 1);
|
||||
surface->flush();
|
||||
gpu->testingOnly_flushGpuAndSync();
|
||||
check_only_fulfilled(reporter, promiseChecker, 2);
|
||||
|
||||
// Because they use different backend formats, each image should have created a different
|
||||
// GrTexture and they both should still be cached.
|
||||
ctx->priv().getResourceCache()->purgeAsNeeded();
|
||||
|
||||
auto keys = promiseChecker.uniqueKeys();
|
||||
REPORTER_ASSERT(reporter, keys.count() == 2);
|
||||
for (const auto& key : keys) {
|
||||
auto surf = ctx->priv().resourceProvider()->findByUniqueKey<GrSurface>(key);
|
||||
REPORTER_ASSERT(reporter, surf && surf->asTexture());
|
||||
if (surf && surf->asTexture()) {
|
||||
GrTexture* texture = surf->asTexture();
|
||||
|
||||
// The backend texture should be shared between the two uses
|
||||
REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(
|
||||
grayBackendTex, texture->getBackendTexture()));
|
||||
}
|
||||
}
|
||||
|
||||
// Invalidate the backing texture, this should invalidate the keys.
|
||||
promiseChecker.releaseTexture();
|
||||
ctx->priv().getResourceCache()->purgeAsNeeded();
|
||||
|
||||
for (const auto& key : keys) {
|
||||
auto surf = ctx->priv().resourceProvider()->findByUniqueKey<GrSurface>(key);
|
||||
REPORTER_ASSERT(reporter, !surf);
|
||||
}
|
||||
alphaImg.reset();
|
||||
ctx->flush(); // We do this to pick up any unref messages that are sent by unref'ing the image.
|
||||
check_fulfill_and_release_cnts(reporter, promiseChecker, 2,
|
||||
ReleaseBalanceExpectation::kUnbalancedByOne,
|
||||
DoneBalanceExpectation::kUnbalancedByOne);
|
||||
grayImg.reset();
|
||||
ctx->flush(); // We do this to pick up any unref messages that are sent by unref'ing the image.
|
||||
check_all_done(reporter, promiseChecker, 2);
|
||||
ctx->deleteBackendTexture(grayBackendTex);
|
||||
}
|
||||
|
||||
DEF_GPUTEST(PromiseImageTextureShutdown, reporter, ctxInfo) {
|
||||
const int kWidth = 10;
|
||||
const int kHeight = 10;
|
||||
|
Loading…
Reference in New Issue
Block a user