blob: e016e4f673c7818c8f13caa3a8331a4f1174fa90 [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"
Robert Phillipsbe9aff22019-02-15 11:33:22 -050011#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"
Robert Phillips6f0e02f2019-02-13 11:02:28 -050015#include "GrRecordingContextPriv.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070016#include "GrRenderTargetContext.h"
17#include "GrRenderTargetContextPriv.h"
18#include "GrSurfaceProxy.h"
Greg Daniel94a6ce82018-01-16 16:14:41 -050019#include "GrSurfaceProxyPriv.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070020#include "GrTexture.h"
21#include "GrTextureProxy.h"
22#include "GrTextureProxyPriv.h"
Brian Salomon67f01952019-02-14 13:05:25 -050023#include "SkExchange.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070024#include "SkMakeUnique.h"
Mike Reed274218e2018-01-08 15:05:02 -050025#include "SkRectPriv.h"
Greg Daniel4684f822018-03-08 15:27:36 -050026#include "mock/GrMockGpu.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070027#include "mock/GrMockTypes.h"
28
29// This test verifies that lazy proxy callbacks get invoked during flush, after onFlush callbacks,
30// but before Ops are executed. It also ensures that lazy proxy callbacks are invoked both for
31// regular Ops and for clips.
32class LazyProxyTest final : public GrOnFlushCallbackObject {
33public:
34 LazyProxyTest(skiatest::Reporter* reporter)
35 : fReporter(reporter)
36 , fHasOpTexture(false)
37 , fHasClipTexture(false) {
38 }
39
40 ~LazyProxyTest() override {
41 REPORTER_ASSERT(fReporter, fHasOpTexture);
42 REPORTER_ASSERT(fReporter, fHasClipTexture);
43 }
44
45 void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int,
46 SkTArray<sk_sp<GrRenderTargetContext>>*) override {
47 REPORTER_ASSERT(fReporter, !fHasOpTexture);
48 REPORTER_ASSERT(fReporter, !fHasClipTexture);
49 }
50
51 void postFlush(GrDeferredUploadToken, const uint32_t* opListIDs, int numOpListIDs) override {
52 REPORTER_ASSERT(fReporter, fHasOpTexture);
53 REPORTER_ASSERT(fReporter, fHasClipTexture);
54 }
55
56 class Op final : public GrDrawOp {
57 public:
58 DEFINE_OP_CLASS_ID
59
Robert Phillips6f0e02f2019-02-13 11:02:28 -050060 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
Robert Phillips88a32ef2018-06-07 11:05:56 -040061 GrProxyProvider* proxyProvider,
62 LazyProxyTest* test,
63 bool nullTexture) {
Robert Phillips9da87e02019-02-04 13:26:26 -050064 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -040065
Greg Daniel4065d452018-11-16 15:43:41 -050066 return pool->allocate<Op>(context, proxyProvider, test, nullTexture);
Robert Phillips88a32ef2018-06-07 11:05:56 -040067 }
68
Brian Salomon7d94bb52018-10-12 14:37:19 -040069 void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
Robert Phillips88a32ef2018-06-07 11:05:56 -040070 func(fProxy.get());
71 }
72
Brian Salomon588cec72018-11-14 13:56:37 -050073 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override {
Robert Phillips88a32ef2018-06-07 11:05:56 -040074 REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture);
75 REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture);
76 }
77
78 private:
Robert Phillips7c525e62018-06-12 10:11:12 -040079 friend class GrOpMemoryPool; // for ctor
80
Robert Phillips6f0e02f2019-02-13 11:02:28 -050081 Op(GrRecordingContext* ctx, GrProxyProvider* proxyProvider,
82 LazyProxyTest* test, bool nullTexture)
Robert Phillips777707b2018-01-17 11:40:14 -050083 : GrDrawOp(ClassID()), fTest(test) {
Greg Daniel4065d452018-11-16 15:43:41 -050084 const GrBackendFormat format =
Robert Phillips9da87e02019-02-04 13:26:26 -050085 ctx->priv().caps()->getBackendFormatFromColorType(kRGB_565_SkColorType);
Chris Dalton4c458b12018-06-16 17:22:59 -060086 fProxy = GrProxyProvider::MakeFullyLazyProxy(
87 [this, nullTexture](GrResourceProvider* rp) {
88 if (!rp) {
89 return sk_sp<GrTexture>();
90 }
91 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
92 fTest->fHasOpTexture = true;
93 if (nullTexture) {
94 return sk_sp<GrTexture>();
95 } else {
96 GrSurfaceDesc desc;
97 desc.fWidth = 1234;
98 desc.fHeight = 567;
99 desc.fConfig = kRGB_565_GrPixelConfig;
100 sk_sp<GrTexture> texture = rp->createTexture(desc, SkBudgeted::kYes);
101 REPORTER_ASSERT(fTest->fReporter, texture);
102 return texture;
103 }
104 },
Greg Daniel4065d452018-11-16 15:43:41 -0500105 format, GrProxyProvider::Renderable::kNo, kTopLeft_GrSurfaceOrigin,
Chris Dalton4c458b12018-06-16 17:22:59 -0600106 kRGB_565_GrPixelConfig, *proxyProvider->caps());
107
108 this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo,
109 GrOp::IsZeroArea::kNo);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700110 }
111
Chris Dalton706a6ff2017-11-29 22:01:06 -0700112 const char* name() const override { return "LazyProxyTest::Op"; }
113 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton4b62aed2019-01-15 11:53:00 -0700114 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*) override {
115 return GrProcessorSet::EmptySetAnalysis();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700116 }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700117 void onPrepare(GrOpFlushState*) override {}
118
119 LazyProxyTest* const fTest;
120 sk_sp<GrTextureProxy> fProxy;
121 };
122
123 class ClipFP : public GrFragmentProcessor {
124 public:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500125 ClipFP(GrRecordingContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test,
Greg Daniel4065d452018-11-16 15:43:41 -0500126 GrTextureProxy* atlas)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700127 : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
Greg Daniel4065d452018-11-16 15:43:41 -0500128 , fContext(ctx)
Robert Phillips777707b2018-01-17 11:40:14 -0500129 , fProxyProvider(proxyProvider)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700130 , fTest(test)
131 , fAtlas(atlas) {
Greg Daniel4065d452018-11-16 15:43:41 -0500132 const GrBackendFormat format =
Robert Phillips9da87e02019-02-04 13:26:26 -0500133 ctx->priv().caps()->getBackendFormatFromGrColorType(GrColorType::kAlpha_F16,
134 GrSRGBEncoded::kNo);
Chris Dalton4c458b12018-06-16 17:22:59 -0600135 fLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
Robert Phillipsce5209a2018-02-13 11:13:51 -0500136 [this](GrResourceProvider* rp) {
137 if (!rp) {
138 return sk_sp<GrTexture>();
139 }
140 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
141 fTest->fHasClipTexture = true;
142 fAtlas->instantiate(rp);
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400143 return sk_ref_sp(fAtlas->peekTexture());
Robert Phillipsce5209a2018-02-13 11:13:51 -0500144 },
Greg Daniel4065d452018-11-16 15:43:41 -0500145 format,
Robert Phillipsce5209a2018-02-13 11:13:51 -0500146 GrProxyProvider::Renderable::kYes,
147 kBottomLeft_GrSurfaceOrigin,
Chris Dalton4c458b12018-06-16 17:22:59 -0600148 kAlpha_half_GrPixelConfig, *proxyProvider->caps());
Chris Dalton706a6ff2017-11-29 22:01:06 -0700149 fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
Brian Salomone782f842018-07-31 13:53:11 -0400150 GrSamplerState::WrapMode::kClamp);
Brian Salomonf7dcd762018-07-30 14:48:15 -0400151 this->setTextureSamplerCnt(1);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700152 }
153
154 private:
155 const char* name() const override { return "LazyProxyTest::ClipFP"; }
156 std::unique_ptr<GrFragmentProcessor> clone() const override {
Greg Daniel4065d452018-11-16 15:43:41 -0500157 return skstd::make_unique<ClipFP>(fContext, fProxyProvider, fTest, fAtlas);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700158 }
159 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
160 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
161 bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
Brian Salomonf7dcd762018-07-30 14:48:15 -0400162 const TextureSampler& onTextureSampler(int) const override { return fAccess; }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700163
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500164 GrRecordingContext* const fContext;
Robert Phillips777707b2018-01-17 11:40:14 -0500165 GrProxyProvider* const fProxyProvider;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700166 LazyProxyTest* const fTest;
167 GrTextureProxy* const fAtlas;
168 sk_sp<GrTextureProxy> fLazyProxy;
169 TextureSampler fAccess;
170 };
171
172
173 class Clip : public GrClip {
174 public:
175 Clip(LazyProxyTest* test, GrTextureProxy* atlas)
176 : fTest(test)
177 , fAtlas(atlas) {}
178
179 private:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500180 bool apply(GrRecordingContext* context, GrRenderTargetContext*, bool useHWAA,
181 bool hasUserStencilSettings, GrAppliedClip* out, SkRect* bounds) const override {
Robert Phillips9da87e02019-02-04 13:26:26 -0500182 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Greg Daniel4065d452018-11-16 15:43:41 -0500183 out->addCoverageFP(skstd::make_unique<ClipFP>(context, proxyProvider, fTest, fAtlas));
Chris Dalton706a6ff2017-11-29 22:01:06 -0700184 return true;
185 }
186 bool quickContains(const SkRect&) const final { return false; }
187 bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; }
188 void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
189 rect->set(0, 0, width, height);
190 if (iior) {
191 *iior = false;
192 }
193 }
194
195 LazyProxyTest* const fTest;
196 GrTextureProxy* fAtlas;
197 };
198
199private:
200 skiatest::Reporter* fReporter;
201 bool fHasOpTexture;
202 bool fHasClipTexture;
203};
204
205DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
206 GrMockOptions mockOptions;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500207 mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderability =
208 GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700209 mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fTexturable = true;
210 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500211 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700212 for (bool nullTexture : {false, true}) {
213 LazyProxyTest test(reporter);
Robert Phillips9da87e02019-02-04 13:26:26 -0500214 ctx->priv().addOnFlushCallbackObject(&test);
Greg Daniel4065d452018-11-16 15:43:41 -0500215 GrBackendFormat format =
Robert Phillips9da87e02019-02-04 13:26:26 -0500216 ctx->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
217 sk_sp<GrRenderTargetContext> rtc = ctx->priv().makeDeferredRenderTargetContext(
Greg Daniel4065d452018-11-16 15:43:41 -0500218 format, SkBackingFit::kExact, 100, 100,
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500219 kRGBA_8888_GrPixelConfig, nullptr);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700220 REPORTER_ASSERT(reporter, rtc);
Greg Daniel4065d452018-11-16 15:43:41 -0500221 format =
Robert Phillips9da87e02019-02-04 13:26:26 -0500222 ctx->priv().caps()->getBackendFormatFromGrColorType(GrColorType::kAlpha_F16,
Greg Daniel4065d452018-11-16 15:43:41 -0500223 GrSRGBEncoded::kNo);
Robert Phillips9da87e02019-02-04 13:26:26 -0500224 sk_sp<GrRenderTargetContext> mockAtlas = ctx->priv().makeDeferredRenderTargetContext(
Greg Daniel4065d452018-11-16 15:43:41 -0500225 format, SkBackingFit::kExact, 10, 10,
Chris Dalton706a6ff2017-11-29 22:01:06 -0700226 kAlpha_half_GrPixelConfig, nullptr);
227 REPORTER_ASSERT(reporter, mockAtlas);
228 rtc->priv().testingOnly_addDrawOp(LazyProxyTest::Clip(&test, mockAtlas->asTextureProxy()),
Robert Phillips88a32ef2018-06-07 11:05:56 -0400229 LazyProxyTest::Op::Make(ctx.get(), proxyProvider, &test, nullTexture));
Robert Phillips9da87e02019-02-04 13:26:26 -0500230 ctx->priv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700231 }
232}
233
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500234static const int kSize = 16;
235
Greg Daniel94a6ce82018-01-16 16:14:41 -0500236DEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) {
237 GrMockOptions mockOptions;
238 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500239 auto proxyProvider = ctx->priv().proxyProvider();
Greg Daniel94a6ce82018-01-16 16:14:41 -0500240
241 GrSurfaceDesc desc;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500242 desc.fWidth = kSize;
243 desc.fHeight = kSize;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500244 desc.fConfig = kRGBA_8888_GrPixelConfig;
245
Greg Daniel4065d452018-11-16 15:43:41 -0500246 GrBackendFormat format =
Robert Phillips9da87e02019-02-04 13:26:26 -0500247 ctx->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
Greg Daniel4065d452018-11-16 15:43:41 -0500248
Greg Daniel457469c2018-02-08 15:05:44 -0500249 using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500250 for (bool doInstantiate : {true, false}) {
Greg Daniel457469c2018-02-08 15:05:44 -0500251 for (auto lazyType : {LazyInstantiationType::kSingleUse,
Greg Daniela8d92112018-03-09 12:05:04 -0500252 LazyInstantiationType::kMultipleUse,
Brian Salomon967df202018-12-07 11:15:53 -0500253 LazyInstantiationType::kDeinstantiate}) {
Greg Daniel457469c2018-02-08 15:05:44 -0500254 int testCount = 0;
Brian Salomon67f01952019-02-14 13:05:25 -0500255 // Sets an integer to 1 when the callback is called and -1 when it is deleted.
256 class TestCallback {
257 public:
258 TestCallback(int* value) : fValue(value) {}
259 TestCallback(const TestCallback& that) { SkASSERT(0); }
260 TestCallback(TestCallback&& that) : fValue(that.fValue) { that.fValue = nullptr; }
261
262 ~TestCallback() { fValue ? (void)(*fValue = -1) : void(); }
263
264 TestCallback& operator=(TestCallback&& that) {
265 fValue = skstd::exchange(that.fValue, nullptr);
266 return *this;
267 }
268 TestCallback& operator=(const TestCallback& that) = delete;
269
270 sk_sp<GrSurface> operator()(GrResourceProvider* resourceProvider) const {
271 *fValue = 1;
272 return {};
273 }
274
275 private:
276 int* fValue = nullptr;
277 };
Greg Daniel457469c2018-02-08 15:05:44 -0500278 sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
Brian Salomon67f01952019-02-14 13:05:25 -0500279 TestCallback(&testCount), format, desc, kTopLeft_GrSurfaceOrigin,
280 GrMipMapped::kNo, GrInternalSurfaceFlags::kNone, SkBackingFit::kExact,
281 SkBudgeted::kNo, lazyType);
Greg Daniel94a6ce82018-01-16 16:14:41 -0500282
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400283 REPORTER_ASSERT(reporter, proxy.get());
Greg Daniel457469c2018-02-08 15:05:44 -0500284 REPORTER_ASSERT(reporter, 0 == testCount);
285
286 if (doInstantiate) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500287 proxy->priv().doLazyInstantiation(ctx->priv().resourceProvider());
Greg Daniel457469c2018-02-08 15:05:44 -0500288 if (LazyInstantiationType::kSingleUse == proxy->priv().lazyInstantiationType()) {
289 // In SingleUse we will call the cleanup and delete the callback in the
290 // doLazyInstantiationCall.
291 REPORTER_ASSERT(reporter, -1 == testCount);
292 } else {
293 REPORTER_ASSERT(reporter, 1 == testCount);
294 }
295 proxy.reset();
296 REPORTER_ASSERT(reporter, -1 == testCount);
297 } else {
298 proxy.reset();
299 REPORTER_ASSERT(reporter, -1 == testCount);
300 }
Greg Daniel94a6ce82018-01-16 16:14:41 -0500301 }
302 }
303}
304
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500305class LazyFailedInstantiationTestOp : public GrDrawOp {
306public:
307 DEFINE_OP_CLASS_ID
308
Robert Phillips88a32ef2018-06-07 11:05:56 -0400309 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
310 GrProxyProvider* proxyProvider,
311 int* testExecuteValue,
312 bool shouldFailInstantiation) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500313 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400314
Greg Daniel4065d452018-11-16 15:43:41 -0500315 return pool->allocate<LazyFailedInstantiationTestOp>(context, proxyProvider,
Robert Phillipsc994a932018-06-19 13:09:54 -0400316 testExecuteValue,
317 shouldFailInstantiation);
Robert Phillips88a32ef2018-06-07 11:05:56 -0400318 }
319
Brian Salomon7d94bb52018-10-12 14:37:19 -0400320 void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
Robert Phillips88a32ef2018-06-07 11:05:56 -0400321 func(fLazyProxy.get());
322 }
323
324private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400325 friend class GrOpMemoryPool; // for ctor
326
Greg Daniel4065d452018-11-16 15:43:41 -0500327 LazyFailedInstantiationTestOp(GrContext* ctx, GrProxyProvider* proxyProvider,
328 int* testExecuteValue, bool shouldFailInstantiation)
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500329 : INHERITED(ClassID())
330 , fTestExecuteValue(testExecuteValue) {
331 GrSurfaceDesc desc;
332 desc.fWidth = kSize;
333 desc.fHeight = kSize;
334 desc.fConfig = kRGBA_8888_GrPixelConfig;
Greg Daniel4065d452018-11-16 15:43:41 -0500335 GrBackendFormat format =
Robert Phillips9da87e02019-02-04 13:26:26 -0500336 ctx->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500337
338 fLazyProxy = proxyProvider->createLazyProxy(
Brian Salomon2a4f9832018-03-03 22:43:43 -0500339 [testExecuteValue, shouldFailInstantiation, desc](GrResourceProvider* rp) {
Greg Daniel0a375db2018-02-01 12:21:39 -0500340 if (shouldFailInstantiation) {
341 *testExecuteValue = 1;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500342 return sk_sp<GrTexture>();
343 }
344 return rp->createTexture(desc, SkBudgeted::kNo);
Brian Salomon2a4f9832018-03-03 22:43:43 -0500345 },
Greg Daniel4065d452018-11-16 15:43:41 -0500346 format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
Brian Salomon7226c232018-07-30 13:13:17 -0400347 SkBackingFit::kExact, SkBudgeted::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500348
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400349 SkASSERT(fLazyProxy.get());
350
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500351 this->setBounds(SkRect::MakeIWH(kSize, kSize),
352 HasAABloat::kNo, IsZeroArea::kNo);
353 }
354
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500355 const char* name() const override { return "LazyFailedInstantiationTestOp"; }
356 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton4b62aed2019-01-15 11:53:00 -0700357 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*) override {
358 return GrProcessorSet::EmptySetAnalysis();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500359 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500360 void onPrepare(GrOpFlushState*) override {}
Brian Salomon588cec72018-11-14 13:56:37 -0500361 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500362 *fTestExecuteValue = 2;
363 }
364
365 int* fTestExecuteValue;
366 sk_sp<GrSurfaceProxy> fLazyProxy;
367
368 typedef GrDrawOp INHERITED;
369};
370
371// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
372// associated with.
373DEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) {
374 GrMockOptions mockOptions;
375 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500376 GrResourceProvider* resourceProvider = ctx->priv().resourceProvider();
377 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Greg Daniel4065d452018-11-16 15:43:41 -0500378 GrBackendFormat format =
Robert Phillips9da87e02019-02-04 13:26:26 -0500379 ctx->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500380 for (bool failInstantiation : {false, true}) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500381 sk_sp<GrRenderTargetContext> rtc = ctx->priv().makeDeferredRenderTargetContext(
Greg Daniel4065d452018-11-16 15:43:41 -0500382 format, SkBackingFit::kExact, 100, 100,
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500383 kRGBA_8888_GrPixelConfig, nullptr);
384 REPORTER_ASSERT(reporter, rtc);
385
Brian Osman9a9baae2018-11-05 15:06:26 -0500386 rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xbaaaaaad),
387 GrRenderTargetContext::CanClearFullscreen::kYes);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500388
389 int executeTestValue = 0;
Robert Phillips88a32ef2018-06-07 11:05:56 -0400390 rtc->priv().testingOnly_addDrawOp(LazyFailedInstantiationTestOp::Make(
391 ctx.get(), proxyProvider, &executeTestValue, failInstantiation));
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500392 ctx->flush();
393
394 if (failInstantiation) {
Robert Phillips4150eea2018-02-07 17:08:21 -0500395 if (resourceProvider->explicitlyAllocateGPUResources()) {
396 REPORTER_ASSERT(reporter, 1 == executeTestValue);
397 } else {
398 // When we disable explicit gpu resource allocation we don't throw away ops that
399 // have uninstantiated proxies.
400 REPORTER_ASSERT(reporter, 2 == executeTestValue);
401 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500402 } else {
403 REPORTER_ASSERT(reporter, 2 == executeTestValue);
404 }
405 }
Greg Daniel4684f822018-03-08 15:27:36 -0500406}
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500407
Brian Salomon967df202018-12-07 11:15:53 -0500408class LazyDeinstantiateTestOp : public GrDrawOp {
Greg Daniel4684f822018-03-08 15:27:36 -0500409public:
410 DEFINE_OP_CLASS_ID
411
Robert Phillips88a32ef2018-06-07 11:05:56 -0400412 static std::unique_ptr<GrDrawOp> Make(GrContext* context, sk_sp<GrTextureProxy> proxy) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500413 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400414
Brian Salomon967df202018-12-07 11:15:53 -0500415 return pool->allocate<LazyDeinstantiateTestOp>(std::move(proxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500416 }
417
Brian Salomon7d94bb52018-10-12 14:37:19 -0400418 void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
Greg Daniel4684f822018-03-08 15:27:36 -0500419 func(fLazyProxy.get());
420 }
421
422private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400423 friend class GrOpMemoryPool; // for ctor
424
Brian Salomon967df202018-12-07 11:15:53 -0500425 LazyDeinstantiateTestOp(sk_sp<GrTextureProxy> proxy)
426 : INHERITED(ClassID()), fLazyProxy(std::move(proxy)) {
Robert Phillips88a32ef2018-06-07 11:05:56 -0400427 this->setBounds(SkRect::MakeIWH(kSize, kSize), HasAABloat::kNo, IsZeroArea::kNo);
428 }
429
Brian Salomon967df202018-12-07 11:15:53 -0500430 const char* name() const override { return "LazyDeinstantiateTestOp"; }
Greg Daniel4684f822018-03-08 15:27:36 -0500431 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton4b62aed2019-01-15 11:53:00 -0700432 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*) override {
433 return GrProcessorSet::EmptySetAnalysis();
Greg Daniel4684f822018-03-08 15:27:36 -0500434 }
Greg Daniel4684f822018-03-08 15:27:36 -0500435 void onPrepare(GrOpFlushState*) override {}
Brian Salomon588cec72018-11-14 13:56:37 -0500436 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {}
Greg Daniel4684f822018-03-08 15:27:36 -0500437
438 sk_sp<GrSurfaceProxy> fLazyProxy;
439
440 typedef GrDrawOp INHERITED;
441};
442
Brian Salomon967df202018-12-07 11:15:53 -0500443static void DeinstantiateReleaseProc(void* releaseValue) { (*static_cast<int*>(releaseValue))++; }
Greg Daniel4684f822018-03-08 15:27:36 -0500444
Brian Salomon967df202018-12-07 11:15:53 -0500445// Test that lazy proxies with the Deinstantiate LazyCallbackType are deinstantiated and released as
Greg Daniel4684f822018-03-08 15:27:36 -0500446// expected.
Brian Salomon967df202018-12-07 11:15:53 -0500447DEF_GPUTEST(LazyProxyDeinstantiateTest, reporter, /* options */) {
Greg Daniel4684f822018-03-08 15:27:36 -0500448 GrMockOptions mockOptions;
449 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500450 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
451 GrGpu* gpu = ctx->priv().getGpu();
Greg Daniel4684f822018-03-08 15:27:36 -0500452
Greg Daniel4065d452018-11-16 15:43:41 -0500453 GrBackendFormat format =
Robert Phillips9da87e02019-02-04 13:26:26 -0500454 ctx->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
Greg Daniel4065d452018-11-16 15:43:41 -0500455
Greg Daniel4684f822018-03-08 15:27:36 -0500456 using LazyType = GrSurfaceProxy::LazyInstantiationType;
Brian Salomon967df202018-12-07 11:15:53 -0500457 for (auto lazyType : {LazyType::kSingleUse, LazyType::kMultipleUse, LazyType::kDeinstantiate}) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500458 sk_sp<GrRenderTargetContext> rtc = ctx->priv().makeDeferredRenderTargetContext(
Greg Daniel4065d452018-11-16 15:43:41 -0500459 format, SkBackingFit::kExact, 100, 100,
Greg Daniel4684f822018-03-08 15:27:36 -0500460 kRGBA_8888_GrPixelConfig, nullptr);
461 REPORTER_ASSERT(reporter, rtc);
462
Brian Osman9a9baae2018-11-05 15:06:26 -0500463 rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xbaaaaaad),
464 GrRenderTargetContext::CanClearFullscreen::kYes);
Greg Daniel4684f822018-03-08 15:27:36 -0500465
466 int instantiateTestValue = 0;
467 int releaseTestValue = 0;
468 int* instantiatePtr = &instantiateTestValue;
469 int* releasePtr = &releaseTestValue;
470 GrSurfaceDesc desc;
471 desc.fWidth = kSize;
472 desc.fHeight = kSize;
473 desc.fConfig = kRGBA_8888_GrPixelConfig;
474
475 GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
Robert Phillips646f6372018-09-25 09:31:10 -0400476 nullptr, kSize, kSize, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
Greg Daniel4684f822018-03-08 15:27:36 -0500477
478 sk_sp<GrTextureProxy> lazyProxy = proxyProvider->createLazyProxy(
479 [instantiatePtr, releasePtr, backendTex](GrResourceProvider* rp) {
Brian Salomonfa2ebea2019-01-24 15:58:58 -0500480 sk_sp<GrTexture> texture =
481 rp->wrapBackendTexture(backendTex, kBorrow_GrWrapOwnership,
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500482 GrWrapCacheable::kNo, kRead_GrIOType);
Greg Daniel4684f822018-03-08 15:27:36 -0500483 if (!texture) {
484 return sk_sp<GrTexture>();
485 }
486 (*instantiatePtr)++;
Brian Salomon967df202018-12-07 11:15:53 -0500487 texture->setRelease(DeinstantiateReleaseProc, releasePtr);
Greg Daniel4684f822018-03-08 15:27:36 -0500488 return texture;
489 },
Greg Daniel4065d452018-11-16 15:43:41 -0500490 format, desc, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
Brian Salomonc67c31c2018-12-06 10:00:03 -0500491 GrInternalSurfaceFlags::kReadOnly, SkBackingFit::kExact, SkBudgeted::kNo, lazyType);
Greg Daniel4684f822018-03-08 15:27:36 -0500492
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400493 REPORTER_ASSERT(reporter, lazyProxy.get());
494
Brian Salomon967df202018-12-07 11:15:53 -0500495 rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500496
497 ctx->flush();
498
499 REPORTER_ASSERT(reporter, 1 == instantiateTestValue);
Brian Salomon967df202018-12-07 11:15:53 -0500500 if (LazyType::kDeinstantiate == lazyType) {
Greg Daniel4684f822018-03-08 15:27:36 -0500501 REPORTER_ASSERT(reporter, 1 == releaseTestValue);
502 } else {
503 REPORTER_ASSERT(reporter, 0 == releaseTestValue);
504 }
505
506 // This should cause the uninstantiate proxies to be instantiated again but have no effect
507 // on the others
Brian Salomon967df202018-12-07 11:15:53 -0500508 rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500509 // Add a second op to make sure we only instantiate once.
Brian Salomon967df202018-12-07 11:15:53 -0500510 rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500511 ctx->flush();
512
Brian Salomon967df202018-12-07 11:15:53 -0500513 if (LazyType::kDeinstantiate == lazyType) {
Greg Daniel4684f822018-03-08 15:27:36 -0500514 REPORTER_ASSERT(reporter, 2 == instantiateTestValue);
515 REPORTER_ASSERT(reporter, 2 == releaseTestValue);
516 } else {
517 REPORTER_ASSERT(reporter, 1 == instantiateTestValue);
518 REPORTER_ASSERT(reporter, 0 == releaseTestValue);
519 }
520
521 lazyProxy.reset();
Brian Salomon967df202018-12-07 11:15:53 -0500522 if (LazyType::kDeinstantiate == lazyType) {
Greg Daniel4684f822018-03-08 15:27:36 -0500523 REPORTER_ASSERT(reporter, 2 == releaseTestValue);
524 } else {
525 REPORTER_ASSERT(reporter, 1 == releaseTestValue);
526 }
527
Brian Salomon26102cb2018-03-09 09:33:19 -0500528 gpu->deleteTestingOnlyBackendTexture(backendTex);
Greg Daniel4684f822018-03-08 15:27:36 -0500529 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500530}