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                                                          kHalf4_GrSLType,
     41                                                          "Color",
     42                                                          &stagedLocalVarName);
     43         fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
     44 
     45         // setup constant solid coverage
     46         fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
     47     }
     48 
     49     void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
     50                         FPCoordTransformHandler* transformHandler) {
     51         int i = 0;
     52         while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) {
     53             GrSLType varyingType =
     54                     coordTransform->getMatrix().hasPerspective() ? kHalf3_GrSLType
     55                                                                  : kHalf2_GrSLType;
     56 
     57             SkString strVaryingName;
     58             strVaryingName.printf("TransformedCoord_%d", i);
     59             GrGLSLVarying v(varyingType);
     60             GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
     61             fInstalledTransforms.push_back().fHandle =
     62                     glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(),
     63                                                                &v).toIndex();
     64             fInstalledTransforms.back().fType = varyingType;
     65 
     66             transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
     67             ++i;
     68         }
     69     }
     70 
     71     void setData(const GrGLSLProgramDataManager& pd,
     72                  const GrPrimitiveProcessor& primProc,
     73                  FPCoordTransformIter&& transformIter) override {
     74         const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
     75         if (pathProc.color() != fColor) {
     76             float c[4];
     77             GrColorToRGBAFloat(pathProc.color(), c);
     78             pd.set4fv(fColorUniform, 1, c);
     79             fColor = pathProc.color();
     80         }
     81 
     82         int t = 0;
     83         while (const GrCoordTransform* coordTransform = transformIter.next()) {
     84             SkASSERT(fInstalledTransforms[t].fHandle.isValid());
     85             const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), *coordTransform);
     86             if (fInstalledTransforms[t].fCurrentValue.cheapEqualTo(m)) {
     87                 continue;
     88             }
     89             fInstalledTransforms[t].fCurrentValue = m;
     90 
     91             SkASSERT(fInstalledTransforms[t].fType == kHalf2_GrSLType ||
     92                      fInstalledTransforms[t].fType == kHalf3_GrSLType);
     93             unsigned components = fInstalledTransforms[t].fType == kHalf2_GrSLType ? 2 : 3;
     94             pd.setPathFragmentInputTransform(fInstalledTransforms[t].fHandle, components, m);
     95             ++t;
     96         }
     97     }
     98 
     99 private:
    100     typedef GrGLSLProgramDataManager::VaryingHandle VaryingHandle;
    101     struct TransformVarying {
    102         VaryingHandle  fHandle;
    103         SkMatrix       fCurrentValue = SkMatrix::InvalidMatrix();
    104         GrSLType       fType = kVoid_GrSLType;
    105     };
    106 
    107     SkTArray<TransformVarying, true> fInstalledTransforms;
    108 
    109     UniformHandle fColorUniform;
    110     GrColor fColor;
    111 
    112     typedef GrGLSLPrimitiveProcessor INHERITED;
    113 };
    114 
    115 GrPathProcessor::GrPathProcessor(GrColor color,
    116                                  const SkMatrix& viewMatrix,
    117                                  const SkMatrix& localMatrix)
    118         : INHERITED(kGrPathProcessor_ClassID)
    119         , fColor(color)
    120         , fViewMatrix(viewMatrix)
    121         , fLocalMatrix(localMatrix) {}
    122 
    123 void GrPathProcessor::getGLSLProcessorKey(const GrShaderCaps& caps,
    124                                           GrProcessorKeyBuilder* b) const {
    125     GrGLPathProcessor::GenKey(*this, caps, b);
    126 }
    127 
    128 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrShaderCaps& caps) const {
    129     SkASSERT(caps.pathRenderingSupport());
    130     return new GrGLPathProcessor();
    131 }
    132