blob: 2fdd97b0c1aef4d80f5222cc7e82fc8bd8fe7249 [file] [log] [blame]
jvanverth50530632015-04-27 10:36:27 -07001/*
2* Copyright 2013 Google Inc.
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/GrPathProcessor.h"
Hal Canaryc640d0d2018-06-13 09:59:02 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/private/SkTo.h"
Brian Osman609f1592020-07-01 15:14:39 -040011#include "src/core/SkMatrixPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/gpu/GrShaderCaps.h"
13#include "src/gpu/gl/GrGLGpu.h"
John Rosasco24cbdab2019-09-25 14:14:35 -070014#ifdef SK_GL
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/gl/GrGLVaryingHandler.h"
John Rosasco24cbdab2019-09-25 14:14:35 -070016#endif
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
18#include "src/gpu/glsl/GrGLSLPrimitiveProcessor.h"
19#include "src/gpu/glsl/GrGLSLUniformHandler.h"
20#include "src/gpu/glsl/GrGLSLVarying.h"
jvanverthcba99b82015-06-24 06:59:57 -070021
egdaniele659a582015-11-13 09:55:43 -080022class GrGLPathProcessor : public GrGLSLPrimitiveProcessor {
joshualitt102081a2015-09-11 11:52:17 -070023public:
Brian Osmancf860852018-10-31 14:04:39 -040024 GrGLPathProcessor() : fColor(SK_PMColor4fILLEGAL) {}
joshualitt102081a2015-09-11 11:52:17 -070025
26 static void GenKey(const GrPathProcessor& pathProc,
Brian Salomon94efbf52016-11-29 13:43:05 -050027 const GrShaderCaps&,
joshualitt102081a2015-09-11 11:52:17 -070028 GrProcessorKeyBuilder* b) {
Brian Salomonbfd51832017-01-04 13:22:08 -050029 b->add32(SkToInt(pathProc.viewMatrix().hasPerspective()));
joshualitt102081a2015-09-11 11:52:17 -070030 }
31
32 void emitCode(EmitArgs& args) override {
Chris Dalton60283612018-02-14 13:38:14 -070033 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
joshualitt102081a2015-09-11 11:52:17 -070034 const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
35
cdaltonc08f1962016-02-12 12:14:06 -080036 if (!pathProc.viewMatrix().hasPerspective()) {
37 args.fVaryingHandler->setNoPerspective();
38 }
39
joshualitt102081a2015-09-11 11:52:17 -070040 // emit transforms
Brian Salomon510eb152020-02-27 13:52:16 -050041 this->emitTransforms(args.fVaryingHandler, args.fUniformHandler,
42 args.fFPCoordTransformHandler);
joshualitt102081a2015-09-11 11:52:17 -070043
44 // Setup uniform color
Brian Salomonbfd51832017-01-04 13:22:08 -050045 const char* stagedLocalVarName;
Ethan Nicholas16464c32020-04-06 13:53:05 -040046 fColorUniform = args.fUniformHandler->addUniform(nullptr,
47 kFragment_GrShaderFlag,
Ethan Nicholasf7b88202017-09-18 14:10:39 -040048 kHalf4_GrSLType,
Brian Salomonbfd51832017-01-04 13:22:08 -050049 "Color",
50 &stagedLocalVarName);
51 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
joshualitt102081a2015-09-11 11:52:17 -070052
53 // setup constant solid coverage
Ethan Nicholasf7b88202017-09-18 14:10:39 -040054 fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
joshualitt102081a2015-09-11 11:52:17 -070055 }
56
egdaniel0eafe792015-11-20 14:01:22 -080057 void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
Brian Salomon510eb152020-02-27 13:52:16 -050058 GrGLSLUniformHandler* uniformHandler,
bsalomona624bf32016-09-20 09:12:47 -070059 FPCoordTransformHandler* transformHandler) {
Brian Salomon7d8b3972019-11-26 22:34:44 -050060 for (int i = 0; *transformHandler; ++*transformHandler, ++i) {
Brian Osman609f1592020-07-01 15:14:39 -040061 const auto& fp = transformHandler->get();
joshualitt102081a2015-09-11 11:52:17 -070062
Brian Salomon510eb152020-02-27 13:52:16 -050063 GrShaderVar fragmentVar;
Brian Salomon8d1dcd72020-03-20 21:06:41 -040064 GrShaderVar transformVar;
Brian Salomon510eb152020-02-27 13:52:16 -050065 if (fp.isSampledWithExplicitCoords()) {
Brian Osman609f1592020-07-01 15:14:39 -040066 transformHandler->omitCoordsForCurrCoordTransform();
Brian Salomon510eb152020-02-27 13:52:16 -050067 } else {
68 SkString strVaryingName;
69 strVaryingName.printf("TransformedCoord_%d", i);
Brian Osman609f1592020-07-01 15:14:39 -040070 GrGLSLVarying v(kFloat2_GrSLType);
John Rosasco24cbdab2019-09-25 14:14:35 -070071#ifdef SK_GL
Brian Salomon510eb152020-02-27 13:52:16 -050072 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*)varyingHandler;
73 fVaryingTransform.push_back().fHandle =
74 glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), &v)
75 .toIndex();
John Rosasco24cbdab2019-09-25 14:14:35 -070076#endif
Brian Osman609f1592020-07-01 15:14:39 -040077 fragmentVar = {SkString(v.fsIn()), kFloat2_GrSLType};
78 transformHandler->specifyCoordsForCurrCoordTransform(transformVar, fragmentVar);
Brian Salomon510eb152020-02-27 13:52:16 -050079 }
joshualitt102081a2015-09-11 11:52:17 -070080 }
81 }
82
egdaniel018fb622015-10-28 07:26:40 -070083 void setData(const GrGLSLProgramDataManager& pd,
Brian Osman609f1592020-07-01 15:14:39 -040084 const GrPrimitiveProcessor& primProc) override {
joshualitt102081a2015-09-11 11:52:17 -070085 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
Brian Salomonbfd51832017-01-04 13:22:08 -050086 if (pathProc.color() != fColor) {
Brian Osmancf860852018-10-31 14:04:39 -040087 pd.set4fv(fColorUniform, 1, pathProc.color().vec());
joshualitt102081a2015-09-11 11:52:17 -070088 fColor = pathProc.color();
89 }
joshualitt102081a2015-09-11 11:52:17 -070090
Brian Osman609f1592020-07-01 15:14:39 -040091 for (int v = 0; v < fVaryingTransform.count(); ++v) {
92 if (fVaryingTransform[v].fHandle.isValid()) {
93 SkMatrix m = pathProc.localMatrix();
Brian Salomon510eb152020-02-27 13:52:16 -050094 if (!SkMatrixPriv::CheapEqual(fVaryingTransform[v].fCurrentValue, m)) {
95 fVaryingTransform[v].fCurrentValue = m;
Brian Osman609f1592020-07-01 15:14:39 -040096 pd.setPathFragmentInputTransform(fVaryingTransform[v].fHandle, 2, m);
Brian Salomon510eb152020-02-27 13:52:16 -050097 }
Brian Salomon7eabfe82019-12-02 14:20:20 -050098 }
joshualitt102081a2015-09-11 11:52:17 -070099 }
100 }
101
102private:
Brian Salomon510eb152020-02-27 13:52:16 -0500103 using VaryingHandle = GrGLSLProgramDataManager::VaryingHandle;
104
105 // Varying transforms are used for non-explicitly sampled FPs. We provide a matrix
106 // to GL as fixed function state and it uses it to compute a varying that we pick up
107 // in the FS as the output of the coord transform.
bsalomon790c90b2016-09-12 12:56:58 -0700108 struct TransformVarying {
Brian Salomon510eb152020-02-27 13:52:16 -0500109 VaryingHandle fHandle;
110 SkMatrix fCurrentValue = SkMatrix::InvalidMatrix();
egdanielfe8a8392016-05-09 10:22:19 -0700111 };
112
Brian Salomon510eb152020-02-27 13:52:16 -0500113 SkTArray<TransformVarying, true> fVaryingTransform;
egdanielfe8a8392016-05-09 10:22:19 -0700114
joshualitt102081a2015-09-11 11:52:17 -0700115 UniformHandle fColorUniform;
Brian Osmancf860852018-10-31 14:04:39 -0400116 SkPMColor4f fColor;
joshualitt102081a2015-09-11 11:52:17 -0700117
egdaniele659a582015-11-13 09:55:43 -0800118 typedef GrGLSLPrimitiveProcessor INHERITED;
joshualitt102081a2015-09-11 11:52:17 -0700119};
120
Brian Osmancf860852018-10-31 14:04:39 -0400121GrPathProcessor::GrPathProcessor(const SkPMColor4f& color,
joshualitt8072caa2015-02-12 14:20:52 -0800122 const SkMatrix& viewMatrix,
123 const SkMatrix& localMatrix)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400124 : INHERITED(kGrPathProcessor_ClassID)
125 , fColor(color)
Brian Salomon92aee3d2016-12-21 09:20:25 -0500126 , fViewMatrix(viewMatrix)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400127 , fLocalMatrix(localMatrix) {}
joshualitt8072caa2015-02-12 14:20:52 -0800128
Brian Salomon94efbf52016-11-29 13:43:05 -0500129void GrPathProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
egdaniel57d3b032015-11-13 11:57:27 -0800130 GrProcessorKeyBuilder* b) const {
joshualitt465283c2015-09-11 08:19:35 -0700131 GrGLPathProcessor::GenKey(*this, caps, b);
joshualitt8072caa2015-02-12 14:20:52 -0800132}
133
Brian Salomon94efbf52016-11-29 13:43:05 -0500134GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrShaderCaps& caps) const {
jvanverth50530632015-04-27 10:36:27 -0700135 SkASSERT(caps.pathRenderingSupport());
joshualitt465283c2015-09-11 08:19:35 -0700136 return new GrGLPathProcessor();
joshualitt8072caa2015-02-12 14:20:52 -0800137}