blob: c190b27a0b155dbac0f285f67bbada176ae936f4 [file] [log] [blame]
Brian Salomone21af502019-11-22 16:56:36 -05001/*
2 * Copyright 2019 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "tools/gpu/TestOps.h"
9
10#include "src/core/SkPointPriv.h"
11#include "src/gpu/GrCaps.h"
12#include "src/gpu/GrGeometryProcessor.h"
13#include "src/gpu/GrMemoryPool.h"
14#include "src/gpu/GrOpFlushState.h"
Robert Phillips4f93c572020-03-18 08:13:53 -040015#include "src/gpu/GrProgramInfo.h"
Brian Salomone21af502019-11-22 16:56:36 -050016#include "src/gpu/GrVertexWriter.h"
17#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
18#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
19#include "src/gpu/glsl/GrGLSLVarying.h"
20#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
Robert Phillips3968fcb2019-12-05 16:40:31 -050021#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
Brian Salomone21af502019-11-22 16:56:36 -050022
23namespace {
24
25class GP : public GrGeometryProcessor {
26public:
27 GP(const SkMatrix& localMatrix, bool wideColor)
28 : GrGeometryProcessor(kTestRectOp_ClassID), fLocalMatrix(localMatrix) {
29 fInColor = MakeColorAttribute("color", wideColor);
30 this->setVertexAttributes(&fInPosition, 3);
31 }
32
33 const char* name() const override { return "TestRectOp::GP"; }
34
Michael Ludwig553db622020-06-19 10:47:30 -040035 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override {
36 return new GLSLGP();
37 }
Brian Salomone21af502019-11-22 16:56:36 -050038
Michael Ludwig553db622020-06-19 10:47:30 -040039 void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
40 GLSLGP::GenKey(*this, b);
41 }
Brian Salomone21af502019-11-22 16:56:36 -050042
43 bool wideColor() const { return fInColor.cpuType() != kUByte4_norm_GrVertexAttribType; }
44
45private:
Brian Salomone21af502019-11-22 16:56:36 -050046 class GLSLGP : public GrGLSLGeometryProcessor {
Michael Ludwig553db622020-06-19 10:47:30 -040047 public:
Brian Salomone21af502019-11-22 16:56:36 -050048 void setData(const GrGLSLProgramDataManager& pdman,
Brian Osman609f1592020-07-01 15:14:39 -040049 const GrPrimitiveProcessor& pp) override {
Brian Salomone21af502019-11-22 16:56:36 -050050 const auto& gp = pp.cast<GP>();
Michael Ludwig553db622020-06-19 10:47:30 -040051 this->setTransform(pdman, fLocalMatrixUni, gp.fLocalMatrix);
52 }
53
54 static void GenKey(const GP& gp, GrProcessorKeyBuilder* b) {
55 b->add32(ComputeMatrixKey(gp.fLocalMatrix));
Brian Salomone21af502019-11-22 16:56:36 -050056 }
57
58 private:
59 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
60 const auto& gp = args.fGP.cast<GP>();
61 args.fVaryingHandler->emitAttributes(gp);
62 GrGLSLVarying colorVarying(kHalf4_GrSLType);
63 args.fVaryingHandler->addVarying("color", &colorVarying,
64 GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
65 args.fVertBuilder->codeAppendf("%s = %s;", colorVarying.vsOut(), gp.fInColor.name());
66 args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorVarying.fsIn());
67 args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
68 this->writeOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name());
Michael Ludwig553db622020-06-19 10:47:30 -040069 this->writeLocalCoord(args.fVertBuilder, args.fUniformHandler, gpArgs,
70 gp.fInLocalCoords.asShaderVar(), gp.fLocalMatrix,
71 &fLocalMatrixUni);
Brian Salomone21af502019-11-22 16:56:36 -050072 }
Michael Ludwig553db622020-06-19 10:47:30 -040073
74 UniformHandle fLocalMatrixUni;
Brian Salomone21af502019-11-22 16:56:36 -050075 };
Michael Ludwig553db622020-06-19 10:47:30 -040076
77 Attribute fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
78 Attribute fInLocalCoords = {"inLocalCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
79 Attribute fInColor;
80 SkMatrix fLocalMatrix;
81};
Brian Salomone21af502019-11-22 16:56:36 -050082
83class TestRectOp final : public GrMeshDrawOp {
84public:
Herb Derbyc76d4092020-10-07 16:46:15 -040085 static GrOp::Owner Make(GrRecordingContext*,
86 GrPaint&&,
87 const SkRect& drawRect,
88 const SkRect& localRect,
89 const SkMatrix& localM);
Brian Salomone21af502019-11-22 16:56:36 -050090
91 const char* name() const override { return "TestRectOp"; }
92
93 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
94
95 GrProcessorSet::Analysis finalize(const GrCaps&,
96 const GrAppliedClip*,
97 bool hasMixedSampledCoverage,
98 GrClampType) override;
99
100 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillips4f93c572020-03-18 08:13:53 -0400101 if (fProgramInfo) {
102 fProgramInfo->visitFPProxies(func);
103 } else {
104 fProcessorSet.visitProxies(func);
105 }
Brian Salomone21af502019-11-22 16:56:36 -0500106 }
107
108private:
109 DEFINE_OP_CLASS_ID
110
111 TestRectOp(const GrCaps*,
112 GrPaint&&,
113 const SkRect& drawRect,
114 const SkRect& localRect,
115 const SkMatrix& localMatrix);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500116
Robert Phillips2669a7b2020-03-12 12:07:19 -0400117 GrProgramInfo* programInfo() override { return fProgramInfo; }
Robert Phillips4133dc42020-03-11 15:55:55 -0400118 void onCreateProgramInfo(const GrCaps*,
119 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500120 const GrSurfaceProxyView& writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400121 GrAppliedClip&&,
Greg Danield358cbe2020-09-11 09:33:54 -0400122 const GrXferProcessor::DstProxyView&,
Greg Daniel42dbca52020-11-20 10:22:43 -0500123 GrXferBarrierFlags renderPassXferBarriers,
124 GrLoadOp colorLoadOp) override;
Robert Phillipsac6156c2020-02-28 16:02:40 -0500125
Brian Salomone21af502019-11-22 16:56:36 -0500126 void onPrepareDraws(Target*) override;
127 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
128
Robert Phillipsac6156c2020-02-28 16:02:40 -0500129 SkRect fDrawRect;
130 SkRect fLocalRect;
131 SkPMColor4f fColor;
132 GP fGP;
Brian Salomone21af502019-11-22 16:56:36 -0500133 GrProcessorSet fProcessorSet;
134
Robert Phillipsac6156c2020-02-28 16:02:40 -0500135 // If this op is prePrepared the created programInfo will be stored here for use in
Robert Phillips6c59fe42020-02-27 09:30:37 -0500136 // onExecute. In the prePrepared case it will have been stored in the record-time arena.
Robert Phillipsac6156c2020-02-28 16:02:40 -0500137 GrProgramInfo* fProgramInfo = nullptr;
Chris Daltoneb694b72020-03-16 09:25:50 -0600138 GrSimpleMesh* fMesh = nullptr;
Robert Phillips6c59fe42020-02-27 09:30:37 -0500139
Herb Derbyc76d4092020-10-07 16:46:15 -0400140 friend class ::GrOp;
Brian Salomone21af502019-11-22 16:56:36 -0500141};
142
Herb Derbyc76d4092020-10-07 16:46:15 -0400143GrOp::Owner TestRectOp::Make(GrRecordingContext* context,
144 GrPaint&& paint,
145 const SkRect& drawRect,
146 const SkRect& localRect,
147 const SkMatrix& localM) {
Brian Salomone21af502019-11-22 16:56:36 -0500148 const auto* caps = context->priv().caps();
Herb Derbyc76d4092020-10-07 16:46:15 -0400149 return GrOp::Make<TestRectOp>(context, caps, std::move(paint), drawRect, localRect, localM);
Brian Salomone21af502019-11-22 16:56:36 -0500150}
151
152GrProcessorSet::Analysis TestRectOp::finalize(const GrCaps& caps,
153 const GrAppliedClip* clip,
154 bool hasMixedSampledCoverage,
155 GrClampType clampType) {
156 return fProcessorSet.finalize(GrProcessorAnalysisColor::Opaque::kYes,
157 GrProcessorAnalysisCoverage::kSingleChannel, clip,
158 &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, caps,
159 clampType, &fColor);
160}
161
162static bool use_wide_color(const GrPaint& paint, const GrCaps* caps) {
163 return !paint.getColor4f().fitsInBytes() && caps->halfFloatVertexAttributeSupport();
164}
165TestRectOp::TestRectOp(const GrCaps* caps,
166 GrPaint&& paint,
167 const SkRect& drawRect,
168 const SkRect& localRect,
169 const SkMatrix& localMatrix)
170 : GrMeshDrawOp(ClassID())
171 , fDrawRect(drawRect)
172 , fLocalRect(localRect)
173 , fColor(paint.getColor4f())
174 , fGP(localMatrix, use_wide_color(paint, caps))
175 , fProcessorSet(std::move(paint)) {
176 this->setBounds(drawRect.makeSorted(), HasAABloat::kNo, IsHairline::kNo);
177}
178
Robert Phillips4133dc42020-03-11 15:55:55 -0400179void TestRectOp::onCreateProgramInfo(const GrCaps* caps,
180 SkArenaAlloc* arena,
Adlai Hollere2296f72020-11-19 13:41:26 -0500181 const GrSurfaceProxyView& writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400182 GrAppliedClip&& appliedClip,
Greg Danield358cbe2020-09-11 09:33:54 -0400183 const GrXferProcessor::DstProxyView& dstProxyView,
Greg Daniel42dbca52020-11-20 10:22:43 -0500184 GrXferBarrierFlags renderPassXferBarriers,
185 GrLoadOp colorLoadOp) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400186 fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
187 arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400188 writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400189 std::move(appliedClip),
190 dstProxyView,
191 &fGP,
192 std::move(fProcessorSet),
193 GrPrimitiveType::kTriangles,
Greg Danield358cbe2020-09-11 09:33:54 -0400194 renderPassXferBarriers,
Greg Daniel42dbca52020-11-20 10:22:43 -0500195 colorLoadOp,
Robert Phillips4133dc42020-03-11 15:55:55 -0400196 GrPipeline::InputFlags::kNone);
Robert Phillipsac6156c2020-02-28 16:02:40 -0500197}
198
Brian Salomone21af502019-11-22 16:56:36 -0500199void TestRectOp::onPrepareDraws(Target* target) {
200 QuadHelper helper(target, fGP.vertexStride(), 1);
201 GrVertexWriter writer{helper.vertices()};
202 auto pos = GrVertexWriter::TriStripFromRect(fDrawRect);
203 auto local = GrVertexWriter::TriStripFromRect(fLocalRect);
204 GrVertexColor color(fColor, fGP.wideColor());
205 writer.writeQuad(pos, local, color);
Robert Phillipsac6156c2020-02-28 16:02:40 -0500206
207 fMesh = helper.mesh();
Brian Salomone21af502019-11-22 16:56:36 -0500208}
209
210void TestRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
Robert Phillipsac6156c2020-02-28 16:02:40 -0500211 if (!fProgramInfo) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400212 this->createProgramInfo(flushState);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500213 }
Robert Phillips3968fcb2019-12-05 16:40:31 -0500214
Chris Dalton765ed362020-03-16 17:34:44 -0600215 flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
216 flushState->bindTextures(fProgramInfo->primProc(), nullptr, fProgramInfo->pipeline());
217 flushState->drawMesh(*fMesh);
Brian Salomone21af502019-11-22 16:56:36 -0500218}
219
220} // anonymous namespace
221
222namespace sk_gpu_test::test_ops {
223
Herb Derbyc76d4092020-10-07 16:46:15 -0400224GrOp::Owner MakeRect(GrRecordingContext* context,
225 GrPaint&& paint,
226 const SkRect& drawRect,
227 const SkRect& localRect,
228 const SkMatrix& localM) {
Brian Salomone21af502019-11-22 16:56:36 -0500229 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
230}
231
Herb Derbyc76d4092020-10-07 16:46:15 -0400232GrOp::Owner MakeRect(GrRecordingContext* context,
233 std::unique_ptr<GrFragmentProcessor> fp,
234 const SkRect& drawRect,
235 const SkRect& localRect,
236 const SkMatrix& localM) {
Brian Salomone21af502019-11-22 16:56:36 -0500237 GrPaint paint;
John Stiles5933d7d2020-07-21 12:28:35 -0400238 paint.setColorFragmentProcessor(std::move(fp));
Brian Salomone21af502019-11-22 16:56:36 -0500239 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
240}
241
Herb Derbyc76d4092020-10-07 16:46:15 -0400242GrOp::Owner MakeRect(GrRecordingContext* context,
243 GrPaint&& paint,
244 const SkRect& rect) {
Brian Salomone21af502019-11-22 16:56:36 -0500245 return TestRectOp::Make(context, std::move(paint), rect, rect, SkMatrix::I());
246}
247
248} // namespace sk_gpu_test::test_ops