LazyProxyTest.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. * Copyright 2017 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. #include "tests/Test.h"
  8. #include "include/gpu/GrTexture.h"
  9. #include "include/gpu/mock/GrMockTypes.h"
  10. #include "src/core/SkExchange.h"
  11. #include "src/core/SkMakeUnique.h"
  12. #include "src/core/SkRectPriv.h"
  13. #include "src/gpu/GrClip.h"
  14. #include "src/gpu/GrContextPriv.h"
  15. #include "src/gpu/GrMemoryPool.h"
  16. #include "src/gpu/GrOnFlushResourceProvider.h"
  17. #include "src/gpu/GrProxyProvider.h"
  18. #include "src/gpu/GrRecordingContextPriv.h"
  19. #include "src/gpu/GrRenderTargetContext.h"
  20. #include "src/gpu/GrRenderTargetContextPriv.h"
  21. #include "src/gpu/GrSurfaceProxy.h"
  22. #include "src/gpu/GrSurfaceProxyPriv.h"
  23. #include "src/gpu/GrTextureProxy.h"
  24. #include "src/gpu/GrTextureProxyPriv.h"
  25. #include "src/gpu/mock/GrMockGpu.h"
  26. // This test verifies that lazy proxy callbacks get invoked during flush, after onFlush callbacks,
  27. // but before Ops are executed. It also ensures that lazy proxy callbacks are invoked both for
  28. // regular Ops and for clips.
  29. class LazyProxyTest final : public GrOnFlushCallbackObject {
  30. public:
  31. LazyProxyTest(skiatest::Reporter* reporter)
  32. : fReporter(reporter)
  33. , fHasOpTexture(false)
  34. , fHasClipTexture(false) {
  35. }
  36. ~LazyProxyTest() override {
  37. REPORTER_ASSERT(fReporter, fHasOpTexture);
  38. REPORTER_ASSERT(fReporter, fHasClipTexture);
  39. }
  40. void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int,
  41. SkTArray<sk_sp<GrRenderTargetContext>>*) override {
  42. REPORTER_ASSERT(fReporter, !fHasOpTexture);
  43. REPORTER_ASSERT(fReporter, !fHasClipTexture);
  44. }
  45. void postFlush(GrDeferredUploadToken, const uint32_t* opListIDs, int numOpListIDs) override {
  46. REPORTER_ASSERT(fReporter, fHasOpTexture);
  47. REPORTER_ASSERT(fReporter, fHasClipTexture);
  48. }
  49. class Op final : public GrDrawOp {
  50. public:
  51. DEFINE_OP_CLASS_ID
  52. static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
  53. GrProxyProvider* proxyProvider,
  54. LazyProxyTest* test,
  55. bool nullTexture) {
  56. GrOpMemoryPool* pool = context->priv().opMemoryPool();
  57. return pool->allocate<Op>(context, proxyProvider, test, nullTexture);
  58. }
  59. void visitProxies(const VisitProxyFunc& func) const override {
  60. func(fProxy.get(), GrMipMapped::kNo);
  61. }
  62. void onExecute(GrOpFlushState*, const SkRect& chainBounds) override {
  63. REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture);
  64. REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture);
  65. }
  66. private:
  67. friend class GrOpMemoryPool; // for ctor
  68. Op(GrRecordingContext* ctx, GrProxyProvider* proxyProvider,
  69. LazyProxyTest* test, bool nullTexture)
  70. : GrDrawOp(ClassID()), fTest(test) {
  71. const GrBackendFormat format =
  72. ctx->priv().caps()->getBackendFormatFromColorType(GrColorType::kBGR_565);
  73. fProxy = GrProxyProvider::MakeFullyLazyProxy(
  74. [this, nullTexture](
  75. GrResourceProvider* rp) -> GrSurfaceProxy::LazyInstantiationResult {
  76. REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
  77. fTest->fHasOpTexture = true;
  78. if (nullTexture) {
  79. return {};
  80. } else {
  81. GrSurfaceDesc desc;
  82. desc.fWidth = 1234;
  83. desc.fHeight = 567;
  84. desc.fConfig = kRGB_565_GrPixelConfig;
  85. sk_sp<GrTexture> texture = rp->createTexture(
  86. desc, GrRenderable::kNo, 1, SkBudgeted::kYes, GrProtected::kNo,
  87. GrResourceProvider::Flags::kNoPendingIO);
  88. REPORTER_ASSERT(fTest->fReporter, texture);
  89. return std::move(texture);
  90. }
  91. },
  92. format, GrRenderable::kNo, 1, GrProtected::kNo, kTopLeft_GrSurfaceOrigin,
  93. kRGB_565_GrPixelConfig, *proxyProvider->caps());
  94. this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo,
  95. GrOp::IsZeroArea::kNo);
  96. }
  97. const char* name() const override { return "LazyProxyTest::Op"; }
  98. FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
  99. GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip* clip,
  100. bool hasMixedSampledCoverage, GrClampType) override {
  101. return GrProcessorSet::EmptySetAnalysis();
  102. }
  103. void onPrepare(GrOpFlushState*) override {}
  104. LazyProxyTest* const fTest;
  105. sk_sp<GrTextureProxy> fProxy;
  106. };
  107. class ClipFP : public GrFragmentProcessor {
  108. public:
  109. ClipFP(GrRecordingContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test,
  110. GrTextureProxy* atlas)
  111. : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
  112. , fContext(ctx)
  113. , fProxyProvider(proxyProvider)
  114. , fTest(test)
  115. , fAtlas(atlas) {
  116. const GrBackendFormat format =
  117. ctx->priv().caps()->getBackendFormatFromColorType(GrColorType::kAlpha_F16);
  118. fLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
  119. [this](GrResourceProvider* rp) -> GrSurfaceProxy::LazyInstantiationResult {
  120. REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
  121. fTest->fHasClipTexture = true;
  122. fAtlas->instantiate(rp);
  123. return sk_ref_sp(fAtlas->peekTexture());
  124. },
  125. format, GrRenderable::kYes, 1, GrProtected::kNo, kBottomLeft_GrSurfaceOrigin,
  126. kAlpha_half_GrPixelConfig, *proxyProvider->caps());
  127. fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
  128. GrSamplerState::WrapMode::kClamp);
  129. this->setTextureSamplerCnt(1);
  130. }
  131. private:
  132. const char* name() const override { return "LazyProxyTest::ClipFP"; }
  133. std::unique_ptr<GrFragmentProcessor> clone() const override {
  134. return skstd::make_unique<ClipFP>(fContext, fProxyProvider, fTest, fAtlas);
  135. }
  136. GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
  137. void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
  138. bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
  139. const TextureSampler& onTextureSampler(int) const override { return fAccess; }
  140. GrRecordingContext* const fContext;
  141. GrProxyProvider* const fProxyProvider;
  142. LazyProxyTest* const fTest;
  143. GrTextureProxy* const fAtlas;
  144. sk_sp<GrTextureProxy> fLazyProxy;
  145. TextureSampler fAccess;
  146. };
  147. class Clip : public GrClip {
  148. public:
  149. Clip(LazyProxyTest* test, GrTextureProxy* atlas)
  150. : fTest(test)
  151. , fAtlas(atlas) {}
  152. private:
  153. bool apply(GrRecordingContext* context, GrRenderTargetContext*, bool useHWAA,
  154. bool hasUserStencilSettings, GrAppliedClip* out, SkRect* bounds) const override {
  155. GrProxyProvider* proxyProvider = context->priv().proxyProvider();
  156. out->addCoverageFP(skstd::make_unique<ClipFP>(context, proxyProvider, fTest, fAtlas));
  157. return true;
  158. }
  159. bool quickContains(const SkRect&) const final { return false; }
  160. bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; }
  161. void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
  162. rect->set(0, 0, width, height);
  163. if (iior) {
  164. *iior = false;
  165. }
  166. }
  167. LazyProxyTest* const fTest;
  168. GrTextureProxy* fAtlas;
  169. };
  170. private:
  171. skiatest::Reporter* fReporter;
  172. bool fHasOpTexture;
  173. bool fHasClipTexture;
  174. };
  175. DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
  176. GrMockOptions mockOptions;
  177. mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fRenderability =
  178. GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
  179. mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fTexturable = true;
  180. sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
  181. GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
  182. for (bool nullTexture : {false, true}) {
  183. LazyProxyTest test(reporter);
  184. ctx->priv().addOnFlushCallbackObject(&test);
  185. sk_sp<GrRenderTargetContext> rtc = ctx->priv().makeDeferredRenderTargetContext(
  186. SkBackingFit::kExact, 100, 100, GrColorType::kRGBA_8888, nullptr);
  187. REPORTER_ASSERT(reporter, rtc);
  188. sk_sp<GrRenderTargetContext> mockAtlas = ctx->priv().makeDeferredRenderTargetContext(
  189. SkBackingFit::kExact, 10, 10, GrColorType::kAlpha_F16, nullptr);
  190. REPORTER_ASSERT(reporter, mockAtlas);
  191. rtc->priv().testingOnly_addDrawOp(LazyProxyTest::Clip(&test, mockAtlas->asTextureProxy()),
  192. LazyProxyTest::Op::Make(ctx.get(), proxyProvider, &test, nullTexture));
  193. ctx->priv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test);
  194. }
  195. }
  196. static const int kSize = 16;
  197. DEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) {
  198. GrMockOptions mockOptions;
  199. sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
  200. auto proxyProvider = ctx->priv().proxyProvider();
  201. GrSurfaceDesc desc;
  202. desc.fWidth = kSize;
  203. desc.fHeight = kSize;
  204. desc.fConfig = kRGBA_8888_GrPixelConfig;
  205. GrBackendFormat format =
  206. ctx->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
  207. using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
  208. using LazyInstantiationResult = GrSurfaceProxy::LazyInstantiationResult;
  209. for (bool doInstantiate : {true, false}) {
  210. for (auto lazyType : {LazyInstantiationType::kSingleUse,
  211. LazyInstantiationType::kMultipleUse,
  212. LazyInstantiationType::kDeinstantiate}) {
  213. int testCount = 0;
  214. // Sets an integer to 1 when the callback is called and -1 when it is deleted.
  215. class TestCallback {
  216. public:
  217. TestCallback(int* value) : fValue(value) {}
  218. TestCallback(const TestCallback& that) { SkASSERT(0); }
  219. TestCallback(TestCallback&& that) : fValue(that.fValue) { that.fValue = nullptr; }
  220. ~TestCallback() { fValue ? (void)(*fValue = -1) : void(); }
  221. TestCallback& operator=(TestCallback&& that) {
  222. fValue = skstd::exchange(that.fValue, nullptr);
  223. return *this;
  224. }
  225. TestCallback& operator=(const TestCallback& that) = delete;
  226. LazyInstantiationResult operator()(GrResourceProvider* resourceProvider) const {
  227. *fValue = 1;
  228. return {};
  229. }
  230. private:
  231. int* fValue = nullptr;
  232. };
  233. sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
  234. TestCallback(&testCount), format, desc, GrRenderable::kNo, 1,
  235. kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
  236. SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, lazyType);
  237. REPORTER_ASSERT(reporter, proxy.get());
  238. REPORTER_ASSERT(reporter, 0 == testCount);
  239. if (doInstantiate) {
  240. proxy->priv().doLazyInstantiation(ctx->priv().resourceProvider());
  241. if (LazyInstantiationType::kSingleUse == proxy->priv().lazyInstantiationType()) {
  242. // In SingleUse we will call the cleanup and delete the callback in the
  243. // doLazyInstantiationCall.
  244. REPORTER_ASSERT(reporter, -1 == testCount);
  245. } else {
  246. REPORTER_ASSERT(reporter, 1 == testCount);
  247. }
  248. proxy.reset();
  249. REPORTER_ASSERT(reporter, -1 == testCount);
  250. } else {
  251. proxy.reset();
  252. REPORTER_ASSERT(reporter, -1 == testCount);
  253. }
  254. }
  255. }
  256. }
  257. class LazyFailedInstantiationTestOp : public GrDrawOp {
  258. public:
  259. DEFINE_OP_CLASS_ID
  260. static std::unique_ptr<GrDrawOp> Make(GrContext* context,
  261. GrProxyProvider* proxyProvider,
  262. int* testExecuteValue,
  263. bool shouldFailInstantiation) {
  264. GrOpMemoryPool* pool = context->priv().opMemoryPool();
  265. return pool->allocate<LazyFailedInstantiationTestOp>(context, proxyProvider,
  266. testExecuteValue,
  267. shouldFailInstantiation);
  268. }
  269. void visitProxies(const VisitProxyFunc& func) const override {
  270. func(fLazyProxy.get(), GrMipMapped::kNo);
  271. }
  272. private:
  273. friend class GrOpMemoryPool; // for ctor
  274. LazyFailedInstantiationTestOp(GrContext* ctx, GrProxyProvider* proxyProvider,
  275. int* testExecuteValue, bool shouldFailInstantiation)
  276. : INHERITED(ClassID())
  277. , fTestExecuteValue(testExecuteValue) {
  278. GrSurfaceDesc desc;
  279. desc.fWidth = kSize;
  280. desc.fHeight = kSize;
  281. desc.fConfig = kRGBA_8888_GrPixelConfig;
  282. GrBackendFormat format =
  283. ctx->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
  284. fLazyProxy = proxyProvider->createLazyProxy(
  285. [testExecuteValue, shouldFailInstantiation,
  286. desc](GrResourceProvider* rp) -> GrSurfaceProxy::LazyInstantiationResult {
  287. if (shouldFailInstantiation) {
  288. *testExecuteValue = 1;
  289. return {};
  290. }
  291. return {rp->createTexture(desc, GrRenderable::kNo, 1, SkBudgeted::kNo,
  292. GrProtected::kNo,
  293. GrResourceProvider::Flags::kNoPendingIO),
  294. GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
  295. },
  296. format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
  297. SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo);
  298. SkASSERT(fLazyProxy.get());
  299. this->setBounds(SkRect::MakeIWH(kSize, kSize),
  300. HasAABloat::kNo, IsZeroArea::kNo);
  301. }
  302. const char* name() const override { return "LazyFailedInstantiationTestOp"; }
  303. FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
  304. GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
  305. bool hasMixedSampledCoverage, GrClampType) override {
  306. return GrProcessorSet::EmptySetAnalysis();
  307. }
  308. void onPrepare(GrOpFlushState*) override {}
  309. void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
  310. *fTestExecuteValue = 2;
  311. }
  312. int* fTestExecuteValue;
  313. sk_sp<GrSurfaceProxy> fLazyProxy;
  314. typedef GrDrawOp INHERITED;
  315. };
  316. // Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
  317. // associated with.
  318. DEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) {
  319. GrMockOptions mockOptions;
  320. sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
  321. GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
  322. for (bool failInstantiation : {false, true}) {
  323. sk_sp<GrRenderTargetContext> rtc = ctx->priv().makeDeferredRenderTargetContext(
  324. SkBackingFit::kExact, 100, 100, GrColorType::kRGBA_8888, nullptr);
  325. REPORTER_ASSERT(reporter, rtc);
  326. rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xbaaaaaad),
  327. GrRenderTargetContext::CanClearFullscreen::kYes);
  328. int executeTestValue = 0;
  329. rtc->priv().testingOnly_addDrawOp(LazyFailedInstantiationTestOp::Make(
  330. ctx.get(), proxyProvider, &executeTestValue, failInstantiation));
  331. ctx->flush();
  332. if (failInstantiation) {
  333. REPORTER_ASSERT(reporter, 1 == executeTestValue);
  334. } else {
  335. REPORTER_ASSERT(reporter, 2 == executeTestValue);
  336. }
  337. }
  338. }
  339. class LazyDeinstantiateTestOp : public GrDrawOp {
  340. public:
  341. DEFINE_OP_CLASS_ID
  342. static std::unique_ptr<GrDrawOp> Make(GrContext* context, sk_sp<GrTextureProxy> proxy) {
  343. GrOpMemoryPool* pool = context->priv().opMemoryPool();
  344. return pool->allocate<LazyDeinstantiateTestOp>(std::move(proxy));
  345. }
  346. void visitProxies(const VisitProxyFunc& func) const override {
  347. func(fLazyProxy.get(), GrMipMapped::kNo);
  348. }
  349. private:
  350. friend class GrOpMemoryPool; // for ctor
  351. LazyDeinstantiateTestOp(sk_sp<GrTextureProxy> proxy)
  352. : INHERITED(ClassID()), fLazyProxy(std::move(proxy)) {
  353. this->setBounds(SkRect::MakeIWH(kSize, kSize), HasAABloat::kNo, IsZeroArea::kNo);
  354. }
  355. const char* name() const override { return "LazyDeinstantiateTestOp"; }
  356. FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
  357. GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
  358. bool hasMixedSampledCoverage, GrClampType) override {
  359. return GrProcessorSet::EmptySetAnalysis();
  360. }
  361. void onPrepare(GrOpFlushState*) override {}
  362. void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {}
  363. sk_sp<GrSurfaceProxy> fLazyProxy;
  364. typedef GrDrawOp INHERITED;
  365. };
  366. static void DeinstantiateReleaseProc(void* releaseValue) { (*static_cast<int*>(releaseValue))++; }
  367. // Test that lazy proxies with the Deinstantiate LazyCallbackType are deinstantiated and released as
  368. // expected.
  369. DEF_GPUTEST(LazyProxyDeinstantiateTest, reporter, /* options */) {
  370. GrMockOptions mockOptions;
  371. sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
  372. GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
  373. GrBackendFormat format =
  374. ctx->priv().caps()->getBackendFormatFromColorType(GrColorType::kRGBA_8888);
  375. using LazyType = GrSurfaceProxy::LazyInstantiationType;
  376. for (auto lazyType : {LazyType::kSingleUse, LazyType::kMultipleUse, LazyType::kDeinstantiate}) {
  377. sk_sp<GrRenderTargetContext> rtc = ctx->priv().makeDeferredRenderTargetContext(
  378. SkBackingFit::kExact, 100, 100, GrColorType::kRGBA_8888, nullptr);
  379. REPORTER_ASSERT(reporter, rtc);
  380. rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xbaaaaaad),
  381. GrRenderTargetContext::CanClearFullscreen::kYes);
  382. int instantiateTestValue = 0;
  383. int releaseTestValue = 0;
  384. int* instantiatePtr = &instantiateTestValue;
  385. int* releasePtr = &releaseTestValue;
  386. GrSurfaceDesc desc;
  387. desc.fWidth = kSize;
  388. desc.fHeight = kSize;
  389. desc.fConfig = kRGBA_8888_GrPixelConfig;
  390. GrBackendTexture backendTex = ctx->createBackendTexture(
  391. kSize, kSize, kRGBA_8888_SkColorType, SkColors::kTransparent,
  392. GrMipMapped::kNo, GrRenderable::kNo, GrProtected::kNo);
  393. sk_sp<GrTextureProxy> lazyProxy = proxyProvider->createLazyProxy(
  394. [instantiatePtr, releasePtr,
  395. backendTex](GrResourceProvider* rp) -> GrSurfaceProxy::LazyInstantiationResult {
  396. sk_sp<GrTexture> texture =
  397. rp->wrapBackendTexture(backendTex, GrColorType::kRGBA_8888,
  398. kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
  399. kRead_GrIOType);
  400. if (!texture) {
  401. return {};
  402. }
  403. (*instantiatePtr)++;
  404. texture->setRelease(DeinstantiateReleaseProc, releasePtr);
  405. return std::move(texture);
  406. },
  407. format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
  408. GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo,
  409. GrProtected::kNo, lazyType);
  410. REPORTER_ASSERT(reporter, lazyProxy.get());
  411. rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
  412. ctx->flush();
  413. REPORTER_ASSERT(reporter, 1 == instantiateTestValue);
  414. if (LazyType::kDeinstantiate == lazyType) {
  415. REPORTER_ASSERT(reporter, 1 == releaseTestValue);
  416. } else {
  417. REPORTER_ASSERT(reporter, 0 == releaseTestValue);
  418. }
  419. // This should cause the uninstantiate proxies to be instantiated again but have no effect
  420. // on the others
  421. rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
  422. // Add a second op to make sure we only instantiate once.
  423. rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
  424. ctx->flush();
  425. if (LazyType::kDeinstantiate == lazyType) {
  426. REPORTER_ASSERT(reporter, 2 == instantiateTestValue);
  427. REPORTER_ASSERT(reporter, 2 == releaseTestValue);
  428. } else {
  429. REPORTER_ASSERT(reporter, 1 == instantiateTestValue);
  430. REPORTER_ASSERT(reporter, 0 == releaseTestValue);
  431. }
  432. lazyProxy.reset();
  433. if (LazyType::kDeinstantiate == lazyType) {
  434. REPORTER_ASSERT(reporter, 2 == releaseTestValue);
  435. } else {
  436. REPORTER_ASSERT(reporter, 1 == releaseTestValue);
  437. }
  438. ctx->deleteBackendTexture(backendTex);
  439. }
  440. }