ProxyRefTest.cpp revision 24429c68c56683252e3fc2a79d9b660eaf96ec0c
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 "GrSurfaceProxy.h" 14#include "GrTextureProvider.h" 15#include "GrTextureProxy.h" 16#include "GrRenderTargetPriv.h" 17#include "GrRenderTargetProxy.h" 18 19int32_t GrIORefProxy::getProxyRefCnt_TestOnly() const { 20 return fRefCnt; 21} 22 23int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const { 24 if (fTarget) { 25 return fTarget->fRefCnt; 26 } 27 28 return fRefCnt; 29} 30 31int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const { 32 if (fTarget) { 33 SkASSERT(!fPendingReads); 34 return fTarget->fPendingReads; 35 } 36 37 return fPendingReads; 38} 39 40int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const { 41 if (fTarget) { 42 SkASSERT(!fPendingWrites); 43 return fTarget->fPendingWrites; 44 } 45 46 return fPendingWrites; 47} 48 49#ifndef SK_DISABLE_DEFERRED_PROXIES 50 51static const int kWidthHeight = 128; 52 53static void check_refs(skiatest::Reporter* reporter, 54 GrSurfaceProxy* proxy, 55 int32_t expectedProxyRefs, 56 int32_t expectedBackingRefs, 57 int32_t expectedNumReads, 58 int32_t expectedNumWrites) { 59 REPORTER_ASSERT(reporter, proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs); 60 REPORTER_ASSERT(reporter, proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs); 61 REPORTER_ASSERT(reporter, proxy->getPendingReadCnt_TestOnly() == expectedNumReads); 62 REPORTER_ASSERT(reporter, proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); 63 64 SkASSERT(proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs); 65 SkASSERT(proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs); 66 SkASSERT(proxy->getPendingReadCnt_TestOnly() == expectedNumReads); 67 SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites); 68} 69 70static sk_sp<GrSurfaceProxy> make_deferred(const GrCaps& caps, GrTextureProvider* provider) { 71 GrSurfaceDesc desc; 72 desc.fFlags = kRenderTarget_GrSurfaceFlag; 73 desc.fWidth = kWidthHeight; 74 desc.fHeight = kWidthHeight; 75 desc.fConfig = kRGBA_8888_GrPixelConfig; 76 77 return GrSurfaceProxy::MakeDeferred(provider, caps, desc, 78 SkBackingFit::kApprox, SkBudgeted::kYes); 79} 80 81static sk_sp<GrSurfaceProxy> make_wrapped(const GrCaps& caps, GrTextureProvider* provider) { 82 GrSurfaceDesc desc; 83 desc.fFlags = kRenderTarget_GrSurfaceFlag; 84 desc.fWidth = kWidthHeight; 85 desc.fHeight = kWidthHeight; 86 desc.fConfig = kRGBA_8888_GrPixelConfig; 87 88 sk_sp<GrTexture> tex(provider->createTexture(desc, SkBudgeted::kNo)); 89 90 // Flush the IOWrite from the initial discard or it will confuse the later ref count checks 91 tex->flushWrites(); 92 93 return GrSurfaceProxy::MakeWrapped(std::move(tex)); 94} 95 96DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) { 97 GrTextureProvider* provider = ctxInfo.grContext()->textureProvider(); 98 const GrCaps& caps = *ctxInfo.grContext()->caps(); 99 100 // Currently the op itself takes a pending write and the render target op list does as well. 101 static const int kWritesForDiscard = 2; 102 for (auto make : { make_deferred, make_wrapped }) { 103 // A single write 104 { 105 sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); 106 107 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(sProxy.get()); 108 109 check_refs(reporter, sProxy.get(), 1, 1, 0, 1); 110 111 // In the deferred case, the discard op created on instantiation adds an 112 // extra ref and write 113 bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && 114 caps.discardRenderTargetSupport(); 115 int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0); 116 117 sProxy->instantiate(provider); 118 119 // In the deferred case, this checks that the refs transfered to the GrSurface 120 check_refs(reporter, sProxy.get(), 1, 1, 0, expectedWrites); 121 } 122 123 // A single read 124 { 125 sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); 126 127 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(sProxy.get()); 128 129 check_refs(reporter, sProxy.get(), 1, 1, 1, 0); 130 131 // In the deferred case, the discard op created on instantiation adds an 132 // extra ref and write 133 bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && 134 caps.discardRenderTargetSupport(); 135 int expectedWrites = proxyGetsDiscardRef ? kWritesForDiscard : 0; 136 137 sProxy->instantiate(provider); 138 139 // In the deferred case, this checks that the refs transfered to the GrSurface 140 check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); 141 } 142 143 // A single read/write pair 144 { 145 sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); 146 147 GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(sProxy.get()); 148 149 check_refs(reporter, sProxy.get(), 1, 1, 1, 1); 150 151 // In the deferred case, the discard op created on instantiation adds an 152 // extra ref and write 153 bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && 154 caps.discardRenderTargetSupport(); 155 int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0); 156 157 sProxy->instantiate(provider); 158 159 // In the deferred case, this checks that the refs transferred to the GrSurface 160 check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); 161 } 162 163 // Multiple normal refs 164 { 165 sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); 166 sProxy->ref(); 167 sProxy->ref(); 168 169 check_refs(reporter, sProxy.get(), 3, 3, 0, 0); 170 171 bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && 172 caps.discardRenderTargetSupport(); 173 int expectedWrites = proxyGetsDiscardRef ? kWritesForDiscard : 0; 174 175 sProxy->instantiate(provider); 176 177 // In the deferred case, this checks that the refs transferred to the GrSurface 178 check_refs(reporter, sProxy.get(), 3, 3, 0, expectedWrites); 179 180 sProxy->unref(); 181 sProxy->unref(); 182 } 183 184 // Continue using (reffing) proxy after instantiation 185 { 186 sk_sp<GrSurfaceProxy> sProxy((*make)(caps, provider)); 187 sProxy->ref(); 188 189 GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(sProxy.get()); 190 191 check_refs(reporter, sProxy.get(), 2, 2, 0, 1); 192 193 bool proxyGetsDiscardRef = !sProxy->isWrapped_ForTesting() && 194 caps.discardRenderTargetSupport(); 195 int expectedWrites = 1 + (proxyGetsDiscardRef ? kWritesForDiscard : 0); 196 197 sProxy->instantiate(provider); 198 199 // In the deferred case, this checks that the refs transfered to the GrSurface 200 check_refs(reporter, sProxy.get(), 2, 2, 0, expectedWrites); 201 202 sProxy->unref(); 203 check_refs(reporter, sProxy.get(), 1, 1, 0, expectedWrites); 204 205 GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(sProxy.get()); 206 check_refs(reporter, sProxy.get(), 1, 1, 1, expectedWrites); 207 } 208 } 209} 210#endif 211 212#endif 213