1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h"
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrClip.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextPriv.h"
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrProxyProvider.h"
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrOnFlushResourceProvider.h"
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContext.h"
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContextPriv.h"
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrSurfaceProxy.h"
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrSurfaceProxyPriv.h"
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTexture.h"
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTextureProxy.h"
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTextureProxyPriv.h"
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMakeUnique.h"
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRectPriv.h"
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "mock/GrMockTypes.h"
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// This test verifies that lazy proxy callbacks get invoked during flush, after onFlush callbacks,
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// but before Ops are executed. It also ensures that lazy proxy callbacks are invoked both for
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// regular Ops and for clips.
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass LazyProxyTest final : public GrOnFlushCallbackObject {
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    LazyProxyTest(skiatest::Reporter* reporter)
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            : fReporter(reporter)
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fHasOpTexture(false)
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fHasClipTexture(false) {
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    ~LazyProxyTest() override {
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(fReporter, fHasOpTexture);
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(fReporter, fHasClipTexture);
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void preFlush(GrOnFlushResourceProvider*, const uint32_t*, int,
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                  SkTArray<sk_sp<GrRenderTargetContext>>*) override {
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(fReporter, !fHasOpTexture);
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(fReporter, !fHasClipTexture);
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void postFlush(GrDeferredUploadToken, const uint32_t* opListIDs, int numOpListIDs) override {
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(fReporter, fHasOpTexture);
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(fReporter, fHasClipTexture);
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class Op final : public GrDrawOp {
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        DEFINE_OP_CLASS_ID
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Op(GrProxyProvider* proxyProvider, LazyProxyTest* test, bool nullTexture)
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    : GrDrawOp(ClassID()), fTest(test) {
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fProxy = proxyProvider->createFullyLazyProxy([this, nullTexture](
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                        GrResourceProvider* rp, GrSurfaceOrigin* origin) {
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (!rp) {
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return sk_sp<GrTexture>();
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(fTest->fReporter, !fTest->fHasOpTexture);
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fTest->fHasOpTexture = true;
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *origin = kTopLeft_GrSurfaceOrigin;
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (nullTexture) {
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return sk_sp<GrTexture>();
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                } else {
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    GrSurfaceDesc desc;
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    desc.fWidth = 1234;
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    desc.fHeight = 567;
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    desc.fConfig = kRGB_565_GrPixelConfig;
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    sk_sp<GrTexture> texture = rp->createTexture(desc, SkBudgeted::kYes);
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    REPORTER_ASSERT(fTest->fReporter, texture);
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return texture;
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }, GrProxyProvider::Renderable::kNo, kRGB_565_GrPixelConfig);
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo, GrOp::IsZeroArea::kNo);
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void visitProxies(const VisitProxyFunc& func) const override {
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            func(fProxy.get());
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void onExecute(GrOpFlushState*) override {
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(fTest->fReporter, fTest->fHasOpTexture);
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(fTest->fReporter, fTest->fHasClipTexture);
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    private:
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* name() const override { return "LazyProxyTest::Op"; }
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*,
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                    GrPixelConfigIsClamped) override {
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return RequiresDstTexture::kNo;
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void wasRecorded(GrRenderTargetOpList*) override {}
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override { return false; }
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void onPrepare(GrOpFlushState*) override {}
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LazyProxyTest* const fTest;
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrTextureProxy> fProxy;
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class ClipFP : public GrFragmentProcessor {
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ClipFP(GrProxyProvider* proxyProvider, LazyProxyTest* test, GrTextureProxy* atlas)
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                : GrFragmentProcessor(kTestFP_ClassID, kNone_OptimizationFlags)
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                , fProxyProvider(proxyProvider)
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                , fTest(test)
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                , fAtlas(atlas) {
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fLazyProxy = proxyProvider->createFullyLazyProxy([this](GrResourceProvider* rp,
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                    GrSurfaceOrigin* origin) {
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                if (!rp) {
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return sk_sp<GrTexture>();
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                REPORTER_ASSERT(fTest->fReporter, !fTest->fHasClipTexture);
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fTest->fHasClipTexture = true;
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *origin = kBottomLeft_GrSurfaceOrigin;
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                fAtlas->instantiate(rp);
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                return sk_ref_sp(fAtlas->priv().peekTexture());
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }, GrProxyProvider::Renderable::kYes, kAlpha_half_GrPixelConfig);
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            fAccess.reset(fLazyProxy, GrSamplerState::Filter::kNearest,
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                          GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag);
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            this->addTextureSampler(&fAccess);
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    private:
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        const char* name() const override { return "LazyProxyTest::ClipFP"; }
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        std::unique_ptr<GrFragmentProcessor> clone() const override {
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return skstd::make_unique<ClipFP>(fProxyProvider, fTest, fAtlas);
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return nullptr; }
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool onIsEqual(const GrFragmentProcessor&) const override { return false; }
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrProxyProvider* const fProxyProvider;
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LazyProxyTest* const fTest;
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrTextureProxy* const fAtlas;
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrTextureProxy> fLazyProxy;
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        TextureSampler fAccess;
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    class Clip : public GrClip {
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    public:
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        Clip(LazyProxyTest* test, GrTextureProxy* atlas)
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                : fTest(test)
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                , fAtlas(atlas) {}
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    private:
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool apply(GrContext* context, GrRenderTargetContext*, bool, bool, GrAppliedClip* out,
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                   SkRect* bounds) const override {
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            out->addCoverageFP(skstd::make_unique<ClipFP>(proxyProvider, fTest, fAtlas));
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool quickContains(const SkRect&) const final { return false; }
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; }
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            rect->set(0, 0, width, height);
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            if (iior) {
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                *iior = false;
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            }
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LazyProxyTest* const fTest;
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrTextureProxy* fAtlas;
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    skiatest::Reporter* fReporter;
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fHasOpTexture;
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool fHasClipTexture;
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST(LazyProxyTest, reporter, /* options */) {
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrMockOptions mockOptions;
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderable[0] = true;
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fTexturable = true;
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (bool nullTexture : {false, true}) {
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        LazyProxyTest test(reporter);
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ctx->contextPriv().addOnFlushCallbackObject(&test);
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrRenderTargetContext> rtc =
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ctx->makeDeferredRenderTargetContext(SkBackingFit::kExact, 100, 100,
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                     kRGBA_8888_GrPixelConfig, nullptr);
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, rtc);
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrRenderTargetContext> mockAtlas =
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ctx->makeDeferredRenderTargetContext(SkBackingFit::kExact, 10, 10,
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                     kAlpha_half_GrPixelConfig, nullptr);
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, mockAtlas);
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        rtc->priv().testingOnly_addDrawOp(LazyProxyTest::Clip(&test, mockAtlas->asTextureProxy()),
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        skstd::make_unique<LazyProxyTest::Op>(proxyProvider, &test, nullTexture));
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ctx->contextPriv().testingOnly_flushAndRemoveOnFlushCallbackObject(&test);
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic const int kSize = 16;
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST(LazyProxyReleaseTest, reporter, /* options */) {
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrMockOptions mockOptions;
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    auto proxyProvider = ctx->contextPriv().proxyProvider();
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrSurfaceDesc desc;
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fWidth = kSize;
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fHeight = kSize;
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    desc.fConfig = kRGBA_8888_GrPixelConfig;
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (bool doInstantiate : {true, false}) {
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int testCount = 0;
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int* testCountPtr = &testCount;
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrTextureProxy> proxy = proxyProvider->createLazyProxy(
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                [testCountPtr](GrResourceProvider* resourceProvider, GrSurfaceOrigin* outOrigin) {
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!resourceProvider) {
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        *testCountPtr = -1;
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        return sk_sp<GrTexture>();
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    *testCountPtr = 1;
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return sk_sp<GrTexture>();
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kNo);
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, 0 == testCount);
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (doInstantiate) {
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            proxy->priv().doLazyInstantiation(ctx->contextPriv().resourceProvider());
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 1 == testCount);
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            proxy.reset();
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, -1 == testCount);
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            proxy.reset();
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, -1 == testCount);
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass LazyFailedInstantiationTestOp : public GrDrawOp {
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic:
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    DEFINE_OP_CLASS_ID
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    LazyFailedInstantiationTestOp(GrProxyProvider* proxyProvider, int* testExecuteValue,
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                  bool shouldFailInstantiation)
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            : INHERITED(ClassID())
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            , fTestExecuteValue(testExecuteValue) {
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        GrSurfaceDesc desc;
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        desc.fWidth = kSize;
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        desc.fHeight = kSize;
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        desc.fConfig = kRGBA_8888_GrPixelConfig;
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        fLazyProxy = proxyProvider->createLazyProxy(
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                [testExecuteValue, shouldFailInstantiation, desc] (
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        GrResourceProvider* rp, GrSurfaceOrigin* /*origin*/) {
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (!rp) {
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        return sk_sp<GrTexture>();
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    if (shouldFailInstantiation) {
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        *testExecuteValue = 1;
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        return sk_sp<GrTexture>();
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    }
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                    return rp->createTexture(desc, SkBudgeted::kNo);
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                }, desc, GrMipMapped::kNo, SkBackingFit::kExact, SkBudgeted::kNo);
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        this->setBounds(SkRect::MakeIWH(kSize, kSize),
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                        HasAABloat::kNo, IsZeroArea::kNo);
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void visitProxies(const VisitProxyFunc& func) const override {
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        func(fLazyProxy.get());
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate:
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    const char* name() const override { return "LazyFailedInstantiationTestOp"; }
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*,
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                GrPixelConfigIsClamped) override {
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return RequiresDstTexture::kNo;
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool onCombineIfPossible(GrOp* other, const GrCaps& caps) override { return false; }
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onPrepare(GrOpFlushState*) override {}
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    void onExecute(GrOpFlushState* state) override {
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        *fTestExecuteValue = 2;
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int* fTestExecuteValue;
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrSurfaceProxy> fLazyProxy;
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    typedef GrDrawOp INHERITED;
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// Test that when a lazy proxy fails to instantiate during flush that we drop the Op that it was
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot// associated with.
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_GPUTEST(LazyProxyFailedInstantiationTest, reporter, /* options */) {
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrMockOptions mockOptions;
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    sk_sp<GrContext> ctx = GrContext::MakeMock(&mockOptions, GrContextOptions());
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    for (bool failInstantiation : {false, true}) {
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        sk_sp<GrRenderTargetContext> rtc =
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                ctx->makeDeferredRenderTargetContext(SkBackingFit::kExact, 100, 100,
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                     kRGBA_8888_GrPixelConfig, nullptr);
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        REPORTER_ASSERT(reporter, rtc);
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        rtc->clear(nullptr, 0xbaaaaaad, GrRenderTargetContext::CanClearFullscreen::kYes);
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        int executeTestValue = 0;
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        rtc->priv().testingOnly_addDrawOp(
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                skstd::make_unique<LazyFailedInstantiationTestOp>(proxyProvider, &executeTestValue,
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                                                                  failInstantiation));
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ctx->flush();
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (failInstantiation) {
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DISABLE_EXPLICIT_GPU_RESOURCE_ALLOCATION
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // When we disable explicit gpu resource allocation we don't throw away ops that have
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            // uninstantiated proxies.
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 2 == executeTestValue);
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#else
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 1 == executeTestValue);
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else {
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            REPORTER_ASSERT(reporter, 2 == executeTestValue);
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
331