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