blob: c0dcbf96477b461ec4067982ea20da04c5a6c359 [file] [log] [blame]
Chris Dalton706a6ff2017-11-29 22:01:06 -07001/*
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
8#include "Test.h"
9
Chris Dalton706a6ff2017-11-29 22:01:06 -070010#include "GrClip.h"
11#include "GrContextPriv.h"
Robert Phillips7c525e62018-06-12 10:11:12 -040012#include "GrMemoryPool.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070013#include "GrOnFlushResourceProvider.h"
Robert Phillips7c525e62018-06-12 10:11:12 -040014#include "GrProxyProvider.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070015#include "GrRenderTargetContext.h"
16#include "GrRenderTargetContextPriv.h"
17#include "GrSurfaceProxy.h"
Greg Daniel94a6ce82018-01-16 16:14:41 -050018#include "GrSurfaceProxyPriv.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070019#include "GrTexture.h"
20#include "GrTextureProxy.h"
21#include "GrTextureProxyPriv.h"
22#include "SkMakeUnique.h"
Mike Reed274218e2018-01-08 15:05:02 -050023#include "SkRectPriv.h"
Greg Daniel4684f822018-03-08 15:27:36 -050024#include "mock/GrMockGpu.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070025#include "mock/GrMockTypes.h"
26
27// This test verifies that lazy proxy callbacks get invoked during flush, after onFlush callbacks,
28// but before Ops are executed. It also ensures that lazy proxy callbacks are invoked both for
29// regular Ops and for clips.
30class LazyProxyTest final : public GrOnFlushCallbackObject {
31public:
32 LazyProxyTest(skiatest::Reporter* reporter)
33 : fReporter(reporter)
34 , fHasOpTexture(false)
35 , fHasClipTexture(false) {
36 }
37
38 ~LazyProxyTest() override {
39 REPORTER_ASSERT(fReporter, fHasOpTexture);
40 REPORTER_ASSERT(fReporter, fHasClipTexture);
41 }
42
43 void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int,
44 SkTArray<sk_sp<GrRenderTargetContext>>*) override {
45 REPORTER_ASSERT(fReporter, !fHasOpTexture);
46 REPORTER_ASSERT(fReporter, !fHasClipTexture);
47 }
48
49 void postFlush(GrDeferredUploadToken, const uint32_t* opListIDs, int numOpListIDs) override {
50 REPORTER_ASSERT(fReporter, fHasOpTexture);
51 REPORTER_ASSERT(fReporter, fHasClipTexture);
52 }
53
54 class Op final : public GrDrawOp {
55 public:
56 DEFINE_OP_CLASS_ID
57
Robert Phillips88a32ef2018-06-07 11:05:56 -040058 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
59 GrProxyProvider* proxyProvider,
60 LazyProxyTest* test,
61 bool nullTexture) {
62 return std::unique_ptr<GrDrawOp>(new Op(proxyProvider, test, nullTexture));
63 }
64
65 void visitProxies(const VisitProxyFunc& func) const override {
66 func(fProxy.get());
67 }
68
69 void onExecute(GrOpFlushState*) override {
70 REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture);
71 REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture);
72 }
73
74 private:
Robert Phillips7c525e62018-06-12 10:11:12 -040075 friend class GrOpMemoryPool; // for ctor
76
Robert Phillips777707b2018-01-17 11:40:14 -050077 Op(GrProxyProvider* proxyProvider, LazyProxyTest* test, bool nullTexture)
78 : GrDrawOp(ClassID()), fTest(test) {
79 fProxy = proxyProvider->createFullyLazyProxy([this, nullTexture](
Robert Phillipsce5209a2018-02-13 11:13:51 -050080 GrResourceProvider* rp) {
Greg Daniel0a375db2018-02-01 12:21:39 -050081 if (!rp) {
82 return sk_sp<GrTexture>();
83 }
Chris Dalton706a6ff2017-11-29 22:01:06 -070084 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
85 fTest->fHasOpTexture = true;
Chris Dalton706a6ff2017-11-29 22:01:06 -070086 if (nullTexture) {
87 return sk_sp<GrTexture>();
88 } else {
89 GrSurfaceDesc desc;
90 desc.fWidth = 1234;
91 desc.fHeight = 567;
Chris Dalton706a6ff2017-11-29 22:01:06 -070092 desc.fConfig = kRGB_565_GrPixelConfig;
93 sk_sp<GrTexture> texture = rp->createTexture(desc, SkBudgeted::kYes);
94 REPORTER_ASSERT(fTest->fReporter, texture);
95 return texture;
96 }
Robert Phillipsce5209a2018-02-13 11:13:51 -050097 }, GrProxyProvider::Renderable::kNo, kTopLeft_GrSurfaceOrigin, kRGB_565_GrPixelConfig);
Mike Reed274218e2018-01-08 15:05:02 -050098 this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo, GrOp::IsZeroArea::kNo);
Chris Dalton706a6ff2017-11-29 22:01:06 -070099 }
100
Chris Dalton706a6ff2017-11-29 22:01:06 -0700101 const char* name() const override { return "LazyProxyTest::Op"; }
102 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
103 RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*,
104 GrPixelConfigIsClamped) override {
105 return RequiresDstTexture::kNo;
106 }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700107 bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override { return false; }
108 void onPrepare(GrOpFlushState*) override {}
109
110 LazyProxyTest* const fTest;
111 sk_sp<GrTextureProxy> fProxy;
112 };
113
114 class ClipFP : public GrFragmentProcessor {
115 public:
Robert Phillips777707b2018-01-17 11:40:14 -0500116 ClipFP(GrProxyProvider* proxyProvider, LazyProxyTest* test, GrTextureProxy* atlas)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700117 : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
Robert Phillips777707b2018-01-17 11:40:14 -0500118 , fProxyProvider(proxyProvider)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700119 , fTest(test)
120 , fAtlas(atlas) {
Robert Phillipsce5209a2018-02-13 11:13:51 -0500121 fLazyProxy = proxyProvider->createFullyLazyProxy(
122 [this](GrResourceProvider* rp) {
123 if (!rp) {
124 return sk_sp<GrTexture>();
125 }
126 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
127 fTest->fHasClipTexture = true;
128 fAtlas->instantiate(rp);
129 return sk_ref_sp(fAtlas->priv().peekTexture());
130 },
131 GrProxyProvider::Renderable::kYes,
132 kBottomLeft_GrSurfaceOrigin,
133 kAlpha_half_GrPixelConfig);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700134 fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
135 GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag);
136 this->addTextureSampler(&fAccess);
137 }
138
139 private:
140 const char* name() const override { return "LazyProxyTest::ClipFP"; }
141 std::unique_ptr<GrFragmentProcessor> clone() const override {
Robert Phillips777707b2018-01-17 11:40:14 -0500142 return skstd::make_unique<ClipFP>(fProxyProvider, fTest, fAtlas);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700143 }
144 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
145 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
146 bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
147
Robert Phillips777707b2018-01-17 11:40:14 -0500148 GrProxyProvider* const fProxyProvider;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700149 LazyProxyTest* const fTest;
150 GrTextureProxy* const fAtlas;
151 sk_sp<GrTextureProxy> fLazyProxy;
152 TextureSampler fAccess;
153 };
154
155
156 class Clip : public GrClip {
157 public:
158 Clip(LazyProxyTest* test, GrTextureProxy* atlas)
159 : fTest(test)
160 , fAtlas(atlas) {}
161
162 private:
Robert Phillips777707b2018-01-17 11:40:14 -0500163 bool apply(GrContext* context, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
Chris Dalton706a6ff2017-11-29 22:01:06 -0700164 SkRect* bounds) const override {
Robert Phillips777707b2018-01-17 11:40:14 -0500165 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
166 out->addCoverageFP(skstd::make_unique<ClipFP>(proxyProvider, fTest, fAtlas));
Chris Dalton706a6ff2017-11-29 22:01:06 -0700167 return true;
168 }
169 bool quickContains(const SkRect&) const final { return false; }
170 bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; }
171 void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
172 rect->set(0, 0, width, height);
173 if (iior) {
174 *iior = false;
175 }
176 }
177
178 LazyProxyTest* const fTest;
179 GrTextureProxy* fAtlas;
180 };
181
182private:
183 skiatest::Reporter* fReporter;
184 bool fHasOpTexture;
185 bool fHasClipTexture;
186};
187
188DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
189 GrMockOptions mockOptions;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500190 mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderability =
191 GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700192 mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fTexturable = true;
193 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips777707b2018-01-17 11:40:14 -0500194 GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700195 for (bool nullTexture : {false, true}) {
196 LazyProxyTest test(reporter);
197 ctx->contextPriv().addOnFlushCallbackObject(&test);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500198 sk_sp<GrRenderTargetContext> rtc = ctx->contextPriv().makeDeferredRenderTargetContext(
199 SkBackingFit::kExact, 100, 100,
200 kRGBA_8888_GrPixelConfig, nullptr);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700201 REPORTER_ASSERT(reporter, rtc);
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500202 sk_sp<GrRenderTargetContext> mockAtlas = ctx->contextPriv().makeDeferredRenderTargetContext(
203 SkBackingFit::kExact, 10, 10,
Chris Dalton706a6ff2017-11-29 22:01:06 -0700204 kAlpha_half_GrPixelConfig, nullptr);
205 REPORTER_ASSERT(reporter, mockAtlas);
206 rtc->priv().testingOnly_addDrawOp(LazyProxyTest::Clip(&test, mockAtlas->asTextureProxy()),
Robert Phillips88a32ef2018-06-07 11:05:56 -0400207 LazyProxyTest::Op::Make(ctx.get(), proxyProvider, &test, nullTexture));
Chris Dalton706a6ff2017-11-29 22:01:06 -0700208 ctx->contextPriv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test);
209 }
210}
211
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500212static const int kSize = 16;
213
Greg Daniel94a6ce82018-01-16 16:14:41 -0500214DEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) {
215 GrMockOptions mockOptions;
216 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips777707b2018-01-17 11:40:14 -0500217 auto proxyProvider = ctx->contextPriv().proxyProvider();
Greg Daniel94a6ce82018-01-16 16:14:41 -0500218
219 GrSurfaceDesc desc;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500220 desc.fWidth = kSize;
221 desc.fHeight = kSize;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500222 desc.fConfig = kRGBA_8888_GrPixelConfig;
223
Greg Daniel457469c2018-02-08 15:05:44 -0500224 using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500225 for (bool doInstantiate : {true, false}) {
Greg Daniel457469c2018-02-08 15:05:44 -0500226 for (auto lazyType : {LazyInstantiationType::kSingleUse,
Greg Daniela8d92112018-03-09 12:05:04 -0500227 LazyInstantiationType::kMultipleUse,
228 LazyInstantiationType::kUninstantiate}) {
Greg Daniel457469c2018-02-08 15:05:44 -0500229 int testCount = 0;
230 int* testCountPtr = &testCount;
231 sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
Robert Phillipsce5209a2018-02-13 11:13:51 -0500232 [testCountPtr](GrResourceProvider* resourceProvider) {
Greg Daniel457469c2018-02-08 15:05:44 -0500233 if (!resourceProvider) {
234 *testCountPtr = -1;
235 return sk_sp<GrTexture>();
236 }
237 *testCountPtr = 1;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500238 return sk_sp<GrTexture>();
Brian Salomon2a4f9832018-03-03 22:43:43 -0500239 },
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400240 desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
Greg Daniela8d92112018-03-09 12:05:04 -0500241 SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
Greg Daniel94a6ce82018-01-16 16:14:41 -0500242
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400243 REPORTER_ASSERT(reporter, proxy.get());
Greg Daniel457469c2018-02-08 15:05:44 -0500244 REPORTER_ASSERT(reporter, 0 == testCount);
245
246 if (doInstantiate) {
247 proxy->priv().doLazyInstantiation(ctx->contextPriv().resourceProvider());
248 if (LazyInstantiationType::kSingleUse == proxy->priv().lazyInstantiationType()) {
249 // In SingleUse we will call the cleanup and delete the callback in the
250 // doLazyInstantiationCall.
251 REPORTER_ASSERT(reporter, -1 == testCount);
252 } else {
253 REPORTER_ASSERT(reporter, 1 == testCount);
254 }
255 proxy.reset();
256 REPORTER_ASSERT(reporter, -1 == testCount);
257 } else {
258 proxy.reset();
259 REPORTER_ASSERT(reporter, -1 == testCount);
260 }
Greg Daniel94a6ce82018-01-16 16:14:41 -0500261 }
262 }
263}
264
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500265class LazyFailedInstantiationTestOp : public GrDrawOp {
266public:
267 DEFINE_OP_CLASS_ID
268
Robert Phillips88a32ef2018-06-07 11:05:56 -0400269 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
270 GrProxyProvider* proxyProvider,
271 int* testExecuteValue,
272 bool shouldFailInstantiation) {
273 return std::unique_ptr<GrDrawOp>(new LazyFailedInstantiationTestOp(
274 proxyProvider, testExecuteValue, shouldFailInstantiation));
275 }
276
277 void visitProxies(const VisitProxyFunc& func) const override {
278 func(fLazyProxy.get());
279 }
280
281private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400282 friend class GrOpMemoryPool; // for ctor
283
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500284 LazyFailedInstantiationTestOp(GrProxyProvider* proxyProvider, int* testExecuteValue,
285 bool shouldFailInstantiation)
286 : INHERITED(ClassID())
287 , fTestExecuteValue(testExecuteValue) {
288 GrSurfaceDesc desc;
289 desc.fWidth = kSize;
290 desc.fHeight = kSize;
291 desc.fConfig = kRGBA_8888_GrPixelConfig;
292
293 fLazyProxy = proxyProvider->createLazyProxy(
Brian Salomon2a4f9832018-03-03 22:43:43 -0500294 [testExecuteValue, shouldFailInstantiation, desc](GrResourceProvider* rp) {
Greg Daniel0a375db2018-02-01 12:21:39 -0500295 if (!rp) {
296 return sk_sp<GrTexture>();
297 }
298 if (shouldFailInstantiation) {
299 *testExecuteValue = 1;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500300 return sk_sp<GrTexture>();
301 }
302 return rp->createTexture(desc, SkBudgeted::kNo);
Brian Salomon2a4f9832018-03-03 22:43:43 -0500303 },
304 desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, SkBackingFit::kExact,
305 SkBudgeted::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500306
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400307 SkASSERT(fLazyProxy.get());
308
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500309 this->setBounds(SkRect::MakeIWH(kSize, kSize),
310 HasAABloat::kNo, IsZeroArea::kNo);
311 }
312
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500313 const char* name() const override { return "LazyFailedInstantiationTestOp"; }
314 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
315 RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*,
316 GrPixelConfigIsClamped) override {
317 return RequiresDstTexture::kNo;
318 }
319 bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override { return false; }
320 void onPrepare(GrOpFlushState*) override {}
321 void onExecute(GrOpFlushState* state) override {
322 *fTestExecuteValue = 2;
323 }
324
325 int* fTestExecuteValue;
326 sk_sp<GrSurfaceProxy> fLazyProxy;
327
328 typedef GrDrawOp INHERITED;
329};
330
331// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
332// associated with.
333DEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) {
334 GrMockOptions mockOptions;
335 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips4150eea2018-02-07 17:08:21 -0500336 GrResourceProvider* resourceProvider = ctx->contextPriv().resourceProvider();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500337 GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
338 for (bool failInstantiation : {false, true}) {
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500339 sk_sp<GrRenderTargetContext> rtc = ctx->contextPriv().makeDeferredRenderTargetContext(
340 SkBackingFit::kExact, 100, 100,
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500341 kRGBA_8888_GrPixelConfig, nullptr);
342 REPORTER_ASSERT(reporter, rtc);
343
344 rtc->clear(nullptr, 0xbaaaaaad, GrRenderTargetContext::CanClearFullscreen::kYes);
345
346 int executeTestValue = 0;
Robert Phillips88a32ef2018-06-07 11:05:56 -0400347 rtc->priv().testingOnly_addDrawOp(LazyFailedInstantiationTestOp::Make(
348 ctx.get(), proxyProvider, &executeTestValue, failInstantiation));
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500349 ctx->flush();
350
351 if (failInstantiation) {
Robert Phillips4150eea2018-02-07 17:08:21 -0500352 if (resourceProvider->explicitlyAllocateGPUResources()) {
353 REPORTER_ASSERT(reporter, 1 == executeTestValue);
354 } else {
355 // When we disable explicit gpu resource allocation we don't throw away ops that
356 // have uninstantiated proxies.
357 REPORTER_ASSERT(reporter, 2 == executeTestValue);
358 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500359 } else {
360 REPORTER_ASSERT(reporter, 2 == executeTestValue);
361 }
362 }
Greg Daniel4684f822018-03-08 15:27:36 -0500363}
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500364
Greg Daniel4684f822018-03-08 15:27:36 -0500365class LazyUninstantiateTestOp : public GrDrawOp {
366public:
367 DEFINE_OP_CLASS_ID
368
Robert Phillips88a32ef2018-06-07 11:05:56 -0400369 static std::unique_ptr<GrDrawOp> Make(GrContext* context, sk_sp<GrTextureProxy> proxy) {
370 return std::unique_ptr<GrDrawOp>(new LazyUninstantiateTestOp(std::move(proxy)));
Greg Daniel4684f822018-03-08 15:27:36 -0500371 }
372
373 void visitProxies(const VisitProxyFunc& func) const override {
374 func(fLazyProxy.get());
375 }
376
377private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400378 friend class GrOpMemoryPool; // for ctor
379
Robert Phillips88a32ef2018-06-07 11:05:56 -0400380 LazyUninstantiateTestOp(sk_sp<GrTextureProxy> proxy)
381 : INHERITED(ClassID())
382 , fLazyProxy(std::move(proxy)) {
383 this->setBounds(SkRect::MakeIWH(kSize, kSize), HasAABloat::kNo, IsZeroArea::kNo);
384 }
385
Greg Daniel4684f822018-03-08 15:27:36 -0500386 const char* name() const override { return "LazyUninstantiateTestOp"; }
387 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
388 RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*,
389 GrPixelConfigIsClamped) override {
390 return RequiresDstTexture::kNo;
391 }
392 bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override { return false; }
393 void onPrepare(GrOpFlushState*) override {}
394 void onExecute(GrOpFlushState* state) override {}
395
396 sk_sp<GrSurfaceProxy> fLazyProxy;
397
398 typedef GrDrawOp INHERITED;
399};
400
401static void UninstantiateReleaseProc(void* releaseValue) {
402 (*static_cast<int*>(releaseValue))++;
403}
404
405// Test that lazy proxies with the Uninstantiate LazyCallbackType are uninstantiated and released as
406// expected.
407DEF_GPUTEST(LazyProxyUninstantiateTest, reporter, /* options */) {
408 GrMockOptions mockOptions;
409 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
410 GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
411 GrGpu* gpu = ctx->contextPriv().getGpu();
412
413 using LazyType = GrSurfaceProxy::LazyInstantiationType;
414 for (auto lazyType : {LazyType::kSingleUse, LazyType::kMultipleUse, LazyType::kUninstantiate}) {
415 sk_sp<GrRenderTargetContext> rtc = ctx->contextPriv().makeDeferredRenderTargetContext(
416 SkBackingFit::kExact, 100, 100,
417 kRGBA_8888_GrPixelConfig, nullptr);
418 REPORTER_ASSERT(reporter, rtc);
419
420 rtc->clear(nullptr, 0xbaaaaaad, GrRenderTargetContext::CanClearFullscreen::kYes);
421
422 int instantiateTestValue = 0;
423 int releaseTestValue = 0;
424 int* instantiatePtr = &instantiateTestValue;
425 int* releasePtr = &releaseTestValue;
426 GrSurfaceDesc desc;
427 desc.fWidth = kSize;
428 desc.fHeight = kSize;
429 desc.fConfig = kRGBA_8888_GrPixelConfig;
430
431 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
432 nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, GrMipMapped::kNo);
433
434 sk_sp<GrTextureProxy> lazyProxy = proxyProvider->createLazyProxy(
435 [instantiatePtr, releasePtr, backendTex](GrResourceProvider* rp) {
436 if (!rp) {
437 return sk_sp<GrTexture>();
438 }
439
440 sk_sp<GrTexture> texture = rp->wrapBackendTexture(backendTex);
441 if (!texture) {
442 return sk_sp<GrTexture>();
443 }
444 (*instantiatePtr)++;
445 texture->setRelease(UninstantiateReleaseProc, releasePtr);
446 return texture;
447 },
Robert Phillipsfe0253f2018-03-16 16:47:25 -0400448 desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrInternalSurfaceFlags::kNone,
Greg Daniela8d92112018-03-09 12:05:04 -0500449 SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
Greg Daniel4684f822018-03-08 15:27:36 -0500450
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400451 REPORTER_ASSERT(reporter, lazyProxy.get());
452
Robert Phillips88a32ef2018-06-07 11:05:56 -0400453 rtc->priv().testingOnly_addDrawOp(LazyUninstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500454
455 ctx->flush();
456
457 REPORTER_ASSERT(reporter, 1 == instantiateTestValue);
458 if (LazyType::kUninstantiate == lazyType) {
459 REPORTER_ASSERT(reporter, 1 == releaseTestValue);
460 } else {
461 REPORTER_ASSERT(reporter, 0 == releaseTestValue);
462 }
463
464 // This should cause the uninstantiate proxies to be instantiated again but have no effect
465 // on the others
Robert Phillips88a32ef2018-06-07 11:05:56 -0400466 rtc->priv().testingOnly_addDrawOp(LazyUninstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500467 // Add a second op to make sure we only instantiate once.
Robert Phillips88a32ef2018-06-07 11:05:56 -0400468 rtc->priv().testingOnly_addDrawOp(LazyUninstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500469 ctx->flush();
470
471 if (LazyType::kUninstantiate == lazyType) {
472 REPORTER_ASSERT(reporter, 2 == instantiateTestValue);
473 REPORTER_ASSERT(reporter, 2 == releaseTestValue);
474 } else {
475 REPORTER_ASSERT(reporter, 1 == instantiateTestValue);
476 REPORTER_ASSERT(reporter, 0 == releaseTestValue);
477 }
478
479 lazyProxy.reset();
480 if (LazyType::kUninstantiate == lazyType) {
481 REPORTER_ASSERT(reporter, 2 == releaseTestValue);
482 } else {
483 REPORTER_ASSERT(reporter, 1 == releaseTestValue);
484 }
485
Brian Salomon26102cb2018-03-09 09:33:19 -0500486 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel4684f822018-03-08 15:27:36 -0500487 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500488}