blob: 2f5db6e685f4a92c3145232105b75e929d3d7628 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "tests/Test.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -07009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/gpu/mock/GrMockTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/core/SkRectPriv.h"
12#include "src/gpu/GrClip.h"
13#include "src/gpu/GrContextPriv.h"
14#include "src/gpu/GrMemoryPool.h"
15#include "src/gpu/GrOnFlushResourceProvider.h"
16#include "src/gpu/GrProxyProvider.h"
17#include "src/gpu/GrRecordingContextPriv.h"
18#include "src/gpu/GrRenderTargetContext.h"
19#include "src/gpu/GrRenderTargetContextPriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040020#include "src/gpu/GrSurfaceProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "src/gpu/GrSurfaceProxyPriv.h"
Greg Daniel456f9b52020-03-05 19:14:18 +000022#include "src/gpu/GrTexture.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040023#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "src/gpu/GrTextureProxyPriv.h"
25#include "src/gpu/mock/GrMockGpu.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070026
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
Chris Daltonc4b47352019-08-23 10:10:36 -060043 void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int) override {
Chris Dalton706a6ff2017-11-29 22:01:06 -070044 REPORTER_ASSERT(fReporter, !fHasOpTexture);
45 REPORTER_ASSERT(fReporter, !fHasClipTexture);
46 }
47
Greg Danielf41b2bd2019-08-22 16:19:24 -040048 void postFlush(GrDeferredUploadToken, const uint32_t* opsTaskIDs, int numOpsTaskIDs) override {
Chris Dalton706a6ff2017-11-29 22:01:06 -070049 REPORTER_ASSERT(fReporter, fHasOpTexture);
50 REPORTER_ASSERT(fReporter, fHasClipTexture);
51 }
52
53 class Op final : public GrDrawOp {
54 public:
55 DEFINE_OP_CLASS_ID
56
Robert Phillips6f0e02f2019-02-13 11:02:28 -050057 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
Robert Phillips88a32ef2018-06-07 11:05:56 -040058 GrProxyProvider* proxyProvider,
59 LazyProxyTest* test,
60 bool nullTexture) {
Robert Phillips9da87e02019-02-04 13:26:26 -050061 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -040062
Greg Daniel4065d452018-11-16 15:43:41 -050063 return pool->allocate<Op>(context, proxyProvider, test, nullTexture);
Robert Phillips88a32ef2018-06-07 11:05:56 -040064 }
65
Chris Dalton1706cbf2019-05-21 19:35:29 -060066 void visitProxies(const VisitProxyFunc& func) const override {
Brian Salomon7e67dca2020-07-21 09:27:25 -040067 func(fProxy.get(), GrMipmapped::kNo);
Robert Phillips88a32ef2018-06-07 11:05:56 -040068 }
69
Brian Salomon588cec72018-11-14 13:56:37 -050070 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override {
Robert Phillips88a32ef2018-06-07 11:05:56 -040071 REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture);
72 REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture);
73 }
74
75 private:
Robert Phillips7c525e62018-06-12 10:11:12 -040076 friend class GrOpMemoryPool; // for ctor
77
Robert Phillips6f0e02f2019-02-13 11:02:28 -050078 Op(GrRecordingContext* ctx, GrProxyProvider* proxyProvider,
79 LazyProxyTest* test, bool nullTexture)
Robert Phillips777707b2018-01-17 11:40:14 -050080 : GrDrawOp(ClassID()), fTest(test) {
Greg Daniel4065d452018-11-16 15:43:41 -050081 const GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -040082 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kBGR_565,
83 GrRenderable::kNo);
Chris Dalton4c458b12018-06-16 17:22:59 -060084 fProxy = GrProxyProvider::MakeFullyLazyProxy(
Brian Salomon63410e92020-03-23 18:32:50 -040085 [this, nullTexture](GrResourceProvider* rp,
86 const GrSurfaceProxy::LazySurfaceDesc& desc)
87 -> GrSurfaceProxy::LazyCallbackResult {
Chris Dalton4c458b12018-06-16 17:22:59 -060088 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
89 fTest->fHasOpTexture = true;
90 if (nullTexture) {
Brian Salomonb6a3a3b2019-04-01 12:29:34 -040091 return {};
Chris Dalton4c458b12018-06-16 17:22:59 -060092 } else {
Brian Salomona56a7462020-02-07 14:17:25 -050093 static constexpr SkISize kDimensions = {1234, 567};
Brian Salomone8a766b2019-07-19 14:24:36 -040094 sk_sp<GrTexture> texture = rp->createTexture(
Brian Salomon63410e92020-03-23 18:32:50 -040095 kDimensions, desc.fFormat, desc.fRenderable, desc.fSampleCnt,
Brian Salomon40a40622020-07-21 10:32:07 -040096 desc.fMipmapped, desc.fBudgeted, desc.fProtected);
Chris Dalton4c458b12018-06-16 17:22:59 -060097 REPORTER_ASSERT(fTest->fReporter, texture);
Brian Salomon9c73e3d2019-08-15 10:55:49 -040098 return texture;
Chris Dalton4c458b12018-06-16 17:22:59 -060099 }
100 },
Brian Salomondf1bd6d2020-03-26 20:37:01 -0400101 format, GrRenderable::kNo, 1, GrProtected::kNo, *proxyProvider->caps(),
102 GrSurfaceProxy::UseAllocator::kYes);
Chris Dalton4c458b12018-06-16 17:22:59 -0600103
104 this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo,
Greg Daniel5faf4742019-10-01 15:14:44 -0400105 GrOp::IsHairline::kNo);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700106 }
107
Chris Dalton706a6ff2017-11-29 22:01:06 -0700108 const char* name() const override { return "LazyProxyTest::Op"; }
109 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600110 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip* clip,
111 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700112 return GrProcessorSet::EmptySetAnalysis();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700113 }
Robert Phillipsc655c3a2020-03-18 13:23:45 -0400114 void onPrePrepare(GrRecordingContext*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400115 const GrSurfaceProxyView* writeView,
Robert Phillipsc655c3a2020-03-18 13:23:45 -0400116 GrAppliedClip*,
Greg Danield358cbe2020-09-11 09:33:54 -0400117 const GrXferProcessor::DstProxyView&,
118 GrXferBarrierFlags renderPassXferBarriers) override {}
Robert Phillipsc655c3a2020-03-18 13:23:45 -0400119
Chris Dalton706a6ff2017-11-29 22:01:06 -0700120 void onPrepare(GrOpFlushState*) override {}
121
122 LazyProxyTest* const fTest;
123 sk_sp<GrTextureProxy> fProxy;
124 };
125
126 class ClipFP : public GrFragmentProcessor {
127 public:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500128 ClipFP(GrRecordingContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test,
Greg Daniel4065d452018-11-16 15:43:41 -0500129 GrTextureProxy* atlas)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700130 : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
Greg Daniel4065d452018-11-16 15:43:41 -0500131 , fContext(ctx)
Robert Phillips777707b2018-01-17 11:40:14 -0500132 , fProxyProvider(proxyProvider)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700133 , fTest(test)
134 , fAtlas(atlas) {
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000135 static const GrColorType kColorType = GrColorType::kAlpha_F16;
136 static const GrSurfaceOrigin kOrigin = kBottomLeft_GrSurfaceOrigin;
Greg Daniel4065d452018-11-16 15:43:41 -0500137 const GrBackendFormat format =
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000138 ctx->priv().caps()->getDefaultBackendFormat(kColorType, GrRenderable::kYes);
Greg Danielce3ddaa2020-01-22 16:58:15 -0500139 GrSwizzle readSwizzle = ctx->priv().caps()->getReadSwizzle(format, kColorType);
Chris Dalton4c458b12018-06-16 17:22:59 -0600140 fLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
Brian Salomon63410e92020-03-23 18:32:50 -0400141 [this](GrResourceProvider* rp, const GrSurfaceProxy::LazySurfaceDesc&)
142 -> GrSurfaceProxy::LazyCallbackResult {
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400143 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
144 fTest->fHasClipTexture = true;
145 fAtlas->instantiate(rp);
146 return sk_ref_sp(fAtlas->peekTexture());
147 },
Brian Salomondf1bd6d2020-03-26 20:37:01 -0400148 format, GrRenderable::kYes, 1, GrProtected::kNo, *proxyProvider->caps(),
149 GrSurfaceProxy::UseAllocator::kYes);
Brian Salomonf629a902020-06-17 13:05:00 -0400150 auto atlasEffect = GrTextureEffect::Make({fLazyProxy, kOrigin, readSwizzle},
151 kPremul_SkAlphaType);
Michael Ludwig9aba6252020-06-22 14:46:36 -0400152 this->registerChild(std::move(atlasEffect));
Chris Dalton706a6ff2017-11-29 22:01:06 -0700153 }
154
155 private:
156 const char* name() const override { return "LazyProxyTest::ClipFP"; }
157 std::unique_ptr<GrFragmentProcessor> clone() const override {
Mike Kleinf46d5ca2019-12-11 10:45:01 -0500158 return std::make_unique<ClipFP>(fContext, fProxyProvider, fTest, fAtlas);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700159 }
160 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
161 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
162 bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
163
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;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700169 };
170
171
172 class Clip : public GrClip {
173 public:
174 Clip(LazyProxyTest* test, GrTextureProxy* atlas)
175 : fTest(test)
176 , fAtlas(atlas) {}
177
178 private:
Michael Ludwige06a8972020-06-11 10:29:00 -0400179 SkIRect getConservativeBounds() const final {
180 return SkIRect::MakeSize(fAtlas->dimensions());
181 }
Michael Ludwig6397e802020-08-05 15:50:01 -0400182 Effect apply(GrRecordingContext* context, GrRenderTargetContext*, GrAAType,
Michael Ludwig4e3cab72020-06-30 11:12:46 -0400183 bool hasUserStencilSettings, GrAppliedClip* out,
184 SkRect* bounds) const override {
Robert Phillips9da87e02019-02-04 13:26:26 -0500185 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Mike Kleinf46d5ca2019-12-11 10:45:01 -0500186 out->addCoverageFP(std::make_unique<ClipFP>(context, proxyProvider, fTest, fAtlas));
Michael Ludwig4e3cab72020-06-30 11:12:46 -0400187 return Effect::kClipped;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700188 }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700189
190 LazyProxyTest* const fTest;
191 GrTextureProxy* fAtlas;
192 };
193
194private:
195 skiatest::Reporter* fReporter;
196 bool fHasOpTexture;
197 bool fHasClipTexture;
198};
199
200DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
201 GrMockOptions mockOptions;
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400202 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fRenderability =
Brian Salomonbdecacf2018-02-02 20:32:49 -0500203 GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400204 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fTexturable = true;
Robert Phillipsf4f80112020-07-13 16:13:31 -0400205 sk_sp<GrDirectContext> ctx = GrDirectContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500206 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700207 for (bool nullTexture : {false, true}) {
208 LazyProxyTest test(reporter);
Robert Phillips9da87e02019-02-04 13:26:26 -0500209 ctx->priv().addOnFlushCallbackObject(&test);
Greg Daniele20fcad2020-01-08 11:52:34 -0500210 auto rtc = GrRenderTargetContext::Make(
211 ctx.get(), GrColorType::kRGBA_8888, nullptr, SkBackingFit::kExact, {100, 100});
Chris Dalton706a6ff2017-11-29 22:01:06 -0700212 REPORTER_ASSERT(reporter, rtc);
Greg Daniele20fcad2020-01-08 11:52:34 -0500213 auto mockAtlas = GrRenderTargetContext::Make(
214 ctx.get(), GrColorType::kAlpha_F16, nullptr, SkBackingFit::kExact, {10, 10});
Chris Dalton706a6ff2017-11-29 22:01:06 -0700215 REPORTER_ASSERT(reporter, mockAtlas);
Michael Ludwig7c12e282020-05-29 09:54:07 -0400216 LazyProxyTest::Clip clip(&test, mockAtlas->asTextureProxy());
217 rtc->priv().testingOnly_addDrawOp(
218 &clip, LazyProxyTest::Op::Make(ctx.get(), proxyProvider, &test, nullTexture));
Robert Phillips9da87e02019-02-04 13:26:26 -0500219 ctx->priv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700220 }
221}
222
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500223static const int kSize = 16;
224
Greg Daniel94a6ce82018-01-16 16:14:41 -0500225DEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) {
226 GrMockOptions mockOptions;
Robert Phillipsf4f80112020-07-13 16:13:31 -0400227 sk_sp<GrDirectContext> ctx = GrDirectContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500228 auto proxyProvider = ctx->priv().proxyProvider();
Robert Phillips0a15cc62019-07-30 12:49:10 -0400229 const GrCaps* caps = ctx->priv().caps();
Greg Daniel94a6ce82018-01-16 16:14:41 -0500230
Robert Phillips0a15cc62019-07-30 12:49:10 -0400231 GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kRGBA_8888,
232 GrRenderable::kNo);
Greg Daniel4065d452018-11-16 15:43:41 -0500233
Brian Salomona56a7462020-02-07 14:17:25 -0500234 auto tex = ctx->priv().resourceProvider()->createTexture({kSize, kSize}, format,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400235 GrRenderable::kNo, 1, GrMipmapped::kNo,
Brian Salomona56a7462020-02-07 14:17:25 -0500236 SkBudgeted::kNo, GrProtected::kNo);
Brian Salomonbeb7f522019-08-30 16:19:42 -0400237 using LazyInstantiationResult = GrSurfaceProxy::LazyCallbackResult;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500238 for (bool doInstantiate : {true, false}) {
Brian Salomonbeb7f522019-08-30 16:19:42 -0400239 for (bool releaseCallback : {false, true}) {
Greg Daniel457469c2018-02-08 15:05:44 -0500240 int testCount = 0;
Brian Salomon67f01952019-02-14 13:05:25 -0500241 // Sets an integer to 1 when the callback is called and -1 when it is deleted.
242 class TestCallback {
243 public:
Brian Salomonbeb7f522019-08-30 16:19:42 -0400244 TestCallback(int* value, bool releaseCallback, sk_sp<GrTexture> tex)
245 : fValue(value)
246 , fReleaseCallback(releaseCallback)
247 , fTexture(std::move(tex)) {}
Brian Salomon67f01952019-02-14 13:05:25 -0500248 TestCallback(const TestCallback& that) { SkASSERT(0); }
Brian Salomonbeb7f522019-08-30 16:19:42 -0400249 TestCallback(TestCallback&& that)
250 : fValue(that.fValue)
251 , fReleaseCallback(that.fReleaseCallback)
252 , fTexture(std::move(that.fTexture)) {
253 that.fValue = nullptr;
254 }
Brian Salomon67f01952019-02-14 13:05:25 -0500255
256 ~TestCallback() { fValue ? (void)(*fValue = -1) : void(); }
257
258 TestCallback& operator=(TestCallback&& that) {
Adlai Holler5ba50af2020-04-29 21:11:14 -0400259 fValue = std::exchange(that.fValue, nullptr);
Brian Salomon67f01952019-02-14 13:05:25 -0500260 return *this;
261 }
262 TestCallback& operator=(const TestCallback& that) = delete;
263
Brian Salomon63410e92020-03-23 18:32:50 -0400264 LazyInstantiationResult operator()(GrResourceProvider*,
265 const GrSurfaceProxy::LazySurfaceDesc&) const {
Brian Salomon67f01952019-02-14 13:05:25 -0500266 *fValue = 1;
Brian Salomonbeb7f522019-08-30 16:19:42 -0400267 return {fTexture, fReleaseCallback};
Brian Salomon67f01952019-02-14 13:05:25 -0500268 }
269
270 private:
271 int* fValue = nullptr;
Brian Salomonbeb7f522019-08-30 16:19:42 -0400272 bool fReleaseCallback;
273 sk_sp<GrTexture> fTexture;
Brian Salomon67f01952019-02-14 13:05:25 -0500274 };
Greg Daniel457469c2018-02-08 15:05:44 -0500275 sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
Brian Salomona56a7462020-02-07 14:17:25 -0500276 TestCallback(&testCount, releaseCallback, tex), format, {kSize, kSize},
Greg Danielc113f002020-08-26 13:28:22 -0400277 GrMipmapped::kNo, GrMipmapStatus::kNotAllocated, GrInternalSurfaceFlags::kNone,
278 SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo,
279 GrSurfaceProxy::UseAllocator::kYes);
Greg Daniel94a6ce82018-01-16 16:14:41 -0500280
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400281 REPORTER_ASSERT(reporter, proxy.get());
Greg Daniel457469c2018-02-08 15:05:44 -0500282 REPORTER_ASSERT(reporter, 0 == testCount);
283
284 if (doInstantiate) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500285 proxy->priv().doLazyInstantiation(ctx->priv().resourceProvider());
Brian Salomonbeb7f522019-08-30 16:19:42 -0400286 if (releaseCallback) {
287 // We will call the cleanup and delete the callback in the
Greg Daniel457469c2018-02-08 15:05:44 -0500288 // doLazyInstantiationCall.
289 REPORTER_ASSERT(reporter, -1 == testCount);
290 } else {
291 REPORTER_ASSERT(reporter, 1 == testCount);
292 }
293 proxy.reset();
294 REPORTER_ASSERT(reporter, -1 == testCount);
295 } else {
296 proxy.reset();
297 REPORTER_ASSERT(reporter, -1 == testCount);
298 }
Greg Daniel94a6ce82018-01-16 16:14:41 -0500299 }
300 }
301}
302
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500303class LazyFailedInstantiationTestOp : public GrDrawOp {
304public:
305 DEFINE_OP_CLASS_ID
306
Robert Phillipsb25e0652020-07-22 09:35:49 -0400307 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* rContext,
Robert Phillips88a32ef2018-06-07 11:05:56 -0400308 GrProxyProvider* proxyProvider,
309 int* testExecuteValue,
310 bool shouldFailInstantiation) {
Robert Phillipsb25e0652020-07-22 09:35:49 -0400311 GrOpMemoryPool* pool = rContext->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400312
Robert Phillipsb25e0652020-07-22 09:35:49 -0400313 return pool->allocate<LazyFailedInstantiationTestOp>(rContext->priv().caps(),
314 proxyProvider,
Robert Phillipsc994a932018-06-19 13:09:54 -0400315 testExecuteValue,
316 shouldFailInstantiation);
Robert Phillips88a32ef2018-06-07 11:05:56 -0400317 }
318
Chris Dalton1706cbf2019-05-21 19:35:29 -0600319 void visitProxies(const VisitProxyFunc& func) const override {
Brian Salomon7e67dca2020-07-21 09:27:25 -0400320 func(fLazyProxy.get(), GrMipmapped::kNo);
Robert Phillips88a32ef2018-06-07 11:05:56 -0400321 }
322
323private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400324 friend class GrOpMemoryPool; // for ctor
325
Robert Phillipsb25e0652020-07-22 09:35:49 -0400326 LazyFailedInstantiationTestOp(const GrCaps* caps, GrProxyProvider* proxyProvider,
Greg Daniel4065d452018-11-16 15:43:41 -0500327 int* testExecuteValue, bool shouldFailInstantiation)
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500328 : INHERITED(ClassID())
329 , fTestExecuteValue(testExecuteValue) {
Brian Salomon63410e92020-03-23 18:32:50 -0400330 SkISize dims = {kSize, kSize};
Robert Phillipsb25e0652020-07-22 09:35:49 -0400331 GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kRGBA_8888,
332 GrRenderable::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500333
334 fLazyProxy = proxyProvider->createLazyProxy(
Brian Salomon63410e92020-03-23 18:32:50 -0400335 [testExecuteValue, shouldFailInstantiation](
336 GrResourceProvider* rp, const GrSurfaceProxy::LazySurfaceDesc& desc)
337 -> GrSurfaceProxy::LazyCallbackResult {
Greg Daniel0a375db2018-02-01 12:21:39 -0500338 if (shouldFailInstantiation) {
339 *testExecuteValue = 1;
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400340 return {};
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500341 }
Brian Salomon63410e92020-03-23 18:32:50 -0400342 return {rp->createTexture(desc.fDimensions, desc.fFormat, desc.fRenderable,
Brian Salomon40a40622020-07-21 10:32:07 -0400343 desc.fSampleCnt, desc.fMipmapped, desc.fBudgeted,
Brian Salomon63410e92020-03-23 18:32:50 -0400344 desc.fProtected),
Brian Salomonbeb7f522019-08-30 16:19:42 -0400345 true, GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
Brian Salomon2a4f9832018-03-03 22:43:43 -0500346 },
Greg Danielc113f002020-08-26 13:28:22 -0400347 format, dims, GrMipmapped::kNo, GrMipmapStatus::kNotAllocated,
348 GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo,
349 GrProtected::kNo, GrSurfaceProxy::UseAllocator::kYes);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500350
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400351 SkASSERT(fLazyProxy.get());
352
Brian Salomon63410e92020-03-23 18:32:50 -0400353 this->setBounds(SkRect::Make(dims), HasAABloat::kNo, IsHairline::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500354 }
355
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500356 const char* name() const override { return "LazyFailedInstantiationTestOp"; }
357 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600358 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
359 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700360 return GrProcessorSet::EmptySetAnalysis();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500361 }
Robert Phillipsc655c3a2020-03-18 13:23:45 -0400362 void onPrePrepare(GrRecordingContext*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400363 const GrSurfaceProxyView* writeView,
Robert Phillipsc655c3a2020-03-18 13:23:45 -0400364 GrAppliedClip*,
Greg Danield358cbe2020-09-11 09:33:54 -0400365 const GrXferProcessor::DstProxyView&,
366 GrXferBarrierFlags renderPassXferBarriers) override {}
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500367 void onPrepare(GrOpFlushState*) override {}
Brian Salomon588cec72018-11-14 13:56:37 -0500368 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500369 *fTestExecuteValue = 2;
370 }
371
372 int* fTestExecuteValue;
Greg Danieldcf9ca12019-08-27 14:30:21 -0400373 sk_sp<GrTextureProxy> fLazyProxy;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500374
John Stiles7571f9e2020-09-02 22:42:33 -0400375 using INHERITED = GrDrawOp;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500376};
377
378// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
379// associated with.
380DEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) {
381 GrMockOptions mockOptions;
Robert Phillipsf4f80112020-07-13 16:13:31 -0400382 sk_sp<GrDirectContext> ctx = GrDirectContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500383 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500384 for (bool failInstantiation : {false, true}) {
Greg Daniele20fcad2020-01-08 11:52:34 -0500385 auto rtc = GrRenderTargetContext::Make(
386 ctx.get(), GrColorType::kRGBA_8888, nullptr, SkBackingFit::kExact, {100, 100});
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500387 REPORTER_ASSERT(reporter, rtc);
388
Michael Ludwig81d41722020-05-26 16:57:38 -0400389 rtc->clear(SkPMColor4f::FromBytes_RGBA(0xbaaaaaad));
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500390
391 int executeTestValue = 0;
Robert Phillips88a32ef2018-06-07 11:05:56 -0400392 rtc->priv().testingOnly_addDrawOp(LazyFailedInstantiationTestOp::Make(
393 ctx.get(), proxyProvider, &executeTestValue, failInstantiation));
Greg Daniel0a2464f2020-05-14 15:45:44 -0400394 ctx->flushAndSubmit();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500395
396 if (failInstantiation) {
Robert Phillips12c46292019-04-23 07:36:17 -0400397 REPORTER_ASSERT(reporter, 1 == executeTestValue);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500398 } else {
399 REPORTER_ASSERT(reporter, 2 == executeTestValue);
400 }
401 }
Greg Daniel4684f822018-03-08 15:27:36 -0500402}