Release YUVA planes in SkImage_GpuYUVA after flattenning to RGBA.
Also removed unused virtual function from SkImage_GpuBase and override on SkImage_GpuYUVA. Change-Id: Ib47b46b529b16976181cb9453976133d66e0f952 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/212734 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
d369a5e9cf
commit
a15f355be8
@ -91,8 +91,9 @@ std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProc
|
||||
bool coordsLimitedToConstraintRect,
|
||||
const GrSamplerState::Filter* filterOrNullForBicubic) {
|
||||
|
||||
// Check simple cases to see if we need to fall back to flattening the image
|
||||
if (!filterOrNullForBicubic || this->domainNeedsDecal()) {
|
||||
// Check simple cases to see if we need to fall back to flattening the image (or whether it's
|
||||
// already been flattened.)
|
||||
if (!filterOrNullForBicubic || this->domainNeedsDecal() || fImage->fRGBProxy) {
|
||||
return this->INHERITED::createFragmentProcessor(textureMatrix, constraintRect,
|
||||
filterConstraint,
|
||||
coordsLimitedToConstraintRect,
|
||||
|
@ -64,8 +64,6 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
virtual bool isYUVA() const { return false; }
|
||||
virtual bool asYUVATextureProxiesRef(sk_sp<GrTextureProxy>[4], SkYUVAIndex[4],
|
||||
SkYUVColorSpace*) const { return false; }
|
||||
virtual GrTexture* onGetTexture() const { return nullptr; }
|
||||
#endif
|
||||
virtual GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO,
|
||||
|
@ -71,8 +71,12 @@ SkImage_GpuYUVA::SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpac
|
||||
SkASSERT(SkYUVAIndex::AreValidIndices(image->fYUVAIndices, &textureCount));
|
||||
SkASSERT(textureCount == fNumProxies);
|
||||
|
||||
for (int i = 0; i < fNumProxies; ++i) {
|
||||
fProxies[i] = image->fProxies[i]; // we ref in this case, not move
|
||||
if (image->fRGBProxy) {
|
||||
fRGBProxy = image->fRGBProxy; // we ref in this case, not move
|
||||
} else {
|
||||
for (int i = 0; i < fNumProxies; ++i) {
|
||||
fProxies[i] = image->fProxies[i]; // we ref in this case, not move
|
||||
}
|
||||
}
|
||||
memcpy(fYUVAIndices, image->fYUVAIndices, 4 * sizeof(SkYUVAIndex));
|
||||
}
|
||||
@ -80,6 +84,8 @@ SkImage_GpuYUVA::SkImage_GpuYUVA(const SkImage_GpuYUVA* image, sk_sp<SkColorSpac
|
||||
SkImage_GpuYUVA::~SkImage_GpuYUVA() {}
|
||||
|
||||
bool SkImage_GpuYUVA::setupMipmapsForPlanes(GrRecordingContext* context) const {
|
||||
// We shouldn't get here if the planes were already flattened to RGBA.
|
||||
SkASSERT(fProxies[0] && !fRGBProxy);
|
||||
if (!context || !fContext->priv().matches(context)) {
|
||||
return false;
|
||||
}
|
||||
@ -108,12 +114,15 @@ GrSemaphoresSubmitted SkImage_GpuYUVA::onFlush(GrContext* context, const GrFlush
|
||||
return GrSemaphoresSubmitted::kNo;
|
||||
}
|
||||
|
||||
GrSurfaceProxy* proxies[5] = {fProxies[0].get(), fProxies[1].get(),
|
||||
fProxies[2].get(), fProxies[3].get(), nullptr};
|
||||
GrSurfaceProxy* proxies[4] = {fProxies[0].get(), fProxies[1].get(),
|
||||
fProxies[2].get(), fProxies[3].get()};
|
||||
int numProxies = fNumProxies;
|
||||
if (fRGBProxy) {
|
||||
proxies[fNumProxies] = fRGBProxy.get();
|
||||
++numProxies;
|
||||
// Either we've already flushed the flattening draw or the flattening is unflushed. In the
|
||||
// latter case it should still be ok to just pass fRGBProxy because it in turn depends on
|
||||
// the planar proxies and will cause all of their work to flush as well.
|
||||
proxies[0] = fRGBProxy.get();
|
||||
numProxies = 1;
|
||||
}
|
||||
return context->priv().flushSurfaces(proxies, numProxies, info);
|
||||
}
|
||||
@ -155,6 +164,9 @@ sk_sp<GrTextureProxy> SkImage_GpuYUVA::asTextureProxyRef(GrRecordingContext* con
|
||||
}
|
||||
|
||||
fRGBProxy = renderTargetContext->asTextureProxyRef();
|
||||
for (auto& p : fProxies) {
|
||||
p.reset();
|
||||
}
|
||||
return fRGBProxy;
|
||||
}
|
||||
|
||||
|
@ -42,23 +42,19 @@ public:
|
||||
SkColorType, sk_sp<SkColorSpace>) const final;
|
||||
|
||||
virtual bool isYUVA() const override { return true; }
|
||||
virtual bool asYUVATextureProxiesRef(sk_sp<GrTextureProxy> proxies[4],
|
||||
SkYUVAIndex yuvaIndices[4],
|
||||
SkYUVColorSpace* yuvColorSpace) const override {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
proxies[i] = fProxies[i];
|
||||
yuvaIndices[i] = fYUVAIndices[i];
|
||||
}
|
||||
*yuvColorSpace = fYUVColorSpace;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setupMipmapsForPlanes(GrRecordingContext*) const;
|
||||
|
||||
// Returns a ref-ed texture proxy with miplevels
|
||||
sk_sp<GrTextureProxy> asMippedTextureProxyRef(GrRecordingContext*) const;
|
||||
|
||||
bool testingOnly_IsFlattened() const { return SkToBool(fRGBProxy); }
|
||||
#if GR_TEST_UTILS
|
||||
bool testingOnly_IsFlattened() const {
|
||||
// We should only have the flattened proxy or the planar proxies at one point in time.
|
||||
SkASSERT(SkToBool(fRGBProxy) != SkToBool(fProxies[0]));
|
||||
return SkToBool(fRGBProxy);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This is the implementation of SkDeferredDisplayListRecorder::makeYUVAPromiseTexture.
|
||||
|
@ -1376,6 +1376,19 @@ DEF_TEST(Image_nonfinite_dst, reporter) {
|
||||
}
|
||||
}
|
||||
|
||||
static sk_sp<SkImage> make_yuva_image(GrContext* c) {
|
||||
SkAutoPixmapStorage pm;
|
||||
pm.alloc(SkImageInfo::Make(1, 1, kAlpha_8_SkColorType, kPremul_SkAlphaType));
|
||||
const SkPixmap pmaps[] = {pm, pm, pm, pm};
|
||||
SkYUVAIndex indices[] = {{0, SkColorChannel::kA},
|
||||
{1, SkColorChannel::kA},
|
||||
{2, SkColorChannel::kA},
|
||||
{3, SkColorChannel::kA}};
|
||||
|
||||
return SkImage::MakeFromYUVAPixmaps(c, kJPEG_SkYUVColorSpace, pmaps, indices,
|
||||
SkISize::Make(1, 1), kTopLeft_GrSurfaceOrigin, false);
|
||||
}
|
||||
|
||||
DEF_GPUTEST_FOR_ALL_CONTEXTS(ImageFlush, reporter, ctxInfo) {
|
||||
auto c = ctxInfo.grContext();
|
||||
auto ii = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
@ -1386,15 +1399,8 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ImageFlush, reporter, ctxInfo) {
|
||||
s->getCanvas()->clear(SK_ColorBLUE);
|
||||
auto i1 = s->makeImageSnapshot();
|
||||
s->getCanvas()->clear(SK_ColorGREEN);
|
||||
|
||||
// Make a YUVA image.
|
||||
SkAutoPixmapStorage pm;
|
||||
pm.alloc(SkImageInfo::Make(1, 1, kAlpha_8_SkColorType, kPremul_SkAlphaType));
|
||||
const SkPixmap pmaps[] = {pm, pm, pm, pm};
|
||||
SkYUVAIndex indices[] = {{0, SkColorChannel::kA}, {1, SkColorChannel::kA},
|
||||
{2, SkColorChannel::kA}, {3, SkColorChannel::kA}};
|
||||
auto i2 = SkImage::MakeFromYUVAPixmaps(c, kJPEG_SkYUVColorSpace, pmaps, indices,
|
||||
SkISize::Make(1, 1), kTopLeft_GrSurfaceOrigin, false);
|
||||
auto i2 = make_yuva_image(c);
|
||||
|
||||
// Flush all the setup work we did above and then make little lambda that reports the flush
|
||||
// count delta since the last time it was called.
|
||||
@ -1448,4 +1454,35 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ImageFlush, reporter, ctxInfo) {
|
||||
// Since we just did a simple image draw it should not have been flattened.
|
||||
REPORTER_ASSERT(reporter,
|
||||
!static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened());
|
||||
|
||||
// Flatten it and repeat.
|
||||
as_IB(i2.get())->asTextureProxyRef(c);
|
||||
REPORTER_ASSERT(reporter,
|
||||
static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened());
|
||||
s->getCanvas()->drawImage(i2, 0, 0);
|
||||
// Flushing image 0 should do nothing.
|
||||
i0->flush(c);
|
||||
REPORTER_ASSERT(reporter, numFlushes() == 0);
|
||||
// Flushing image 1 do nothing.
|
||||
i1->flush(c);
|
||||
REPORTER_ASSERT(reporter, numFlushes() == 0);
|
||||
// Flushing image 2 should flush.
|
||||
i2->flush(c);
|
||||
REPORTER_ASSERT(reporter, numFlushes() == 1);
|
||||
|
||||
// Test case where flatten happens before the first flush.
|
||||
i2 = make_yuva_image(c);
|
||||
as_IB(i2.get())->asTextureProxyRef(c);
|
||||
REPORTER_ASSERT(reporter,
|
||||
static_cast<SkImage_GpuYUVA*>(as_IB(i2.get()))->testingOnly_IsFlattened());
|
||||
s->getCanvas()->drawImage(i2, 0, 0);
|
||||
// Flushing image 0 should do nothing.
|
||||
i0->flush(c);
|
||||
REPORTER_ASSERT(reporter, numFlushes() == 0);
|
||||
// Flushing image 1 do nothing.
|
||||
i1->flush(c);
|
||||
REPORTER_ASSERT(reporter, numFlushes() == 0);
|
||||
// Flushing image 2 should flush.
|
||||
i2->flush(c);
|
||||
REPORTER_ASSERT(reporter, numFlushes() == 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user