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 14GrGLPathProcessor::GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&) 15 : fColor(GrColor_ILLEGAL) {} 16 17void 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 42void 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 50void 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 62void 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 92void 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 105void 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