1/* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8// This is a GPU-backend specific test. 9 10#include "Test.h" 11 12#if SK_SUPPORT_GPU 13#include "GrContextPriv.h" 14#include "GrGpuResourceRef.h" 15#include "GrProxyProvider.h" 16#include "GrRenderTargetProxy.h" 17#include "GrResourceProvider.h" 18#include "GrSurfaceProxy.h" 19#include "GrTexture.h" 20#include "GrTextureProxy.h" 21 22int32_t GrIORefProxy::getProxyRefCnt_TestOnly() const { 23 return fRefCnt; 24} 25 26int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const { 27 if (fTarget) { 28 return fTarget->fRefCnt; 29 } 30 31 return fRefCnt; 32} 33 34int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const { 35 if (fTarget) { 36 return fTarget->fPendingReads; 37 } 38 39 return fPendingReads; 40} 41 42int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const { 43 if (fTarget) { 44 return fTarget->fPendingWrites; 45 } 46 47 return fPendingWrites; 48} 49 50static const int kWidthHeight = 128; 51 52static void check_refs(skiatest::Reporter* reporter, 53 GrTextureProxy* proxy, 54 int32_t expectedProxyRefs, 55 int32_t expectedBackingRefs, 56 int32_t expectedNumReads, 57 int32_t expectedNumWrites) { 58 REPORTER_ASSERT(reporter, proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs); 59 REPORTER_ASSERT(reporter, proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs); 60 REPORTER_ASSERT(reporter, proxy->getPendingReadCnt_TestOnly() == expectedNumReads); 61 REPORTER_ASSERT(reporter, proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); 62 63 SkASSERT(proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs); 64 SkASSERT(proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs); 65 SkASSERT(proxy->getPendingReadCnt_TestOnly() == expectedNumReads); 66 SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); 67} 68 69static sk_sp<GrTextureProxy> make_deferred(GrProxyProvider* proxyProvider) { 70 GrSurfaceDesc desc; 71 desc.fFlags = kRenderTarget_GrSurfaceFlag; 72 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; 73 desc.fWidth = kWidthHeight; 74 desc.fHeight = kWidthHeight; 75 desc.fConfig = kRGBA_8888_GrPixelConfig; 76 77 return proxyProvider->createProxy(desc, SkBackingFit::kApprox, SkBudgeted::kYes, 78 GrResourceProvider::kNoPendingIO_Flag); 79} 80 81static sk_sp<GrTextureProxy> make_wrapped(GrProxyProvider* proxyProvider) { 82 GrSurfaceDesc desc; 83 desc.fFlags = kRenderTarget_GrSurfaceFlag; 84 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; 85 desc.fWidth = kWidthHeight; 86 desc.fHeight = kWidthHeight; 87 desc.fConfig = kRGBA_8888_GrPixelConfig; 88 89 return proxyProvider->createInstantiatedProxy(desc, SkBackingFit::kExact, SkBudgeted::kNo); 90} 91 92DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) { 93 GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider(); 94 GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider(); 95 96 for (auto make : { make_deferred, make_wrapped }) { 97 // A single write 98 { 99 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider)); 100 if (proxy.get()) { 101 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get()); 102 103 static const int kExpectedReads = 0; 104 static const int kExpectedWrites = 1; 105 106 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); 107 108 proxy->instantiate(resourceProvider); 109 110 // In the deferred case, this checks that the refs transfered to the GrSurface 111 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); 112 } 113 } 114 115 // A single read 116 { 117 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider)); 118 if (proxy.get()) { 119 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get()); 120 121 static const int kExpectedReads = 1; 122 static const int kExpectedWrites = 0; 123 124 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); 125 126 proxy->instantiate(resourceProvider); 127 128 // In the deferred case, this checks that the refs transfered to the GrSurface 129 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); 130 } 131 } 132 133 // A single read/write pair 134 { 135 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider)); 136 if (proxy.get()) { 137 GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(proxy.get()); 138 139 static const int kExpectedReads = 1; 140 static const int kExpectedWrites = 1; 141 142 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); 143 144 proxy->instantiate(resourceProvider); 145 146 // In the deferred case, this checks that the refs transferred to the GrSurface 147 check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites); 148 } 149 } 150 151 // Multiple normal refs 152 { 153 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider)); 154 if (proxy.get()) { 155 proxy->ref(); 156 proxy->ref(); 157 158 static const int kExpectedReads = 0; 159 static const int kExpectedWrites = 0; 160 161 check_refs(reporter, proxy.get(), 3, 3,kExpectedReads, kExpectedWrites); 162 163 proxy->instantiate(resourceProvider); 164 165 // In the deferred case, this checks that the refs transferred to the GrSurface 166 check_refs(reporter, proxy.get(), 3, 3, kExpectedReads, kExpectedWrites); 167 168 proxy->unref(); 169 proxy->unref(); 170 } 171 } 172 173 // Continue using (reffing) proxy after instantiation 174 { 175 sk_sp<GrTextureProxy> proxy((*make)(proxyProvider)); 176 if (proxy.get()) { 177 proxy->ref(); 178 179 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get()); 180 181 static const int kExpectedWrites = 1; 182 183 check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites); 184 185 proxy->instantiate(resourceProvider); 186 187 // In the deferred case, this checks that the refs transfered to the GrSurface 188 check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites); 189 190 proxy->unref(); 191 check_refs(reporter, proxy.get(), 1, 1, 0, kExpectedWrites); 192 193 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get()); 194 check_refs(reporter, proxy.get(), 1, 1, 1, kExpectedWrites); 195 } 196 } 197 } 198} 199 200#endif 201