blob: 8524b72f2d0bb3d9772319333fe30f4233dbbb0c [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"
11#include "src/gpu/GrShaderCaps.h"
12#include "src/gpu/gl/GrGLGpu.h"
John Rosasco24cbdab2019-09-25 14:14:35 -070013#ifdef SK_GL
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "src/gpu/gl/GrGLVaryingHandler.h"
John Rosasco24cbdab2019-09-25 14:14:35 -070015#endif
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
17#include "src/gpu/glsl/GrGLSLPrimitiveProcessor.h"
18#include "src/gpu/glsl/GrGLSLUniformHandler.h"
19#include "src/gpu/glsl/GrGLSLVarying.h"
jvanverthcba99b82015-06-24 06:59:57 -070020
egdaniele659a582015-11-13 09:55:43 -080021class GrGLPathProcessor : public GrGLSLPrimitiveProcessor {
joshualitt102081a2015-09-11 11:52:17 -070022public:
Brian Osmancf860852018-10-31 14:04:39 -040023 GrGLPathProcessor() : fColor(SK_PMColor4fILLEGAL) {}
joshualitt102081a2015-09-11 11:52:17 -070024
25 static void GenKey(const GrPathProcessor& pathProc,
Brian Salomon94efbf52016-11-29 13:43:05 -050026 const GrShaderCaps&,
joshualitt102081a2015-09-11 11:52:17 -070027 GrProcessorKeyBuilder* b) {
Brian Salomonbfd51832017-01-04 13:22:08 -050028 b->add32(SkToInt(pathProc.viewMatrix().hasPerspective()));
joshualitt102081a2015-09-11 11:52:17 -070029 }
30
31 void emitCode(EmitArgs& args) override {
Chris Dalton60283612018-02-14 13:38:14 -070032 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
joshualitt102081a2015-09-11 11:52:17 -070033 const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
34
cdaltonc08f1962016-02-12 12:14:06 -080035 if (!pathProc.viewMatrix().hasPerspective()) {
36 args.fVaryingHandler->setNoPerspective();
37 }
38
joshualitt102081a2015-09-11 11:52:17 -070039 // emit transforms
bsalomona624bf32016-09-20 09:12:47 -070040 this->emitTransforms(args.fVaryingHandler, args.fFPCoordTransformHandler);
joshualitt102081a2015-09-11 11:52:17 -070041
42 // Setup uniform color
Brian Salomonbfd51832017-01-04 13:22:08 -050043 const char* stagedLocalVarName;
44 fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
Ethan Nicholasf7b88202017-09-18 14:10:39 -040045 kHalf4_GrSLType,
Brian Salomonbfd51832017-01-04 13:22:08 -050046 "Color",
47 &stagedLocalVarName);
48 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
joshualitt102081a2015-09-11 11:52:17 -070049
50 // setup constant solid coverage
Ethan Nicholasf7b88202017-09-18 14:10:39 -040051 fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
joshualitt102081a2015-09-11 11:52:17 -070052 }
53
Ethan Nicholasd4efe682019-08-29 16:10:13 -040054 SkString matrix_to_sksl(const SkMatrix& m) {
55 return SkStringPrintf("float3x3(%f, %f, %f, %f, %f, %f, %f, %f, %f)", m[0], m[1], m[2],
56 m[3], m[4], m[5], m[6], m[7], m[8]);
57 }
58
egdaniel0eafe792015-11-20 14:01:22 -080059 void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
bsalomona624bf32016-09-20 09:12:47 -070060 FPCoordTransformHandler* transformHandler) {
61 int i = 0;
62 while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) {
63 GrSLType varyingType =
Ethan Nicholasf7b88202017-09-18 14:10:39 -040064 coordTransform->getMatrix().hasPerspective() ? kHalf3_GrSLType
65 : kHalf2_GrSLType;
joshualitt102081a2015-09-11 11:52:17 -070066
bsalomona624bf32016-09-20 09:12:47 -070067 SkString strVaryingName;
68 strVaryingName.printf("TransformedCoord_%d", i);
Chris Dalton27372882017-12-08 13:34:21 -070069 GrGLSLVarying v(varyingType);
John Rosasco24cbdab2019-09-25 14:14:35 -070070#ifdef SK_GL
bsalomona624bf32016-09-20 09:12:47 -070071 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
72 fInstalledTransforms.push_back().fHandle =
John Rosasco24cbdab2019-09-25 14:14:35 -070073 glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), &v).toIndex();
74#endif
bsalomona624bf32016-09-20 09:12:47 -070075 fInstalledTransforms.back().fType = varyingType;
joshualitt102081a2015-09-11 11:52:17 -070076
Ethan Nicholasd4efe682019-08-29 16:10:13 -040077 transformHandler->specifyCoordsForCurrCoordTransform(
78 matrix_to_sksl(coordTransform->getMatrix()),
79 UniformHandle(),
80 GrShaderVar(SkString(v.fsIn()),
81 varyingType));
bsalomona624bf32016-09-20 09:12:47 -070082 ++i;
joshualitt102081a2015-09-11 11:52:17 -070083 }
84 }
85
egdaniel018fb622015-10-28 07:26:40 -070086 void setData(const GrGLSLProgramDataManager& pd,
bsalomona624bf32016-09-20 09:12:47 -070087 const GrPrimitiveProcessor& primProc,
88 FPCoordTransformIter&& transformIter) override {
joshualitt102081a2015-09-11 11:52:17 -070089 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
Brian Salomonbfd51832017-01-04 13:22:08 -050090 if (pathProc.color() != fColor) {
Brian Osmancf860852018-10-31 14:04:39 -040091 pd.set4fv(fColorUniform, 1, pathProc.color().vec());
joshualitt102081a2015-09-11 11:52:17 -070092 fColor = pathProc.color();
93 }
joshualitt102081a2015-09-11 11:52:17 -070094
bsalomona624bf32016-09-20 09:12:47 -070095 int t = 0;
96 while (const GrCoordTransform* coordTransform = transformIter.next()) {
97 SkASSERT(fInstalledTransforms[t].fHandle.isValid());
98 const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), *coordTransform);
99 if (fInstalledTransforms[t].fCurrentValue.cheapEqualTo(m)) {
joshualitt102081a2015-09-11 11:52:17 -0700100 continue;
101 }
bsalomona624bf32016-09-20 09:12:47 -0700102 fInstalledTransforms[t].fCurrentValue = m;
joshualitt102081a2015-09-11 11:52:17 -0700103
Ethan Nicholasf7b88202017-09-18 14:10:39 -0400104 SkASSERT(fInstalledTransforms[t].fType == kHalf2_GrSLType ||
105 fInstalledTransforms[t].fType == kHalf3_GrSLType);
106 unsigned components = fInstalledTransforms[t].fType == kHalf2_GrSLType ? 2 : 3;
bsalomona624bf32016-09-20 09:12:47 -0700107 pd.setPathFragmentInputTransform(fInstalledTransforms[t].fHandle, components, m);
108 ++t;
joshualitt102081a2015-09-11 11:52:17 -0700109 }
110 }
111
112private:
egdanielfe8a8392016-05-09 10:22:19 -0700113 typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle;
bsalomon790c90b2016-09-12 12:56:58 -0700114 struct TransformVarying {
egdanielfe8a8392016-05-09 10:22:19 -0700115 VaryingHandle fHandle;
bsalomon790c90b2016-09-12 12:56:58 -0700116 SkMatrix fCurrentValue = SkMatrix::InvalidMatrix();
117 GrSLType fType = kVoid_GrSLType;
egdanielfe8a8392016-05-09 10:22:19 -0700118 };
119
bsalomona624bf32016-09-20 09:12:47 -0700120 SkTArray<TransformVarying, true> fInstalledTransforms;
egdanielfe8a8392016-05-09 10:22:19 -0700121
joshualitt102081a2015-09-11 11:52:17 -0700122 UniformHandle fColorUniform;
Brian Osmancf860852018-10-31 14:04:39 -0400123 SkPMColor4f fColor;
joshualitt102081a2015-09-11 11:52:17 -0700124
egdaniele659a582015-11-13 09:55:43 -0800125 typedef GrGLSLPrimitiveProcessor INHERITED;
joshualitt102081a2015-09-11 11:52:17 -0700126};
127
Brian Osmancf860852018-10-31 14:04:39 -0400128GrPathProcessor::GrPathProcessor(const SkPMColor4f& color,
joshualitt8072caa2015-02-12 14:20:52 -0800129 const SkMatrix& viewMatrix,
130 const SkMatrix& localMatrix)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400131 : INHERITED(kGrPathProcessor_ClassID)
132 , fColor(color)
Brian Salomon92aee3d2016-12-21 09:20:25 -0500133 , fViewMatrix(viewMatrix)
Ethan Nicholasabff9562017-10-09 10:54:08 -0400134 , fLocalMatrix(localMatrix) {}
joshualitt8072caa2015-02-12 14:20:52 -0800135
Brian Salomon94efbf52016-11-29 13:43:05 -0500136void GrPathProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
egdaniel57d3b032015-11-13 11:57:27 -0800137 GrProcessorKeyBuilder* b) const {
joshualitt465283c2015-09-11 08:19:35 -0700138 GrGLPathProcessor::GenKey(*this, caps, b);
joshualitt8072caa2015-02-12 14:20:52 -0800139}
140
Brian Salomon94efbf52016-11-29 13:43:05 -0500141GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrShaderCaps& caps) const {
jvanverth50530632015-04-27 10:36:27 -0700142 SkASSERT(caps.pathRenderingSupport());
joshualitt465283c2015-09-11 08:19:35 -0700143 return new GrGLPathProcessor();
joshualitt8072caa2015-02-12 14:20:52 -0800144}