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