Home | History | Annotate | Download | only in gpu
      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 "GrPathProcessor.h"
      9 
     10 #include "GrShaderCaps.h"
     11 #include "gl/GrGLGpu.h"
     12 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     13 #include "glsl/GrGLSLUniformHandler.h"
     14 #include "glsl/GrGLSLVarying.h"
     15 
     16 class GrGLPathProcessor : public GrGLSLPrimitiveProcessor {
     17 public:
     18     GrGLPathProcessor() : fColor(GrColor_ILLEGAL) {}
     19 
     20     static void GenKey(const GrPathProcessor& pathProc,
     21                        const GrShaderCaps&,
     22                        GrProcessorKeyBuilder* b) {
     23         b->add32(SkToInt(pathProc.viewMatrix().hasPerspective()));
     24     }
     25 
     26     void emitCode(EmitArgs& args) override {
     27         GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
     28         const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
     29 
     30         if (!pathProc.viewMatrix().hasPerspective()) {
     31             args.fVaryingHandler->setNoPerspective();
     32         }
     33 
     34         // emit transforms
     35         this->emitTransforms(args.fVaryingHandler, args.fFPCoordTransformHandler);
     36 
     37         // Setup uniform color
     38         const char* stagedLocalVarName;
     39         fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
     40                                                          kVec4f_GrSLType,
     41                                                          kDefault_GrSLPrecision,
     42                                                          "Color",
     43                                                          &stagedLocalVarName);
     44         fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
     45 
     46         // setup constant solid coverage
     47         fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
     48     }
     49 
     50     void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
     51                         FPCoordTransformHandler* transformHandler) {
     52         int i = 0;
     53         while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) {
     54             GrSLType varyingType =
     55                     coordTransform->getMatrix().hasPerspective() ? kVec3f_GrSLType
     56                                                                  : kVec2f_GrSLType;
     57 
     58             SkString strVaryingName;
     59             strVaryingName.printf("TransformedCoord_%d", i);
     60             GrGLSLVertToFrag v(varyingType);
     61             GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
     62             fInstalledTransforms.push_back().fHandle =
     63                     glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(),
     64                                                                &v).toIndex();
     65             fInstalledTransforms.back().fType = varyingType;
     66 
     67             transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
     68             ++i;
     69         }
     70     }
     71 
     72     void setData(const GrGLSLProgramDataManager& pd,
     73                  const GrPrimitiveProcessor& primProc,
     74                  FPCoordTransformIter&& transformIter) override {
     75         const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
     76         if (pathProc.color() != fColor) {
     77             float c[4];
     78             GrColorToRGBAFloat(pathProc.color(), c);
     79             pd.set4fv(fColorUniform, 1, c);
     80             fColor = pathProc.color();
     81         }
     82 
     83         int t = 0;
     84         while (const GrCoordTransform* coordTransform = transformIter.next()) {
     85             SkASSERT(fInstalledTransforms[t].fHandle.isValid());
     86             const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), *coordTransform);
     87             if (fInstalledTransforms[t].fCurrentValue.cheapEqualTo(m)) {
     88                 continue;
     89             }
     90             fInstalledTransforms[t].fCurrentValue = m;
     91 
     92             SkASSERT(fInstalledTransforms[t].fType == kVec2f_GrSLType ||
     93                      fInstalledTransforms[t].fType == kVec3f_GrSLType);
     94             unsigned components = fInstalledTransforms[t].fType == kVec2f_GrSLType ? 2 : 3;
     95             pd.setPathFragmentInputTransform(fInstalledTransforms[t].fHandle, components, m);
     96             ++t;
     97         }
     98     }
     99 
    100 private:
    101     typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle;
    102     struct TransformVarying {
    103         VaryingHandle  fHandle;
    104         SkMatrix       fCurrentValue = SkMatrix::InvalidMatrix();
    105         GrSLType       fType = kVoid_GrSLType;
    106     };
    107 
    108     SkTArray<TransformVarying, true> fInstalledTransforms;
    109 
    110     UniformHandle fColorUniform;
    111     GrColor fColor;
    112 
    113     typedef GrGLSLPrimitiveProcessor INHERITED;
    114 };
    115 
    116 GrPathProcessor::GrPathProcessor(GrColor color,
    117                                  const SkMatrix& viewMatrix,
    118                                  const SkMatrix& localMatrix)
    119         : fColor(color)
    120         , fViewMatrix(viewMatrix)
    121         , fLocalMatrix(localMatrix) {
    122     this->initClassID<GrPathProcessor>();
    123 }
    124 
    125 void GrPathProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
    126                                           GrProcessorKeyBuilder* b) const {
    127     GrGLPathProcessor::GenKey(*this, caps, b);
    128 }
    129 
    130 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrShaderCaps& caps) const {
    131     SkASSERT(caps.pathRenderingSupport());
    132     return new GrGLPathProcessor();
    133 }
    134