Treat cross context images as Ganesh-created resources
Always create them budgeted, and register them with the cache (not as wrapped resources). BUG=skia: Change-Id: Id18ecf6e9e512db4be21b4f2bfd8e8c060bbe805 Reviewed-on: https://skia-review.googlesource.com/9497 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
dc175eaab6
commit
cccda60aca
@ -676,6 +676,9 @@ enum GrWrapOwnership {
|
||||
|
||||
/** Skia will assume ownership of the resource and free it. */
|
||||
kAdopt_GrWrapOwnership,
|
||||
|
||||
/** Skia will assume ownership of the resource, free it, and reuse it within the cache. */
|
||||
kAdoptAndCache_GrWrapOwnership,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -520,6 +520,7 @@ sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
|
||||
|
||||
// next line relies on GrBackendTextureDesc's flags matching GrTexture's
|
||||
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
|
||||
SkASSERT(!renderTarget || kAdoptAndCache_GrWrapOwnership != ownership); // Not supported
|
||||
|
||||
GrGLTexture::IDDesc idDesc;
|
||||
idDesc.fInfo = *info;
|
||||
@ -546,10 +547,10 @@ sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (kAdopt_GrWrapOwnership == ownership) {
|
||||
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
|
||||
} else {
|
||||
if (kBorrow_GrWrapOwnership == ownership) {
|
||||
idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed;
|
||||
} else {
|
||||
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
|
||||
}
|
||||
|
||||
GrSurfaceDesc surfDesc;
|
||||
@ -575,7 +576,12 @@ sk_sp<GrTexture> GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
|
||||
}
|
||||
return GrGLTextureRenderTarget::MakeWrapped(this, surfDesc, idDesc, rtIDDesc);
|
||||
}
|
||||
return GrGLTexture::MakeWrapped(this, surfDesc, idDesc);
|
||||
|
||||
if (kAdoptAndCache_GrWrapOwnership == ownership) {
|
||||
return sk_sp<GrTexture>(new GrGLTexture(this, SkBudgeted::kYes, surfDesc, idDesc));
|
||||
} else {
|
||||
return GrGLTexture::MakeWrapped(this, surfDesc, idDesc);
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<GrRenderTarget> GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDesc& wrapDesc){
|
||||
|
@ -779,6 +779,7 @@ sk_sp<GrTexture> GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
|
||||
surfDesc.fConfig = desc.fConfig;
|
||||
surfDesc.fSampleCnt = SkTMin(desc.fSampleCnt, this->caps()->maxSampleCount());
|
||||
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrBackendTextureFlag);
|
||||
SkASSERT(!renderTarget || kAdoptAndCache_GrWrapOwnership != ownership); // Not supported
|
||||
// In GL, Chrome assumes all textures are BottomLeft
|
||||
// In VK, we don't have this restriction
|
||||
surfDesc.fOrigin = resolve_origin(desc.fOrigin);
|
||||
|
@ -96,10 +96,13 @@ sk_sp<GrVkTexture> GrVkTexture::MakeWrappedTexture(GrVkGpu* gpu,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrVkImage::Wrapped wrapped = kBorrow_GrWrapOwnership == ownership ? GrVkImage::kBorrowed_Wrapped
|
||||
: GrVkImage::kAdopted_Wrapped;
|
||||
|
||||
return sk_sp<GrVkTexture>(new GrVkTexture(gpu, kWrapped, desc, *info, imageView, wrapped));
|
||||
if (kAdoptAndCache_GrWrapOwnership == ownership) {
|
||||
return sk_sp<GrVkTexture>(new GrVkTexture(gpu, SkBudgeted::kYes, desc, *info, imageView));
|
||||
} else {
|
||||
GrVkImage::Wrapped wrapped = kBorrow_GrWrapOwnership == ownership
|
||||
? GrVkImage::kBorrowed_Wrapped : GrVkImage::kAdopted_Wrapped;
|
||||
return sk_sp<GrVkTexture>(new GrVkTexture(gpu, kWrapped, desc, *info, imageView, wrapped));
|
||||
}
|
||||
}
|
||||
|
||||
GrVkTexture::~GrVkTexture() {
|
||||
|
@ -143,6 +143,7 @@ GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget(GrVkGpu* gpu,
|
||||
SkASSERT(info);
|
||||
// Wrapped textures require both image and allocation (because they can be mapped)
|
||||
SkASSERT(VK_NULL_HANDLE != info->fImage && VK_NULL_HANDLE != info->fAlloc.fMemory);
|
||||
SkASSERT(kAdoptAndCache_GrWrapOwnership != ownership); // Not supported
|
||||
|
||||
GrVkImage::Wrapped wrapped = kBorrow_GrWrapOwnership == ownership ? GrVkImage::kBorrowed_Wrapped
|
||||
: GrVkImage::kAdopted_Wrapped;
|
||||
|
@ -264,7 +264,8 @@ static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx, const GrBackend
|
||||
tex->setRelease(releaseProc, releaseCtx);
|
||||
}
|
||||
|
||||
const SkBudgeted budgeted = SkBudgeted::kNo;
|
||||
const SkBudgeted budgeted = (kAdoptAndCache_GrWrapOwnership == ownership)
|
||||
? SkBudgeted::kYes : SkBudgeted::kNo;
|
||||
return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
|
||||
at, std::move(tex), std::move(colorSpace), budgeted);
|
||||
}
|
||||
@ -476,8 +477,11 @@ sk_sp<SkImage> SkImage::MakeFromCrossContextImageData(
|
||||
ccid->fTextureData->attachToContext(context);
|
||||
}
|
||||
|
||||
return MakeFromAdoptedTexture(context, ccid->fDesc, ccid->fAlphaType,
|
||||
std::move(ccid->fColorSpace));
|
||||
// This texture was created by Ganesh on another thread (see MakeFromEncoded, above).
|
||||
// Thus, we can import it back into our cache and treat it as our own (again).
|
||||
GrWrapOwnership ownership = kAdoptAndCache_GrWrapOwnership;
|
||||
return new_wrapped_texture_common(context, ccid->fDesc, ccid->fAlphaType,
|
||||
std::move(ccid->fColorSpace), ownership, nullptr, nullptr);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::makeNonTextureImage() const {
|
||||
|
@ -140,9 +140,24 @@ DEF_GPUTEST(CrossContextImage_SharedContextSameThread, reporter, /*factory*/) {
|
||||
REPORTER_ASSERT(reporter, ccid != nullptr);
|
||||
|
||||
ContextInfo info2 = factory.getSharedContextInfo(info.grContext());
|
||||
auto image = SkImage::MakeFromCrossContextImageData(info2.grContext(), std::move(ccid));
|
||||
GrContext* ctx2 = info2.grContext();
|
||||
int resourceCountBefore = 0, resourceCountAfter = 0;
|
||||
size_t resourceBytesBefore = 0, resourceBytesAfter = 0;
|
||||
if (ctx2) {
|
||||
ctx2->getResourceCacheUsage(&resourceCountBefore, &resourceBytesBefore);
|
||||
}
|
||||
|
||||
auto image = SkImage::MakeFromCrossContextImageData(ctx2, std::move(ccid));
|
||||
REPORTER_ASSERT(reporter, image != nullptr);
|
||||
|
||||
if (ctx2) {
|
||||
// MakeFromCrossContextImageData should have imported the texture back into our
|
||||
// cache, so we should see an uptick.
|
||||
ctx2->getResourceCacheUsage(&resourceCountAfter, &resourceBytesAfter);
|
||||
REPORTER_ASSERT(reporter, resourceCountAfter == resourceCountBefore + 1);
|
||||
REPORTER_ASSERT(reporter, resourceBytesAfter > resourceBytesBefore);
|
||||
}
|
||||
|
||||
// JPEG encode -> decode won't round trip the image perfectly
|
||||
assert_equal(reporter, testImage.get(), image.get(),
|
||||
SkEncodedImageFormat::kJPEG == format ? 2 : 0);
|
||||
|
@ -208,12 +208,13 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheWrappedResources, reporter, ctxI
|
||||
return;
|
||||
}
|
||||
|
||||
GrBackendObject texHandles[2];
|
||||
GrBackendObject texHandles[3];
|
||||
static const int kW = 100;
|
||||
static const int kH = 100;
|
||||
|
||||
texHandles[0] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kRGBA_8888_GrPixelConfig);
|
||||
texHandles[1] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kRGBA_8888_GrPixelConfig);
|
||||
texHandles[2] = gpu->createTestingOnlyBackendTexture(nullptr, kW, kH, kRGBA_8888_GrPixelConfig);
|
||||
|
||||
context->resetContext();
|
||||
|
||||
@ -230,26 +231,40 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheWrappedResources, reporter, ctxI
|
||||
sk_sp<GrTexture> adopted(context->resourceProvider()->wrapBackendTexture(
|
||||
desc, kAdopt_GrWrapOwnership));
|
||||
|
||||
REPORTER_ASSERT(reporter, borrowed != nullptr && adopted != nullptr);
|
||||
if (!borrowed || !adopted) {
|
||||
desc.fTextureHandle = texHandles[2];
|
||||
sk_sp<GrTexture> adoptedAndCached(context->resourceProvider()->wrapBackendTexture(
|
||||
desc, kAdoptAndCache_GrWrapOwnership));
|
||||
|
||||
REPORTER_ASSERT(reporter, borrowed != nullptr && adopted != nullptr &&
|
||||
adoptedAndCached != nullptr);
|
||||
if (!borrowed || !adopted || !adoptedAndCached) {
|
||||
return;
|
||||
}
|
||||
|
||||
borrowed.reset(nullptr);
|
||||
adopted.reset(nullptr);
|
||||
adoptedAndCached.reset(nullptr);
|
||||
|
||||
context->flush();
|
||||
|
||||
bool borrowedIsAlive = gpu->isTestingOnlyBackendTexture(texHandles[0]);
|
||||
bool adoptedIsAlive = gpu->isTestingOnlyBackendTexture(texHandles[1]);
|
||||
bool adoptedAndCachedIsAlive = gpu->isTestingOnlyBackendTexture(texHandles[2]);
|
||||
|
||||
REPORTER_ASSERT(reporter, borrowedIsAlive);
|
||||
REPORTER_ASSERT(reporter, !adoptedIsAlive);
|
||||
REPORTER_ASSERT(reporter, adoptedAndCachedIsAlive); // Still alive because it's in the cache
|
||||
|
||||
gpu->deleteTestingOnlyBackendTexture(texHandles[0], !borrowedIsAlive);
|
||||
gpu->deleteTestingOnlyBackendTexture(texHandles[1], !adoptedIsAlive);
|
||||
// We can't delete texHandles[2] - we've given control of the lifetime to the context/cache
|
||||
|
||||
context->resetContext();
|
||||
|
||||
// Purge the cache. This should force texHandles[2] to be deleted
|
||||
context->getResourceCache()->purgeAllUnlocked();
|
||||
adoptedAndCachedIsAlive = gpu->isTestingOnlyBackendTexture(texHandles[2]);
|
||||
REPORTER_ASSERT(reporter, !adoptedAndCachedIsAlive);
|
||||
}
|
||||
|
||||
class TestResource : public GrGpuResource {
|
||||
|
Loading…
Reference in New Issue
Block a user