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