blob: 64c050b18c423283b24e413508dc7209d723615f [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*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400120 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400121 GrAppliedClip&&,
Greg Danield358cbe2020-09-11 09:33:54 -0400122 const GrXferProcessor::DstProxyView&,
123 GrXferBarrierFlags renderPassXferBarriers) override;
Robert Phillipsac6156c2020-02-28 16:02:40 -0500124
Brian Salomone21af502019-11-22 16:56:36 -0500125 void onPrepareDraws(Target*) override;
126 void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
127
Robert Phillipsac6156c2020-02-28 16:02:40 -0500128 SkRect fDrawRect;
129 SkRect fLocalRect;
130 SkPMColor4f fColor;
131 GP fGP;
Brian Salomone21af502019-11-22 16:56:36 -0500132 GrProcessorSet fProcessorSet;
133
Robert Phillipsac6156c2020-02-28 16:02:40 -0500134 // If this op is prePrepared the created programInfo will be stored here for use in
Robert Phillips6c59fe42020-02-27 09:30:37 -0500135 // onExecute. In the prePrepared case it will have been stored in the record-time arena.
Robert Phillipsac6156c2020-02-28 16:02:40 -0500136 GrProgramInfo* fProgramInfo = nullptr;
Chris Daltoneb694b72020-03-16 09:25:50 -0600137 GrSimpleMesh* fMesh = nullptr;
Robert Phillips6c59fe42020-02-27 09:30:37 -0500138
Herb Derbyc76d4092020-10-07 16:46:15 -0400139 friend class ::GrOp;
Brian Salomone21af502019-11-22 16:56:36 -0500140};
141
Herb Derbyc76d4092020-10-07 16:46:15 -0400142GrOp::Owner TestRectOp::Make(GrRecordingContext* context,
143 GrPaint&& paint,
144 const SkRect& drawRect,
145 const SkRect& localRect,
146 const SkMatrix& localM) {
Brian Salomone21af502019-11-22 16:56:36 -0500147 const auto* caps = context->priv().caps();
Herb Derbyc76d4092020-10-07 16:46:15 -0400148 return GrOp::Make<TestRectOp>(context, caps, std::move(paint), drawRect, localRect, localM);
Brian Salomone21af502019-11-22 16:56:36 -0500149}
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,
Greg Danield358cbe2020-09-11 09:33:54 -0400182 const GrXferProcessor::DstProxyView& dstProxyView,
183 GrXferBarrierFlags renderPassXferBarriers) {
Robert Phillips4133dc42020-03-11 15:55:55 -0400184 fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps,
185 arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400186 writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400187 std::move(appliedClip),
188 dstProxyView,
189 &fGP,
190 std::move(fProcessorSet),
191 GrPrimitiveType::kTriangles,
Greg Danield358cbe2020-09-11 09:33:54 -0400192 renderPassXferBarriers,
Robert Phillips4133dc42020-03-11 15:55:55 -0400193 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
Herb Derbyc76d4092020-10-07 16:46:15 -0400221GrOp::Owner MakeRect(GrRecordingContext* context,
222 GrPaint&& paint,
223 const SkRect& drawRect,
224 const SkRect& localRect,
225 const SkMatrix& localM) {
Brian Salomone21af502019-11-22 16:56:36 -0500226 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
227}
228
Herb Derbyc76d4092020-10-07 16:46:15 -0400229GrOp::Owner MakeRect(GrRecordingContext* context,
230 std::unique_ptr<GrFragmentProcessor> fp,
231 const SkRect& drawRect,
232 const SkRect& localRect,
233 const SkMatrix& localM) {
Brian Salomone21af502019-11-22 16:56:36 -0500234 GrPaint paint;
John Stiles5933d7d2020-07-21 12:28:35 -0400235 paint.setColorFragmentProcessor(std::move(fp));
Brian Salomone21af502019-11-22 16:56:36 -0500236 return TestRectOp::Make(context, std::move(paint), drawRect, localRect, localM);
237}
238
Herb Derbyc76d4092020-10-07 16:46:15 -0400239GrOp::Owner MakeRect(GrRecordingContext* context,
240 GrPaint&& paint,
241 const SkRect& rect) {
Brian Salomone21af502019-11-22 16:56:36 -0500242 return TestRectOp::Make(context, std::move(paint), rect, rect, SkMatrix::I());
243}
244
245} // namespace sk_gpu_test::test_ops