xref: /aosp_15_r20/external/skia/tests/GrPipelineDynamicStateTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/SkBlendMode.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkArenaAlloc.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkSLTypeShared.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkBackingFit.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrBuffer.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrColor.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGeometryProcessor.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrImageInfo.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrOpFlushState.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPipeline.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPixmap.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProcessorSet.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProgramInfo.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceProvider.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderVar.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSimpleMesh.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxyView.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrUserStencilSettings.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceDrawContext.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/GrDrawOp.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/GrOp.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
47*c8dee2aaSAndroid Build Coastguard Worker 
48*c8dee2aaSAndroid Build Coastguard Worker #include <array>
49*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
50*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
51*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
52*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker class GrAppliedClip;
57*c8dee2aaSAndroid Build Coastguard Worker class GrDstProxyView;
58*c8dee2aaSAndroid Build Coastguard Worker class GrGLSLProgramDataManager;
59*c8dee2aaSAndroid Build Coastguard Worker class GrRecordingContext;
60*c8dee2aaSAndroid Build Coastguard Worker class GrCaps;
61*c8dee2aaSAndroid Build Coastguard Worker enum class GrXferBarrierFlags;
62*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu { class KeyBuilder; }
63*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
64*c8dee2aaSAndroid Build Coastguard Worker struct GrShaderCaps;
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker /**
67*c8dee2aaSAndroid Build Coastguard Worker  * This is a GPU-backend specific test for dynamic pipeline state. It draws boxes using dynamic
68*c8dee2aaSAndroid Build Coastguard Worker  * scissor rectangles then reads back the result to verify a successful test.
69*c8dee2aaSAndroid Build Coastguard Worker  */
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kScreenSize = 6;
72*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kNumMeshes = 4;
73*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kScreenSplitX = kScreenSize/2;
74*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kScreenSplitY = kScreenSize/2;
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker static const SkIRect kDynamicScissors[kNumMeshes] = {
77*c8dee2aaSAndroid Build Coastguard Worker     SkIRect::MakeLTRB(0,              0,              kScreenSplitX,  kScreenSplitY),
78*c8dee2aaSAndroid Build Coastguard Worker     SkIRect::MakeLTRB(0,              kScreenSplitY,  kScreenSplitX,  kScreenSize),
79*c8dee2aaSAndroid Build Coastguard Worker     SkIRect::MakeLTRB(kScreenSplitX,  0,              kScreenSize,    kScreenSplitY),
80*c8dee2aaSAndroid Build Coastguard Worker     SkIRect::MakeLTRB(kScreenSplitX,  kScreenSplitY,  kScreenSize,    kScreenSize),
81*c8dee2aaSAndroid Build Coastguard Worker };
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker static const GrColor kMeshColors[kNumMeshes] {
84*c8dee2aaSAndroid Build Coastguard Worker     GrColorPackRGBA(255, 0, 0, 255),
85*c8dee2aaSAndroid Build Coastguard Worker     GrColorPackRGBA(0, 255, 0, 255),
86*c8dee2aaSAndroid Build Coastguard Worker     GrColorPackRGBA(0, 0, 255, 255),
87*c8dee2aaSAndroid Build Coastguard Worker     GrColorPackRGBA(0, 0, 0, 255)
88*c8dee2aaSAndroid Build Coastguard Worker };
89*c8dee2aaSAndroid Build Coastguard Worker 
90*c8dee2aaSAndroid Build Coastguard Worker struct Vertex {
91*c8dee2aaSAndroid Build Coastguard Worker     float     fX;
92*c8dee2aaSAndroid Build Coastguard Worker     float     fY;
93*c8dee2aaSAndroid Build Coastguard Worker     GrColor   fColor;
94*c8dee2aaSAndroid Build Coastguard Worker };
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker namespace {
97*c8dee2aaSAndroid Build Coastguard Worker class PipelineDynamicStateTestProcessor : public GrGeometryProcessor {
98*c8dee2aaSAndroid Build Coastguard Worker public:
Make(SkArenaAlloc * arena)99*c8dee2aaSAndroid Build Coastguard Worker     static GrGeometryProcessor* Make(SkArenaAlloc* arena) {
100*c8dee2aaSAndroid Build Coastguard Worker         return arena->make(
101*c8dee2aaSAndroid Build Coastguard Worker                 [&](void* ptr) { return new (ptr) PipelineDynamicStateTestProcessor(); });
102*c8dee2aaSAndroid Build Coastguard Worker     }
103*c8dee2aaSAndroid Build Coastguard Worker 
name() const104*c8dee2aaSAndroid Build Coastguard Worker     const char* name() const override { return "GrPipelineDynamicStateTest Processor"; }
105*c8dee2aaSAndroid Build Coastguard Worker 
addToKey(const GrShaderCaps &,skgpu::KeyBuilder *) const106*c8dee2aaSAndroid Build Coastguard Worker     void addToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const final {}
107*c8dee2aaSAndroid Build Coastguard Worker 
108*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const final;
109*c8dee2aaSAndroid Build Coastguard Worker 
110*c8dee2aaSAndroid Build Coastguard Worker private:
PipelineDynamicStateTestProcessor()111*c8dee2aaSAndroid Build Coastguard Worker     PipelineDynamicStateTestProcessor() : INHERITED(kGrPipelineDynamicStateTestProcessor_ClassID) {
112*c8dee2aaSAndroid Build Coastguard Worker         this->setVertexAttributesWithImplicitOffsets(kAttributes, std::size(kAttributes));
113*c8dee2aaSAndroid Build Coastguard Worker     }
114*c8dee2aaSAndroid Build Coastguard Worker 
inVertex() const115*c8dee2aaSAndroid Build Coastguard Worker     const Attribute& inVertex() const { return kAttributes[0]; }
inColor() const116*c8dee2aaSAndroid Build Coastguard Worker     const Attribute& inColor() const { return kAttributes[1]; }
117*c8dee2aaSAndroid Build Coastguard Worker 
118*c8dee2aaSAndroid Build Coastguard Worker     inline static constexpr Attribute kAttributes[] = {
119*c8dee2aaSAndroid Build Coastguard Worker             {"vertex", kFloat2_GrVertexAttribType, SkSLType::kHalf2},
120*c8dee2aaSAndroid Build Coastguard Worker             {"color", kUByte4_norm_GrVertexAttribType, SkSLType::kHalf4},
121*c8dee2aaSAndroid Build Coastguard Worker     };
122*c8dee2aaSAndroid Build Coastguard Worker 
123*c8dee2aaSAndroid Build Coastguard Worker     friend class GLSLPipelineDynamicStateTestProcessor;
124*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = GrGeometryProcessor;
125*c8dee2aaSAndroid Build Coastguard Worker };
126*c8dee2aaSAndroid Build Coastguard Worker }  // anonymous namespace
127*c8dee2aaSAndroid Build Coastguard Worker 
128*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrGeometryProcessor::ProgramImpl>
makeProgramImpl(const GrShaderCaps &) const129*c8dee2aaSAndroid Build Coastguard Worker PipelineDynamicStateTestProcessor::makeProgramImpl(const GrShaderCaps&) const {
130*c8dee2aaSAndroid Build Coastguard Worker     class Impl : public GrGeometryProcessor::ProgramImpl {
131*c8dee2aaSAndroid Build Coastguard Worker     public:
132*c8dee2aaSAndroid Build Coastguard Worker         void setData(const GrGLSLProgramDataManager&,
133*c8dee2aaSAndroid Build Coastguard Worker                      const GrShaderCaps&,
134*c8dee2aaSAndroid Build Coastguard Worker                      const GrGeometryProcessor&) final {}
135*c8dee2aaSAndroid Build Coastguard Worker 
136*c8dee2aaSAndroid Build Coastguard Worker         void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
137*c8dee2aaSAndroid Build Coastguard Worker             const PipelineDynamicStateTestProcessor& mp =
138*c8dee2aaSAndroid Build Coastguard Worker                     args.fGeomProc.cast<PipelineDynamicStateTestProcessor>();
139*c8dee2aaSAndroid Build Coastguard Worker             GrGLSLVertexBuilder* v = args.fVertBuilder;
140*c8dee2aaSAndroid Build Coastguard Worker             GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
141*c8dee2aaSAndroid Build Coastguard Worker 
142*c8dee2aaSAndroid Build Coastguard Worker             GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
143*c8dee2aaSAndroid Build Coastguard Worker             varyingHandler->emitAttributes(mp);
144*c8dee2aaSAndroid Build Coastguard Worker             f->codeAppendf("half4 %s;", args.fOutputColor);
145*c8dee2aaSAndroid Build Coastguard Worker             varyingHandler->addPassThroughAttribute(mp.inColor().asShaderVar(), args.fOutputColor);
146*c8dee2aaSAndroid Build Coastguard Worker 
147*c8dee2aaSAndroid Build Coastguard Worker             v->codeAppendf("float2 vertex = %s;", mp.inVertex().name());
148*c8dee2aaSAndroid Build Coastguard Worker             gpArgs->fPositionVar.set(SkSLType::kFloat2, "vertex");
149*c8dee2aaSAndroid Build Coastguard Worker             f->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
150*c8dee2aaSAndroid Build Coastguard Worker         }
151*c8dee2aaSAndroid Build Coastguard Worker     };
152*c8dee2aaSAndroid Build Coastguard Worker     return std::make_unique<Impl>();
153*c8dee2aaSAndroid Build Coastguard Worker }
154*c8dee2aaSAndroid Build Coastguard Worker 
155*c8dee2aaSAndroid Build Coastguard Worker namespace {
156*c8dee2aaSAndroid Build Coastguard Worker class GrPipelineDynamicStateTestOp : public GrDrawOp {
157*c8dee2aaSAndroid Build Coastguard Worker public:
158*c8dee2aaSAndroid Build Coastguard Worker     DEFINE_OP_CLASS_ID
159*c8dee2aaSAndroid Build Coastguard Worker 
Make(GrRecordingContext * context,GrScissorTest scissorTest,sk_sp<const GrBuffer> vbuff)160*c8dee2aaSAndroid Build Coastguard Worker     static GrOp::Owner Make(GrRecordingContext* context,
161*c8dee2aaSAndroid Build Coastguard Worker                             GrScissorTest scissorTest,
162*c8dee2aaSAndroid Build Coastguard Worker                             sk_sp<const GrBuffer> vbuff) {
163*c8dee2aaSAndroid Build Coastguard Worker         return GrOp::Make<GrPipelineDynamicStateTestOp>(context, scissorTest, std::move(vbuff));
164*c8dee2aaSAndroid Build Coastguard Worker     }
165*c8dee2aaSAndroid Build Coastguard Worker 
166*c8dee2aaSAndroid Build Coastguard Worker private:
167*c8dee2aaSAndroid Build Coastguard Worker     friend class GrOp;
168*c8dee2aaSAndroid Build Coastguard Worker 
GrPipelineDynamicStateTestOp(GrScissorTest scissorTest,sk_sp<const GrBuffer> vbuff)169*c8dee2aaSAndroid Build Coastguard Worker     GrPipelineDynamicStateTestOp(GrScissorTest scissorTest, sk_sp<const GrBuffer> vbuff)
170*c8dee2aaSAndroid Build Coastguard Worker         : INHERITED(ClassID())
171*c8dee2aaSAndroid Build Coastguard Worker         , fScissorTest(scissorTest)
172*c8dee2aaSAndroid Build Coastguard Worker         , fVertexBuffer(std::move(vbuff)) {
173*c8dee2aaSAndroid Build Coastguard Worker         this->setBounds(SkRect::MakeIWH(kScreenSize, kScreenSize),
174*c8dee2aaSAndroid Build Coastguard Worker                         HasAABloat::kNo, IsHairline::kNo);
175*c8dee2aaSAndroid Build Coastguard Worker     }
176*c8dee2aaSAndroid Build Coastguard Worker 
name() const177*c8dee2aaSAndroid Build Coastguard Worker     const char* name() const override { return "GrPipelineDynamicStateTestOp"; }
fixedFunctionFlags() const178*c8dee2aaSAndroid Build Coastguard Worker     FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
finalize(const GrCaps &,const GrAppliedClip *,GrClampType)179*c8dee2aaSAndroid Build Coastguard Worker     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override {
180*c8dee2aaSAndroid Build Coastguard Worker         return GrProcessorSet::EmptySetAnalysis();
181*c8dee2aaSAndroid Build Coastguard Worker     }
onPrePrepare(GrRecordingContext *,const GrSurfaceProxyView & writeView,GrAppliedClip *,const GrDstProxyView &,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)182*c8dee2aaSAndroid Build Coastguard Worker     void onPrePrepare(GrRecordingContext*,
183*c8dee2aaSAndroid Build Coastguard Worker                       const GrSurfaceProxyView& writeView,
184*c8dee2aaSAndroid Build Coastguard Worker                       GrAppliedClip*,
185*c8dee2aaSAndroid Build Coastguard Worker                       const GrDstProxyView&,
186*c8dee2aaSAndroid Build Coastguard Worker                       GrXferBarrierFlags renderPassXferBarriers,
187*c8dee2aaSAndroid Build Coastguard Worker                       GrLoadOp colorLoadOp) override {}
onPrepare(GrOpFlushState *)188*c8dee2aaSAndroid Build Coastguard Worker     void onPrepare(GrOpFlushState*) override {}
onExecute(GrOpFlushState * flushState,const SkRect & chainBounds)189*c8dee2aaSAndroid Build Coastguard Worker     void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
190*c8dee2aaSAndroid Build Coastguard Worker         GrPipeline pipeline(fScissorTest, SkBlendMode::kSrc,
191*c8dee2aaSAndroid Build Coastguard Worker                             flushState->drawOpArgs().writeView().swizzle());
192*c8dee2aaSAndroid Build Coastguard Worker         STArray<kNumMeshes, GrSimpleMesh> meshes;
193*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < kNumMeshes; ++i) {
194*c8dee2aaSAndroid Build Coastguard Worker             GrSimpleMesh& mesh = meshes.push_back();
195*c8dee2aaSAndroid Build Coastguard Worker             mesh.set(fVertexBuffer, 4, 4 * i);
196*c8dee2aaSAndroid Build Coastguard Worker         }
197*c8dee2aaSAndroid Build Coastguard Worker 
198*c8dee2aaSAndroid Build Coastguard Worker         auto geomProc = PipelineDynamicStateTestProcessor::Make(flushState->allocator());
199*c8dee2aaSAndroid Build Coastguard Worker 
200*c8dee2aaSAndroid Build Coastguard Worker         GrProgramInfo programInfo(flushState->caps(),
201*c8dee2aaSAndroid Build Coastguard Worker                                   flushState->writeView(),
202*c8dee2aaSAndroid Build Coastguard Worker                                   flushState->usesMSAASurface(),
203*c8dee2aaSAndroid Build Coastguard Worker                                   &pipeline,
204*c8dee2aaSAndroid Build Coastguard Worker                                   &GrUserStencilSettings::kUnused,
205*c8dee2aaSAndroid Build Coastguard Worker                                   geomProc,
206*c8dee2aaSAndroid Build Coastguard Worker                                   GrPrimitiveType::kTriangleStrip,
207*c8dee2aaSAndroid Build Coastguard Worker                                   flushState->renderPassBarriers(),
208*c8dee2aaSAndroid Build Coastguard Worker                                   flushState->colorLoadOp());
209*c8dee2aaSAndroid Build Coastguard Worker 
210*c8dee2aaSAndroid Build Coastguard Worker         flushState->bindPipeline(programInfo, SkRect::MakeIWH(kScreenSize, kScreenSize));
211*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < 4; ++i) {
212*c8dee2aaSAndroid Build Coastguard Worker             if (fScissorTest == GrScissorTest::kEnabled) {
213*c8dee2aaSAndroid Build Coastguard Worker                 flushState->setScissorRect(kDynamicScissors[i]);
214*c8dee2aaSAndroid Build Coastguard Worker             }
215*c8dee2aaSAndroid Build Coastguard Worker             flushState->drawMesh(meshes[i]);
216*c8dee2aaSAndroid Build Coastguard Worker         }
217*c8dee2aaSAndroid Build Coastguard Worker     }
218*c8dee2aaSAndroid Build Coastguard Worker 
219*c8dee2aaSAndroid Build Coastguard Worker     GrScissorTest               fScissorTest;
220*c8dee2aaSAndroid Build Coastguard Worker     const sk_sp<const GrBuffer> fVertexBuffer;
221*c8dee2aaSAndroid Build Coastguard Worker 
222*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = GrDrawOp;
223*c8dee2aaSAndroid Build Coastguard Worker };
224*c8dee2aaSAndroid Build Coastguard Worker }  // anonymous namespace
225*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrPipelineDynamicStateTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)226*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrPipelineDynamicStateTest,
227*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
228*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
229*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kApiLevel_T) {
230*c8dee2aaSAndroid Build Coastguard Worker     auto dContext = ctxInfo.directContext();
231*c8dee2aaSAndroid Build Coastguard Worker     GrResourceProvider* rp = dContext->priv().resourceProvider();
232*c8dee2aaSAndroid Build Coastguard Worker 
233*c8dee2aaSAndroid Build Coastguard Worker     auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dContext,
234*c8dee2aaSAndroid Build Coastguard Worker                                                        GrColorType::kRGBA_8888,
235*c8dee2aaSAndroid Build Coastguard Worker                                                        nullptr,
236*c8dee2aaSAndroid Build Coastguard Worker                                                        SkBackingFit::kExact,
237*c8dee2aaSAndroid Build Coastguard Worker                                                        {kScreenSize, kScreenSize},
238*c8dee2aaSAndroid Build Coastguard Worker                                                        SkSurfaceProps(),
239*c8dee2aaSAndroid Build Coastguard Worker                                                        /*label=*/{});
240*c8dee2aaSAndroid Build Coastguard Worker     if (!sdc) {
241*c8dee2aaSAndroid Build Coastguard Worker         ERRORF(reporter, "could not create render target context.");
242*c8dee2aaSAndroid Build Coastguard Worker         return;
243*c8dee2aaSAndroid Build Coastguard Worker     }
244*c8dee2aaSAndroid Build Coastguard Worker 
245*c8dee2aaSAndroid Build Coastguard Worker     constexpr float d = (float) kScreenSize;
246*c8dee2aaSAndroid Build Coastguard Worker     Vertex vdata[kNumMeshes * 4] = {
247*c8dee2aaSAndroid Build Coastguard Worker         {0, 0, kMeshColors[0]},
248*c8dee2aaSAndroid Build Coastguard Worker         {0, d, kMeshColors[0]},
249*c8dee2aaSAndroid Build Coastguard Worker         {d, 0, kMeshColors[0]},
250*c8dee2aaSAndroid Build Coastguard Worker         {d, d, kMeshColors[0]},
251*c8dee2aaSAndroid Build Coastguard Worker 
252*c8dee2aaSAndroid Build Coastguard Worker         {0, 0, kMeshColors[1]},
253*c8dee2aaSAndroid Build Coastguard Worker         {0, d, kMeshColors[1]},
254*c8dee2aaSAndroid Build Coastguard Worker         {d, 0, kMeshColors[1]},
255*c8dee2aaSAndroid Build Coastguard Worker         {d, d, kMeshColors[1]},
256*c8dee2aaSAndroid Build Coastguard Worker 
257*c8dee2aaSAndroid Build Coastguard Worker         {0, 0, kMeshColors[2]},
258*c8dee2aaSAndroid Build Coastguard Worker         {0, d, kMeshColors[2]},
259*c8dee2aaSAndroid Build Coastguard Worker         {d, 0, kMeshColors[2]},
260*c8dee2aaSAndroid Build Coastguard Worker         {d, d, kMeshColors[2]},
261*c8dee2aaSAndroid Build Coastguard Worker 
262*c8dee2aaSAndroid Build Coastguard Worker         {0, 0, kMeshColors[3]},
263*c8dee2aaSAndroid Build Coastguard Worker         {0, d, kMeshColors[3]},
264*c8dee2aaSAndroid Build Coastguard Worker         {d, 0, kMeshColors[3]},
265*c8dee2aaSAndroid Build Coastguard Worker         {d, d, kMeshColors[3]}
266*c8dee2aaSAndroid Build Coastguard Worker     };
267*c8dee2aaSAndroid Build Coastguard Worker 
268*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<const GrBuffer> vbuff(rp->createBuffer(vdata,
269*c8dee2aaSAndroid Build Coastguard Worker                                                  sizeof(vdata),
270*c8dee2aaSAndroid Build Coastguard Worker                                                  GrGpuBufferType::kVertex,
271*c8dee2aaSAndroid Build Coastguard Worker                                                  kDynamic_GrAccessPattern));
272*c8dee2aaSAndroid Build Coastguard Worker     if (!vbuff) {
273*c8dee2aaSAndroid Build Coastguard Worker         ERRORF(reporter, "vbuff is null.");
274*c8dee2aaSAndroid Build Coastguard Worker         return;
275*c8dee2aaSAndroid Build Coastguard Worker     }
276*c8dee2aaSAndroid Build Coastguard Worker 
277*c8dee2aaSAndroid Build Coastguard Worker     uint32_t resultPx[kScreenSize * kScreenSize];
278*c8dee2aaSAndroid Build Coastguard Worker 
279*c8dee2aaSAndroid Build Coastguard Worker     for (GrScissorTest scissorTest : {GrScissorTest::kEnabled, GrScissorTest::kDisabled}) {
280*c8dee2aaSAndroid Build Coastguard Worker         sdc->clear(SkPMColor4f::FromBytes_RGBA(0xbaaaaaad));
281*c8dee2aaSAndroid Build Coastguard Worker         sdc->addDrawOp(GrPipelineDynamicStateTestOp::Make(dContext, scissorTest, vbuff));
282*c8dee2aaSAndroid Build Coastguard Worker         auto ii = SkImageInfo::Make(kScreenSize, kScreenSize,
283*c8dee2aaSAndroid Build Coastguard Worker                                     kRGBA_8888_SkColorType, kPremul_SkAlphaType);
284*c8dee2aaSAndroid Build Coastguard Worker         GrPixmap resultPM(ii, resultPx, kScreenSize*sizeof(uint32_t));
285*c8dee2aaSAndroid Build Coastguard Worker         sdc->readPixels(dContext, resultPM, {0, 0});
286*c8dee2aaSAndroid Build Coastguard Worker         for (int y = 0; y < kScreenSize; ++y) {
287*c8dee2aaSAndroid Build Coastguard Worker             for (int x = 0; x < kScreenSize; ++x) {
288*c8dee2aaSAndroid Build Coastguard Worker                 int expectedColorIdx;
289*c8dee2aaSAndroid Build Coastguard Worker                 if (GrScissorTest::kEnabled == scissorTest) {
290*c8dee2aaSAndroid Build Coastguard Worker                     expectedColorIdx = (x < kScreenSplitX ? 0 : 2) + (y < kScreenSplitY ? 0 : 1);
291*c8dee2aaSAndroid Build Coastguard Worker                 } else {
292*c8dee2aaSAndroid Build Coastguard Worker                     expectedColorIdx = kNumMeshes - 1;
293*c8dee2aaSAndroid Build Coastguard Worker                 }
294*c8dee2aaSAndroid Build Coastguard Worker                 uint32_t expected = kMeshColors[expectedColorIdx];
295*c8dee2aaSAndroid Build Coastguard Worker                 uint32_t actual = resultPx[y * kScreenSize + x];
296*c8dee2aaSAndroid Build Coastguard Worker                 if (expected != actual) {
297*c8dee2aaSAndroid Build Coastguard Worker                     ERRORF(reporter, "[scissor=%s] pixel (%i,%i): got 0x%x expected 0x%x",
298*c8dee2aaSAndroid Build Coastguard Worker                            GrScissorTest::kEnabled == scissorTest ? "enabled" : "disabled", x, y,
299*c8dee2aaSAndroid Build Coastguard Worker                            actual, expected);
300*c8dee2aaSAndroid Build Coastguard Worker                     return;
301*c8dee2aaSAndroid Build Coastguard Worker                 }
302*c8dee2aaSAndroid Build Coastguard Worker             }
303*c8dee2aaSAndroid Build Coastguard Worker         }
304*c8dee2aaSAndroid Build Coastguard Worker     }
305*c8dee2aaSAndroid Build Coastguard Worker }
306