Index: tests/ProxyRefTest.cpp |
diff --git a/tests/ProxyRefTest.cpp b/tests/ProxyRefTest.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4f6a3e368c201a16c86737ca437ac499d10d3e1c |
--- /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 |