Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2014 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 #ifndef GrPipelineAnalysis_DEFINED
      9 #define GrPipelineAnalysis_DEFINED
     10 
     11 #include "GrColor.h"
     12 
     13 class GrDrawOp;
     14 class GrFragmentProcessor;
     15 class GrPrimitiveProcessor;
     16 
     17 class GrPipelineAnalysisColor {
     18 public:
     19     enum class Opaque {
     20         kNo,
     21         kYes,
     22     };
     23 
     24     GrPipelineAnalysisColor(Opaque opaque = Opaque::kNo)
     25             : fFlags(opaque == Opaque::kYes ? kIsOpaque_Flag : 0) {}
     26 
     27     GrPipelineAnalysisColor(GrColor color) { this->setToConstant(color); }
     28 
     29     void setToConstant(GrColor color) {
     30         fColor = color;
     31         if (GrColorIsOpaque(color)) {
     32             fFlags = kColorIsKnown_Flag | kIsOpaque_Flag;
     33         } else {
     34             fFlags = kColorIsKnown_Flag;
     35         }
     36     }
     37 
     38     void setToUnknown() { fFlags = 0; }
     39 
     40     void setToUnknownOpaque() { fFlags = kIsOpaque_Flag; }
     41 
     42     bool isOpaque() const { return SkToBool(kIsOpaque_Flag & fFlags); }
     43 
     44     bool isConstant(GrColor* color) const {
     45         if (kColorIsKnown_Flag & fFlags) {
     46             *color = fColor;
     47             return true;
     48         }
     49         return false;
     50     }
     51 
     52 private:
     53     enum Flags {
     54         kColorIsKnown_Flag = 0x1,
     55         kIsOpaque_Flag = 0x2,
     56     };
     57     uint32_t fFlags;
     58     GrColor fColor;
     59 };
     60 
     61 enum class GrPipelineAnalysisCoverage { kNone, kSingleChannel, kLCD };
     62 
     63 /**
     64  * GrColorFragmentProcessorAnalysis gathers invariant data from a set of color fragment processor.
     65  * It is used to recognize optimizations that can simplify the generated shader or make blending
     66  * more effecient.
     67  */
     68 class GrColorFragmentProcessorAnalysis {
     69 public:
     70     GrColorFragmentProcessorAnalysis() = default;
     71 
     72     GrColorFragmentProcessorAnalysis(const GrPipelineAnalysisColor& input)
     73             : GrColorFragmentProcessorAnalysis() {
     74         fAllProcessorsCompatibleWithCoverageAsAlpha = true;
     75         fIsOpaque = input.isOpaque();
     76         GrColor color;
     77         if (input.isConstant(&color)) {
     78             fLastKnownOutputColor = GrColor4f::FromGrColor(color);
     79             fProcessorsVisitedWithKnownOutput = 0;
     80         }
     81     }
     82 
     83     void reset(const GrPipelineAnalysisColor& input) {
     84         *this = GrColorFragmentProcessorAnalysis(input);
     85     }
     86 
     87     /**
     88      * Runs through a series of processors and updates calculated values. This can be called
     89      * repeatedly for cases when the sequence of processors is not in a contiguous array.
     90      */
     91     void analyzeProcessors(const GrFragmentProcessor* const* processors, int cnt);
     92 
     93     bool isOpaque() const { return fIsOpaque; }
     94 
     95     /**
     96      * Are all the fragment processors compatible with conflating coverage with color prior to the
     97      * the first fragment processor. This result does not consider processors that should be
     98      * eliminated as indicated by initialProcessorsToEliminate().
     99      */
    100     bool allProcessorsCompatibleWithCoverageAsAlpha() const {
    101         return fAllProcessorsCompatibleWithCoverageAsAlpha;
    102     }
    103 
    104     /**
    105      * Do any of the fragment processors require local coords. This result does not consider
    106      * processors that should be eliminated as indicated by initialProcessorsToEliminate().
    107      */
    108     bool usesLocalCoords() const { return fUsesLocalCoords; }
    109 
    110     /**
    111      * If we detected that the result after the first N processors is a known color then we
    112      * eliminate those N processors and replace the GrDrawOp's color input to the GrPipeline with
    113      * the known output of the Nth processor, so that the Nth+1 fragment processor (or the XP if
    114      * there are only N processors) sees its expected input. If this returns 0 then there are no
    115      * processors to eliminate.
    116      */
    117     int initialProcessorsToEliminate(GrColor* newPipelineInputColor) const {
    118         if (fProcessorsVisitedWithKnownOutput > 0) {
    119             *newPipelineInputColor = fLastKnownOutputColor.toGrColor();
    120         }
    121         return SkTMax(0, fProcessorsVisitedWithKnownOutput);
    122     }
    123 
    124     int initialProcessorsToEliminate(GrColor4f* newPipelineInputColor) const {
    125         if (fProcessorsVisitedWithKnownOutput > 0) {
    126             *newPipelineInputColor = fLastKnownOutputColor;
    127         }
    128         return SkTMax(0, fProcessorsVisitedWithKnownOutput);
    129     }
    130 
    131     GrPipelineAnalysisColor outputColor() const {
    132         if (fProcessorsVisitedWithKnownOutput != fTotalProcessorsVisited) {
    133             return GrPipelineAnalysisColor(fIsOpaque ? GrPipelineAnalysisColor::Opaque::kYes
    134                                                      : GrPipelineAnalysisColor::Opaque::kNo);
    135         }
    136         return GrPipelineAnalysisColor(fLastKnownOutputColor.toGrColor());
    137     }
    138 
    139 private:
    140     int fTotalProcessorsVisited = 0;
    141     // negative one means even the color is unknown before adding the first processor.
    142     int fProcessorsVisitedWithKnownOutput = -1;
    143     bool fIsOpaque = false;
    144     bool fAllProcessorsCompatibleWithCoverageAsAlpha = true;
    145     bool fUsesLocalCoords = false;
    146     GrColor4f fLastKnownOutputColor;
    147 };
    148 
    149 #endif
    150