diff options
author | robertphillips <robertphillips@google.com> | 2016-11-16 11:17:17 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-11-16 11:17:17 -0800 |
commit | 1125a030c726854f94fd2b8eed49d1323fc1d038 (patch) | |
tree | 56a26a60c160186a4cada83e904d0d3c60c25a6e /tests/ProxyRefTest.cpp | |
parent | 20079a94e82fd7345dfb119a8777e5ba482a041c (diff) |
Add IORef capability to GrSurfaceProxy objects - take 2
Re-landing of https://skia-review.googlesource.com/c/4734/ (Add IORef capability to GrSurfaceProxy objects) with fixes for:
platforms that don't support discards.
memory leak due to copying over of GrSurfaceProxy's creation ref to instantiated GrSurface in instantiate()
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4827
BUG=skia:
Change-Id: If0b695d5cafc5ef3fdd251c38262849d09e5d27f
Review-Url: https://codereview.chromium.org/2502923003
Diffstat (limited to 'tests/ProxyRefTest.cpp')
-rw-r--r-- | tests/ProxyRefTest.cpp | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/tests/ProxyRefTest.cpp b/tests/ProxyRefTest.cpp new file mode 100644 index 0000000000..4f6a3e368c --- /dev/null +++ b/tests/ProxyRefTest.cpp @@ -0,0 +1,205 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// This is a GPU-backend specific test. + +#include "Test.h" + +#if SK_SUPPORT_GPU +#include "GrSurfaceProxy.h" +#include "GrTextureProxy.h" +#include "GrRenderTargetPriv.h" +#include "GrRenderTargetProxy.h" + +static const int kWidthHeight = 128; + +int32_t GrIORefProxy::getProxyRefCnt_TestOnly() const { + return fRefCnt; +} + +int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const { + if (fTarget) { + return fTarget->fRefCnt; + } + + return fRefCnt; +} + +int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const { + if (fTarget) { + SkASSERT(!fPendingReads); + return fTarget->fPendingReads; + } + + return fPendingReads; +} + +int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const { + if (fTarget) { + SkASSERT(!fPendingWrites); + return fTarget->fPendingWrites; + } + + return fPendingWrites; +} + +static void check_refs(skiatest::Reporter* reporter, + GrSurfaceProxy* proxy, + int32_t expectedProxyRefs, + int32_t expectedBackingRefs, + int32_t expectedNumReads, + int32_t expectedNumWrites) { + REPORTER_ASSERT(reporter, proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs); + REPORTER_ASSERT(reporter, proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs); + REPORTER_ASSERT(reporter, proxy->getPendingReadCnt_TestOnly() == expectedNumReads); + REPORTER_ASSERT(reporter, proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); + + SkASSERT(proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs); + SkASSERT(proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs); + SkASSERT(proxy->getPendingReadCnt_TestOnly() == expectedNumReads); + SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); +} + +static sk_sp<GrSurfaceProxy> make_deferred(const GrCaps& caps, GrTextureProvider* provider) { + GrSurfaceDesc desc; + desc.fFlags = kRenderTarget_GrSurfaceFlag; + desc.fWidth = kWidthHeight; + desc.fHeight = kWidthHeight; + desc.fConfig = kRGBA_8888_GrPixelConfig; + + return GrSurfaceProxy::MakeDeferred(caps, desc, SkBackingFit::kApprox, SkBudgeted::kYes); +} + +static sk_sp<GrSurfaceProxy> make_wrapped(const GrCaps& caps, GrTextureProvider* provider) { + GrSurfaceDesc desc; + desc.fFlags = kRenderTarget_GrSurfaceFlag; + desc.fWidth = kWidthHeight; + desc.fHeight = kWidthHeight; + desc.fConfig = kRGBA_8888_GrPixelConfig; + + sk_sp<GrTexture> tex(provider->createTexture(desc, SkBudgeted::kNo)); + + // Flush the IOWrite from the initial discard or it will confuse the later ref count checks + tex->flushWrites(); + + return GrSurfaceProxy::MakeWrapped(std::move(tex)); +} + +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) { + GrTextureProvider* provider = ctxInfo.grContext()->textureProvider(); + const GrCaps& caps = *ctxInfo.grContext()->caps(); + + for (auto make : { make_deferred, make_wrapped }) { + // A single write + { + sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); + + GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(sProxy.get()); + + check_refs(reporter, sProxy.get(), 1, 1, 0, 1); + + // In the deferred case, the discard batch created on instantiation adds an + // extra ref and write + bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + caps.discardRenderTargetSupport(); + int expectedWrites = proxyGetsDiscardRef ? 2 : 1; + + sProxy->instantiate(provider); + + // In the deferred case, this checks that the refs transfered to the GrSurface + check_refs(reporter, sProxy.get(), 1, 1, 0, expectedWrites); + } + + // A single read + { + sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); + + GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(sProxy.get()); + + check_refs(reporter, sProxy.get(), 1, 1, 1, 0); + + // In the deferred case, the discard batch created on instantiation adds an + // extra ref and write + bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + caps.discardRenderTargetSupport(); + int expectedWrites = proxyGetsDiscardRef ? 1 : 0; + + sProxy->instantiate(provider); + + // In the deferred case, this checks that the refs transfered to the GrSurface + check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); + } + + // A single read/write pair + { + sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); + + GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(sProxy.get()); + + check_refs(reporter, sProxy.get(), 1, 1, 1, 1); + + // In the deferred case, the discard batch created on instantiation adds an + // extra ref and write + bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + caps.discardRenderTargetSupport(); + int expectedWrites = proxyGetsDiscardRef ? 2 : 1; + + sProxy->instantiate(provider); + + // In the deferred case, this checks that the refs transfered to the GrSurface + check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); + } + + // Multiple normal refs + { + sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); + sProxy->ref(); + sProxy->ref(); + + check_refs(reporter, sProxy.get(), 3, 3, 0, 0); + + bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + caps.discardRenderTargetSupport(); + int expectedWrites = proxyGetsDiscardRef ? 1 : 0; + + sProxy->instantiate(provider); + + // In the deferred case, this checks that the refs transfered to the GrSurface + check_refs(reporter, sProxy.get(), 3, 3, 0, expectedWrites); + + sProxy->unref(); + sProxy->unref(); + } + + // Continue using (reffing) proxy after instantiation + { + sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); + sProxy->ref(); + + GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(sProxy.get()); + + check_refs(reporter, sProxy.get(), 2, 2, 0, 1); + + bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && + caps.discardRenderTargetSupport(); + int expectedWrites = proxyGetsDiscardRef ? 2 : 1; + + sProxy->instantiate(provider); + + // In the deferred case, this checks that the refs transfered to the GrSurface + check_refs(reporter, sProxy.get(), 2, 2, 0, expectedWrites); + + sProxy->unref(); + check_refs(reporter, sProxy.get(), 1, 1, 0, expectedWrites); + + GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(sProxy.get()); + check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); + } + } +} + +#endif |