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 "gl/GrGLGpu.h"
     11 #include "glsl/GrGLSLCaps.h"
     12 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     13 #include "glsl/GrGLSLProcessorTypes.h"
     14 #include "glsl/GrGLSLUniformHandler.h"
     15 #include "glsl/GrGLSLVarying.h"
     16 
     17 class GrGLPathProcessor : public GrGLSLPrimitiveProcessor {
     18 public:
     19     GrGLPathProcessor() : fColor(GrColor_ILLEGAL) {}
     20 
     21     static void GenKey(const GrPathProcessor& pathProc,
     22                        const GrGLSLCaps&,
     23                        GrProcessorKeyBuilder* b) {
     24         b->add32(SkToInt(pathProc.overrides().readsColor()) |
     25                  (SkToInt(pathProc.overrides().readsCoverage()) << 1) |
     26                  (SkToInt(pathProc.viewMatrix().hasPerspective()) << 2));
     27     }
     28 
     29     void emitCode(EmitArgs& args) override {
     30         GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
     31         const GrPathProcessor& pathProc = args.fGP.cast<GrPathProcessor>();
     32 
     33         if (!pathProc.viewMatrix().hasPerspective()) {
     34             args.fVaryingHandler->setNoPerspective();
     35         }
     36 
     37         // emit transforms
     38         this->emitTransforms(args.fVaryingHandler, args.fTransformsIn, args.fTransformsOut);
     39 
     40         // Setup uniform color
     41         if (pathProc.overrides().readsColor()) {
     42             const char* stagedLocalVarName;
     43             fColorUniform = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
     44                                                              kVec4f_GrSLType,
     45                                                              kDefault_GrSLPrecision,
     46                                                              "Color",
     47                                                              &stagedLocalVarName);
     48             fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName);
     49         }
     50 
     51         // setup constant solid coverage
     52         if (pathProc.overrides().readsCoverage()) {
     53             fragBuilder->codeAppendf("%s = vec4(1);", args.fOutputCoverage);
     54         }
     55     }
     56 
     57     void emitTransforms(GrGLSLVaryingHandler* varyingHandler,
     58                         const TransformsIn& tin,
     59                         TransformsOut* tout) {
     60         tout->push_back_n(tin.count());
     61         fInstalledTransforms.push_back_n(tin.count());
     62         for (int i = 0; i < tin.count(); i++) {
     63             const ProcCoords& coordTransforms = tin[i];
     64             fInstalledTransforms[i].push_back_n(coordTransforms.count());
     65             for (int t = 0; t < coordTransforms.count(); t++) {
     66                 GrSLType varyingType =
     67                         coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
     68                                                                            kVec2f_GrSLType;
     69 
     70                 SkString strVaryingName("MatrixCoord");
     71                 strVaryingName.appendf("_%i_%i", i, t);
     72                 GrGLSLVertToFrag v(varyingType);
     73                 GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler;
     74                 fInstalledTransforms[i][t].fHandle =
     75                         glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(),
     76                                                                    &v).toIndex();
     77                 fInstalledTransforms[i][t].fType = varyingType;
     78 
     79                 (*tout)[i].emplace_back(SkString(v.fsIn()), varyingType);
     80             }
     81         }
     82     }
     83 
     84     void setData(const GrGLSLProgramDataManager& pd,
     85                  const GrPrimitiveProcessor& primProc) override {
     86         const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
     87         if (pathProc.overrides().readsColor() && pathProc.color() != fColor) {
     88             float c[4];
     89             GrColorToRGBAFloat(pathProc.color(), c);
     90             pd.set4fv(fColorUniform, 1, c);
     91             fColor = pathProc.color();
     92         }
     93     }
     94 
     95     void setTransformData(const GrPrimitiveProcessor& primProc,
     96                           const GrGLSLProgramDataManager& pdman,
     97                           int index,
     98                           const SkTArray<const GrCoordTransform*, true>& coordTransforms) override {
     99         const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
    100         SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index];
    101         int numTransforms = transforms.count();
    102         for (int t = 0; t < numTransforms; ++t) {
    103             SkASSERT(transforms[t].fHandle.isValid());
    104             const SkMatrix& transform = GetTransformMatrix(pathProc.localMatrix(),
    105                                                            *coordTransforms[t]);
    106             if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
    107                 continue;
    108             }
    109             transforms[t].fCurrentValue = transform;
    110 
    111             SkASSERT(transforms[t].fType == kVec2f_GrSLType ||
    112                      transforms[t].fType == kVec3f_GrSLType);
    113             unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3;
    114             pdman.setPathFragmentInputTransform(transforms[t].fHandle, components, transform);
    115         }
    116     }
    117 
    118 private:
    119     UniformHandle fColorUniform;
    120     GrColor fColor;
    121 
    122     typedef GrGLSLPrimitiveProcessor INHERITED;
    123 };
    124 
    125 GrPathProcessor::GrPathProcessor(GrColor color,
    126                                  const GrXPOverridesForBatch& overrides,
    127                                  const SkMatrix& viewMatrix,
    128                                  const SkMatrix& localMatrix)
    129     : fColor(color)
    130     , fViewMatrix(viewMatrix)
    131     , fLocalMatrix(localMatrix)
    132     , fOverrides(overrides) {
    133     this->initClassID<GrPathProcessor>();
    134 }
    135 
    136 void GrPathProcessor::getGLSLProcessorKey(const GrGLSLCaps& caps,
    137                                           GrProcessorKeyBuilder* b) const {
    138     GrGLPathProcessor::GenKey(*this, caps, b);
    139 }
    140 
    141 GrGLSLPrimitiveProcessor* GrPathProcessor::createGLSLInstance(const GrGLSLCaps& caps) const {
    142     SkASSERT(caps.pathRenderingSupport());
    143     return new GrGLPathProcessor();
    144 }
    145