1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "tests/Test.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/gpu/mock/GrMockTypes.h" 11cb93a386Sopenharmony_ci#include "src/core/SkRectPriv.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrClip.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrMemoryPool.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrOnFlushResourceProvider.h" 16cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 17cb93a386Sopenharmony_ci#include "src/gpu/GrRecordingContextPriv.h" 18cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 19cb93a386Sopenharmony_ci#include "src/gpu/GrSurfaceProxy.h" 20cb93a386Sopenharmony_ci#include "src/gpu/GrSurfaceProxyPriv.h" 21cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 22cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxy.h" 23cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxyPriv.h" 24cb93a386Sopenharmony_ci#include "src/gpu/effects/GrTextureEffect.h" 25cb93a386Sopenharmony_ci#include "src/gpu/mock/GrMockGpu.h" 26cb93a386Sopenharmony_ci#include "src/gpu/ops/GrDrawOp.h" 27cb93a386Sopenharmony_ci#include "src/gpu/v1/SurfaceDrawContext_v1.h" 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci// This test verifies that lazy proxy callbacks get invoked during flush, after onFlush callbacks, 30cb93a386Sopenharmony_ci// but before Ops are executed. It also ensures that lazy proxy callbacks are invoked both for 31cb93a386Sopenharmony_ci// regular Ops and for clips. 32cb93a386Sopenharmony_ciclass LazyProxyTest final : public GrOnFlushCallbackObject { 33cb93a386Sopenharmony_cipublic: 34cb93a386Sopenharmony_ci LazyProxyTest(skiatest::Reporter* reporter) 35cb93a386Sopenharmony_ci : fReporter(reporter) 36cb93a386Sopenharmony_ci , fHasOpTexture(false) 37cb93a386Sopenharmony_ci , fHasClipTexture(false) { 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci ~LazyProxyTest() override { 41cb93a386Sopenharmony_ci REPORTER_ASSERT(fReporter, fHasOpTexture); 42cb93a386Sopenharmony_ci REPORTER_ASSERT(fReporter, fHasClipTexture); 43cb93a386Sopenharmony_ci } 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci void preFlush(GrOnFlushResourceProvider*, SkSpan<const uint32_t>) override { 46cb93a386Sopenharmony_ci REPORTER_ASSERT(fReporter, !fHasOpTexture); 47cb93a386Sopenharmony_ci REPORTER_ASSERT(fReporter, !fHasClipTexture); 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci void postFlush(GrDeferredUploadToken, SkSpan<const uint32_t>) override { 51cb93a386Sopenharmony_ci REPORTER_ASSERT(fReporter, fHasOpTexture); 52cb93a386Sopenharmony_ci REPORTER_ASSERT(fReporter, fHasClipTexture); 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci class Op final : public GrDrawOp { 56cb93a386Sopenharmony_ci public: 57cb93a386Sopenharmony_ci DEFINE_OP_CLASS_ID 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci static GrOp::Owner Make(GrRecordingContext* context, 60cb93a386Sopenharmony_ci GrProxyProvider* proxyProvider, 61cb93a386Sopenharmony_ci LazyProxyTest* test, 62cb93a386Sopenharmony_ci bool nullTexture) { 63cb93a386Sopenharmony_ci return GrOp::Make<Op>(context, context, proxyProvider, test, nullTexture); 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci void visitProxies(const GrVisitProxyFunc& func) const override { 67cb93a386Sopenharmony_ci func(fProxy.get(), GrMipmapped::kNo); 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci void onExecute(GrOpFlushState*, const SkRect& chainBounds) override { 71cb93a386Sopenharmony_ci REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture); 72cb93a386Sopenharmony_ci REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture); 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ci private: 76cb93a386Sopenharmony_ci friend class GrOp; // for ctor 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci Op(GrRecordingContext* ctx, GrProxyProvider* proxyProvider, 79cb93a386Sopenharmony_ci LazyProxyTest* test, bool nullTexture) 80cb93a386Sopenharmony_ci : GrDrawOp(ClassID()), fTest(test) { 81cb93a386Sopenharmony_ci const GrBackendFormat format = 82cb93a386Sopenharmony_ci ctx->priv().caps()->getDefaultBackendFormat(GrColorType::kBGR_565, 83cb93a386Sopenharmony_ci GrRenderable::kNo); 84cb93a386Sopenharmony_ci fProxy = GrProxyProvider::MakeFullyLazyProxy( 85cb93a386Sopenharmony_ci [this, nullTexture](GrResourceProvider* rp, 86cb93a386Sopenharmony_ci const GrSurfaceProxy::LazySurfaceDesc& desc) 87cb93a386Sopenharmony_ci -> GrSurfaceProxy::LazyCallbackResult { 88cb93a386Sopenharmony_ci REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture); 89cb93a386Sopenharmony_ci fTest->fHasOpTexture = true; 90cb93a386Sopenharmony_ci if (nullTexture) { 91cb93a386Sopenharmony_ci return {}; 92cb93a386Sopenharmony_ci } else { 93cb93a386Sopenharmony_ci static constexpr SkISize kDimensions = {1234, 567}; 94cb93a386Sopenharmony_ci sk_sp<GrTexture> texture = rp->createTexture( 95cb93a386Sopenharmony_ci kDimensions, 96cb93a386Sopenharmony_ci desc.fFormat, 97cb93a386Sopenharmony_ci desc.fTextureType, 98cb93a386Sopenharmony_ci desc.fRenderable, 99cb93a386Sopenharmony_ci desc.fSampleCnt, 100cb93a386Sopenharmony_ci desc.fMipmapped, 101cb93a386Sopenharmony_ci desc.fBudgeted, 102cb93a386Sopenharmony_ci desc.fProtected); 103cb93a386Sopenharmony_ci REPORTER_ASSERT(fTest->fReporter, texture); 104cb93a386Sopenharmony_ci return texture; 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci }, 107cb93a386Sopenharmony_ci format, GrRenderable::kNo, 1, GrProtected::kNo, *proxyProvider->caps(), 108cb93a386Sopenharmony_ci GrSurfaceProxy::UseAllocator::kYes); 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo, 111cb93a386Sopenharmony_ci GrOp::IsHairline::kNo); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci const char* name() const override { return "LazyProxyTest::Op"; } 115cb93a386Sopenharmony_ci FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; } 116cb93a386Sopenharmony_ci GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip* clip, 117cb93a386Sopenharmony_ci GrClampType) override { 118cb93a386Sopenharmony_ci return GrProcessorSet::EmptySetAnalysis(); 119cb93a386Sopenharmony_ci } 120cb93a386Sopenharmony_ci void onPrePrepare(GrRecordingContext*, 121cb93a386Sopenharmony_ci const GrSurfaceProxyView& writeView, 122cb93a386Sopenharmony_ci GrAppliedClip*, 123cb93a386Sopenharmony_ci const GrDstProxyView&, 124cb93a386Sopenharmony_ci GrXferBarrierFlags renderPassXferBarriers, 125cb93a386Sopenharmony_ci GrLoadOp colorLoadOp) override {} 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci void onPrepare(GrOpFlushState*) override {} 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci LazyProxyTest* const fTest; 130cb93a386Sopenharmony_ci sk_sp<GrTextureProxy> fProxy; 131cb93a386Sopenharmony_ci }; 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci class ClipFP : public GrFragmentProcessor { 134cb93a386Sopenharmony_ci public: 135cb93a386Sopenharmony_ci ClipFP(GrRecordingContext* ctx, GrProxyProvider* proxyProvider, LazyProxyTest* test, 136cb93a386Sopenharmony_ci GrTextureProxy* atlas) 137cb93a386Sopenharmony_ci : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags) 138cb93a386Sopenharmony_ci , fContext(ctx) 139cb93a386Sopenharmony_ci , fProxyProvider(proxyProvider) 140cb93a386Sopenharmony_ci , fTest(test) 141cb93a386Sopenharmony_ci , fAtlas(atlas) { 142cb93a386Sopenharmony_ci static const GrColorType kColorType = GrColorType::kAlpha_F16; 143cb93a386Sopenharmony_ci static const GrSurfaceOrigin kOrigin = kBottomLeft_GrSurfaceOrigin; 144cb93a386Sopenharmony_ci const GrBackendFormat format = 145cb93a386Sopenharmony_ci ctx->priv().caps()->getDefaultBackendFormat(kColorType, GrRenderable::kYes); 146cb93a386Sopenharmony_ci GrSwizzle readSwizzle = ctx->priv().caps()->getReadSwizzle(format, kColorType); 147cb93a386Sopenharmony_ci fLazyProxy = GrProxyProvider::MakeFullyLazyProxy( 148cb93a386Sopenharmony_ci [this](GrResourceProvider* rp, const GrSurfaceProxy::LazySurfaceDesc&) 149cb93a386Sopenharmony_ci -> GrSurfaceProxy::LazyCallbackResult { 150cb93a386Sopenharmony_ci REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture); 151cb93a386Sopenharmony_ci fTest->fHasClipTexture = true; 152cb93a386Sopenharmony_ci fAtlas->instantiate(rp); 153cb93a386Sopenharmony_ci return sk_ref_sp(fAtlas->peekTexture()); 154cb93a386Sopenharmony_ci }, 155cb93a386Sopenharmony_ci format, GrRenderable::kYes, 1, GrProtected::kNo, *proxyProvider->caps(), 156cb93a386Sopenharmony_ci GrSurfaceProxy::UseAllocator::kYes); 157cb93a386Sopenharmony_ci auto atlasEffect = GrTextureEffect::Make({fLazyProxy, kOrigin, readSwizzle}, 158cb93a386Sopenharmony_ci kPremul_SkAlphaType); 159cb93a386Sopenharmony_ci this->registerChild(std::move(atlasEffect)); 160cb93a386Sopenharmony_ci } 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_ci private: 163cb93a386Sopenharmony_ci const char* name() const override { return "LazyProxyTest::ClipFP"; } 164cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> clone() const override { 165cb93a386Sopenharmony_ci return std::make_unique<ClipFP>(fContext, fProxyProvider, fTest, fAtlas); 166cb93a386Sopenharmony_ci } 167cb93a386Sopenharmony_ci std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override { 168cb93a386Sopenharmony_ci return nullptr; 169cb93a386Sopenharmony_ci } 170cb93a386Sopenharmony_ci void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {} 171cb93a386Sopenharmony_ci bool onIsEqual(const GrFragmentProcessor&) const override { return false; } 172cb93a386Sopenharmony_ci 173cb93a386Sopenharmony_ci GrRecordingContext* const fContext; 174cb93a386Sopenharmony_ci GrProxyProvider* const fProxyProvider; 175cb93a386Sopenharmony_ci LazyProxyTest* const fTest; 176cb93a386Sopenharmony_ci GrTextureProxy* const fAtlas; 177cb93a386Sopenharmony_ci sk_sp<GrTextureProxy> fLazyProxy; 178cb93a386Sopenharmony_ci }; 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci 181cb93a386Sopenharmony_ci class Clip : public GrClip { 182cb93a386Sopenharmony_ci public: 183cb93a386Sopenharmony_ci Clip(LazyProxyTest* test, GrTextureProxy* atlas) 184cb93a386Sopenharmony_ci : fTest(test) 185cb93a386Sopenharmony_ci , fAtlas(atlas) {} 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci private: 188cb93a386Sopenharmony_ci SkIRect getConservativeBounds() const final { 189cb93a386Sopenharmony_ci return SkIRect::MakeSize(fAtlas->dimensions()); 190cb93a386Sopenharmony_ci } 191cb93a386Sopenharmony_ci Effect apply(GrRecordingContext* rContext, 192cb93a386Sopenharmony_ci skgpu::v1::SurfaceDrawContext*, 193cb93a386Sopenharmony_ci GrDrawOp*, 194cb93a386Sopenharmony_ci GrAAType, 195cb93a386Sopenharmony_ci GrAppliedClip* out, 196cb93a386Sopenharmony_ci SkRect* bounds) const override { 197cb93a386Sopenharmony_ci GrProxyProvider* proxyProvider = rContext->priv().proxyProvider(); 198cb93a386Sopenharmony_ci out->addCoverageFP(std::make_unique<ClipFP>(rContext, proxyProvider, fTest, fAtlas)); 199cb93a386Sopenharmony_ci return Effect::kClipped; 200cb93a386Sopenharmony_ci } 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_ci LazyProxyTest* const fTest; 203cb93a386Sopenharmony_ci GrTextureProxy* fAtlas; 204cb93a386Sopenharmony_ci }; 205cb93a386Sopenharmony_ci 206cb93a386Sopenharmony_ciprivate: 207cb93a386Sopenharmony_ci skiatest::Reporter* fReporter; 208cb93a386Sopenharmony_ci bool fHasOpTexture; 209cb93a386Sopenharmony_ci bool fHasClipTexture; 210cb93a386Sopenharmony_ci}; 211cb93a386Sopenharmony_ci 212cb93a386Sopenharmony_ciDEF_GPUTEST(LazyProxyTest, reporter, /* options */) { 213cb93a386Sopenharmony_ci GrMockOptions mockOptions; 214cb93a386Sopenharmony_ci mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fRenderability = 215cb93a386Sopenharmony_ci GrMockOptions::ConfigOptions::Renderability::kNonMSAA; 216cb93a386Sopenharmony_ci mockOptions.fConfigOptions[(int)GrColorType::kAlpha_F16].fTexturable = true; 217cb93a386Sopenharmony_ci sk_sp<GrDirectContext> ctx = GrDirectContext::MakeMock(&mockOptions, GrContextOptions()); 218cb93a386Sopenharmony_ci GrProxyProvider* proxyProvider = ctx->priv().proxyProvider(); 219cb93a386Sopenharmony_ci for (bool nullTexture : {false, true}) { 220cb93a386Sopenharmony_ci LazyProxyTest test(reporter); 221cb93a386Sopenharmony_ci ctx->priv().addOnFlushCallbackObject(&test); 222cb93a386Sopenharmony_ci auto sdc = skgpu::v1::SurfaceDrawContext::Make(ctx.get(), GrColorType::kRGBA_8888, nullptr, 223cb93a386Sopenharmony_ci SkBackingFit::kExact, {100, 100}, 224cb93a386Sopenharmony_ci SkSurfaceProps()); 225cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, sdc); 226cb93a386Sopenharmony_ci auto mockAtlas = skgpu::v1::SurfaceDrawContext::Make(ctx.get(), GrColorType::kAlpha_F16, 227cb93a386Sopenharmony_ci nullptr, SkBackingFit::kExact, 228cb93a386Sopenharmony_ci {10, 10}, SkSurfaceProps()); 229cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, mockAtlas); 230cb93a386Sopenharmony_ci LazyProxyTest::Clip clip(&test, mockAtlas->asTextureProxy()); 231cb93a386Sopenharmony_ci sdc->addDrawOp(&clip, 232cb93a386Sopenharmony_ci LazyProxyTest::Op::Make(ctx.get(), proxyProvider, &test, nullTexture)); 233cb93a386Sopenharmony_ci ctx->priv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test); 234cb93a386Sopenharmony_ci } 235cb93a386Sopenharmony_ci} 236cb93a386Sopenharmony_ci 237cb93a386Sopenharmony_cistatic const int kSize = 16; 238cb93a386Sopenharmony_ci 239cb93a386Sopenharmony_ciDEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) { 240cb93a386Sopenharmony_ci GrMockOptions mockOptions; 241cb93a386Sopenharmony_ci sk_sp<GrDirectContext> ctx = GrDirectContext::MakeMock(&mockOptions, GrContextOptions()); 242cb93a386Sopenharmony_ci auto proxyProvider = ctx->priv().proxyProvider(); 243cb93a386Sopenharmony_ci const GrCaps* caps = ctx->priv().caps(); 244cb93a386Sopenharmony_ci 245cb93a386Sopenharmony_ci GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kRGBA_8888, 246cb93a386Sopenharmony_ci GrRenderable::kNo); 247cb93a386Sopenharmony_ci 248cb93a386Sopenharmony_ci auto tex = ctx->priv().resourceProvider()->createTexture({kSize, kSize}, 249cb93a386Sopenharmony_ci format, 250cb93a386Sopenharmony_ci GrTextureType::k2D, 251cb93a386Sopenharmony_ci GrRenderable::kNo, 252cb93a386Sopenharmony_ci 1, 253cb93a386Sopenharmony_ci GrMipmapped::kNo, 254cb93a386Sopenharmony_ci SkBudgeted::kNo, 255cb93a386Sopenharmony_ci GrProtected::kNo); 256cb93a386Sopenharmony_ci using LazyInstantiationResult = GrSurfaceProxy::LazyCallbackResult; 257cb93a386Sopenharmony_ci for (bool doInstantiate : {true, false}) { 258cb93a386Sopenharmony_ci for (bool releaseCallback : {false, true}) { 259cb93a386Sopenharmony_ci int testCount = 0; 260cb93a386Sopenharmony_ci // Sets an integer to 1 when the callback is called and -1 when it is deleted. 261cb93a386Sopenharmony_ci class TestCallback { 262cb93a386Sopenharmony_ci public: 263cb93a386Sopenharmony_ci TestCallback(int* value, bool releaseCallback, sk_sp<GrTexture> tex) 264cb93a386Sopenharmony_ci : fValue(value) 265cb93a386Sopenharmony_ci , fReleaseCallback(releaseCallback) 266cb93a386Sopenharmony_ci , fTexture(std::move(tex)) {} 267cb93a386Sopenharmony_ci TestCallback(const TestCallback& that) { SkASSERT(0); } 268cb93a386Sopenharmony_ci TestCallback(TestCallback&& that) 269cb93a386Sopenharmony_ci : fValue(that.fValue) 270cb93a386Sopenharmony_ci , fReleaseCallback(that.fReleaseCallback) 271cb93a386Sopenharmony_ci , fTexture(std::move(that.fTexture)) { 272cb93a386Sopenharmony_ci that.fValue = nullptr; 273cb93a386Sopenharmony_ci } 274cb93a386Sopenharmony_ci 275cb93a386Sopenharmony_ci ~TestCallback() { fValue ? (void)(*fValue = -1) : void(); } 276cb93a386Sopenharmony_ci 277cb93a386Sopenharmony_ci TestCallback& operator=(TestCallback&& that) { 278cb93a386Sopenharmony_ci fValue = std::exchange(that.fValue, nullptr); 279cb93a386Sopenharmony_ci return *this; 280cb93a386Sopenharmony_ci } 281cb93a386Sopenharmony_ci TestCallback& operator=(const TestCallback& that) = delete; 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_ci LazyInstantiationResult operator()(GrResourceProvider*, 284cb93a386Sopenharmony_ci const GrSurfaceProxy::LazySurfaceDesc&) const { 285cb93a386Sopenharmony_ci *fValue = 1; 286cb93a386Sopenharmony_ci return {fTexture, fReleaseCallback}; 287cb93a386Sopenharmony_ci } 288cb93a386Sopenharmony_ci 289cb93a386Sopenharmony_ci private: 290cb93a386Sopenharmony_ci int* fValue = nullptr; 291cb93a386Sopenharmony_ci bool fReleaseCallback; 292cb93a386Sopenharmony_ci sk_sp<GrTexture> fTexture; 293cb93a386Sopenharmony_ci }; 294cb93a386Sopenharmony_ci sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy( 295cb93a386Sopenharmony_ci TestCallback(&testCount, releaseCallback, tex), format, {kSize, kSize}, 296cb93a386Sopenharmony_ci GrMipmapped::kNo, GrMipmapStatus::kNotAllocated, GrInternalSurfaceFlags::kNone, 297cb93a386Sopenharmony_ci SkBackingFit::kExact, SkBudgeted::kNo, GrProtected::kNo, 298cb93a386Sopenharmony_ci GrSurfaceProxy::UseAllocator::kYes); 299cb93a386Sopenharmony_ci 300cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, proxy.get()); 301cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 0 == testCount); 302cb93a386Sopenharmony_ci 303cb93a386Sopenharmony_ci if (doInstantiate) { 304cb93a386Sopenharmony_ci proxy->priv().doLazyInstantiation(ctx->priv().resourceProvider()); 305cb93a386Sopenharmony_ci if (releaseCallback) { 306cb93a386Sopenharmony_ci // We will call the cleanup and delete the callback in the 307cb93a386Sopenharmony_ci // doLazyInstantiationCall. 308cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, -1 == testCount); 309cb93a386Sopenharmony_ci } else { 310cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == testCount); 311cb93a386Sopenharmony_ci } 312cb93a386Sopenharmony_ci proxy.reset(); 313cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, -1 == testCount); 314cb93a386Sopenharmony_ci } else { 315cb93a386Sopenharmony_ci proxy.reset(); 316cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, -1 == testCount); 317cb93a386Sopenharmony_ci } 318cb93a386Sopenharmony_ci } 319cb93a386Sopenharmony_ci } 320cb93a386Sopenharmony_ci} 321cb93a386Sopenharmony_ci 322cb93a386Sopenharmony_ciclass LazyFailedInstantiationTestOp : public GrDrawOp { 323cb93a386Sopenharmony_cipublic: 324cb93a386Sopenharmony_ci DEFINE_OP_CLASS_ID 325cb93a386Sopenharmony_ci 326cb93a386Sopenharmony_ci static GrOp::Owner Make(GrRecordingContext* rContext, 327cb93a386Sopenharmony_ci GrProxyProvider* proxyProvider, 328cb93a386Sopenharmony_ci int* testExecuteValue, 329cb93a386Sopenharmony_ci bool shouldFailInstantiation) { 330cb93a386Sopenharmony_ci return GrOp::Make<LazyFailedInstantiationTestOp>(rContext, 331cb93a386Sopenharmony_ci rContext->priv().caps(), 332cb93a386Sopenharmony_ci proxyProvider, 333cb93a386Sopenharmony_ci testExecuteValue, 334cb93a386Sopenharmony_ci shouldFailInstantiation); 335cb93a386Sopenharmony_ci } 336cb93a386Sopenharmony_ci 337cb93a386Sopenharmony_ci void visitProxies(const GrVisitProxyFunc& func) const override { 338cb93a386Sopenharmony_ci func(fLazyProxy.get(), GrMipmapped::kNo); 339cb93a386Sopenharmony_ci } 340cb93a386Sopenharmony_ci 341cb93a386Sopenharmony_ciprivate: 342cb93a386Sopenharmony_ci friend class GrOp; // for ctor 343cb93a386Sopenharmony_ci 344cb93a386Sopenharmony_ci LazyFailedInstantiationTestOp(const GrCaps* caps, GrProxyProvider* proxyProvider, 345cb93a386Sopenharmony_ci int* testExecuteValue, bool shouldFailInstantiation) 346cb93a386Sopenharmony_ci : INHERITED(ClassID()) 347cb93a386Sopenharmony_ci , fTestExecuteValue(testExecuteValue) { 348cb93a386Sopenharmony_ci SkISize dims = {kSize, kSize}; 349cb93a386Sopenharmony_ci GrBackendFormat format = caps->getDefaultBackendFormat(GrColorType::kRGBA_8888, 350cb93a386Sopenharmony_ci GrRenderable::kNo); 351cb93a386Sopenharmony_ci 352cb93a386Sopenharmony_ci fLazyProxy = proxyProvider->createLazyProxy( 353cb93a386Sopenharmony_ci [testExecuteValue, shouldFailInstantiation]( 354cb93a386Sopenharmony_ci GrResourceProvider* rp, const GrSurfaceProxy::LazySurfaceDesc& desc) 355cb93a386Sopenharmony_ci -> GrSurfaceProxy::LazyCallbackResult { 356cb93a386Sopenharmony_ci if (shouldFailInstantiation) { 357cb93a386Sopenharmony_ci *testExecuteValue = 1; 358cb93a386Sopenharmony_ci return {}; 359cb93a386Sopenharmony_ci } 360cb93a386Sopenharmony_ci return {rp->createTexture(desc.fDimensions, 361cb93a386Sopenharmony_ci desc.fFormat, 362cb93a386Sopenharmony_ci desc.fTextureType, 363cb93a386Sopenharmony_ci desc.fRenderable, 364cb93a386Sopenharmony_ci desc.fSampleCnt, 365cb93a386Sopenharmony_ci desc.fMipmapped, 366cb93a386Sopenharmony_ci desc.fBudgeted, 367cb93a386Sopenharmony_ci desc.fProtected), 368cb93a386Sopenharmony_ci true, GrSurfaceProxy::LazyInstantiationKeyMode::kUnsynced}; 369cb93a386Sopenharmony_ci }, 370cb93a386Sopenharmony_ci format, dims, GrMipmapped::kNo, GrMipmapStatus::kNotAllocated, 371cb93a386Sopenharmony_ci GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, SkBudgeted::kNo, 372cb93a386Sopenharmony_ci GrProtected::kNo, GrSurfaceProxy::UseAllocator::kYes); 373cb93a386Sopenharmony_ci 374cb93a386Sopenharmony_ci SkASSERT(fLazyProxy.get()); 375cb93a386Sopenharmony_ci 376cb93a386Sopenharmony_ci this->setBounds(SkRect::Make(dims), HasAABloat::kNo, IsHairline::kNo); 377cb93a386Sopenharmony_ci } 378cb93a386Sopenharmony_ci 379cb93a386Sopenharmony_ci const char* name() const override { return "LazyFailedInstantiationTestOp"; } 380cb93a386Sopenharmony_ci FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; } 381cb93a386Sopenharmony_ci GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override { 382cb93a386Sopenharmony_ci return GrProcessorSet::EmptySetAnalysis(); 383cb93a386Sopenharmony_ci } 384cb93a386Sopenharmony_ci void onPrePrepare(GrRecordingContext*, 385cb93a386Sopenharmony_ci const GrSurfaceProxyView& writeView, 386cb93a386Sopenharmony_ci GrAppliedClip*, 387cb93a386Sopenharmony_ci const GrDstProxyView&, 388cb93a386Sopenharmony_ci GrXferBarrierFlags renderPassXferBarriers, 389cb93a386Sopenharmony_ci GrLoadOp colorLoadOp) override {} 390cb93a386Sopenharmony_ci void onPrepare(GrOpFlushState*) override {} 391cb93a386Sopenharmony_ci void onExecute(GrOpFlushState* state, const SkRect& chainBounds) override { 392cb93a386Sopenharmony_ci *fTestExecuteValue = 2; 393cb93a386Sopenharmony_ci } 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_ci int* fTestExecuteValue; 396cb93a386Sopenharmony_ci sk_sp<GrTextureProxy> fLazyProxy; 397cb93a386Sopenharmony_ci 398cb93a386Sopenharmony_ci using INHERITED = GrDrawOp; 399cb93a386Sopenharmony_ci}; 400cb93a386Sopenharmony_ci 401cb93a386Sopenharmony_ci// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was 402cb93a386Sopenharmony_ci// associated with. 403cb93a386Sopenharmony_ciDEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) { 404cb93a386Sopenharmony_ci GrMockOptions mockOptions; 405cb93a386Sopenharmony_ci sk_sp<GrDirectContext> ctx = GrDirectContext::MakeMock(&mockOptions, GrContextOptions()); 406cb93a386Sopenharmony_ci GrProxyProvider* proxyProvider = ctx->priv().proxyProvider(); 407cb93a386Sopenharmony_ci for (bool failInstantiation : {false, true}) { 408cb93a386Sopenharmony_ci auto sdc = skgpu::v1::SurfaceDrawContext::Make(ctx.get(), GrColorType::kRGBA_8888, nullptr, 409cb93a386Sopenharmony_ci SkBackingFit::kExact, {100, 100}, 410cb93a386Sopenharmony_ci SkSurfaceProps()); 411cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, sdc); 412cb93a386Sopenharmony_ci 413cb93a386Sopenharmony_ci sdc->clear(SkPMColor4f::FromBytes_RGBA(0xbaaaaaad)); 414cb93a386Sopenharmony_ci 415cb93a386Sopenharmony_ci int executeTestValue = 0; 416cb93a386Sopenharmony_ci sdc->addDrawOp(LazyFailedInstantiationTestOp::Make(ctx.get(), proxyProvider, 417cb93a386Sopenharmony_ci &executeTestValue, failInstantiation)); 418cb93a386Sopenharmony_ci ctx->flushAndSubmit(); 419cb93a386Sopenharmony_ci 420cb93a386Sopenharmony_ci if (failInstantiation) { 421cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 1 == executeTestValue); 422cb93a386Sopenharmony_ci } else { 423cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 2 == executeTestValue); 424cb93a386Sopenharmony_ci } 425cb93a386Sopenharmony_ci } 426cb93a386Sopenharmony_ci} 427