/* * 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" #include "GrContextPriv.h" #include "GrPendingIOResource.h" #include "GrProxyProvider.h" #include "GrRenderTargetProxy.h" #include "GrResourceProvider.h" #include "GrSurfaceProxy.h" #include "GrTexture.h" #include "GrTextureProxy.h" int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const { if (fTarget) { return fTarget->fRefCnt; } return -1; // no backing GrSurface } int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const { if (fTarget) { return fTarget->fPendingReads; } return fPendingReads; } int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const { if (fTarget) { return fTarget->fPendingWrites; } return fPendingWrites; } static const int kWidthHeight = 128; static void check_refs(skiatest::Reporter* reporter, GrTextureProxy* proxy, int32_t expectedProxyRefs, int32_t expectedBackingRefs, int32_t expectedNumReads, int32_t expectedNumWrites) { REPORTER_ASSERT(reporter, proxy->priv().getProxyRefCnt() == expectedProxyRefs); REPORTER_ASSERT(reporter, proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs); REPORTER_ASSERT(reporter, proxy->getPendingReadCnt_TestOnly() == expectedNumReads); REPORTER_ASSERT(reporter, proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); SkASSERT(proxy->priv().getProxyRefCnt() == expectedProxyRefs); SkASSERT(proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs); SkASSERT(proxy->getPendingReadCnt_TestOnly() == expectedNumReads); SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); } static sk_sp<GrTextureProxy> make_deferred(GrProxyProvider* proxyProvider, const GrCaps* caps) { GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = kWidthHeight; desc.fHeight = kWidthHeight; desc.fConfig = kRGBA_8888_GrPixelConfig; const GrBackendFormat format = caps->getBackendFormatFromColorType(kRGBA_8888_SkColorType); return proxyProvider->createProxy(format, desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes, GrInternalSurfaceFlags::kNoPendingIO); } static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider, const GrCaps* caps) { GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = kWidthHeight; desc.fHeight = kWidthHeight; desc.fConfig = kRGBA_8888_GrPixelConfig; return proxyProvider->testingOnly_createInstantiatedProxy( desc, kBottomLeft_GrSurfaceOrigin, SkBackingFit::kExact, SkBudgeted::kNo); } DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) { GrProxyProvider* proxyProvider = ctxInfo.grContext()->priv().proxyProvider(); GrResourceProvider* resourceProvider = ctxInfo.grContext()->priv().resourceProvider(); const GrCaps* caps = ctxInfo.grContext()->priv().caps(); for (auto make : { make_deferred, make_wrapped }) { // A single write { sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps)); if (proxy.get()) { GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get()); static const int kExpectedReads = 0; static const int kExpectedWrites = 1; int backingRefs = proxy->isWrapped_ForTesting() ? 1 : -1; check_refs(reporter, proxy.get(), 1, backingRefs, kExpectedReads, kExpectedWrites); proxy->instantiate(resourceProvider); // In the deferred case, this checks that the refs transfered to the GrSurface check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); } } // A single read { sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps)); if (proxy.get()) { GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get()); static const int kExpectedReads = 1; static const int kExpectedWrites = 0; int backingRefs = proxy->isWrapped_ForTesting() ? 1 : -1; check_refs(reporter, proxy.get(), 1, backingRefs, kExpectedReads, kExpectedWrites); proxy->instantiate(resourceProvider); // In the deferred case, this checks that the refs transfered to the GrSurface check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); } } // A single read/write pair { sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps)); if (proxy.get()) { GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(proxy.get()); static const int kExpectedReads = 1; static const int kExpectedWrites = 1; int backingRefs = proxy->isWrapped_ForTesting() ? 1 : -1; check_refs(reporter, proxy.get(), 1, backingRefs, kExpectedReads, kExpectedWrites); proxy->instantiate(resourceProvider); // In the deferred case, this checks that the refs transferred to the GrSurface check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); } } // Multiple normal refs { sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps)); if (proxy.get()) { proxy->ref(); proxy->ref(); static const int kExpectedReads = 0; static const int kExpectedWrites = 0; int backingRefs = proxy->isWrapped_ForTesting() ? 3 : -1; check_refs(reporter, proxy.get(), 3, backingRefs, kExpectedReads, kExpectedWrites); proxy->instantiate(resourceProvider); // In the deferred case, this checks that the refs transferred to the GrSurface check_refs(reporter, proxy.get(), 3, 3, kExpectedReads, kExpectedWrites); proxy->unref(); proxy->unref(); } } // Continue using (reffing) proxy after instantiation { sk_sp<GrTextureProxy> proxy((*make)(proxyProvider, caps)); if (proxy.get()) { proxy->ref(); GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get()); static const int kExpectedWrites = 1; int backingRefs = proxy->isWrapped_ForTesting() ? 2 : -1; check_refs(reporter, proxy.get(), 2, backingRefs, 0, kExpectedWrites); proxy->instantiate(resourceProvider); // In the deferred case, this checks that the refs transfered to the GrSurface check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites); proxy->unref(); check_refs(reporter, proxy.get(), 1, 1, 0, kExpectedWrites); GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get()); check_refs(reporter, proxy.get(), 1, 1, 1, kExpectedWrites); } } } }