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