blob: 1ef7420d74c86f25e1da6e61248a018bb2be1c98 [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,
49 const GrPrimitiveProcessor& pp,
Brian Salomonc241b582019-11-27 08:57:17 -050050 const CoordTransformRange& transformRange) override {
Brian Salomone21af502019-11-22 16:56:36 -050051 const auto& gp = pp.cast<GP>();
Michael Ludwig553db622020-06-19 10:47:30 -040052 this->setTransformDataHelper(pdman, transformRange);
53 this->setTransform(pdman, fLocalMatrixUni, gp.fLocalMatrix);
54 }
55
56 static void GenKey(const GP& gp, GrProcessorKeyBuilder* b) {
57 b->add32(ComputeMatrixKey(gp.fLocalMatrix));
Brian Salomone21af502019-11-22 16:56:36 -050058 }
59
60 private:
61 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
62 const auto& gp = args.fGP.cast<GP>();
63 args.fVaryingHandler->emitAttributes(gp);
64 GrGLSLVarying colorVarying(kHalf4_GrSLType);
65 args.fVaryingHandler->addVarying("color", &colorVarying,
66 GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
67 args.fVertBuilder->codeAppendf("%s = %s;", colorVarying.vsOut(), gp.fInColor.name());
68 args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorVarying.fsIn());
69 args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
70 this->writeOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name());
Michael Ludwig553db622020-06-19 10:47:30 -040071 this->writeLocalCoord(args.fVertBuilder, args.fUniformHandler, gpArgs,
72 gp.fInLocalCoords.asShaderVar(), gp.fLocalMatrix,
73 &fLocalMatrixUni);
Brian Salomone21af502019-11-22 16:56:36 -050074 }
Michael Ludwig553db622020-06-19 10:47:30 -040075
76 UniformHandle fLocalMatrixUni;
Brian Salomone21af502019-11-22 16:56:36 -050077 };
Michael Ludwig553db622020-06-19 10:47:30 -040078
79 Attribute fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
80 Attribute fInLocalCoords = {"inLocalCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
81 Attribute fInColor;
82 SkMatrix fLocalMatrix;
83};
Brian Salomone21af502019-11-22 16:56:36 -050084
85class TestRectOp final : public GrMeshDrawOp {
86public:
87 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext*,
88 GrPaint&&,
89 const SkRect& drawRect,
90 const SkRect& localRect,
91 const SkMatrix& localM);
92
93 const char* name() const override { return "TestRectOp"; }
94
95 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
96
97 GrProcessorSet::Analysis finalize(const GrCaps&,
98 const GrAppliedClip*,
99 bool hasMixedSampledCoverage,
100 GrClampType) override;
101
102 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillips4f93c572020-03-18 08:13:53 -0400103 if (fProgramInfo) {
104 fProgramInfo->visitFPProxies(func);
105 } else {
106 fProcessorSet.visitProxies(func);
107 }
Brian Salomone21af502019-11-22 16:56:36 -0500108 }
109
110private:
111 DEFINE_OP_CLASS_ID
112
113 TestRectOp(const GrCaps*,
114 GrPaint&&,
115 const SkRect& drawRect,
116 const SkRect& localRect,
117 const SkMatrix& localMatrix);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500118
Robert Phillips2669a7b2020-03-12 12:07:19 -0400119 GrProgramInfo* programInfo() override { return fProgramInfo; }
Robert Phillips4133dc42020-03-11 15:55:55 -0400120 void onCreateProgramInfo(const GrCaps*,
121 SkArenaAlloc*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400122 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400123 GrAppliedClip&&,
124 const GrXferProcessor::DstProxyView&) 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
Brian Salomone21af502019-11-22 16:56:36 -0500140 friend class ::GrOpMemoryPool;
141};
142
143std::unique_ptr<GrDrawOp> TestRectOp::Make(GrRecordingContext* context,
144 GrPaint&& paint,
145 const SkRect& drawRect,
146 const SkRect& localRect,
147 const SkMatrix& localM) {
148 auto* pool = context->priv().opMemoryPool();
149 const auto* caps = context->priv().caps();
150 return pool->allocate<TestRectOp>(caps, std::move(paint), drawRect, localRect, localM);
151}
152
153GrProcessorSet::Analysis TestRectOp::finalize(const GrCaps& caps,
154 const GrAppliedClip* clip,
155 bool hasMixedSampledCoverage,
156 GrClampType clampType) {
157 return fProcessorSet.finalize(GrProcessorAnalysisColor::Opaque::kYes,
158 GrProcessorAnalysisCoverage::kSingleChannel, clip,
159 &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, caps,
160 clampType, &fColor);
161}
162
163static bool use_wide_color(const GrPaint& paint, const GrCaps* caps) {
164 return !paint.getColor4f().fitsInBytes() && caps->halfFloatVertexAttributeSupport();
165}
166TestRectOp::TestRectOp(const GrCaps* caps,
167 GrPaint&& paint,
168 const SkRect& drawRect,
169 const SkRect& localRect,
170 const SkMatrix& localMatrix)
171 : GrMeshDrawOp(ClassID())
172 , fDrawRect(drawRect)
173 , fLocalRect(localRect)
174 , fColor(paint.getColor4f())
175 , fGP(localMatrix, use_wide_color(paint, caps))
176 , fProcessorSet(std::move(paint)) {
177 this->setBounds(drawRect.makeSorted(), HasAABloat::kNo, IsHairline::kNo);
178}
179
Robert Phillips4133dc42020-03-11 15:55:55 -0400180void TestRectOp::onCreateProgramInfo(const GrCaps* caps,
181 SkArenaAlloc* arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400182 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400183 GrAppliedClip&& appliedClip,
184 const GrXferProcessor::DstProxyView& dstProxyView) {
185 fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
186 arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400187 writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400188 std::move(appliedClip),
189 dstProxyView,
190 &fGP,
191 std::move(fProcessorSet),
192 GrPrimitiveType::kTriangles,
193 GrPipeline::InputFlags::kNone);
Robert Phillipsac6156c2020-02-28 16:02:40 -0500194}
195
Brian Salomone21af502019-11-22 16:56:36 -0500196void TestRectOp::onPrepareDraws(Target* target) {
197 QuadHelper helper(target, fGP.vertexStride(), 1);
198 GrVertexWriter writer{helper.vertices()};
199 auto pos = GrVertexWriter::TriStripFromRect(fDrawRect);
200 auto local = GrVertexWriter::TriStripFromRect(fLocalRect);
201 GrVertexColor color(fColor, fGP.wideColor());
202 writer.writeQuad(pos, local, color);
Robert Phillipsac6156c2020-02-28 16:02:40 -0500203
204 fMesh = helper.mesh();
Brian Salomone21af502019-11-22 16:56:36 -0500205}
206
207void TestRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
Robert Phillipsac6156c2020-02-28 16:02:40 -0500208 if (!fProgramInfo) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400209 this->createProgramInfo(flushState);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500210 }
Robert Phillips3968fcb2019-12-05 16:40:31 -0500211
Chris Dalton765ed362020-03-16 17:34:44 -0600212 flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
213 flushState->bindTextures(fProgramInfo->primProc(), nullptr, fProgramInfo->pipeline());
214 flushState->drawMesh(*fMesh);
Brian Salomone21af502019-11-22 16:56:36 -0500215}
216
217} // anonymous namespace
218
219namespace sk_gpu_test::test_ops {
220
221std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
222 GrPaint&& paint,
223 const SkRect& drawRect,
224 const SkRect& localRect,
225 const SkMatrix& localM) {
226 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
227}
228
229std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
230 std::unique_ptr<GrFragmentProcessor> fp,
231 const SkRect& drawRect,
232 const SkRect& localRect,
233 const SkMatrix& localM) {
234 GrPaint paint;
235 paint.addColorFragmentProcessor(std::move(fp));
236 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
237}
238
239std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
240 GrPaint&& paint,
241 const SkRect& rect) {
242 return TestRectOp::Make(context, std::move(paint), rect, rect, SkMatrix::I());
243}
244
245} // namespace sk_gpu_test::test_ops