blob: 819e2b9f302f205213c7fd14901b512b8eb08d84 [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/GrTexture.h"
11#include "include/gpu/mock/GrMockTypes.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/core/SkExchange.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/core/SkRectPriv.h"
14#include "src/gpu/GrClip.h"
15#include "src/gpu/GrContextPriv.h"
16#include "src/gpu/GrMemoryPool.h"
17#include "src/gpu/GrOnFlushResourceProvider.h"
18#include "src/gpu/GrProxyProvider.h"
19#include "src/gpu/GrRecordingContextPriv.h"
20#include "src/gpu/GrRenderTargetContext.h"
21#include "src/gpu/GrRenderTargetContextPriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040022#include "src/gpu/GrSurfaceProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/GrSurfaceProxyPriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040024#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "src/gpu/GrTextureProxyPriv.h"
26#include "src/gpu/mock/GrMockGpu.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070027
28// This test verifies that lazy proxy callbacks get invoked during flush, after onFlush callbacks,
29// but before Ops are executed. It also ensures that lazy proxy callbacks are invoked both for
30// regular Ops and for clips.
31class LazyProxyTest final : public GrOnFlushCallbackObject {
32public:
33 LazyProxyTest(skiatest::Reporter* reporter)
34 : fReporter(reporter)
35 , fHasOpTexture(false)
36 , fHasClipTexture(false) {
37 }
38
39 ~LazyProxyTest() override {
40 REPORTER_ASSERT(fReporter, fHasOpTexture);
41 REPORTER_ASSERT(fReporter, fHasClipTexture);
42 }
43
Chris Daltonc4b47352019-08-23 10:10:36 -060044 void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int) override {
Chris Dalton706a6ff2017-11-29 22:01:06 -070045 REPORTER_ASSERT(fReporter, !fHasOpTexture);
46 REPORTER_ASSERT(fReporter, !fHasClipTexture);
47 }
48
Greg Danielf41b2bd2019-08-22 16:19:24 -040049 void postFlush(GrDeferredUploadToken, const uint32_t* opsTaskIDs, int numOpsTaskIDs) override {
Chris Dalton706a6ff2017-11-29 22:01:06 -070050 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 Phillips6f0e02f2019-02-13 11:02:28 -050058 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
Robert Phillips88a32ef2018-06-07 11:05:56 -040059 GrProxyProvider* proxyProvider,
60 LazyProxyTest* test,
61 bool nullTexture) {
Robert Phillips9da87e02019-02-04 13:26:26 -050062 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -040063
Greg Daniel4065d452018-11-16 15:43:41 -050064 return pool->allocate<Op>(context, proxyProvider, test, nullTexture);
Robert Phillips88a32ef2018-06-07 11:05:56 -040065 }
66
Chris Dalton1706cbf2019-05-21 19:35:29 -060067 void visitProxies(const VisitProxyFunc& func) const override {
Chris Dalton7eb5c0f2019-05-23 15:15:47 -060068 func(fProxy.get(), GrMipMapped::kNo);
Robert Phillips88a32ef2018-06-07 11:05:56 -040069 }
70
Brian Salomon588cec72018-11-14 13:56:37 -050071 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override {
Robert Phillips88a32ef2018-06-07 11:05:56 -040072 REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture);
73 REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture);
74 }
75
76 private:
Robert Phillips7c525e62018-06-12 10:11:12 -040077 friend class GrOpMemoryPool; // for ctor
78
Robert Phillips6f0e02f2019-02-13 11:02:28 -050079 Op(GrRecordingContext* ctx, GrProxyProvider* proxyProvider,
80 LazyProxyTest* test, bool nullTexture)
Robert Phillips777707b2018-01-17 11:40:14 -050081 : GrDrawOp(ClassID()), fTest(test) {
Greg Daniel4065d452018-11-16 15:43:41 -050082 const GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -040083 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kBGR_565,
84 GrRenderable::kNo);
Greg Danielce3ddaa2020-01-22 16:58:15 -050085 GrSwizzle readSwizzle = ctx->priv().caps()->getReadSwizzle(
86 format, GrColorType::kBGR_565);
Chris Dalton4c458b12018-06-16 17:22:59 -060087 fProxy = GrProxyProvider::MakeFullyLazyProxy(
Brian Salomonbeb7f522019-08-30 16:19:42 -040088 [this, format,
89 nullTexture](GrResourceProvider* rp) -> GrSurfaceProxy::LazyCallbackResult {
Chris Dalton4c458b12018-06-16 17:22:59 -060090 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
91 fTest->fHasOpTexture = true;
92 if (nullTexture) {
Brian Salomonb6a3a3b2019-04-01 12:29:34 -040093 return {};
Chris Dalton4c458b12018-06-16 17:22:59 -060094 } else {
Brian Salomona56a7462020-02-07 14:17:25 -050095 static constexpr SkISize kDimensions = {1234, 567};
Brian Salomone8a766b2019-07-19 14:24:36 -040096 sk_sp<GrTexture> texture = rp->createTexture(
Brian Salomona56a7462020-02-07 14:17:25 -050097 kDimensions, format, GrRenderable::kNo, 1, GrMipMapped::kNo,
Brian Salomona90382f2019-09-17 09:01:56 -040098 SkBudgeted::kYes, GrProtected::kNo);
Chris Dalton4c458b12018-06-16 17:22:59 -060099 REPORTER_ASSERT(fTest->fReporter, texture);
Brian Salomon9c73e3d2019-08-15 10:55:49 -0400100 return texture;
Chris Dalton4c458b12018-06-16 17:22:59 -0600101 }
102 },
Greg Danielce3ddaa2020-01-22 16:58:15 -0500103 format, readSwizzle, GrRenderable::kNo, 1, GrProtected::kNo,
Greg Daniel3a365112020-02-14 10:47:18 -0500104 *proxyProvider->caps(), GrSurfaceProxy::UseAllocator::kYes);
Chris Dalton4c458b12018-06-16 17:22:59 -0600105
106 this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo,
Greg Daniel5faf4742019-10-01 15:14:44 -0400107 GrOp::IsHairline::kNo);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700108 }
109
Chris Dalton706a6ff2017-11-29 22:01:06 -0700110 const char* name() const override { return "LazyProxyTest::Op"; }
111 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600112 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip* clip,
113 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700114 return GrProcessorSet::EmptySetAnalysis();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700115 }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700116 void onPrepare(GrOpFlushState*) override {}
117
118 LazyProxyTest* const fTest;
119 sk_sp<GrTextureProxy> fProxy;
120 };
121
122 class ClipFP : public GrFragmentProcessor {
123 public:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500124 ClipFP(GrRecordingContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test,
Greg Daniel4065d452018-11-16 15:43:41 -0500125 GrTextureProxy* atlas)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700126 : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
Greg Daniel4065d452018-11-16 15:43:41 -0500127 , fContext(ctx)
Robert Phillips777707b2018-01-17 11:40:14 -0500128 , fProxyProvider(proxyProvider)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700129 , fTest(test)
130 , fAtlas(atlas) {
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000131 static const GrColorType kColorType = GrColorType::kAlpha_F16;
132 static const GrSurfaceOrigin kOrigin = kBottomLeft_GrSurfaceOrigin;
Greg Daniel4065d452018-11-16 15:43:41 -0500133 const GrBackendFormat format =
Robert Phillipsbd99c0c2019-12-12 13:26:58 +0000134 ctx->priv().caps()->getDefaultBackendFormat(kColorType, GrRenderable::kYes);
Greg Danielce3ddaa2020-01-22 16:58:15 -0500135 GrSwizzle readSwizzle = ctx->priv().caps()->getReadSwizzle(format, kColorType);
Chris Dalton4c458b12018-06-16 17:22:59 -0600136 fLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
Brian Salomonbeb7f522019-08-30 16:19:42 -0400137 [this](GrResourceProvider* rp) -> GrSurfaceProxy::LazyCallbackResult {
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400138 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
139 fTest->fHasClipTexture = true;
140 fAtlas->instantiate(rp);
141 return sk_ref_sp(fAtlas->peekTexture());
142 },
Greg Daniel3a365112020-02-14 10:47:18 -0500143 format, readSwizzle, GrRenderable::kYes, 1, GrProtected::kNo,
Greg Danielb58a3c72020-01-23 10:05:14 -0500144 *proxyProvider->caps(), GrSurfaceProxy::UseAllocator::kYes);
Greg Danielce3ddaa2020-01-22 16:58:15 -0500145 fAccess.set(GrSurfaceProxyView(fLazyProxy, kOrigin, readSwizzle),
Brian Salomonccb61422020-01-09 10:46:36 -0500146 GrSamplerState::Filter::kNearest);
Brian Salomonf7dcd762018-07-30 14:48:15 -0400147 this->setTextureSamplerCnt(1);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700148 }
149
150 private:
151 const char* name() const override { return "LazyProxyTest::ClipFP"; }
152 std::unique_ptr<GrFragmentProcessor> clone() const override {
Mike Kleinf46d5ca2019-12-11 10:45:01 -0500153 return std::make_unique<ClipFP>(fContext, fProxyProvider, fTest, fAtlas);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700154 }
155 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
156 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
157 bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
Brian Salomonf7dcd762018-07-30 14:48:15 -0400158 const TextureSampler& onTextureSampler(int) const override { return fAccess; }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700159
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500160 GrRecordingContext* const fContext;
Robert Phillips777707b2018-01-17 11:40:14 -0500161 GrProxyProvider* const fProxyProvider;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700162 LazyProxyTest* const fTest;
163 GrTextureProxy* const fAtlas;
164 sk_sp<GrTextureProxy> fLazyProxy;
165 TextureSampler fAccess;
166 };
167
168
169 class Clip : public GrClip {
170 public:
171 Clip(LazyProxyTest* test, GrTextureProxy* atlas)
172 : fTest(test)
173 , fAtlas(atlas) {}
174
175 private:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500176 bool apply(GrRecordingContext* context, GrRenderTargetContext*, bool useHWAA,
177 bool hasUserStencilSettings, GrAppliedClip* out, SkRect* bounds) const override {
Robert Phillips9da87e02019-02-04 13:26:26 -0500178 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Mike Kleinf46d5ca2019-12-11 10:45:01 -0500179 out->addCoverageFP(std::make_unique<ClipFP>(context, proxyProvider, fTest, fAtlas));
Chris Dalton706a6ff2017-11-29 22:01:06 -0700180 return true;
181 }
182 bool quickContains(const SkRect&) const final { return false; }
183 bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; }
184 void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
Mike Reed92b33352019-08-24 19:39:13 -0400185 rect->setLTRB(0, 0, width, height);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700186 if (iior) {
187 *iior = false;
188 }
189 }
190
191 LazyProxyTest* const fTest;
192 GrTextureProxy* fAtlas;
193 };
194
195private:
196 skiatest::Reporter* fReporter;
197 bool fHasOpTexture;
198 bool fHasClipTexture;
199};
200
201DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
202 GrMockOptions mockOptions;
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400203 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fRenderability =
Brian Salomonbdecacf2018-02-02 20:32:49 -0500204 GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400205 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fTexturable = true;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700206 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500207 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700208 for (bool nullTexture : {false, true}) {
209 LazyProxyTest test(reporter);
Robert Phillips9da87e02019-02-04 13:26:26 -0500210 ctx->priv().addOnFlushCallbackObject(&test);
Greg Daniele20fcad2020-01-08 11:52:34 -0500211 auto rtc = GrRenderTargetContext::Make(
212 ctx.get(), GrColorType::kRGBA_8888, nullptr, SkBackingFit::kExact, {100, 100});
Chris Dalton706a6ff2017-11-29 22:01:06 -0700213 REPORTER_ASSERT(reporter, rtc);
Greg Daniele20fcad2020-01-08 11:52:34 -0500214 auto mockAtlas = GrRenderTargetContext::Make(
215 ctx.get(), GrColorType::kAlpha_F16, nullptr, SkBackingFit::kExact, {10, 10});
Chris Dalton706a6ff2017-11-29 22:01:06 -0700216 REPORTER_ASSERT(reporter, mockAtlas);
217 rtc->priv().testingOnly_addDrawOp(LazyProxyTest::Clip(&test, mockAtlas->asTextureProxy()),
Robert Phillips88a32ef2018-06-07 11:05:56 -0400218 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;
227 sk_sp<GrContext> ctx = GrContext::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,
235 GrRenderable::kNo, 1, GrMipMapped::kNo,
236 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) {
259 fValue = skstd::exchange(that.fValue, nullptr);
260 return *this;
261 }
262 TestCallback& operator=(const TestCallback& that) = delete;
263
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400264 LazyInstantiationResult operator()(GrResourceProvider* resourceProvider) const {
Brian Salomon67f01952019-02-14 13:05:25 -0500265 *fValue = 1;
Brian Salomonbeb7f522019-08-30 16:19:42 -0400266 return {fTexture, fReleaseCallback};
Brian Salomon67f01952019-02-14 13:05:25 -0500267 }
268
269 private:
270 int* fValue = nullptr;
Brian Salomonbeb7f522019-08-30 16:19:42 -0400271 bool fReleaseCallback;
272 sk_sp<GrTexture> fTexture;
Brian Salomon67f01952019-02-14 13:05:25 -0500273 };
Greg Danielce3ddaa2020-01-22 16:58:15 -0500274 GrSwizzle readSwizzle = caps->getReadSwizzle(format, GrColorType::kRGBA_8888);
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 Daniel3a365112020-02-14 10:47:18 -0500277 readSwizzle, GrRenderable::kNo, 1, GrMipMapped::kNo,
Greg Danielce3ddaa2020-01-22 16:58:15 -0500278 GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kNone,
279 SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo,
280 GrSurfaceProxy::UseAllocator::kYes);
Greg Daniel94a6ce82018-01-16 16:14:41 -0500281
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400282 REPORTER_ASSERT(reporter, proxy.get());
Greg Daniel457469c2018-02-08 15:05:44 -0500283 REPORTER_ASSERT(reporter, 0 == testCount);
284
285 if (doInstantiate) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500286 proxy->priv().doLazyInstantiation(ctx->priv().resourceProvider());
Brian Salomonbeb7f522019-08-30 16:19:42 -0400287 if (releaseCallback) {
288 // We will call the cleanup and delete the callback in the
Greg Daniel457469c2018-02-08 15:05:44 -0500289 // doLazyInstantiationCall.
290 REPORTER_ASSERT(reporter, -1 == testCount);
291 } else {
292 REPORTER_ASSERT(reporter, 1 == testCount);
293 }
294 proxy.reset();
295 REPORTER_ASSERT(reporter, -1 == testCount);
296 } else {
297 proxy.reset();
298 REPORTER_ASSERT(reporter, -1 == testCount);
299 }
Greg Daniel94a6ce82018-01-16 16:14:41 -0500300 }
301 }
302}
303
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500304class LazyFailedInstantiationTestOp : public GrDrawOp {
305public:
306 DEFINE_OP_CLASS_ID
307
Robert Phillips88a32ef2018-06-07 11:05:56 -0400308 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
309 GrProxyProvider* proxyProvider,
310 int* testExecuteValue,
311 bool shouldFailInstantiation) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500312 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400313
Greg Daniel4065d452018-11-16 15:43:41 -0500314 return pool->allocate<LazyFailedInstantiationTestOp>(context, 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 {
Chris Dalton7eb5c0f2019-05-23 15:15:47 -0600320 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
Greg Daniel4065d452018-11-16 15:43:41 -0500326 LazyFailedInstantiationTestOp(GrContext* ctx, GrProxyProvider* proxyProvider,
327 int* testExecuteValue, bool shouldFailInstantiation)
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500328 : INHERITED(ClassID())
329 , fTestExecuteValue(testExecuteValue) {
Brian Salomona56a7462020-02-07 14:17:25 -0500330 SkISize desc;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500331 desc.fWidth = kSize;
332 desc.fHeight = kSize;
Greg Daniel4065d452018-11-16 15:43:41 -0500333 GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -0400334 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
335 GrRenderable::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500336
Greg Danielce3ddaa2020-01-22 16:58:15 -0500337 GrSwizzle readSwizzle = ctx->priv().caps()->getReadSwizzle(
338 format, GrColorType::kRGBA_8888);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500339 fLazyProxy = proxyProvider->createLazyProxy(
Brian Salomon4eb38b72019-08-05 12:58:39 -0400340 [testExecuteValue, shouldFailInstantiation, desc,
Brian Salomonbeb7f522019-08-30 16:19:42 -0400341 format](GrResourceProvider* rp) -> GrSurfaceProxy::LazyCallbackResult {
Greg Daniel0a375db2018-02-01 12:21:39 -0500342 if (shouldFailInstantiation) {
343 *testExecuteValue = 1;
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400344 return {};
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500345 }
Brian Salomona90382f2019-09-17 09:01:56 -0400346 return {rp->createTexture(desc, format, GrRenderable::kNo, 1, GrMipMapped::kNo,
347 SkBudgeted::kNo, GrProtected::kNo),
Brian Salomonbeb7f522019-08-30 16:19:42 -0400348 true, GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
Brian Salomon2a4f9832018-03-03 22:43:43 -0500349 },
Greg Daniel3a365112020-02-14 10:47:18 -0500350 format, desc, readSwizzle, GrRenderable::kNo, 1, GrMipMapped::kNo,
351 GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kNone, SkBackingFit::kExact,
352 SkBudgeted::kNo, GrProtected::kNo, GrSurfaceProxy::UseAllocator::kYes);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500353
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400354 SkASSERT(fLazyProxy.get());
355
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500356 this->setBounds(SkRect::MakeIWH(kSize, kSize),
Greg Daniel5faf4742019-10-01 15:14:44 -0400357 HasAABloat::kNo, IsHairline::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500358 }
359
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500360 const char* name() const override { return "LazyFailedInstantiationTestOp"; }
361 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600362 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
363 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700364 return GrProcessorSet::EmptySetAnalysis();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500365 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500366 void onPrepare(GrOpFlushState*) override {}
Brian Salomon588cec72018-11-14 13:56:37 -0500367 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500368 *fTestExecuteValue = 2;
369 }
370
371 int* fTestExecuteValue;
Greg Danieldcf9ca12019-08-27 14:30:21 -0400372 sk_sp<GrTextureProxy> fLazyProxy;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500373
374 typedef GrDrawOp INHERITED;
375};
376
377// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
378// associated with.
379DEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) {
380 GrMockOptions mockOptions;
381 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500382 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500383 for (bool failInstantiation : {false, true}) {
Greg Daniele20fcad2020-01-08 11:52:34 -0500384 auto rtc = GrRenderTargetContext::Make(
385 ctx.get(), GrColorType::kRGBA_8888, nullptr, SkBackingFit::kExact, {100, 100});
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500386 REPORTER_ASSERT(reporter, rtc);
387
Brian Osman9a9baae2018-11-05 15:06:26 -0500388 rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xbaaaaaad),
389 GrRenderTargetContext::CanClearFullscreen::kYes);
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 Danielaa3dfbe2018-01-29 10:34:25 -0500394 ctx->flush();
395
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}