blob: cfd6815ce9ae4cc7a4b24026a6a615272d13494c [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:
85 static std::unique_ptr<GrDrawOp> Make(GrRecordingContext*,
86 GrPaint&&,
87 const SkRect& drawRect,
88 const SkRect& localRect,
89 const SkMatrix& localM);
90
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*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400120 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400121 GrAppliedClip&&,
122 const GrXferProcessor::DstProxyView&) override;
Robert Phillipsac6156c2020-02-28 16:02:40 -0500123
Brian Salomone21af502019-11-22 16:56:36 -0500124 void onPrepareDraws(Target*) override;
125 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
126
Robert Phillipsac6156c2020-02-28 16:02:40 -0500127 SkRect fDrawRect;
128 SkRect fLocalRect;
129 SkPMColor4f fColor;
130 GP fGP;
Brian Salomone21af502019-11-22 16:56:36 -0500131 GrProcessorSet fProcessorSet;
132
Robert Phillipsac6156c2020-02-28 16:02:40 -0500133 // If this op is prePrepared the created programInfo will be stored here for use in
Robert Phillips6c59fe42020-02-27 09:30:37 -0500134 // onExecute. In the prePrepared case it will have been stored in the record-time arena.
Robert Phillipsac6156c2020-02-28 16:02:40 -0500135 GrProgramInfo* fProgramInfo = nullptr;
Chris Daltoneb694b72020-03-16 09:25:50 -0600136 GrSimpleMesh* fMesh = nullptr;
Robert Phillips6c59fe42020-02-27 09:30:37 -0500137
Brian Salomone21af502019-11-22 16:56:36 -0500138 friend class ::GrOpMemoryPool;
139};
140
141std::unique_ptr<GrDrawOp> TestRectOp::Make(GrRecordingContext* context,
142 GrPaint&& paint,
143 const SkRect& drawRect,
144 const SkRect& localRect,
145 const SkMatrix& localM) {
146 auto* pool = context->priv().opMemoryPool();
147 const auto* caps = context->priv().caps();
148 return pool->allocate<TestRectOp>(caps, std::move(paint), drawRect, localRect, localM);
149}
150
151GrProcessorSet::Analysis TestRectOp::finalize(const GrCaps& caps,
152 const GrAppliedClip* clip,
153 bool hasMixedSampledCoverage,
154 GrClampType clampType) {
155 return fProcessorSet.finalize(GrProcessorAnalysisColor::Opaque::kYes,
156 GrProcessorAnalysisCoverage::kSingleChannel, clip,
157 &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, caps,
158 clampType, &fColor);
159}
160
161static bool use_wide_color(const GrPaint& paint, const GrCaps* caps) {
162 return !paint.getColor4f().fitsInBytes() && caps->halfFloatVertexAttributeSupport();
163}
164TestRectOp::TestRectOp(const GrCaps* caps,
165 GrPaint&& paint,
166 const SkRect& drawRect,
167 const SkRect& localRect,
168 const SkMatrix& localMatrix)
169 : GrMeshDrawOp(ClassID())
170 , fDrawRect(drawRect)
171 , fLocalRect(localRect)
172 , fColor(paint.getColor4f())
173 , fGP(localMatrix, use_wide_color(paint, caps))
174 , fProcessorSet(std::move(paint)) {
175 this->setBounds(drawRect.makeSorted(), HasAABloat::kNo, IsHairline::kNo);
176}
177
Robert Phillips4133dc42020-03-11 15:55:55 -0400178void TestRectOp::onCreateProgramInfo(const GrCaps* caps,
179 SkArenaAlloc* arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400180 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400181 GrAppliedClip&& appliedClip,
182 const GrXferProcessor::DstProxyView& dstProxyView) {
183 fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
184 arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400185 writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400186 std::move(appliedClip),
187 dstProxyView,
188 &fGP,
189 std::move(fProcessorSet),
190 GrPrimitiveType::kTriangles,
191 GrPipeline::InputFlags::kNone);
Robert Phillipsac6156c2020-02-28 16:02:40 -0500192}
193
Brian Salomone21af502019-11-22 16:56:36 -0500194void TestRectOp::onPrepareDraws(Target* target) {
195 QuadHelper helper(target, fGP.vertexStride(), 1);
196 GrVertexWriter writer{helper.vertices()};
197 auto pos = GrVertexWriter::TriStripFromRect(fDrawRect);
198 auto local = GrVertexWriter::TriStripFromRect(fLocalRect);
199 GrVertexColor color(fColor, fGP.wideColor());
200 writer.writeQuad(pos, local, color);
Robert Phillipsac6156c2020-02-28 16:02:40 -0500201
202 fMesh = helper.mesh();
Brian Salomone21af502019-11-22 16:56:36 -0500203}
204
205void TestRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
Robert Phillipsac6156c2020-02-28 16:02:40 -0500206 if (!fProgramInfo) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400207 this->createProgramInfo(flushState);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500208 }
Robert Phillips3968fcb2019-12-05 16:40:31 -0500209
Chris Dalton765ed362020-03-16 17:34:44 -0600210 flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
211 flushState->bindTextures(fProgramInfo->primProc(), nullptr, fProgramInfo->pipeline());
212 flushState->drawMesh(*fMesh);
Brian Salomone21af502019-11-22 16:56:36 -0500213}
214
215} // anonymous namespace
216
217namespace sk_gpu_test::test_ops {
218
219std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
220 GrPaint&& paint,
221 const SkRect& drawRect,
222 const SkRect& localRect,
223 const SkMatrix& localM) {
224 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
225}
226
227std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
228 std::unique_ptr<GrFragmentProcessor> fp,
229 const SkRect& drawRect,
230 const SkRect& localRect,
231 const SkMatrix& localM) {
232 GrPaint paint;
John Stiles5933d7d2020-07-21 12:28:35 -0400233 paint.setColorFragmentProcessor(std::move(fp));
Brian Salomone21af502019-11-22 16:56:36 -0500234 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
235}
236
237std::unique_ptr<GrDrawOp> MakeRect(GrRecordingContext* context,
238 GrPaint&& paint,
239 const SkRect& rect) {
240 return TestRectOp::Make(context, std::move(paint), rect, rect, SkMatrix::I());
241}
242
243} // namespace sk_gpu_test::test_ops