Flutter Engine
The Flutter Engine
LazyProxyTest.cpp
Go to the documentation of this file.
1/*
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
10#include "include/core/SkRect.h"
12#include "include/core/SkSize.h"
20#include "include/gpu/GrTypes.h"
24#include "src/core/SkRectPriv.h"
25#include "src/gpu/AtlasTypes.h"
27#include "src/gpu/Swizzle.h"
48#include "tests/Test.h"
49
50#include <functional>
51#include <initializer_list>
52#include <memory>
53#include <utility>
54
55class GrDstProxyView;
56class GrOpFlushState;
58enum class GrXferBarrierFlags;
59namespace skgpu { class KeyBuilder; }
60struct GrShaderCaps;
61
62// This test verifies that lazy proxy callbacks get invoked during flush, after onFlush callbacks,
63// but before Ops are executed. It also ensures that lazy proxy callbacks are invoked both for
64// regular Ops and for clips.
66public:
68 : fReporter(reporter)
69 , fHasOpTexture(false)
70 , fHasClipTexture(false) {
71 }
72
73 ~LazyProxyTest() override {
74 REPORTER_ASSERT(fReporter, fHasOpTexture);
75 REPORTER_ASSERT(fReporter, fHasClipTexture);
76 }
77
78 bool preFlush(GrOnFlushResourceProvider* onFlushRP) override {
79#if defined(GR_TEST_UTILS)
80 if (onFlushRP->failFlushTimeCallbacks()) {
81 return false;
82 }
83#endif
84
85 REPORTER_ASSERT(fReporter, !fHasOpTexture);
86 REPORTER_ASSERT(fReporter, !fHasClipTexture);
87 return true;
88 }
89
91 REPORTER_ASSERT(fReporter, fHasOpTexture);
92 REPORTER_ASSERT(fReporter, fHasClipTexture);
93 }
94
95 class Op final : public GrDrawOp {
96 public:
98
100 GrProxyProvider* proxyProvider,
102 bool nullTexture) {
103 return GrOp::Make<Op>(context, context, proxyProvider, test, nullTexture);
104 }
105
106 void visitProxies(const GrVisitProxyFunc& func) const override {
107 func(fProxy.get(), skgpu::Mipmapped::kNo);
108 }
109
110 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override {
111 REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture);
112 REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture);
113 }
114
115 private:
116 friend class GrOp; // for ctor
117
118 Op(GrRecordingContext* ctx, GrProxyProvider* proxyProvider,
119 LazyProxyTest* test, bool nullTexture)
120 : GrDrawOp(ClassID()), fTest(test) {
121 const GrBackendFormat format =
125 [this, nullTexture](GrResourceProvider* rp,
128 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
129 fTest->fHasOpTexture = true;
130 if (nullTexture) {
131 return {};
132 } else {
133 static constexpr SkISize kDimensions = {1234, 567};
134 sk_sp<GrTexture> texture = rp->createTexture(kDimensions,
135 desc.fFormat,
136 desc.fTextureType,
137 desc.fRenderable,
138 desc.fSampleCnt,
139 desc.fMipmapped,
140 desc.fBudgeted,
141 desc.fProtected,
142 /*label=*/{});
143 REPORTER_ASSERT(fTest->fReporter, texture);
144 return texture;
145 }
146 },
147 format, GrRenderable::kNo, 1, GrProtected::kNo, *proxyProvider->caps(),
149
152 }
153
154 const char* name() const override { return "LazyProxyTest::Op"; }
155 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
156 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip* clip,
157 GrClampType) override {
159 }
161 const GrSurfaceProxyView& writeView,
163 const GrDstProxyView&,
164 GrXferBarrierFlags renderPassXferBarriers,
165 GrLoadOp colorLoadOp) override {}
166
167 void onPrepare(GrOpFlushState*) override {}
168
169 LazyProxyTest* const fTest;
171 };
172
174 public:
178 , fContext(ctx)
179 , fProxyProvider(proxyProvider)
180 , fTest(test)
181 , fAtlas(atlas) {
183 static const GrSurfaceOrigin kOrigin = kBottomLeft_GrSurfaceOrigin;
184 const GrBackendFormat format =
186 skgpu::Swizzle readSwizzle = ctx->priv().caps()->getReadSwizzle(format, kColorType);
190 REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
191 fTest->fHasClipTexture = true;
192 fAtlas->instantiate(rp);
193 return sk_ref_sp(fAtlas->peekTexture());
194 },
195 format, GrRenderable::kYes, 1, GrProtected::kNo, *proxyProvider->caps(),
197 auto atlasEffect = GrTextureEffect::Make({fLazyProxy, kOrigin, readSwizzle},
199 this->registerChild(std::move(atlasEffect));
200 }
201
202 private:
203 const char* name() const override { return "LazyProxyTest::ClipFP"; }
204 std::unique_ptr<GrFragmentProcessor> clone() const override {
205 return std::make_unique<ClipFP>(fContext, fProxyProvider, fTest, fAtlas);
206 }
207 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override {
208 return nullptr;
209 }
210 void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override {}
211 bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
212
213 GrRecordingContext* const fContext;
214 GrProxyProvider* const fProxyProvider;
215 LazyProxyTest* const fTest;
216 GrTextureProxy* const fAtlas;
217 sk_sp<GrTextureProxy> fLazyProxy;
218 };
219
220
221 class Clip : public GrClip {
222 public:
224 : fTest(test)
225 , fAtlas(atlas) {}
226
227 private:
228 SkIRect getConservativeBounds() const final {
229 return SkIRect::MakeSize(fAtlas->dimensions());
230 }
231 Effect apply(GrRecordingContext* rContext,
233 GrDrawOp*,
234 GrAAType,
236 SkRect* bounds) const override {
237 GrProxyProvider* proxyProvider = rContext->priv().proxyProvider();
238 out->addCoverageFP(std::make_unique<ClipFP>(rContext, proxyProvider, fTest, fAtlas));
239 return Effect::kClipped;
240 }
241
242 LazyProxyTest* const fTest;
243 GrTextureProxy* fAtlas;
244 };
245
246private:
247 skiatest::Reporter* fReporter;
248 bool fHasOpTexture;
249 bool fHasClipTexture;
250};
251
253 GrMockOptions mockOptions;
254 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fRenderability =
255 GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
256 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fTexturable = true;
258 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
259 for (bool nullTexture : {false, true}) {
264 nullptr,
266 {100, 100},
268 /*label=*/{});
270 auto mockAtlas = skgpu::ganesh::SurfaceDrawContext::Make(ctx.get(),
272 nullptr,
274 {10, 10},
276 /*label=*/{});
277 REPORTER_ASSERT(reporter, mockAtlas);
278 LazyProxyTest::Clip clip(&test, mockAtlas->asTextureProxy());
279 sdc->addDrawOp(&clip,
280 LazyProxyTest::Op::Make(ctx.get(), proxyProvider, &test, nullTexture));
281 ctx->priv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test);
282 }
283}
284
285static const int kSize = 16;
286
287DEF_GANESH_TEST(LazyProxyReleaseTest, reporter, /* options */, CtsEnforcement::kApiLevel_T) {
288 GrMockOptions mockOptions;
290 auto proxyProvider = ctx->priv().proxyProvider();
291 const GrCaps* caps = ctx->priv().caps();
292
295
296 auto tex = ctx->priv().resourceProvider()->createTexture({kSize, kSize},
297 format,
300 1,
304 /*label=*/{});
305 using LazyInstantiationResult = GrSurfaceProxy::LazyCallbackResult;
306 for (bool doInstantiate : {true, false}) {
307 for (bool releaseCallback : {false, true}) {
308 int testCount = 0;
309 // Sets an integer to 1 when the callback is called and -1 when it is deleted.
310 class TestCallback {
311 public:
312 TestCallback(int* value, bool releaseCallback, sk_sp<GrTexture> tex)
313 : fValue(value)
314 , fReleaseCallback(releaseCallback)
315 , fTexture(std::move(tex)) {}
316 TestCallback(const TestCallback& that) { SkASSERT(0); }
317 TestCallback(TestCallback&& that)
318 : fValue(that.fValue)
319 , fReleaseCallback(that.fReleaseCallback)
320 , fTexture(std::move(that.fTexture)) {
321 that.fValue = nullptr;
322 }
323
324 ~TestCallback() { fValue ? (void)(*fValue = -1) : void(); }
325
326 TestCallback& operator=(TestCallback&& that) {
327 fValue = std::exchange(that.fValue, nullptr);
328 return *this;
329 }
330 TestCallback& operator=(const TestCallback& that) = delete;
331
332 LazyInstantiationResult operator()(GrResourceProvider*,
333 const GrSurfaceProxy::LazySurfaceDesc&) const {
334 *fValue = 1;
335 return {fTexture, fReleaseCallback};
336 }
337
338 private:
339 int* fValue = nullptr;
340 bool fReleaseCallback;
341 sk_sp<GrTexture> fTexture;
342 };
344 proxyProvider->createLazyProxy(TestCallback(&testCount, releaseCallback, tex),
345 format,
346 {kSize, kSize},
354 /*label=*/{});
355
356 REPORTER_ASSERT(reporter, proxy.get());
358
359 if (doInstantiate) {
361 if (releaseCallback) {
362 // We will call the cleanup and delete the callback in the
363 // doLazyInstantiationCall.
365 } else {
367 }
368 proxy.reset();
370 } else {
371 proxy.reset();
373 }
374 }
375 }
376}
377
379public:
381
383 GrProxyProvider* proxyProvider,
384 int* testExecuteValue,
385 bool shouldFailInstantiation) {
386 return GrOp::Make<LazyFailedInstantiationTestOp>(rContext,
387 rContext->priv().caps(),
388 proxyProvider,
389 testExecuteValue,
390 shouldFailInstantiation);
391 }
392
393 void visitProxies(const GrVisitProxyFunc& func) const override {
394 func(fLazyProxy.get(), skgpu::Mipmapped::kNo);
395 }
396
397private:
398 friend class GrOp; // for ctor
399
400 LazyFailedInstantiationTestOp(const GrCaps* caps, GrProxyProvider* proxyProvider,
401 int* testExecuteValue, bool shouldFailInstantiation)
402 : INHERITED(ClassID())
403 , fTestExecuteValue(testExecuteValue) {
404 SkISize dims = {kSize, kSize};
407
408 fLazyProxy = proxyProvider->createLazyProxy(
409 [testExecuteValue, shouldFailInstantiation](
412 if (shouldFailInstantiation) {
413 *testExecuteValue = 1;
414 return {};
415 }
416 return {rp->createTexture(desc.fDimensions,
417 desc.fFormat,
418 desc.fTextureType,
419 desc.fRenderable,
420 desc.fSampleCnt,
421 desc.fMipmapped,
422 desc.fBudgeted,
423 desc.fProtected,
424 /*label=*/{}),
426 },
427 format,
428 dims,
436 /*label=*/{});
437
438 SkASSERT(fLazyProxy.get());
439
441 }
442
443 const char* name() const override { return "LazyFailedInstantiationTestOp"; }
444 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
445 GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override {
447 }
449 const GrSurfaceProxyView& writeView,
451 const GrDstProxyView&,
452 GrXferBarrierFlags renderPassXferBarriers,
453 GrLoadOp colorLoadOp) override {}
454 void onPrepare(GrOpFlushState*) override {}
455 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override {
456 *fTestExecuteValue = 2;
457 }
458
459 int* fTestExecuteValue;
460 sk_sp<GrTextureProxy> fLazyProxy;
461
462 using INHERITED = GrDrawOp;
463};
464
465// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
466// associated with.
467DEF_GANESH_TEST(LazyProxyFailedInstantiationTest,
468 reporter,
469 /* options */,
471 GrMockOptions mockOptions;
473 GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
474 for (bool failInstantiation : {false, true}) {
477 nullptr,
479 {100, 100},
481 /*label=*/{});
483
484 sdc->clear(SkPMColor4f::FromBytes_RGBA(0xbaaaaaad));
485
486 int executeTestValue = 0;
487 sdc->addDrawOp(LazyFailedInstantiationTestOp::Make(ctx.get(), proxyProvider,
488 &executeTestValue, failInstantiation));
489 ctx->flushAndSubmit();
490
491 if (failInstantiation) {
492 REPORTER_ASSERT(reporter, 1 == executeTestValue);
493 } else {
494 REPORTER_ASSERT(reporter, 2 == executeTestValue);
495 }
496 }
497}
const TextureProxy * fProxy
Definition: DrawPass.cpp:180
#define test(name)
reporter
Definition: FontMgrTest.cpp:39
#define DEFINE_OP_CLASS_ID
Definition: GrOp.h:64
GrClampType
Definition: GrTypesPriv.h:228
std::function< void(GrSurfaceProxy *, skgpu::Mipmapped)> GrVisitProxyFunc
Definition: GrTypesPriv.h:943
GrAAType
Definition: GrTypesPriv.h:200
GrColorType
Definition: GrTypesPriv.h:540
GrLoadOp
Definition: GrTypesPriv.h:155
GrSurfaceOrigin
Definition: GrTypes.h:147
@ kBottomLeft_GrSurfaceOrigin
Definition: GrTypes.h:149
GrXferBarrierFlags
DEF_GANESH_TEST(LazyProxyTest, reporter,, CtsEnforcement::kApiLevel_T)
static const int kSize
static const size_t testCount
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SkASSERT(cond)
Definition: SkAssert.h:116
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
static constexpr auto kColorType
const GrCaps * caps() const
Definition: GrCaps.h:57
GrBackendFormat getDefaultBackendFormat(GrColorType, GrRenderable) const
Definition: GrCaps.cpp:400
skgpu::Swizzle getReadSwizzle(const GrBackendFormat &format, GrColorType colorType) const
Definition: GrCaps.cpp:443
Definition: GrClip.h:29
GrResourceProvider * resourceProvider()
static sk_sp< GrDirectContext > MakeMock(const GrMockOptions *, const GrContextOptions &)
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
GrDirectContextPriv priv()
GrDrawOp(uint32_t classID)
Definition: GrDrawOp.h:31
FixedFunctionFlags
Definition: GrDrawOp.h:104
void registerChild(std::unique_ptr< GrFragmentProcessor > child, SkSL::SampleUsage sampleUsage=SkSL::SampleUsage::PassThrough())
Definition: GrOp.h:70
virtual void onExecute(GrOpFlushState *, const SkRect &chainBounds)=0
std::unique_ptr< GrOp > Owner
Definition: GrOp.h:72
virtual void onPrepare(GrOpFlushState *)=0
virtual const char * name() const =0
virtual void onPrePrepare(GrRecordingContext *, const GrSurfaceProxyView &writeView, GrAppliedClip *, const GrDstProxyView &, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp)=0
void setBounds(const SkRect &newBounds, HasAABloat aabloat, IsHairline zeroArea)
Definition: GrOp.h:279
static constexpr Analysis EmptySetAnalysis()
sk_sp< GrTextureProxy > createLazyProxy(LazyInstantiateCallback &&, const GrBackendFormat &, SkISize dimensions, skgpu::Mipmapped, GrMipmapStatus, GrInternalSurfaceFlags, SkBackingFit, skgpu::Budgeted, GrProtected, UseAllocator, std::string_view label)
static sk_sp< GrTextureProxy > MakeFullyLazyProxy(LazyInstantiateCallback &&, const GrBackendFormat &, GrRenderable, int renderTargetSampleCnt, GrProtected, const GrCaps &, UseAllocator)
const GrCaps * caps() const
void addOnFlushCallbackObject(GrOnFlushCallbackObject *)
GrProxyProvider * proxyProvider()
GrRecordingContextPriv priv()
sk_sp< GrTexture > createTexture(SkISize dimensions, const GrBackendFormat &format, GrTextureType textureType, skgpu::Renderable renderable, int renderTargetSampleCnt, skgpu::Mipmapped mipmapped, skgpu::Budgeted budgeted, skgpu::Protected isProtected, std::string_view label)
bool doLazyInstantiation(GrResourceProvider *)
GrSurfaceProxyPriv priv()
GrTexture * peekTexture() const
SkISize dimensions() const
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView, SkAlphaType, const SkMatrix &=SkMatrix::I(), GrSamplerState::Filter=GrSamplerState::Filter::kNearest, GrSamplerState::MipmapMode mipmapMode=GrSamplerState::MipmapMode::kNone)
bool instantiate(GrResourceProvider *) override
void visitProxies(const GrVisitProxyFunc &func) const override
static DEFINE_OP_CLASS_ID GrOp::Owner Make(GrRecordingContext *rContext, GrProxyProvider *proxyProvider, int *testExecuteValue, bool shouldFailInstantiation)
ClipFP(GrRecordingContext *ctx, GrProxyProvider *proxyProvider, LazyProxyTest *test, GrTextureProxy *atlas)
Clip(LazyProxyTest *test, GrTextureProxy *atlas)
void onExecute(GrOpFlushState *, const SkRect &chainBounds) override
void visitProxies(const GrVisitProxyFunc &func) const override
static DEFINE_OP_CLASS_ID GrOp::Owner Make(GrRecordingContext *context, GrProxyProvider *proxyProvider, LazyProxyTest *test, bool nullTexture)
bool preFlush(GrOnFlushResourceProvider *onFlushRP) override
void postFlush(skgpu::AtlasToken) override
LazyProxyTest(skiatest::Reporter *reporter)
~LazyProxyTest() override
static SkRect MakeLargest()
Definition: SkRectPriv.h:39
T * get() const
Definition: SkRefCnt.h:303
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
static std::unique_ptr< SurfaceDrawContext > Make(GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)
AtkStateType state
uint8_t value
uint32_t uint32_t * format
FlTexture * texture
sk_sp< const SkImage > atlas
Definition: SkRecords.h:331
Optional< SkRect > bounds
Definition: SkRecords.h:189
@ kNone
Definition: layer.h:53
Definition: GpuTools.h:21
ConfigOptions fConfigOptions[kGrColorTypeCnt]
Definition: GrMockTypes.h:151
Definition: SkRect.h:32
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
Definition: SkSize.h:16
static SkRGBA4f FromBytes_RGBA(uint32_t color)
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669