Home | History | Annotate | Download | only in gpu
      1 /*
      2 * Copyright 2015 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 "GrFragmentProcessor.h"
      9 #include "GrCoordTransform.h"
     10 #include "GrPipeline.h"
     11 #include "GrPipelineAnalysis.h"
     12 #include "effects/GrConstColorProcessor.h"
     13 #include "effects/GrXfermodeFragmentProcessor.h"
     14 #include "glsl/GrGLSLFragmentProcessor.h"
     15 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     16 #include "glsl/GrGLSLProgramDataManager.h"
     17 #include "glsl/GrGLSLUniformHandler.h"
     18 
     19 GrFragmentProcessor::~GrFragmentProcessor() {
     20     // If we got here then our ref count must have reached zero, so we will have converted refs
     21     // to pending executions for all children.
     22     for (int i = 0; i < fChildProcessors.count(); ++i) {
     23         fChildProcessors[i]->completedExecution();
     24     }
     25 }
     26 
     27 bool GrFragmentProcessor::isEqual(const GrFragmentProcessor& that) const {
     28     if (this->classID() != that.classID() ||
     29         !this->hasSameSamplersAndAccesses(that)) {
     30         return false;
     31     }
     32     if (!this->hasSameTransforms(that)) {
     33         return false;
     34     }
     35     if (!this->onIsEqual(that)) {
     36         return false;
     37     }
     38     if (this->numChildProcessors() != that.numChildProcessors()) {
     39         return false;
     40     }
     41     for (int i = 0; i < this->numChildProcessors(); ++i) {
     42         if (!this->childProcessor(i).isEqual(that.childProcessor(i))) {
     43             return false;
     44         }
     45     }
     46     return true;
     47 }
     48 
     49 GrGLSLFragmentProcessor* GrFragmentProcessor::createGLSLInstance() const {
     50     GrGLSLFragmentProcessor* glFragProc = this->onCreateGLSLInstance();
     51     glFragProc->fChildProcessors.push_back_n(fChildProcessors.count());
     52     for (int i = 0; i < fChildProcessors.count(); ++i) {
     53         glFragProc->fChildProcessors[i] = fChildProcessors[i]->createGLSLInstance();
     54     }
     55     return glFragProc;
     56 }
     57 
     58 void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
     59     fCoordTransforms.push_back(transform);
     60     fFlags |= kUsesLocalCoords_Flag;
     61     SkDEBUGCODE(transform->setInProcessor();)
     62 }
     63 
     64 int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child) {
     65     this->combineRequiredFeatures(*child);
     66 
     67     if (child->usesLocalCoords()) {
     68         fFlags |= kUsesLocalCoords_Flag;
     69     }
     70     if (child->usesDistanceVectorField()) {
     71         fFlags |= kUsesDistanceVectorField_Flag;
     72     }
     73 
     74     int index = fChildProcessors.count();
     75     fChildProcessors.push_back(child.release());
     76 
     77     return index;
     78 }
     79 
     80 void GrFragmentProcessor::notifyRefCntIsZero() const {
     81     // See comment above GrProgramElement for a detailed explanation of why we do this.
     82     for (int i = 0; i < fChildProcessors.count(); ++i) {
     83         fChildProcessors[i]->addPendingExecution();
     84         fChildProcessors[i]->unref();
     85     }
     86 }
     87 
     88 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const {
     89     if (this->numCoordTransforms() != that.numCoordTransforms()) {
     90         return false;
     91     }
     92     int count = this->numCoordTransforms();
     93     for (int i = 0; i < count; ++i) {
     94         if (!this->coordTransform(i).hasSameEffectAs(that.coordTransform(i))) {
     95             return false;
     96         }
     97     }
     98     return true;
     99 }
    100 
    101 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputAlpha(
    102     sk_sp<GrFragmentProcessor> fp) {
    103     if (!fp) {
    104         return nullptr;
    105     }
    106     return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), SkBlendMode::kDstIn);
    107 }
    108 
    109 namespace {
    110 
    111 class PremulInputFragmentProcessor : public GrFragmentProcessor {
    112 public:
    113     PremulInputFragmentProcessor()
    114             : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
    115                         kConstantOutputForConstantInput_OptimizationFlag) {
    116         this->initClassID<PremulInputFragmentProcessor>();
    117     }
    118 
    119     const char* name() const override { return "PremultiplyInput"; }
    120 
    121 private:
    122     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
    123         class GLFP : public GrGLSLFragmentProcessor {
    124         public:
    125             void emitCode(EmitArgs& args) override {
    126                 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
    127 
    128                 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor);
    129                 fragBuilder->codeAppendf("%s.rgb *= %s.a;",
    130                                             args.fOutputColor, args.fInputColor);
    131             }
    132         };
    133         return new GLFP;
    134     }
    135 
    136     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
    137 
    138     bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
    139 
    140     GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
    141         return input.premul();
    142     }
    143 
    144     typedef GrFragmentProcessor INHERITED;
    145 };
    146 
    147 class UnpremulInputFragmentProcessor : public GrFragmentProcessor {
    148 public:
    149     UnpremulInputFragmentProcessor()
    150             : INHERITED(kPreservesOpaqueInput_OptimizationFlag |
    151                         kConstantOutputForConstantInput_OptimizationFlag) {
    152         this->initClassID<UnpremulInputFragmentProcessor>();
    153     }
    154 
    155     const char* name() const override { return "UnpremultiplyInput"; }
    156 
    157 private:
    158     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
    159         class GLFP : public GrGLSLFragmentProcessor {
    160         public:
    161             void emitCode(EmitArgs& args) override {
    162                 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
    163 
    164                 fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor);
    165                 fragBuilder->codeAppendf("float invAlpha = %s.a <= 0.0 ? 0.0 : 1.0 / %s.a;",
    166                                          args.fInputColor, args.fInputColor);
    167                 fragBuilder->codeAppendf("%s.rgb *= invAlpha;", args.fOutputColor);
    168             }
    169         };
    170         return new GLFP;
    171     }
    172 
    173     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
    174 
    175     bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
    176 
    177     GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
    178         return input.unpremul();
    179     }
    180 
    181     typedef GrFragmentProcessor INHERITED;
    182 };
    183 
    184 }
    185 
    186 sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulInput(sk_sp<GrFragmentProcessor> fp) {
    187     if (!fp) {
    188         return nullptr;
    189     }
    190     sk_sp<GrFragmentProcessor> fpPipeline[] = { sk_make_sp<PremulInputFragmentProcessor>(), fp};
    191     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
    192 }
    193 
    194 sk_sp<GrFragmentProcessor> GrFragmentProcessor::PremulOutput(sk_sp<GrFragmentProcessor> fp) {
    195     if (!fp) {
    196         return nullptr;
    197     }
    198     sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<PremulInputFragmentProcessor>() };
    199     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
    200 }
    201 
    202 sk_sp<GrFragmentProcessor> GrFragmentProcessor::UnpremulOutput(sk_sp<GrFragmentProcessor> fp) {
    203     if (!fp) {
    204         return nullptr;
    205     }
    206     sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<UnpremulInputFragmentProcessor>() };
    207     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
    208 }
    209 
    210 sk_sp<GrFragmentProcessor> GrFragmentProcessor::SwizzleOutput(sk_sp<GrFragmentProcessor> fp,
    211                                                               const GrSwizzle& swizzle) {
    212     class SwizzleFragmentProcessor : public GrFragmentProcessor {
    213     public:
    214         SwizzleFragmentProcessor(const GrSwizzle& swizzle)
    215                 : INHERITED(kAll_OptimizationFlags)
    216                 , fSwizzle(swizzle) {
    217             this->initClassID<SwizzleFragmentProcessor>();
    218         }
    219 
    220         const char* name() const override { return "Swizzle"; }
    221         const GrSwizzle& swizzle() const { return fSwizzle; }
    222 
    223     private:
    224         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
    225             class GLFP : public GrGLSLFragmentProcessor {
    226             public:
    227                 void emitCode(EmitArgs& args) override {
    228                     const SwizzleFragmentProcessor& sfp = args.fFp.cast<SwizzleFragmentProcessor>();
    229                     const GrSwizzle& swizzle = sfp.swizzle();
    230                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
    231 
    232                     fragBuilder->codeAppendf("%s = %s.%s;",
    233                                              args.fOutputColor, args.fInputColor, swizzle.c_str());
    234                 }
    235             };
    236             return new GLFP;
    237         }
    238 
    239         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
    240             b->add32(fSwizzle.asKey());
    241         }
    242 
    243         bool onIsEqual(const GrFragmentProcessor& other) const override {
    244             const SwizzleFragmentProcessor& sfp = other.cast<SwizzleFragmentProcessor>();
    245             return fSwizzle == sfp.fSwizzle;
    246         }
    247 
    248         GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
    249             return fSwizzle.applyTo(input);
    250         }
    251 
    252         GrSwizzle fSwizzle;
    253 
    254         typedef GrFragmentProcessor INHERITED;
    255     };
    256 
    257     if (!fp) {
    258         return nullptr;
    259     }
    260     if (GrSwizzle::RGBA() == swizzle) {
    261         return fp;
    262     }
    263     sk_sp<GrFragmentProcessor> fpPipeline[] = { fp, sk_make_sp<SwizzleFragmentProcessor>(swizzle) };
    264     return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
    265 }
    266 
    267 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MakeInputPremulAndMulByOutput(
    268         sk_sp<GrFragmentProcessor> fp) {
    269 
    270     class PremulFragmentProcessor : public GrFragmentProcessor {
    271     public:
    272         PremulFragmentProcessor(sk_sp<GrFragmentProcessor> processor)
    273                 : INHERITED(OptFlags(processor.get())) {
    274             this->initClassID<PremulFragmentProcessor>();
    275             this->registerChildProcessor(processor);
    276         }
    277 
    278         const char* name() const override { return "Premultiply"; }
    279 
    280     private:
    281         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
    282             class GLFP : public GrGLSLFragmentProcessor {
    283             public:
    284                 void emitCode(EmitArgs& args) override {
    285                     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
    286                     this->emitChild(0, nullptr, args);
    287                     fragBuilder->codeAppendf("%s.rgb *= %s.rgb;", args.fOutputColor,
    288                                                                 args.fInputColor);
    289                     fragBuilder->codeAppendf("%s *= %s.a;", args.fOutputColor, args.fInputColor);
    290                 }
    291             };
    292             return new GLFP;
    293         }
    294 
    295         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
    296 
    297         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
    298 
    299         static OptimizationFlags OptFlags(const GrFragmentProcessor* inner) {
    300             OptimizationFlags flags = kNone_OptimizationFlags;
    301             if (inner->preservesOpaqueInput()) {
    302                 flags |= kPreservesOpaqueInput_OptimizationFlag;
    303             }
    304             if (inner->hasConstantOutputForConstantInput()) {
    305                 flags |= kConstantOutputForConstantInput_OptimizationFlag;
    306             }
    307             return flags;
    308         }
    309 
    310         GrColor4f constantOutputForConstantInput(GrColor4f input) const override {
    311             GrColor4f childColor = ConstantOutputForConstantInput(this->childProcessor(0),
    312                                                                   GrColor4f::OpaqueWhite());
    313             return GrColor4f(input.fRGBA[3] * input.fRGBA[0] * childColor.fRGBA[0],
    314                              input.fRGBA[3] * input.fRGBA[1] * childColor.fRGBA[1],
    315                              input.fRGBA[3] * input.fRGBA[2] * childColor.fRGBA[2],
    316                              input.fRGBA[3] * childColor.fRGBA[3]);
    317         }
    318 
    319         typedef GrFragmentProcessor INHERITED;
    320     };
    321     if (!fp) {
    322         return nullptr;
    323     }
    324     return sk_sp<GrFragmentProcessor>(new PremulFragmentProcessor(std::move(fp)));
    325 }
    326 
    327 //////////////////////////////////////////////////////////////////////////////
    328 
    329 sk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentProcessor> fp,
    330                                                               GrColor4f color) {
    331     class ReplaceInputFragmentProcessor : public GrFragmentProcessor {
    332     public:
    333         ReplaceInputFragmentProcessor(sk_sp<GrFragmentProcessor> child, GrColor4f color)
    334                 : INHERITED(OptFlags(child.get(), color)), fColor(color) {
    335             this->initClassID<ReplaceInputFragmentProcessor>();
    336             this->registerChildProcessor(std::move(child));
    337         }
    338 
    339         const char* name() const override { return "Replace Color"; }
    340 
    341         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
    342             class GLFP : public GrGLSLFragmentProcessor {
    343             public:
    344                 GLFP() : fHaveSetColor(false) {}
    345                 void emitCode(EmitArgs& args) override {
    346                     const char* colorName;
    347                     fColorUni = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
    348                                                                  kVec4f_GrSLType,
    349                                                                  kDefault_GrSLPrecision,
    350                                                                  "Color", &colorName);
    351                     this->emitChild(0, colorName, args);
    352                 }
    353 
    354             private:
    355                 void onSetData(const GrGLSLProgramDataManager& pdman,
    356                                const GrProcessor& fp) override {
    357                     GrColor4f color = fp.cast<ReplaceInputFragmentProcessor>().fColor;
    358                     if (!fHaveSetColor || color != fPreviousColor) {
    359                         pdman.set4fv(fColorUni, 1, color.fRGBA);
    360                         fPreviousColor = color;
    361                         fHaveSetColor = true;
    362                     }
    363                 }
    364 
    365                 GrGLSLProgramDataManager::UniformHandle fColorUni;
    366                 bool      fHaveSetColor;
    367                 GrColor4f fPreviousColor;
    368             };
    369 
    370             return new GLFP;
    371         }
    372 
    373     private:
    374         static OptimizationFlags OptFlags(const GrFragmentProcessor* child, GrColor4f color) {
    375             OptimizationFlags childFlags = child->optimizationFlags();
    376             OptimizationFlags flags = kNone_OptimizationFlags;
    377             if (childFlags & kConstantOutputForConstantInput_OptimizationFlag) {
    378                 flags |= kConstantOutputForConstantInput_OptimizationFlag;
    379             }
    380             if ((childFlags & kPreservesOpaqueInput_OptimizationFlag) && color.isOpaque()) {
    381                 flags |= kPreservesOpaqueInput_OptimizationFlag;
    382             }
    383             return flags;
    384         }
    385 
    386         void onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override
    387         {}
    388 
    389         bool onIsEqual(const GrFragmentProcessor& that) const override {
    390             return fColor == that.cast<ReplaceInputFragmentProcessor>().fColor;
    391         }
    392 
    393         GrColor4f constantOutputForConstantInput(GrColor4f) const override {
    394             return ConstantOutputForConstantInput(this->childProcessor(0), fColor);
    395         }
    396 
    397         GrColor4f fColor;
    398 
    399         typedef GrFragmentProcessor INHERITED;
    400     };
    401 
    402     return sk_sp<GrFragmentProcessor>(new ReplaceInputFragmentProcessor(std::move(fp), color));
    403 }
    404 
    405 sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProcessor>* series,
    406                                                             int cnt) {
    407     class SeriesFragmentProcessor : public GrFragmentProcessor {
    408     public:
    409         SeriesFragmentProcessor(sk_sp<GrFragmentProcessor>* children, int cnt)
    410                 : INHERITED(OptFlags(children, cnt)) {
    411             SkASSERT(cnt > 1);
    412             this->initClassID<SeriesFragmentProcessor>();
    413             for (int i = 0; i < cnt; ++i) {
    414                 this->registerChildProcessor(std::move(children[i]));
    415             }
    416         }
    417 
    418         const char* name() const override { return "Series"; }
    419 
    420         GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
    421             class GLFP : public GrGLSLFragmentProcessor {
    422             public:
    423                 void emitCode(EmitArgs& args) override {
    424                     // First guy's input might be nil.
    425                     SkString temp("out0");
    426                     this->emitChild(0, args.fInputColor, &temp, args);
    427                     SkString input = temp;
    428                     for (int i = 1; i < this->numChildProcessors() - 1; ++i) {
    429                         temp.printf("out%d", i);
    430                         this->emitChild(i, input.c_str(), &temp, args);
    431                         input = temp;
    432                     }
    433                     // Last guy writes to our output variable.
    434                     this->emitChild(this->numChildProcessors() - 1, input.c_str(), args);
    435                 }
    436             };
    437             return new GLFP;
    438         }
    439     private:
    440         static OptimizationFlags OptFlags(sk_sp<GrFragmentProcessor>* children, int cnt) {
    441             OptimizationFlags flags = kAll_OptimizationFlags;
    442             for (int i = 0; i < cnt && flags != kNone_OptimizationFlags; ++i) {
    443                 flags &= children[i]->optimizationFlags();
    444             }
    445             return flags;
    446         }
    447         void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
    448 
    449         bool onIsEqual(const GrFragmentProcessor&) const override { return true; }
    450 
    451         GrColor4f constantOutputForConstantInput(GrColor4f color) const override {
    452             int childCnt = this->numChildProcessors();
    453             for (int i = 0; i < childCnt; ++i) {
    454                 color = ConstantOutputForConstantInput(this->childProcessor(i), color);
    455             }
    456             return color;
    457         }
    458 
    459         typedef GrFragmentProcessor INHERITED;
    460     };
    461 
    462     if (!cnt) {
    463         return nullptr;
    464     }
    465     if (1 == cnt) {
    466         return series[0];
    467     }
    468     // Run the through the series, do the invariant output processing, and look for eliminations.
    469     GrColorFragmentProcessorAnalysis info;
    470     info.analyzeProcessors(sk_sp_address_as_pointer_address(series), cnt);
    471     SkTArray<sk_sp<GrFragmentProcessor>> replacementSeries;
    472     GrColor4f knownColor;
    473     int leadingFPsToEliminate = info.initialProcessorsToEliminate(&knownColor);
    474     if (leadingFPsToEliminate) {
    475         sk_sp<GrFragmentProcessor> colorFP(
    476                 GrConstColorProcessor::Make(knownColor, GrConstColorProcessor::kIgnore_InputMode));
    477         if (leadingFPsToEliminate == cnt) {
    478             return colorFP;
    479         }
    480         cnt = cnt - leadingFPsToEliminate + 1;
    481         replacementSeries.reserve(cnt);
    482         replacementSeries.emplace_back(std::move(colorFP));
    483         for (int i = 0; i < cnt - 1; ++i) {
    484             replacementSeries.emplace_back(std::move(series[leadingFPsToEliminate + i]));
    485         }
    486         series = replacementSeries.begin();
    487     }
    488     return sk_sp<GrFragmentProcessor>(new SeriesFragmentProcessor(series, cnt));
    489 }
    490 
    491 //////////////////////////////////////////////////////////////////////////////
    492 
    493 GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) {
    494     for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) {
    495         fFPStack.push_back(&pipeline.getFragmentProcessor(i));
    496     }
    497 }
    498 
    499 const GrFragmentProcessor* GrFragmentProcessor::Iter::next() {
    500     if (fFPStack.empty()) {
    501         return nullptr;
    502     }
    503     const GrFragmentProcessor* back = fFPStack.back();
    504     fFPStack.pop_back();
    505     for (int i = back->numChildProcessors() - 1; i >= 0; --i) {
    506         fFPStack.push_back(&back->childProcessor(i));
    507     }
    508     return back;
    509 }
    510 
    511