blob: ff5201a2c98759ae670eb231337ecdbe3d74d8e0 [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
35 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps& caps) const override;
36
37 void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
38
39 bool wideColor() const { return fInColor.cpuType() != kUByte4_norm_GrVertexAttribType; }
40
41private:
42 Attribute fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
43 Attribute fInLocalCoords = {"inLocalCoords", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
44 Attribute fInColor;
45 SkMatrix fLocalMatrix;
46};
47
48GrGLSLPrimitiveProcessor* GP::createGLSLInstance(const GrShaderCaps& caps) const {
49 class GLSLGP : public GrGLSLGeometryProcessor {
50 void setData(const GrGLSLProgramDataManager& pdman,
51 const GrPrimitiveProcessor& pp,
Brian Salomonc241b582019-11-27 08:57:17 -050052 const CoordTransformRange& transformRange) override {
Brian Salomone21af502019-11-22 16:56:36 -050053 const auto& gp = pp.cast<GP>();
Brian Salomonc241b582019-11-27 08:57:17 -050054 this->setTransformDataHelper(gp.fLocalMatrix, pdman, transformRange);
Brian Salomone21af502019-11-22 16:56:36 -050055 }
56
57 private:
58 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
59 const auto& gp = args.fGP.cast<GP>();
60 args.fVaryingHandler->emitAttributes(gp);
61 GrGLSLVarying colorVarying(kHalf4_GrSLType);
62 args.fVaryingHandler->addVarying("color", &colorVarying,
63 GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
64 args.fVertBuilder->codeAppendf("%s = %s;", colorVarying.vsOut(), gp.fInColor.name());
65 args.fFragBuilder->codeAppendf("%s = %s;", args.fOutputColor, colorVarying.fsIn());
66 args.fFragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
67 this->writeOutputPosition(args.fVertBuilder, gpArgs, gp.fInPosition.name());
68 this->emitTransforms(args.fVertBuilder, args.fVaryingHandler, args.fUniformHandler,
69 gp.fInLocalCoords.asShaderVar(), gp.fLocalMatrix,
70 args.fFPCoordTransformHandler);
71 }
72 };
73 return new GLSLGP();
74}
75
76class TestRectOp final : public GrMeshDrawOp {
77public:
78 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext*,
79 GrPaint&&,
80 const SkRect& drawRect,
81 const SkRect& localRect,
82 const SkMatrix& localM);
83
84 const char* name() const override { return "TestRectOp"; }
85
86 FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
87
88 GrProcessorSet::Analysis finalize(const GrCaps&,
89 const GrAppliedClip*,
90 bool hasMixedSampledCoverage,
91 GrClampType) override;
92
93 void visitProxies(const VisitProxyFunc& func) const override {
Robert Phillips4f93c572020-03-18 08:13:53 -040094 if (fProgramInfo) {
95 fProgramInfo->visitFPProxies(func);
96 } else {
97 fProcessorSet.visitProxies(func);
98 }
Brian Salomone21af502019-11-22 16:56:36 -050099 }
100
101private:
102 DEFINE_OP_CLASS_ID
103
104 TestRectOp(const GrCaps*,
105 GrPaint&&,
106 const SkRect& drawRect,
107 const SkRect& localRect,
108 const SkMatrix& localMatrix);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500109
Robert Phillips2669a7b2020-03-12 12:07:19 -0400110 GrProgramInfo* programInfo() override { return fProgramInfo; }
Robert Phillips4133dc42020-03-11 15:55:55 -0400111 void onCreateProgramInfo(const GrCaps*,
112 SkArenaAlloc*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400113 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400114 GrAppliedClip&&,
115 const GrXferProcessor::DstProxyView&) override;
Robert Phillipsac6156c2020-02-28 16:02:40 -0500116
Brian Salomone21af502019-11-22 16:56:36 -0500117 void onPrepareDraws(Target*) override;
118 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
119
Robert Phillipsac6156c2020-02-28 16:02:40 -0500120 SkRect fDrawRect;
121 SkRect fLocalRect;
122 SkPMColor4f fColor;
123 GP fGP;
Brian Salomone21af502019-11-22 16:56:36 -0500124 GrProcessorSet fProcessorSet;
125
Robert Phillipsac6156c2020-02-28 16:02:40 -0500126 // If this op is prePrepared the created programInfo will be stored here for use in
Robert Phillips6c59fe42020-02-27 09:30:37 -0500127 // onExecute. In the prePrepared case it will have been stored in the record-time arena.
Robert Phillipsac6156c2020-02-28 16:02:40 -0500128 GrProgramInfo* fProgramInfo = nullptr;
Chris Daltoneb694b72020-03-16 09:25:50 -0600129 GrSimpleMesh* fMesh = nullptr;
Robert Phillips6c59fe42020-02-27 09:30:37 -0500130
Brian Salomone21af502019-11-22 16:56:36 -0500131 friend class ::GrOpMemoryPool;
132};
133
134std::unique_ptr<GrDrawOp> TestRectOp::Make(GrRecordingContext* context,
135 GrPaint&& paint,
136 const SkRect& drawRect,
137 const SkRect& localRect,
138 const SkMatrix& localM) {
139 auto* pool = context->priv().opMemoryPool();
140 const auto* caps = context->priv().caps();
141 return pool->allocate<TestRectOp>(caps, std::move(paint), drawRect, localRect, localM);
142}
143
144GrProcessorSet::Analysis TestRectOp::finalize(const GrCaps& caps,
145 const GrAppliedClip* clip,
146 bool hasMixedSampledCoverage,
147 GrClampType clampType) {
148 return fProcessorSet.finalize(GrProcessorAnalysisColor::Opaque::kYes,
149 GrProcessorAnalysisCoverage::kSingleChannel, clip,
150 &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, caps,
151 clampType, &fColor);
152}
153
154static bool use_wide_color(const GrPaint& paint, const GrCaps* caps) {
155 return !paint.getColor4f().fitsInBytes() && caps->halfFloatVertexAttributeSupport();
156}
157TestRectOp::TestRectOp(const GrCaps* caps,
158 GrPaint&& paint,
159 const SkRect& drawRect,
160 const SkRect& localRect,
161 const SkMatrix& localMatrix)
162 : GrMeshDrawOp(ClassID())
163 , fDrawRect(drawRect)
164 , fLocalRect(localRect)
165 , fColor(paint.getColor4f())
166 , fGP(localMatrix, use_wide_color(paint, caps))
167 , fProcessorSet(std::move(paint)) {
168 this->setBounds(drawRect.makeSorted(), HasAABloat::kNo, IsHairline::kNo);
169}
170
Robert Phillips4133dc42020-03-11 15:55:55 -0400171void TestRectOp::onCreateProgramInfo(const GrCaps* caps,
172 SkArenaAlloc* arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400173 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400174 GrAppliedClip&& appliedClip,
175 const GrXferProcessor::DstProxyView& dstProxyView) {
176 fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
177 arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400178 writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400179 std::move(appliedClip),
180 dstProxyView,
181 &fGP,
182 std::move(fProcessorSet),
183 GrPrimitiveType::kTriangles,
184 GrPipeline::InputFlags::kNone);
Robert Phillipsac6156c2020-02-28 16:02:40 -0500185}
186
Brian Salomone21af502019-11-22 16:56:36 -0500187void TestRectOp::onPrepareDraws(Target* target) {
188 QuadHelper helper(target, fGP.vertexStride(), 1);
189 GrVertexWriter writer{helper.vertices()};
190 auto pos = GrVertexWriter::TriStripFromRect(fDrawRect);
191 auto local = GrVertexWriter::TriStripFromRect(fLocalRect);
192 GrVertexColor color(fColor, fGP.wideColor());
193 writer.writeQuad(pos, local, color);
Robert Phillipsac6156c2020-02-28 16:02:40 -0500194
195 fMesh = helper.mesh();
Brian Salomone21af502019-11-22 16:56:36 -0500196}
197
198void TestRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
Robert Phillipsac6156c2020-02-28 16:02:40 -0500199 if (!fProgramInfo) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400200 this->createProgramInfo(flushState);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500201 }
Robert Phillips3968fcb2019-12-05 16:40:31 -0500202
Chris Dalton765ed362020-03-16 17:34:44 -0600203 flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
204 flushState->bindTextures(fProgramInfo->primProc(), nullptr, fProgramInfo->pipeline());
205 flushState->drawMesh(*fMesh);
Brian Salomone21af502019-11-22 16:56:36 -0500206}
207
208} // anonymous namespace
209
210namespace sk_gpu_test::test_ops {
211
212std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
213 GrPaint&& paint,
214 const SkRect& drawRect,
215 const SkRect& localRect,
216 const SkMatrix& localM) {
217 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
218}
219
220std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
221 std::unique_ptr<GrFragmentProcessor> fp,
222 const SkRect& drawRect,
223 const SkRect& localRect,
224 const SkMatrix& localM) {
225 GrPaint paint;
226 paint.addColorFragmentProcessor(std::move(fp));
227 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
228}
229
230std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
231 GrPaint&& paint,
232 const SkRect& rect) {
233 return TestRectOp::Make(context, std::move(paint), rect, rect, SkMatrix::I());
234}
235
236} // namespace sk_gpu_test::test_ops