blob: 120f85e7b9cfd938134cb3619a824895bc3fb824 [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"
13#include "src/core/SkMakeUnique.h"
14#include "src/core/SkRectPriv.h"
15#include "src/gpu/GrClip.h"
16#include "src/gpu/GrContextPriv.h"
17#include "src/gpu/GrMemoryPool.h"
18#include "src/gpu/GrOnFlushResourceProvider.h"
19#include "src/gpu/GrProxyProvider.h"
20#include "src/gpu/GrRecordingContextPriv.h"
21#include "src/gpu/GrRenderTargetContext.h"
22#include "src/gpu/GrRenderTargetContextPriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040023#include "src/gpu/GrSurfaceProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "src/gpu/GrSurfaceProxyPriv.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040025#include "src/gpu/GrTextureProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "src/gpu/GrTextureProxyPriv.h"
27#include "src/gpu/mock/GrMockGpu.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070028
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
Chris Daltonc4b47352019-08-23 10:10:36 -060045 void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int) override {
Chris Dalton706a6ff2017-11-29 22:01:06 -070046 REPORTER_ASSERT(fReporter, !fHasOpTexture);
47 REPORTER_ASSERT(fReporter, !fHasClipTexture);
48 }
49
Greg Danielf41b2bd2019-08-22 16:19:24 -040050 void postFlush(GrDeferredUploadToken, const uint32_t* opsTaskIDs, int numOpsTaskIDs) override {
Chris Dalton706a6ff2017-11-29 22:01:06 -070051 REPORTER_ASSERT(fReporter, fHasOpTexture);
52 REPORTER_ASSERT(fReporter, fHasClipTexture);
53 }
54
55 class Op final : public GrDrawOp {
56 public:
57 DEFINE_OP_CLASS_ID
58
Robert Phillips6f0e02f2019-02-13 11:02:28 -050059 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* context,
Robert Phillips88a32ef2018-06-07 11:05:56 -040060 GrProxyProvider* proxyProvider,
61 LazyProxyTest* test,
62 bool nullTexture) {
Robert Phillips9da87e02019-02-04 13:26:26 -050063 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -040064
Greg Daniel4065d452018-11-16 15:43:41 -050065 return pool->allocate<Op>(context, proxyProvider, test, nullTexture);
Robert Phillips88a32ef2018-06-07 11:05:56 -040066 }
67
Chris Dalton1706cbf2019-05-21 19:35:29 -060068 void visitProxies(const VisitProxyFunc& func) const override {
Chris Dalton7eb5c0f2019-05-23 15:15:47 -060069 func(fProxy.get(), GrMipMapped::kNo);
Robert Phillips88a32ef2018-06-07 11:05:56 -040070 }
71
Brian Salomon588cec72018-11-14 13:56:37 -050072 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override {
Robert Phillips88a32ef2018-06-07 11:05:56 -040073 REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture);
74 REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture);
75 }
76
77 private:
Robert Phillips7c525e62018-06-12 10:11:12 -040078 friend class GrOpMemoryPool; // for ctor
79
Robert Phillips6f0e02f2019-02-13 11:02:28 -050080 Op(GrRecordingContext* ctx, GrProxyProvider* proxyProvider,
81 LazyProxyTest* test, bool nullTexture)
Robert Phillips777707b2018-01-17 11:40:14 -050082 : GrDrawOp(ClassID()), fTest(test) {
Greg Daniel4065d452018-11-16 15:43:41 -050083 const GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -040084 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kBGR_565,
85 GrRenderable::kNo);
Chris Dalton4c458b12018-06-16 17:22:59 -060086 fProxy = GrProxyProvider::MakeFullyLazyProxy(
Brian Salomonbeb7f522019-08-30 16:19:42 -040087 [this, format,
88 nullTexture](GrResourceProvider* rp) -> GrSurfaceProxy::LazyCallbackResult {
Chris Dalton4c458b12018-06-16 17:22:59 -060089 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
90 fTest->fHasOpTexture = true;
91 if (nullTexture) {
Brian Salomonb6a3a3b2019-04-01 12:29:34 -040092 return {};
Chris Dalton4c458b12018-06-16 17:22:59 -060093 } else {
94 GrSurfaceDesc desc;
95 desc.fWidth = 1234;
96 desc.fHeight = 567;
97 desc.fConfig = kRGB_565_GrPixelConfig;
Brian Salomone8a766b2019-07-19 14:24:36 -040098 sk_sp<GrTexture> texture = rp->createTexture(
Brian Salomona90382f2019-09-17 09:01:56 -040099 desc, format, GrRenderable::kNo, 1, GrMipMapped::kNo,
100 SkBudgeted::kYes, GrProtected::kNo);
Chris Dalton4c458b12018-06-16 17:22:59 -0600101 REPORTER_ASSERT(fTest->fReporter, texture);
Brian Salomon9c73e3d2019-08-15 10:55:49 -0400102 return texture;
Chris Dalton4c458b12018-06-16 17:22:59 -0600103 }
104 },
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400105 format, GrRenderable::kNo, 1, GrProtected::kNo, kTopLeft_GrSurfaceOrigin,
Brian Salomonbeb7f522019-08-30 16:19:42 -0400106 kRGB_565_GrPixelConfig, *proxyProvider->caps(),
107 GrSurfaceProxy::UseAllocator::kYes);
Chris Dalton4c458b12018-06-16 17:22:59 -0600108
109 this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo,
Greg Daniel5faf4742019-10-01 15:14:44 -0400110 GrOp::IsHairline::kNo);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700111 }
112
Chris Dalton706a6ff2017-11-29 22:01:06 -0700113 const char* name() const override { return "LazyProxyTest::Op"; }
114 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600115 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip* clip,
116 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700117 return GrProcessorSet::EmptySetAnalysis();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700118 }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700119 void onPrepare(GrOpFlushState*) override {}
120
121 LazyProxyTest* const fTest;
122 sk_sp<GrTextureProxy> fProxy;
123 };
124
125 class ClipFP : public GrFragmentProcessor {
126 public:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500127 ClipFP(GrRecordingContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test,
Greg Daniel4065d452018-11-16 15:43:41 -0500128 GrTextureProxy* atlas)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700129 : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
Greg Daniel4065d452018-11-16 15:43:41 -0500130 , fContext(ctx)
Robert Phillips777707b2018-01-17 11:40:14 -0500131 , fProxyProvider(proxyProvider)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700132 , fTest(test)
133 , fAtlas(atlas) {
Greg Daniel4065d452018-11-16 15:43:41 -0500134 const GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -0400135 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kAlpha_F16,
136 GrRenderable::kYes);
Chris Dalton4c458b12018-06-16 17:22:59 -0600137 fLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
Brian Salomonbeb7f522019-08-30 16:19:42 -0400138 [this](GrResourceProvider* rp) -> GrSurfaceProxy::LazyCallbackResult {
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400139 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
140 fTest->fHasClipTexture = true;
141 fAtlas->instantiate(rp);
142 return sk_ref_sp(fAtlas->peekTexture());
143 },
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400144 format, GrRenderable::kYes, 1, GrProtected::kNo, kBottomLeft_GrSurfaceOrigin,
Brian Salomonbeb7f522019-08-30 16:19:42 -0400145 kAlpha_half_GrPixelConfig, *proxyProvider->caps(),
146 GrSurfaceProxy::UseAllocator::kYes);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700147 fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
Brian Salomone782f842018-07-31 13:53:11 -0400148 GrSamplerState::WrapMode::kClamp);
Brian Salomonf7dcd762018-07-30 14:48:15 -0400149 this->setTextureSamplerCnt(1);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700150 }
151
152 private:
153 const char* name() const override { return "LazyProxyTest::ClipFP"; }
154 std::unique_ptr<GrFragmentProcessor> clone() const override {
Greg Daniel4065d452018-11-16 15:43:41 -0500155 return skstd::make_unique<ClipFP>(fContext, fProxyProvider, fTest, fAtlas);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700156 }
157 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
158 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
159 bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
Brian Salomonf7dcd762018-07-30 14:48:15 -0400160 const TextureSampler& onTextureSampler(int) const override { return fAccess; }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700161
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500162 GrRecordingContext* const fContext;
Robert Phillips777707b2018-01-17 11:40:14 -0500163 GrProxyProvider* const fProxyProvider;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700164 LazyProxyTest* const fTest;
165 GrTextureProxy* const fAtlas;
166 sk_sp<GrTextureProxy> fLazyProxy;
167 TextureSampler fAccess;
168 };
169
170
171 class Clip : public GrClip {
172 public:
173 Clip(LazyProxyTest* test, GrTextureProxy* atlas)
174 : fTest(test)
175 , fAtlas(atlas) {}
176
177 private:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500178 bool apply(GrRecordingContext* context, GrRenderTargetContext*, bool useHWAA,
179 bool hasUserStencilSettings, GrAppliedClip* out, SkRect* bounds) const override {
Robert Phillips9da87e02019-02-04 13:26:26 -0500180 GrProxyProvider* proxyProvider = context->priv().proxyProvider();
Greg Daniel4065d452018-11-16 15:43:41 -0500181 out->addCoverageFP(skstd::make_unique<ClipFP>(context, proxyProvider, fTest, fAtlas));
Chris Dalton706a6ff2017-11-29 22:01:06 -0700182 return true;
183 }
184 bool quickContains(const SkRect&) const final { return false; }
185 bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; }
186 void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
Mike Reed92b33352019-08-24 19:39:13 -0400187 rect->setLTRB(0, 0, width, height);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700188 if (iior) {
189 *iior = false;
190 }
191 }
192
193 LazyProxyTest* const fTest;
194 GrTextureProxy* fAtlas;
195 };
196
197private:
198 skiatest::Reporter* fReporter;
199 bool fHasOpTexture;
200 bool fHasClipTexture;
201};
202
203DEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
204 GrMockOptions mockOptions;
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400205 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fRenderability =
Brian Salomonbdecacf2018-02-02 20:32:49 -0500206 GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
Robert Phillipsa5e78be2019-07-09 12:34:38 -0400207 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fTexturable = true;
Chris Dalton706a6ff2017-11-29 22:01:06 -0700208 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500209 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700210 for (bool nullTexture : {false, true}) {
211 LazyProxyTest test(reporter);
Robert Phillips9da87e02019-02-04 13:26:26 -0500212 ctx->priv().addOnFlushCallbackObject(&test);
Brian Salomonbf6b9792019-08-21 09:38:10 -0400213 auto rtc = ctx->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact, 100, 100,
214 GrColorType::kRGBA_8888, nullptr);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700215 REPORTER_ASSERT(reporter, rtc);
Brian Salomonbf6b9792019-08-21 09:38:10 -0400216 auto mockAtlas = ctx->priv().makeDeferredRenderTargetContext(
Brian Salomon27ae52c2019-07-03 11:27:44 -0400217 SkBackingFit::kExact, 10, 10, GrColorType::kAlpha_F16, nullptr);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700218 REPORTER_ASSERT(reporter, mockAtlas);
219 rtc->priv().testingOnly_addDrawOp(LazyProxyTest::Clip(&test, mockAtlas->asTextureProxy()),
Robert Phillips88a32ef2018-06-07 11:05:56 -0400220 LazyProxyTest::Op::Make(ctx.get(), proxyProvider, &test, nullTexture));
Robert Phillips9da87e02019-02-04 13:26:26 -0500221 ctx->priv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700222 }
223}
224
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500225static const int kSize = 16;
226
Greg Daniel94a6ce82018-01-16 16:14:41 -0500227DEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) {
228 GrMockOptions mockOptions;
229 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500230 auto proxyProvider = ctx->priv().proxyProvider();
Robert Phillips0a15cc62019-07-30 12:49:10 -0400231 const GrCaps* caps = ctx->priv().caps();
Greg Daniel94a6ce82018-01-16 16:14:41 -0500232
233 GrSurfaceDesc desc;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500234 desc.fWidth = kSize;
235 desc.fHeight = kSize;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500236 desc.fConfig = kRGBA_8888_GrPixelConfig;
237
Robert Phillips0a15cc62019-07-30 12:49:10 -0400238 GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kRGBA_8888,
239 GrRenderable::kNo);
Greg Daniel4065d452018-11-16 15:43:41 -0500240
Brian Salomonbeb7f522019-08-30 16:19:42 -0400241 auto tex = ctx->priv().resourceProvider()->createTexture(desc, format, GrRenderable::kNo, 1,
Brian Salomona90382f2019-09-17 09:01:56 -0400242 GrMipMapped::kNo, SkBudgeted::kNo,
243 GrProtected::kNo);
Brian Salomonbeb7f522019-08-30 16:19:42 -0400244 using LazyInstantiationResult = GrSurfaceProxy::LazyCallbackResult;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500245 for (bool doInstantiate : {true, false}) {
Brian Salomonbeb7f522019-08-30 16:19:42 -0400246 for (bool releaseCallback : {false, true}) {
Greg Daniel457469c2018-02-08 15:05:44 -0500247 int testCount = 0;
Brian Salomon67f01952019-02-14 13:05:25 -0500248 // Sets an integer to 1 when the callback is called and -1 when it is deleted.
249 class TestCallback {
250 public:
Brian Salomonbeb7f522019-08-30 16:19:42 -0400251 TestCallback(int* value, bool releaseCallback, sk_sp<GrTexture> tex)
252 : fValue(value)
253 , fReleaseCallback(releaseCallback)
254 , fTexture(std::move(tex)) {}
Brian Salomon67f01952019-02-14 13:05:25 -0500255 TestCallback(const TestCallback& that) { SkASSERT(0); }
Brian Salomonbeb7f522019-08-30 16:19:42 -0400256 TestCallback(TestCallback&& that)
257 : fValue(that.fValue)
258 , fReleaseCallback(that.fReleaseCallback)
259 , fTexture(std::move(that.fTexture)) {
260 that.fValue = nullptr;
261 }
Brian Salomon67f01952019-02-14 13:05:25 -0500262
263 ~TestCallback() { fValue ? (void)(*fValue = -1) : void(); }
264
265 TestCallback& operator=(TestCallback&& that) {
266 fValue = skstd::exchange(that.fValue, nullptr);
267 return *this;
268 }
269 TestCallback& operator=(const TestCallback& that) = delete;
270
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400271 LazyInstantiationResult operator()(GrResourceProvider* resourceProvider) const {
Brian Salomon67f01952019-02-14 13:05:25 -0500272 *fValue = 1;
Brian Salomonbeb7f522019-08-30 16:19:42 -0400273 return {fTexture, fReleaseCallback};
Brian Salomon67f01952019-02-14 13:05:25 -0500274 }
275
276 private:
277 int* fValue = nullptr;
Brian Salomonbeb7f522019-08-30 16:19:42 -0400278 bool fReleaseCallback;
279 sk_sp<GrTexture> fTexture;
Brian Salomon67f01952019-02-14 13:05:25 -0500280 };
Greg Daniel457469c2018-02-08 15:05:44 -0500281 sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
Brian Salomonbeb7f522019-08-30 16:19:42 -0400282 TestCallback(&testCount, releaseCallback, tex), format, desc, GrRenderable::kNo,
283 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrMipMapsStatus::kNotAllocated,
Chris Dalton95d8ceb2019-07-30 11:17:59 -0600284 GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo,
Brian Salomonbeb7f522019-08-30 16:19:42 -0400285 GrProtected::kNo, GrSurfaceProxy::UseAllocator::kYes);
Greg Daniel94a6ce82018-01-16 16:14:41 -0500286
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400287 REPORTER_ASSERT(reporter, proxy.get());
Greg Daniel457469c2018-02-08 15:05:44 -0500288 REPORTER_ASSERT(reporter, 0 == testCount);
289
290 if (doInstantiate) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500291 proxy->priv().doLazyInstantiation(ctx->priv().resourceProvider());
Brian Salomonbeb7f522019-08-30 16:19:42 -0400292 if (releaseCallback) {
293 // We will call the cleanup and delete the callback in the
Greg Daniel457469c2018-02-08 15:05:44 -0500294 // doLazyInstantiationCall.
295 REPORTER_ASSERT(reporter, -1 == testCount);
296 } else {
297 REPORTER_ASSERT(reporter, 1 == testCount);
298 }
299 proxy.reset();
300 REPORTER_ASSERT(reporter, -1 == testCount);
301 } else {
302 proxy.reset();
303 REPORTER_ASSERT(reporter, -1 == testCount);
304 }
Greg Daniel94a6ce82018-01-16 16:14:41 -0500305 }
306 }
307}
308
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500309class LazyFailedInstantiationTestOp : public GrDrawOp {
310public:
311 DEFINE_OP_CLASS_ID
312
Robert Phillips88a32ef2018-06-07 11:05:56 -0400313 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
314 GrProxyProvider* proxyProvider,
315 int* testExecuteValue,
316 bool shouldFailInstantiation) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500317 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400318
Greg Daniel4065d452018-11-16 15:43:41 -0500319 return pool->allocate<LazyFailedInstantiationTestOp>(context, proxyProvider,
Robert Phillipsc994a932018-06-19 13:09:54 -0400320 testExecuteValue,
321 shouldFailInstantiation);
Robert Phillips88a32ef2018-06-07 11:05:56 -0400322 }
323
Chris Dalton1706cbf2019-05-21 19:35:29 -0600324 void visitProxies(const VisitProxyFunc& func) const override {
Chris Dalton7eb5c0f2019-05-23 15:15:47 -0600325 func(fLazyProxy.get(), GrMipMapped::kNo);
Robert Phillips88a32ef2018-06-07 11:05:56 -0400326 }
327
328private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400329 friend class GrOpMemoryPool; // for ctor
330
Greg Daniel4065d452018-11-16 15:43:41 -0500331 LazyFailedInstantiationTestOp(GrContext* ctx, GrProxyProvider* proxyProvider,
332 int* testExecuteValue, bool shouldFailInstantiation)
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500333 : INHERITED(ClassID())
334 , fTestExecuteValue(testExecuteValue) {
335 GrSurfaceDesc desc;
336 desc.fWidth = kSize;
337 desc.fHeight = kSize;
338 desc.fConfig = kRGBA_8888_GrPixelConfig;
Greg Daniel4065d452018-11-16 15:43:41 -0500339 GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -0400340 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
341 GrRenderable::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500342
343 fLazyProxy = proxyProvider->createLazyProxy(
Brian Salomon4eb38b72019-08-05 12:58:39 -0400344 [testExecuteValue, shouldFailInstantiation, desc,
Brian Salomonbeb7f522019-08-30 16:19:42 -0400345 format](GrResourceProvider* rp) -> GrSurfaceProxy::LazyCallbackResult {
Greg Daniel0a375db2018-02-01 12:21:39 -0500346 if (shouldFailInstantiation) {
347 *testExecuteValue = 1;
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400348 return {};
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500349 }
Brian Salomona90382f2019-09-17 09:01:56 -0400350 return {rp->createTexture(desc, format, GrRenderable::kNo, 1, GrMipMapped::kNo,
351 SkBudgeted::kNo, GrProtected::kNo),
Brian Salomonbeb7f522019-08-30 16:19:42 -0400352 true, GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
Brian Salomon2a4f9832018-03-03 22:43:43 -0500353 },
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400354 format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
Brian Salomonbeb7f522019-08-30 16:19:42 -0400355 GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kNone, SkBackingFit::kExact,
356 SkBudgeted::kNo, GrProtected::kNo, GrSurfaceProxy::UseAllocator::kYes);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500357
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400358 SkASSERT(fLazyProxy.get());
359
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500360 this->setBounds(SkRect::MakeIWH(kSize, kSize),
Greg Daniel5faf4742019-10-01 15:14:44 -0400361 HasAABloat::kNo, IsHairline::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500362 }
363
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500364 const char* name() const override { return "LazyFailedInstantiationTestOp"; }
365 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600366 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
367 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700368 return GrProcessorSet::EmptySetAnalysis();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500369 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500370 void onPrepare(GrOpFlushState*) override {}
Brian Salomon588cec72018-11-14 13:56:37 -0500371 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500372 *fTestExecuteValue = 2;
373 }
374
375 int* fTestExecuteValue;
Greg Danieldcf9ca12019-08-27 14:30:21 -0400376 sk_sp<GrTextureProxy> fLazyProxy;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500377
378 typedef GrDrawOp INHERITED;
379};
380
381// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
382// associated with.
383DEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) {
384 GrMockOptions mockOptions;
385 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500386 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500387 for (bool failInstantiation : {false, true}) {
Brian Salomonbf6b9792019-08-21 09:38:10 -0400388 auto rtc = ctx->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact, 100, 100,
389 GrColorType::kRGBA_8888, nullptr);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500390 REPORTER_ASSERT(reporter, rtc);
391
Brian Osman9a9baae2018-11-05 15:06:26 -0500392 rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xbaaaaaad),
393 GrRenderTargetContext::CanClearFullscreen::kYes);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500394
395 int executeTestValue = 0;
Robert Phillips88a32ef2018-06-07 11:05:56 -0400396 rtc->priv().testingOnly_addDrawOp(LazyFailedInstantiationTestOp::Make(
397 ctx.get(), proxyProvider, &executeTestValue, failInstantiation));
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500398 ctx->flush();
399
400 if (failInstantiation) {
Robert Phillips12c46292019-04-23 07:36:17 -0400401 REPORTER_ASSERT(reporter, 1 == executeTestValue);
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}