blob: ef5e727b1362e67842b7dbe3a597b91237103391 [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 Salomon4eb38b72019-08-05 12:58:39 -040087 [this, format, nullTexture](
Brian Salomonb6a3a3b2019-04-01 12:29:34 -040088 GrResourceProvider* rp) -> GrSurfaceProxy::LazyInstantiationResult {
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 Salomon4eb38b72019-08-05 12:58:39 -040099 desc, format, GrRenderable::kNo, 1, SkBudgeted::kYes,
100 GrProtected::kNo, GrResourceProvider::Flags::kNoPendingIO);
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,
106 kRGB_565_GrPixelConfig, *proxyProvider->caps());
Chris Dalton4c458b12018-06-16 17:22:59 -0600107
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 Dalton6ce447a2019-06-23 18:07:38 -0600114 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip* clip,
115 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700116 return GrProcessorSet::EmptySetAnalysis();
Chris Dalton706a6ff2017-11-29 22:01:06 -0700117 }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700118 void onPrepare(GrOpFlushState*) override {}
119
120 LazyProxyTest* const fTest;
121 sk_sp<GrTextureProxy> fProxy;
122 };
123
124 class ClipFP : public GrFragmentProcessor {
125 public:
Robert Phillips6f0e02f2019-02-13 11:02:28 -0500126 ClipFP(GrRecordingContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test,
Greg Daniel4065d452018-11-16 15:43:41 -0500127 GrTextureProxy* atlas)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700128 : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
Greg Daniel4065d452018-11-16 15:43:41 -0500129 , fContext(ctx)
Robert Phillips777707b2018-01-17 11:40:14 -0500130 , fProxyProvider(proxyProvider)
Chris Dalton706a6ff2017-11-29 22:01:06 -0700131 , fTest(test)
132 , fAtlas(atlas) {
Greg Daniel4065d452018-11-16 15:43:41 -0500133 const GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -0400134 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kAlpha_F16,
135 GrRenderable::kYes);
Chris Dalton4c458b12018-06-16 17:22:59 -0600136 fLazyProxy = GrProxyProvider::MakeFullyLazyProxy(
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400137 [this](GrResourceProvider* rp) -> GrSurfaceProxy::LazyInstantiationResult {
138 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
139 fTest->fHasClipTexture = true;
140 fAtlas->instantiate(rp);
141 return sk_ref_sp(fAtlas->peekTexture());
142 },
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400143 format, GrRenderable::kYes, 1, GrProtected::kNo, kBottomLeft_GrSurfaceOrigin,
144 kAlpha_half_GrPixelConfig, *proxyProvider->caps());
Chris Dalton706a6ff2017-11-29 22:01:06 -0700145 fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
Brian Salomone782f842018-07-31 13:53:11 -0400146 GrSamplerState::WrapMode::kClamp);
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 {
Greg Daniel4065d452018-11-16 15:43:41 -0500153 return skstd::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();
Greg Daniel4065d452018-11-16 15:43:41 -0500179 out->addCoverageFP(skstd::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 {
185 rect->set(0, 0, width, height);
186 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);
Brian Salomonbf6b9792019-08-21 09:38:10 -0400211 auto rtc = ctx->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact, 100, 100,
212 GrColorType::kRGBA_8888, nullptr);
Chris Dalton706a6ff2017-11-29 22:01:06 -0700213 REPORTER_ASSERT(reporter, rtc);
Brian Salomonbf6b9792019-08-21 09:38:10 -0400214 auto mockAtlas = ctx->priv().makeDeferredRenderTargetContext(
Brian Salomon27ae52c2019-07-03 11:27:44 -0400215 SkBackingFit::kExact, 10, 10, GrColorType::kAlpha_F16, nullptr);
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
231 GrSurfaceDesc desc;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500232 desc.fWidth = kSize;
233 desc.fHeight = kSize;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500234 desc.fConfig = kRGBA_8888_GrPixelConfig;
235
Robert Phillips0a15cc62019-07-30 12:49:10 -0400236 GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kRGBA_8888,
237 GrRenderable::kNo);
Greg Daniel4065d452018-11-16 15:43:41 -0500238
Greg Daniel457469c2018-02-08 15:05:44 -0500239 using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400240 using LazyInstantiationResult = GrSurfaceProxy::LazyInstantiationResult;
Greg Daniel94a6ce82018-01-16 16:14:41 -0500241 for (bool doInstantiate : {true, false}) {
Brian Salomon876a0172019-03-08 11:12:14 -0500242 for (auto lazyType : {LazyInstantiationType::kSingleUse,
243 LazyInstantiationType::kMultipleUse,
244 LazyInstantiationType::kDeinstantiate}) {
Greg Daniel457469c2018-02-08 15:05:44 -0500245 int testCount = 0;
Brian Salomon67f01952019-02-14 13:05:25 -0500246 // Sets an integer to 1 when the callback is called and -1 when it is deleted.
247 class TestCallback {
248 public:
249 TestCallback(int* value) : fValue(value) {}
250 TestCallback(const TestCallback& that) { SkASSERT(0); }
251 TestCallback(TestCallback&& that) : fValue(that.fValue) { that.fValue = nullptr; }
252
253 ~TestCallback() { fValue ? (void)(*fValue = -1) : void(); }
254
255 TestCallback& operator=(TestCallback&& that) {
256 fValue = skstd::exchange(that.fValue, nullptr);
257 return *this;
258 }
259 TestCallback& operator=(const TestCallback& that) = delete;
260
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400261 LazyInstantiationResult operator()(GrResourceProvider* resourceProvider) const {
Brian Salomon67f01952019-02-14 13:05:25 -0500262 *fValue = 1;
263 return {};
264 }
265
266 private:
267 int* fValue = nullptr;
268 };
Greg Daniel457469c2018-02-08 15:05:44 -0500269 sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400270 TestCallback(&testCount), format, desc, GrRenderable::kNo, 1,
Chris Dalton95d8ceb2019-07-30 11:17:59 -0600271 kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo, GrMipMapsStatus::kNotAllocated,
272 GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo,
273 GrProtected::kNo, lazyType);
Greg Daniel94a6ce82018-01-16 16:14:41 -0500274
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400275 REPORTER_ASSERT(reporter, proxy.get());
Greg Daniel457469c2018-02-08 15:05:44 -0500276 REPORTER_ASSERT(reporter, 0 == testCount);
277
278 if (doInstantiate) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500279 proxy->priv().doLazyInstantiation(ctx->priv().resourceProvider());
Greg Daniel457469c2018-02-08 15:05:44 -0500280 if (LazyInstantiationType::kSingleUse == proxy->priv().lazyInstantiationType()) {
281 // In SingleUse we will call the cleanup and delete the callback in the
282 // doLazyInstantiationCall.
283 REPORTER_ASSERT(reporter, -1 == testCount);
284 } else {
285 REPORTER_ASSERT(reporter, 1 == testCount);
286 }
287 proxy.reset();
288 REPORTER_ASSERT(reporter, -1 == testCount);
289 } else {
290 proxy.reset();
291 REPORTER_ASSERT(reporter, -1 == testCount);
292 }
Greg Daniel94a6ce82018-01-16 16:14:41 -0500293 }
294 }
295}
296
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500297class LazyFailedInstantiationTestOp : public GrDrawOp {
298public:
299 DEFINE_OP_CLASS_ID
300
Robert Phillips88a32ef2018-06-07 11:05:56 -0400301 static std::unique_ptr<GrDrawOp> Make(GrContext* context,
302 GrProxyProvider* proxyProvider,
303 int* testExecuteValue,
304 bool shouldFailInstantiation) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500305 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400306
Greg Daniel4065d452018-11-16 15:43:41 -0500307 return pool->allocate<LazyFailedInstantiationTestOp>(context, proxyProvider,
Robert Phillipsc994a932018-06-19 13:09:54 -0400308 testExecuteValue,
309 shouldFailInstantiation);
Robert Phillips88a32ef2018-06-07 11:05:56 -0400310 }
311
Chris Dalton1706cbf2019-05-21 19:35:29 -0600312 void visitProxies(const VisitProxyFunc& func) const override {
Chris Dalton7eb5c0f2019-05-23 15:15:47 -0600313 func(fLazyProxy.get(), GrMipMapped::kNo);
Robert Phillips88a32ef2018-06-07 11:05:56 -0400314 }
315
316private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400317 friend class GrOpMemoryPool; // for ctor
318
Greg Daniel4065d452018-11-16 15:43:41 -0500319 LazyFailedInstantiationTestOp(GrContext* ctx, GrProxyProvider* proxyProvider,
320 int* testExecuteValue, bool shouldFailInstantiation)
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500321 : INHERITED(ClassID())
322 , fTestExecuteValue(testExecuteValue) {
323 GrSurfaceDesc desc;
324 desc.fWidth = kSize;
325 desc.fHeight = kSize;
326 desc.fConfig = kRGBA_8888_GrPixelConfig;
Greg Daniel4065d452018-11-16 15:43:41 -0500327 GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -0400328 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
329 GrRenderable::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500330
331 fLazyProxy = proxyProvider->createLazyProxy(
Brian Salomon4eb38b72019-08-05 12:58:39 -0400332 [testExecuteValue, shouldFailInstantiation, desc,
333 format](GrResourceProvider* rp) -> GrSurfaceProxy::LazyInstantiationResult {
Greg Daniel0a375db2018-02-01 12:21:39 -0500334 if (shouldFailInstantiation) {
335 *testExecuteValue = 1;
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400336 return {};
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500337 }
Brian Salomon4eb38b72019-08-05 12:58:39 -0400338 return {rp->createTexture(desc, format, GrRenderable::kNo, 1, SkBudgeted::kNo,
Brian Salomone8a766b2019-07-19 14:24:36 -0400339 GrProtected::kNo,
Robert Phillips9313aa72019-04-09 18:41:27 -0400340 GrResourceProvider::Flags::kNoPendingIO),
Brian Salomon01ceae92019-04-02 11:49:54 -0400341 GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced};
Brian Salomon2a4f9832018-03-03 22:43:43 -0500342 },
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400343 format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
Chris Dalton95d8ceb2019-07-30 11:17:59 -0600344 GrMipMapsStatus::kNotAllocated, SkBackingFit::kExact, SkBudgeted::kNo,
345 GrProtected::kNo);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500346
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400347 SkASSERT(fLazyProxy.get());
348
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500349 this->setBounds(SkRect::MakeIWH(kSize, kSize),
350 HasAABloat::kNo, IsZeroArea::kNo);
351 }
352
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500353 const char* name() const override { return "LazyFailedInstantiationTestOp"; }
354 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600355 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
356 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700357 return GrProcessorSet::EmptySetAnalysis();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500358 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500359 void onPrepare(GrOpFlushState*) override {}
Brian Salomon588cec72018-11-14 13:56:37 -0500360 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500361 *fTestExecuteValue = 2;
362 }
363
364 int* fTestExecuteValue;
365 sk_sp<GrSurfaceProxy> fLazyProxy;
366
367 typedef GrDrawOp INHERITED;
368};
369
370// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
371// associated with.
372DEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) {
373 GrMockOptions mockOptions;
374 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500375 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500376 for (bool failInstantiation : {false, true}) {
Brian Salomonbf6b9792019-08-21 09:38:10 -0400377 auto rtc = ctx->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact, 100, 100,
378 GrColorType::kRGBA_8888, nullptr);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500379 REPORTER_ASSERT(reporter, rtc);
380
Brian Osman9a9baae2018-11-05 15:06:26 -0500381 rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xbaaaaaad),
382 GrRenderTargetContext::CanClearFullscreen::kYes);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500383
384 int executeTestValue = 0;
Robert Phillips88a32ef2018-06-07 11:05:56 -0400385 rtc->priv().testingOnly_addDrawOp(LazyFailedInstantiationTestOp::Make(
386 ctx.get(), proxyProvider, &executeTestValue, failInstantiation));
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500387 ctx->flush();
388
389 if (failInstantiation) {
Robert Phillips12c46292019-04-23 07:36:17 -0400390 REPORTER_ASSERT(reporter, 1 == executeTestValue);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500391 } else {
392 REPORTER_ASSERT(reporter, 2 == executeTestValue);
393 }
394 }
Greg Daniel4684f822018-03-08 15:27:36 -0500395}
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500396
Brian Salomon967df202018-12-07 11:15:53 -0500397class LazyDeinstantiateTestOp : public GrDrawOp {
Greg Daniel4684f822018-03-08 15:27:36 -0500398public:
399 DEFINE_OP_CLASS_ID
400
Robert Phillips88a32ef2018-06-07 11:05:56 -0400401 static std::unique_ptr<GrDrawOp> Make(GrContext* context, sk_sp<GrTextureProxy> proxy) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500402 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400403
Brian Salomon967df202018-12-07 11:15:53 -0500404 return pool->allocate<LazyDeinstantiateTestOp>(std::move(proxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500405 }
406
Chris Dalton1706cbf2019-05-21 19:35:29 -0600407 void visitProxies(const VisitProxyFunc& func) const override {
Chris Dalton7eb5c0f2019-05-23 15:15:47 -0600408 func(fLazyProxy.get(), GrMipMapped::kNo);
Greg Daniel4684f822018-03-08 15:27:36 -0500409 }
410
411private:
Robert Phillips7c525e62018-06-12 10:11:12 -0400412 friend class GrOpMemoryPool; // for ctor
413
Brian Salomon967df202018-12-07 11:15:53 -0500414 LazyDeinstantiateTestOp(sk_sp<GrTextureProxy> proxy)
415 : INHERITED(ClassID()), fLazyProxy(std::move(proxy)) {
Robert Phillips88a32ef2018-06-07 11:05:56 -0400416 this->setBounds(SkRect::MakeIWH(kSize, kSize), HasAABloat::kNo, IsZeroArea::kNo);
417 }
418
Brian Salomon967df202018-12-07 11:15:53 -0500419 const char* name() const override { return "LazyDeinstantiateTestOp"; }
Greg Daniel4684f822018-03-08 15:27:36 -0500420 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
Chris Dalton6ce447a2019-06-23 18:07:38 -0600421 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*,
422 bool hasMixedSampledCoverage, GrClampType) override {
Chris Dalton4b62aed2019-01-15 11:53:00 -0700423 return GrProcessorSet::EmptySetAnalysis();
Greg Daniel4684f822018-03-08 15:27:36 -0500424 }
Greg Daniel4684f822018-03-08 15:27:36 -0500425 void onPrepare(GrOpFlushState*) override {}
Brian Salomon588cec72018-11-14 13:56:37 -0500426 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {}
Greg Daniel4684f822018-03-08 15:27:36 -0500427
428 sk_sp<GrSurfaceProxy> fLazyProxy;
429
430 typedef GrDrawOp INHERITED;
431};
432
Brian Salomon967df202018-12-07 11:15:53 -0500433static void DeinstantiateReleaseProc(void* releaseValue) { (*static_cast<int*>(releaseValue))++; }
Greg Daniel4684f822018-03-08 15:27:36 -0500434
Brian Salomon967df202018-12-07 11:15:53 -0500435// Test that lazy proxies with the Deinstantiate LazyCallbackType are deinstantiated and released as
Greg Daniel4684f822018-03-08 15:27:36 -0500436// expected.
Brian Salomon967df202018-12-07 11:15:53 -0500437DEF_GPUTEST(LazyProxyDeinstantiateTest, reporter, /* options */) {
Greg Daniel4684f822018-03-08 15:27:36 -0500438 GrMockOptions mockOptions;
439 sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
Robert Phillips9da87e02019-02-04 13:26:26 -0500440 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
Greg Daniel4684f822018-03-08 15:27:36 -0500441
Greg Daniel4065d452018-11-16 15:43:41 -0500442 GrBackendFormat format =
Robert Phillips0a15cc62019-07-30 12:49:10 -0400443 ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
444 GrRenderable::kNo);
Greg Daniel4065d452018-11-16 15:43:41 -0500445
Greg Daniel4684f822018-03-08 15:27:36 -0500446 using LazyType = GrSurfaceProxy::LazyInstantiationType;
Brian Salomon876a0172019-03-08 11:12:14 -0500447 for (auto lazyType : {LazyType::kSingleUse, LazyType::kMultipleUse, LazyType::kDeinstantiate}) {
Brian Salomonbf6b9792019-08-21 09:38:10 -0400448 auto rtc = ctx->priv().makeDeferredRenderTargetContext(SkBackingFit::kExact, 100, 100,
449 GrColorType::kRGBA_8888, nullptr);
Greg Daniel4684f822018-03-08 15:27:36 -0500450 REPORTER_ASSERT(reporter, rtc);
451
Brian Osman9a9baae2018-11-05 15:06:26 -0500452 rtc->clear(nullptr, SkPMColor4f::FromBytes_RGBA(0xbaaaaaad),
453 GrRenderTargetContext::CanClearFullscreen::kYes);
Greg Daniel4684f822018-03-08 15:27:36 -0500454
455 int instantiateTestValue = 0;
456 int releaseTestValue = 0;
457 int* instantiatePtr = &instantiateTestValue;
458 int* releasePtr = &releaseTestValue;
459 GrSurfaceDesc desc;
460 desc.fWidth = kSize;
461 desc.fHeight = kSize;
462 desc.fConfig = kRGBA_8888_GrPixelConfig;
463
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400464 GrBackendTexture backendTex = ctx->createBackendTexture(
Robert Phillips80626792019-06-04 07:16:10 -0400465 kSize, kSize, kRGBA_8888_SkColorType, SkColors::kTransparent,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400466 GrMipMapped::kNo, GrRenderable::kNo, GrProtected::kNo);
Greg Daniel4684f822018-03-08 15:27:36 -0500467
468 sk_sp<GrTextureProxy> lazyProxy = proxyProvider->createLazyProxy(
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400469 [instantiatePtr, releasePtr,
470 backendTex](GrResourceProvider* rp) -> GrSurfaceProxy::LazyInstantiationResult {
Brian Salomonfa2ebea2019-01-24 15:58:58 -0500471 sk_sp<GrTexture> texture =
Robert Phillipsc80b0e92019-07-23 10:27:09 -0400472 rp->wrapBackendTexture(backendTex, GrColorType::kRGBA_8888,
473 kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
474 kRead_GrIOType);
Greg Daniel4684f822018-03-08 15:27:36 -0500475 if (!texture) {
Brian Salomonb6a3a3b2019-04-01 12:29:34 -0400476 return {};
Greg Daniel4684f822018-03-08 15:27:36 -0500477 }
478 (*instantiatePtr)++;
Brian Salomon967df202018-12-07 11:15:53 -0500479 texture->setRelease(DeinstantiateReleaseProc, releasePtr);
Brian Salomon9c73e3d2019-08-15 10:55:49 -0400480 return texture;
Greg Daniel4684f822018-03-08 15:27:36 -0500481 },
Brian Salomon27b4d8d2019-07-22 14:23:45 -0400482 format, desc, GrRenderable::kNo, 1, kTopLeft_GrSurfaceOrigin, GrMipMapped::kNo,
Chris Dalton95d8ceb2019-07-30 11:17:59 -0600483 GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kReadOnly,
484 SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, lazyType);
Greg Daniel4684f822018-03-08 15:27:36 -0500485
Greg Daniel92cbf3f2018-04-12 16:50:17 -0400486 REPORTER_ASSERT(reporter, lazyProxy.get());
487
Brian Salomon967df202018-12-07 11:15:53 -0500488 rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500489
490 ctx->flush();
491
492 REPORTER_ASSERT(reporter, 1 == instantiateTestValue);
Brian Salomon876a0172019-03-08 11:12:14 -0500493 if (LazyType::kDeinstantiate == lazyType) {
494 REPORTER_ASSERT(reporter, 1 == releaseTestValue);
495 } else {
496 REPORTER_ASSERT(reporter, 0 == releaseTestValue);
497 }
Greg Daniel4684f822018-03-08 15:27:36 -0500498
499 // This should cause the uninstantiate proxies to be instantiated again but have no effect
500 // on the others
Brian Salomon967df202018-12-07 11:15:53 -0500501 rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500502 // Add a second op to make sure we only instantiate once.
Brian Salomon967df202018-12-07 11:15:53 -0500503 rtc->priv().testingOnly_addDrawOp(LazyDeinstantiateTestOp::Make(ctx.get(), lazyProxy));
Greg Daniel4684f822018-03-08 15:27:36 -0500504 ctx->flush();
505
Brian Salomon876a0172019-03-08 11:12:14 -0500506 if (LazyType::kDeinstantiate == lazyType) {
507 REPORTER_ASSERT(reporter, 2 == instantiateTestValue);
508 REPORTER_ASSERT(reporter, 2 == releaseTestValue);
509 } else {
510 REPORTER_ASSERT(reporter, 1 == instantiateTestValue);
511 REPORTER_ASSERT(reporter, 0 == releaseTestValue);
512 }
Greg Daniel4684f822018-03-08 15:27:36 -0500513
514 lazyProxy.reset();
Brian Salomon876a0172019-03-08 11:12:14 -0500515 if (LazyType::kDeinstantiate == lazyType) {
516 REPORTER_ASSERT(reporter, 2 == releaseTestValue);
517 } else {
518 REPORTER_ASSERT(reporter, 1 == releaseTestValue);
519 }
Greg Daniel4684f822018-03-08 15:27:36 -0500520
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400521 ctx->deleteBackendTexture(backendTex);
Greg Daniel4684f822018-03-08 15:27:36 -0500522 }
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500523}