1 /*
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
8 #include "GrGLPathProcessor.h"
9
10 #include "GrPathProcessor.h"
11 #include "GrGLGpu.h"
12 #include "GrGLPathRendering.h"
13
GrGLPathProcessor(const GrPathProcessor &,const GrBatchTracker &)14 GrGLPathProcessor::GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&)
15 : fColor(GrColor_ILLEGAL) {}
16
emitCode(EmitArgs & args)17 void GrGLPathProcessor::emitCode(EmitArgs& args) {
18 GrGLGPBuilder* pb = args.fPB;
19 GrGLFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder();
20 const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>();
21
22 // emit transforms
23 this->emitTransforms(args.fPB, args.fTransformsIn, args.fTransformsOut);
24
25 // Setup uniform color
26 if (kUniform_GrGPInput == local.fInputColorType) {
27 const char* stagedLocalVarName;
28 fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
29 kVec4f_GrSLType,
30 kDefault_GrSLPrecision,
31 "Color",
32 &stagedLocalVarName);
33 fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
34 }
35
36 // setup constant solid coverage
37 if (kAllOnes_GrGPInput == local.fInputCoverageType) {
38 fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
39 }
40 }
41
GenKey(const GrPathProcessor &,const GrBatchTracker & bt,const GrGLSLCaps &,GrProcessorKeyBuilder * b)42 void GrGLPathProcessor::GenKey(const GrPathProcessor&,
43 const GrBatchTracker& bt,
44 const GrGLSLCaps&,
45 GrProcessorKeyBuilder* b) {
46 const PathBatchTracker& local = bt.cast<PathBatchTracker>();
47 b->add32(local.fInputColorType | local.fInputCoverageType << 16);
48 }
49
setData(const GrGLProgramDataManager & pdman,const GrPrimitiveProcessor & primProc,const GrBatchTracker & bt)50 void GrGLPathProcessor::setData(const GrGLProgramDataManager& pdman,
51 const GrPrimitiveProcessor& primProc,
52 const GrBatchTracker& bt) {
53 const PathBatchTracker& local = bt.cast<PathBatchTracker>();
54 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) {
55 GrGLfloat c[4];
56 GrColorToRGBAFloat(local.fColor, c);
57 pdman.set4fv(fColorUniform, 1, c);
58 fColor = local.fColor;
59 }
60 }
61
emitTransforms(GrGLGPBuilder * pb,const TransformsIn & tin,TransformsOut * tout)62 void GrGLPathProcessor::emitTransforms(GrGLGPBuilder* pb, const TransformsIn& tin,
63 TransformsOut* tout) {
64 tout->push_back_n(tin.count());
65 fInstalledTransforms.push_back_n(tin.count());
66 for (int i = 0; i < tin.count(); i++) {
67 const ProcCoords& coordTransforms = tin[i];
68 fInstalledTransforms[i].push_back_n(coordTransforms.count());
69 for (int t = 0; t < coordTransforms.count(); t++) {
70 GrSLType varyingType =
71 coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
72 kVec2f_GrSLType;
73
74
75 SkString strVaryingName("MatrixCoord");
76 strVaryingName.appendf("_%i_%i", i, t);
77 GrGLVertToFrag v(varyingType);
78 pb->addVarying(strVaryingName.c_str(), &v);
79 SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back();
80 varyingInfo.fVariable = pb->getFragmentShaderBuilder()->fInputs.back();
81 varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1;
82 varyingInfo.fType = varyingType;
83 fInstalledTransforms[i][t].fHandle = ShaderVarHandle(varyingInfo.fLocation);
84 fInstalledTransforms[i][t].fType = varyingType;
85
86 SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords,
87 (SkString(v.fsIn()), varyingType));
88 }
89 }
90 }
91
resolveSeparableVaryings(GrGLGpu * gpu,GrGLuint programId)92 void GrGLPathProcessor::resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId) {
93 int count = fSeparableVaryingInfos.count();
94 for (int i = 0; i < count; ++i) {
95 GrGLint location;
96 GR_GL_CALL_RET(gpu->glInterface(),
97 location,
98 GetProgramResourceLocation(programId,
99 GR_GL_FRAGMENT_INPUT,
100 fSeparableVaryingInfos[i].fVariable.c_str()));
101 fSeparableVaryingInfos[i].fLocation = location;
102 }
103 }
104
setTransformData(const GrPrimitiveProcessor & primProc,int index,const SkTArray<const GrCoordTransform *,true> & coordTransforms,GrGLPathRendering * glpr,GrGLuint programID)105 void GrGLPathProcessor::setTransformData(
106 const GrPrimitiveProcessor& primProc,
107 int index,
108 const SkTArray<const GrCoordTransform*, true>& coordTransforms,
109 GrGLPathRendering* glpr,
110 GrGLuint programID) {
111 const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
112 SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index];
113 int numTransforms = transforms.count();
114 for (int t = 0; t < numTransforms; ++t) {
115 SkASSERT(transforms[t].fHandle.isValid());
116 const SkMatrix& transform = GetTransformMatrix(pathProc.localMatrix(),
117 *coordTransforms[t]);
118 if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
119 continue;
120 }
121 transforms[t].fCurrentValue = transform;
122 const SeparableVaryingInfo& fragmentInput =
123 fSeparableVaryingInfos[transforms[t].fHandle.handle()];
124 SkASSERT(transforms[t].fType == kVec2f_GrSLType ||
125 transforms[t].fType == kVec3f_GrSLType);
126 unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3;
127 glpr->setProgramPathFragmentInputTransform(programID,
128 fragmentInput.fLocation,
129 GR_GL_OBJECT_LINEAR,
130 components,
131 transform);
132 }
133 }
134