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