1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2014 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef GrProcessorAnalysis_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define GrProcessorAnalysis_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h" 13*c8dee2aaSAndroid Build Coastguard Worker 14*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint> 15*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker class GrCaps; 18*c8dee2aaSAndroid Build Coastguard Worker class GrFragmentProcessor; 19*c8dee2aaSAndroid Build Coastguard Worker 20*c8dee2aaSAndroid Build Coastguard Worker class GrProcessorAnalysisColor { 21*c8dee2aaSAndroid Build Coastguard Worker public: 22*c8dee2aaSAndroid Build Coastguard Worker enum class Opaque { 23*c8dee2aaSAndroid Build Coastguard Worker kNo, 24*c8dee2aaSAndroid Build Coastguard Worker kYes, 25*c8dee2aaSAndroid Build Coastguard Worker }; 26*c8dee2aaSAndroid Build Coastguard Worker 27*c8dee2aaSAndroid Build Coastguard Worker constexpr GrProcessorAnalysisColor(Opaque opaque = Opaque::kNo) 28*c8dee2aaSAndroid Build Coastguard Worker : fFlags(opaque == Opaque::kYes ? kIsOpaque_Flag : 0) 29*c8dee2aaSAndroid Build Coastguard Worker , fColor(SK_PMColor4fTRANSPARENT) {} 30*c8dee2aaSAndroid Build Coastguard Worker GrProcessorAnalysisColor(const SkPMColor4f & color)31*c8dee2aaSAndroid Build Coastguard Worker GrProcessorAnalysisColor(const SkPMColor4f& color) { this->setToConstant(color); } 32*c8dee2aaSAndroid Build Coastguard Worker setToConstant(const SkPMColor4f & color)33*c8dee2aaSAndroid Build Coastguard Worker void setToConstant(const SkPMColor4f& color) { 34*c8dee2aaSAndroid Build Coastguard Worker fColor = color; 35*c8dee2aaSAndroid Build Coastguard Worker if (color.isOpaque()) { 36*c8dee2aaSAndroid Build Coastguard Worker fFlags = kColorIsKnown_Flag | kIsOpaque_Flag; 37*c8dee2aaSAndroid Build Coastguard Worker } else { 38*c8dee2aaSAndroid Build Coastguard Worker fFlags = kColorIsKnown_Flag; 39*c8dee2aaSAndroid Build Coastguard Worker } 40*c8dee2aaSAndroid Build Coastguard Worker } 41*c8dee2aaSAndroid Build Coastguard Worker setToUnknown()42*c8dee2aaSAndroid Build Coastguard Worker void setToUnknown() { fFlags = 0; } 43*c8dee2aaSAndroid Build Coastguard Worker setToUnknownOpaque()44*c8dee2aaSAndroid Build Coastguard Worker void setToUnknownOpaque() { fFlags = kIsOpaque_Flag; } 45*c8dee2aaSAndroid Build Coastguard Worker isUnknown()46*c8dee2aaSAndroid Build Coastguard Worker bool isUnknown() const { return SkToBool(fFlags == 0); } 47*c8dee2aaSAndroid Build Coastguard Worker isOpaque()48*c8dee2aaSAndroid Build Coastguard Worker bool isOpaque() const { return SkToBool(kIsOpaque_Flag & fFlags); } 49*c8dee2aaSAndroid Build Coastguard Worker 50*c8dee2aaSAndroid Build Coastguard Worker bool isConstant(SkPMColor4f* color = nullptr) const { 51*c8dee2aaSAndroid Build Coastguard Worker if (kColorIsKnown_Flag & fFlags) { 52*c8dee2aaSAndroid Build Coastguard Worker if (color) { 53*c8dee2aaSAndroid Build Coastguard Worker *color = fColor; 54*c8dee2aaSAndroid Build Coastguard Worker } 55*c8dee2aaSAndroid Build Coastguard Worker return true; 56*c8dee2aaSAndroid Build Coastguard Worker } 57*c8dee2aaSAndroid Build Coastguard Worker return false; 58*c8dee2aaSAndroid Build Coastguard Worker } 59*c8dee2aaSAndroid Build Coastguard Worker 60*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const GrProcessorAnalysisColor& that) const { 61*c8dee2aaSAndroid Build Coastguard Worker if (fFlags != that.fFlags) { 62*c8dee2aaSAndroid Build Coastguard Worker return false; 63*c8dee2aaSAndroid Build Coastguard Worker } 64*c8dee2aaSAndroid Build Coastguard Worker return (kColorIsKnown_Flag & fFlags) ? fColor == that.fColor : true; 65*c8dee2aaSAndroid Build Coastguard Worker } 66*c8dee2aaSAndroid Build Coastguard Worker 67*c8dee2aaSAndroid Build Coastguard Worker /** The returned value reflects the common properties of the two inputs. */ Combine(const GrProcessorAnalysisColor & a,const GrProcessorAnalysisColor & b)68*c8dee2aaSAndroid Build Coastguard Worker static GrProcessorAnalysisColor Combine(const GrProcessorAnalysisColor& a, 69*c8dee2aaSAndroid Build Coastguard Worker const GrProcessorAnalysisColor& b) { 70*c8dee2aaSAndroid Build Coastguard Worker GrProcessorAnalysisColor result; 71*c8dee2aaSAndroid Build Coastguard Worker uint32_t commonFlags = a.fFlags & b.fFlags; 72*c8dee2aaSAndroid Build Coastguard Worker if ((kColorIsKnown_Flag & commonFlags) && a.fColor == b.fColor) { 73*c8dee2aaSAndroid Build Coastguard Worker result.fColor = a.fColor; 74*c8dee2aaSAndroid Build Coastguard Worker result.fFlags = a.fFlags; 75*c8dee2aaSAndroid Build Coastguard Worker } else if (kIsOpaque_Flag & commonFlags) { 76*c8dee2aaSAndroid Build Coastguard Worker result.fFlags = kIsOpaque_Flag; 77*c8dee2aaSAndroid Build Coastguard Worker } 78*c8dee2aaSAndroid Build Coastguard Worker return result; 79*c8dee2aaSAndroid Build Coastguard Worker } 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker private: 82*c8dee2aaSAndroid Build Coastguard Worker enum Flags { 83*c8dee2aaSAndroid Build Coastguard Worker kColorIsKnown_Flag = 0x1, 84*c8dee2aaSAndroid Build Coastguard Worker kIsOpaque_Flag = 0x2, 85*c8dee2aaSAndroid Build Coastguard Worker }; 86*c8dee2aaSAndroid Build Coastguard Worker uint32_t fFlags; 87*c8dee2aaSAndroid Build Coastguard Worker SkPMColor4f fColor; 88*c8dee2aaSAndroid Build Coastguard Worker }; 89*c8dee2aaSAndroid Build Coastguard Worker 90*c8dee2aaSAndroid Build Coastguard Worker enum class GrProcessorAnalysisCoverage { kNone, kSingleChannel, kLCD }; 91*c8dee2aaSAndroid Build Coastguard Worker 92*c8dee2aaSAndroid Build Coastguard Worker /** 93*c8dee2aaSAndroid Build Coastguard Worker * GrColorFragmentProcessorAnalysis gathers invariant data from a set of color fragment processors. 94*c8dee2aaSAndroid Build Coastguard Worker * It is used to recognize optimizations that can simplify the generated shader or make blending 95*c8dee2aaSAndroid Build Coastguard Worker * more effecient. 96*c8dee2aaSAndroid Build Coastguard Worker */ 97*c8dee2aaSAndroid Build Coastguard Worker class GrColorFragmentProcessorAnalysis { 98*c8dee2aaSAndroid Build Coastguard Worker public: 99*c8dee2aaSAndroid Build Coastguard Worker GrColorFragmentProcessorAnalysis() = delete; 100*c8dee2aaSAndroid Build Coastguard Worker 101*c8dee2aaSAndroid Build Coastguard Worker GrColorFragmentProcessorAnalysis(const GrProcessorAnalysisColor& input, 102*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> const fps[], 103*c8dee2aaSAndroid Build Coastguard Worker int count); 104*c8dee2aaSAndroid Build Coastguard Worker isOpaque()105*c8dee2aaSAndroid Build Coastguard Worker bool isOpaque() const { return fIsOpaque; } 106*c8dee2aaSAndroid Build Coastguard Worker 107*c8dee2aaSAndroid Build Coastguard Worker /** 108*c8dee2aaSAndroid Build Coastguard Worker * Are all the fragment processors compatible with conflating coverage with color prior to the 109*c8dee2aaSAndroid Build Coastguard Worker * the first fragment processor. This result assumes that processors that should be eliminated 110*c8dee2aaSAndroid Build Coastguard Worker * as indicated by initialProcessorsToEliminate() are in fact eliminated. 111*c8dee2aaSAndroid Build Coastguard Worker */ allProcessorsCompatibleWithCoverageAsAlpha()112*c8dee2aaSAndroid Build Coastguard Worker bool allProcessorsCompatibleWithCoverageAsAlpha() const { 113*c8dee2aaSAndroid Build Coastguard Worker return fCompatibleWithCoverageAsAlpha; 114*c8dee2aaSAndroid Build Coastguard Worker } 115*c8dee2aaSAndroid Build Coastguard Worker 116*c8dee2aaSAndroid Build Coastguard Worker /** 117*c8dee2aaSAndroid Build Coastguard Worker * Do any of the fragment processors require local coords. This result assumes that 118*c8dee2aaSAndroid Build Coastguard Worker * processors that should be eliminated as indicated by initialProcessorsToEliminate() are in 119*c8dee2aaSAndroid Build Coastguard Worker * fact eliminated. 120*c8dee2aaSAndroid Build Coastguard Worker */ usesLocalCoords()121*c8dee2aaSAndroid Build Coastguard Worker bool usesLocalCoords() const { return fUsesLocalCoords; } 122*c8dee2aaSAndroid Build Coastguard Worker 123*c8dee2aaSAndroid Build Coastguard Worker /** 124*c8dee2aaSAndroid Build Coastguard Worker * Do any of the fragment processors read back the destination color? 125*c8dee2aaSAndroid Build Coastguard Worker */ willReadDstColor()126*c8dee2aaSAndroid Build Coastguard Worker bool willReadDstColor() const { return fWillReadDstColor; } 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker /** 129*c8dee2aaSAndroid Build Coastguard Worker * Will we require a destination-surface texture? 130*c8dee2aaSAndroid Build Coastguard Worker */ 131*c8dee2aaSAndroid Build Coastguard Worker bool requiresDstTexture(const GrCaps& caps) const; 132*c8dee2aaSAndroid Build Coastguard Worker 133*c8dee2aaSAndroid Build Coastguard Worker /** 134*c8dee2aaSAndroid Build Coastguard Worker * If we detected that the result after the first N processors is a known color then we 135*c8dee2aaSAndroid Build Coastguard Worker * eliminate those N processors and replace the GrDrawOp's color input to the GrPipeline with 136*c8dee2aaSAndroid Build Coastguard Worker * the known output of the Nth processor, so that the Nth+1 fragment processor (or the XP if 137*c8dee2aaSAndroid Build Coastguard Worker * there are only N processors) sees its expected input. If this returns 0 then there are no 138*c8dee2aaSAndroid Build Coastguard Worker * processors to eliminate. 139*c8dee2aaSAndroid Build Coastguard Worker */ initialProcessorsToEliminate(SkPMColor4f * newPipelineInputColor)140*c8dee2aaSAndroid Build Coastguard Worker int initialProcessorsToEliminate(SkPMColor4f* newPipelineInputColor) const { 141*c8dee2aaSAndroid Build Coastguard Worker if (fProcessorsToEliminate > 0) { 142*c8dee2aaSAndroid Build Coastguard Worker *newPipelineInputColor = fLastKnownOutputColor; 143*c8dee2aaSAndroid Build Coastguard Worker } 144*c8dee2aaSAndroid Build Coastguard Worker return fProcessorsToEliminate; 145*c8dee2aaSAndroid Build Coastguard Worker } 146*c8dee2aaSAndroid Build Coastguard Worker 147*c8dee2aaSAndroid Build Coastguard Worker /** 148*c8dee2aaSAndroid Build Coastguard Worker * Provides known information about the last processor's output color. 149*c8dee2aaSAndroid Build Coastguard Worker */ outputColor()150*c8dee2aaSAndroid Build Coastguard Worker GrProcessorAnalysisColor outputColor() const { 151*c8dee2aaSAndroid Build Coastguard Worker if (fOutputColorKnown) { 152*c8dee2aaSAndroid Build Coastguard Worker return fLastKnownOutputColor; 153*c8dee2aaSAndroid Build Coastguard Worker } 154*c8dee2aaSAndroid Build Coastguard Worker return fIsOpaque ? GrProcessorAnalysisColor::Opaque::kYes 155*c8dee2aaSAndroid Build Coastguard Worker : GrProcessorAnalysisColor::Opaque::kNo; 156*c8dee2aaSAndroid Build Coastguard Worker } 157*c8dee2aaSAndroid Build Coastguard Worker 158*c8dee2aaSAndroid Build Coastguard Worker private: 159*c8dee2aaSAndroid Build Coastguard Worker bool fIsOpaque; 160*c8dee2aaSAndroid Build Coastguard Worker bool fCompatibleWithCoverageAsAlpha; 161*c8dee2aaSAndroid Build Coastguard Worker bool fUsesLocalCoords; 162*c8dee2aaSAndroid Build Coastguard Worker bool fWillReadDstColor; 163*c8dee2aaSAndroid Build Coastguard Worker bool fOutputColorKnown; 164*c8dee2aaSAndroid Build Coastguard Worker int fProcessorsToEliminate; 165*c8dee2aaSAndroid Build Coastguard Worker SkPMColor4f fLastKnownOutputColor; 166*c8dee2aaSAndroid Build Coastguard Worker }; 167*c8dee2aaSAndroid Build Coastguard Worker 168*c8dee2aaSAndroid Build Coastguard Worker #endif 169