From 4684f82ebca85d4c7043e5c1028e34cf5631da32 Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Thu, 8 Mar 2018 15:27:36 -0500 Subject: Add ability to uninstantiate lazy proxies after every flush. Bug: skia: Change-Id: Id32540cda54a9c5e3e6cb721776699be3cc8ac1a Reviewed-on: https://skia-review.googlesource.com/113263 Commit-Queue: Greg Daniel Reviewed-by: Brian Salomon Reviewed-by: Robert Phillips --- tests/LazyProxyTest.cpp | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) (limited to 'tests/LazyProxyTest.cpp') diff --git a/tests/LazyProxyTest.cpp b/tests/LazyProxyTest.cpp index 9253678dbb..88cbd01649 100644 --- a/tests/LazyProxyTest.cpp +++ b/tests/LazyProxyTest.cpp @@ -22,6 +22,7 @@ #include "GrTextureProxyPriv.h" #include "SkMakeUnique.h" #include "SkRectPriv.h" +#include "mock/GrMockGpu.h" #include "mock/GrMockTypes.h" // This test verifies that lazy proxy callbacks get invoked during flush, after onFlush callbacks, @@ -341,7 +342,127 @@ DEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) { REPORTER_ASSERT(reporter, 2 == executeTestValue); } } +} + +class LazyUninstantiateTestOp : public GrDrawOp { +public: + DEFINE_OP_CLASS_ID + + LazyUninstantiateTestOp(sk_sp proxy) + : INHERITED(ClassID()) + , fLazyProxy(std::move(proxy)) { + + this->setBounds(SkRect::MakeIWH(kSize, kSize), + HasAABloat::kNo, IsZeroArea::kNo); + } + + void visitProxies(const VisitProxyFunc& func) const override { + func(fLazyProxy.get()); + } + +private: + const char* name() const override { return "LazyUninstantiateTestOp"; } + FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; } + RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*, + GrPixelConfigIsClamped) override { + return RequiresDstTexture::kNo; + } + bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override { return false; } + void onPrepare(GrOpFlushState*) override {} + void onExecute(GrOpFlushState* state) override {} + + sk_sp fLazyProxy; + + typedef GrDrawOp INHERITED; +}; + +static void UninstantiateReleaseProc(void* releaseValue) { + (*static_cast(releaseValue))++; +} + +// Test that lazy proxies with the Uninstantiate LazyCallbackType are uninstantiated and released as +// expected. +DEF_GPUTEST(LazyProxyUninstantiateTest, reporter, /* options */) { + GrMockOptions mockOptions; + sk_sp ctx = GrContext::MakeMock(&mockOptions, GrContextOptions()); + GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider(); + GrGpu* gpu = ctx->contextPriv().getGpu(); + + using LazyType = GrSurfaceProxy::LazyInstantiationType; + for (auto lazyType : {LazyType::kSingleUse, LazyType::kMultipleUse, LazyType::kUninstantiate}) { + sk_sp rtc = ctx->contextPriv().makeDeferredRenderTargetContext( + SkBackingFit::kExact, 100, 100, + kRGBA_8888_GrPixelConfig, nullptr); + REPORTER_ASSERT(reporter, rtc); + + rtc->clear(nullptr, 0xbaaaaaad, GrRenderTargetContext::CanClearFullscreen::kYes); + + int instantiateTestValue = 0; + int releaseTestValue = 0; + int* instantiatePtr = &instantiateTestValue; + int* releasePtr = &releaseTestValue; + GrSurfaceDesc desc; + desc.fWidth = kSize; + desc.fHeight = kSize; + desc.fConfig = kRGBA_8888_GrPixelConfig; + + GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture( + nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, GrMipMapped::kNo); + + sk_sp lazyProxy = proxyProvider->createLazyProxy( + [instantiatePtr, releasePtr, backendTex](GrResourceProvider* rp) { + if (!rp) { + return sk_sp(); + } + + sk_sp texture = rp->wrapBackendTexture(backendTex); + if (!texture) { + return sk_sp(); + } + (*instantiatePtr)++; + texture->setRelease(UninstantiateReleaseProc, releasePtr); + return texture; + }, + desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact, + SkBudgeted::kNo); + + lazyProxy->priv().testingOnly_setLazyInstantiationType(lazyType); + + rtc->priv().testingOnly_addDrawOp(skstd::make_unique(lazyProxy)); + + ctx->flush(); + + REPORTER_ASSERT(reporter, 1 == instantiateTestValue); + if (LazyType::kUninstantiate == lazyType) { + REPORTER_ASSERT(reporter, 1 == releaseTestValue); + } else { + REPORTER_ASSERT(reporter, 0 == releaseTestValue); + } + // This should cause the uninstantiate proxies to be instantiated again but have no effect + // on the others + rtc->priv().testingOnly_addDrawOp(skstd::make_unique(lazyProxy)); + // Add a second op to make sure we only instantiate once. + rtc->priv().testingOnly_addDrawOp(skstd::make_unique(lazyProxy)); + ctx->flush(); + + if (LazyType::kUninstantiate == lazyType) { + REPORTER_ASSERT(reporter, 2 == instantiateTestValue); + REPORTER_ASSERT(reporter, 2 == releaseTestValue); + } else { + REPORTER_ASSERT(reporter, 1 == instantiateTestValue); + REPORTER_ASSERT(reporter, 0 == releaseTestValue); + } + + lazyProxy.reset(); + if (LazyType::kUninstantiate == lazyType) { + REPORTER_ASSERT(reporter, 2 == releaseTestValue); + } else { + REPORTER_ASSERT(reporter, 1 == releaseTestValue); + } + + gpu->deleteTestingOnlyBackendTexture(&backendTex); + } } #endif -- cgit v1.2.3