1*c8dee2aaSAndroid Build Coastguard Worker 2*c8dee2aaSAndroid Build Coastguard Worker /* 3*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc. 4*c8dee2aaSAndroid Build Coastguard Worker * 5*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 6*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 7*c8dee2aaSAndroid Build Coastguard Worker */ 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef GrPaint_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define GrPaint_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRegion.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrFragmentProcessor.h" 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 19*c8dee2aaSAndroid Build Coastguard Worker #include <utility> 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker class GrXPFactory; 22*c8dee2aaSAndroid Build Coastguard Worker enum class SkBlendMode; 23*c8dee2aaSAndroid Build Coastguard Worker 24*c8dee2aaSAndroid Build Coastguard Worker /** 25*c8dee2aaSAndroid Build Coastguard Worker * The paint describes how color and coverage are computed at each pixel by GrContext draw 26*c8dee2aaSAndroid Build Coastguard Worker * functions and the how color is blended with the destination pixel. 27*c8dee2aaSAndroid Build Coastguard Worker * 28*c8dee2aaSAndroid Build Coastguard Worker * The paint allows installation of custom color and coverage stages. New types of stages are 29*c8dee2aaSAndroid Build Coastguard Worker * created by subclassing GrProcessor. 30*c8dee2aaSAndroid Build Coastguard Worker * 31*c8dee2aaSAndroid Build Coastguard Worker * The primitive color computation starts with the color specified by setColor(). This color is the 32*c8dee2aaSAndroid Build Coastguard Worker * input to the first color stage. Each color stage feeds its output to the next color stage. 33*c8dee2aaSAndroid Build Coastguard Worker * 34*c8dee2aaSAndroid Build Coastguard Worker * Fractional pixel coverage follows a similar flow. The GrGeometryProcessor (specified elsewhere) 35*c8dee2aaSAndroid Build Coastguard Worker * provides the initial coverage which is passed to the first coverage fragment processor, which 36*c8dee2aaSAndroid Build Coastguard Worker * feeds its output to next coverage fragment processor. 37*c8dee2aaSAndroid Build Coastguard Worker * 38*c8dee2aaSAndroid Build Coastguard Worker * setXPFactory is used to control blending between the output color and dest. It also implements 39*c8dee2aaSAndroid Build Coastguard Worker * the application of fractional coverage from the coverage pipeline. 40*c8dee2aaSAndroid Build Coastguard Worker */ 41*c8dee2aaSAndroid Build Coastguard Worker class GrPaint { 42*c8dee2aaSAndroid Build Coastguard Worker public: 43*c8dee2aaSAndroid Build Coastguard Worker GrPaint() = default; 44*c8dee2aaSAndroid Build Coastguard Worker ~GrPaint() = default; 45*c8dee2aaSAndroid Build Coastguard Worker Clone(const GrPaint & src)46*c8dee2aaSAndroid Build Coastguard Worker static GrPaint Clone(const GrPaint& src) { return GrPaint(src); } 47*c8dee2aaSAndroid Build Coastguard Worker 48*c8dee2aaSAndroid Build Coastguard Worker /** 49*c8dee2aaSAndroid Build Coastguard Worker * The initial color of the drawn primitive. Defaults to solid white. 50*c8dee2aaSAndroid Build Coastguard Worker */ setColor4f(const SkPMColor4f & color)51*c8dee2aaSAndroid Build Coastguard Worker void setColor4f(const SkPMColor4f& color) { fColor = color; } getColor4f()52*c8dee2aaSAndroid Build Coastguard Worker const SkPMColor4f& getColor4f() const { return fColor; } 53*c8dee2aaSAndroid Build Coastguard Worker setXPFactory(const GrXPFactory * xpFactory)54*c8dee2aaSAndroid Build Coastguard Worker void setXPFactory(const GrXPFactory* xpFactory) { 55*c8dee2aaSAndroid Build Coastguard Worker fXPFactory = xpFactory; 56*c8dee2aaSAndroid Build Coastguard Worker fTrivial &= !SkToBool(xpFactory); 57*c8dee2aaSAndroid Build Coastguard Worker } 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker void setPorterDuffXPFactory(SkBlendMode mode); 60*c8dee2aaSAndroid Build Coastguard Worker 61*c8dee2aaSAndroid Build Coastguard Worker void setCoverageSetOpXPFactory(SkRegion::Op, bool invertCoverage = false); 62*c8dee2aaSAndroid Build Coastguard Worker 63*c8dee2aaSAndroid Build Coastguard Worker /** 64*c8dee2aaSAndroid Build Coastguard Worker * Sets a processor for color computation. 65*c8dee2aaSAndroid Build Coastguard Worker */ setColorFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp)66*c8dee2aaSAndroid Build Coastguard Worker void setColorFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp) { 67*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fp); 68*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fColorFragmentProcessor == nullptr); 69*c8dee2aaSAndroid Build Coastguard Worker fColorFragmentProcessor = std::move(fp); 70*c8dee2aaSAndroid Build Coastguard Worker fTrivial = false; 71*c8dee2aaSAndroid Build Coastguard Worker } 72*c8dee2aaSAndroid Build Coastguard Worker 73*c8dee2aaSAndroid Build Coastguard Worker /** 74*c8dee2aaSAndroid Build Coastguard Worker * Appends an additional coverage processor to the coverage computation. 75*c8dee2aaSAndroid Build Coastguard Worker */ setCoverageFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp)76*c8dee2aaSAndroid Build Coastguard Worker void setCoverageFragmentProcessor(std::unique_ptr<GrFragmentProcessor> fp) { 77*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fp); 78*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fCoverageFragmentProcessor == nullptr); 79*c8dee2aaSAndroid Build Coastguard Worker fCoverageFragmentProcessor = std::move(fp); 80*c8dee2aaSAndroid Build Coastguard Worker fTrivial = false; 81*c8dee2aaSAndroid Build Coastguard Worker } 82*c8dee2aaSAndroid Build Coastguard Worker hasColorFragmentProcessor()83*c8dee2aaSAndroid Build Coastguard Worker bool hasColorFragmentProcessor() const { return fColorFragmentProcessor ? true : false; } hasCoverageFragmentProcessor()84*c8dee2aaSAndroid Build Coastguard Worker int hasCoverageFragmentProcessor() const { return fCoverageFragmentProcessor ? true : false; } numTotalFragmentProcessors()85*c8dee2aaSAndroid Build Coastguard Worker int numTotalFragmentProcessors() const { 86*c8dee2aaSAndroid Build Coastguard Worker return (this->hasColorFragmentProcessor() ? 1 : 0) + 87*c8dee2aaSAndroid Build Coastguard Worker (this->hasCoverageFragmentProcessor() ? 1 : 0); 88*c8dee2aaSAndroid Build Coastguard Worker } 89*c8dee2aaSAndroid Build Coastguard Worker getXPFactory()90*c8dee2aaSAndroid Build Coastguard Worker const GrXPFactory* getXPFactory() const { return fXPFactory; } 91*c8dee2aaSAndroid Build Coastguard Worker getColorFragmentProcessor()92*c8dee2aaSAndroid Build Coastguard Worker GrFragmentProcessor* getColorFragmentProcessor() const { 93*c8dee2aaSAndroid Build Coastguard Worker return fColorFragmentProcessor.get(); 94*c8dee2aaSAndroid Build Coastguard Worker } getCoverageFragmentProcessor()95*c8dee2aaSAndroid Build Coastguard Worker GrFragmentProcessor* getCoverageFragmentProcessor() const { 96*c8dee2aaSAndroid Build Coastguard Worker return fCoverageFragmentProcessor.get(); 97*c8dee2aaSAndroid Build Coastguard Worker } usesLocalCoords()98*c8dee2aaSAndroid Build Coastguard Worker bool usesLocalCoords() const { 99*c8dee2aaSAndroid Build Coastguard Worker // The sample coords for the top level FPs are implicitly the GP's local coords. 100*c8dee2aaSAndroid Build Coastguard Worker return (fColorFragmentProcessor && fColorFragmentProcessor->usesSampleCoords()) || 101*c8dee2aaSAndroid Build Coastguard Worker (fCoverageFragmentProcessor && fCoverageFragmentProcessor->usesSampleCoords()); 102*c8dee2aaSAndroid Build Coastguard Worker } 103*c8dee2aaSAndroid Build Coastguard Worker 104*c8dee2aaSAndroid Build Coastguard Worker /** 105*c8dee2aaSAndroid Build Coastguard Worker * Returns true if the paint's output color will be constant after blending. If the result is 106*c8dee2aaSAndroid Build Coastguard Worker * true, constantColor will be updated to contain the constant color. Note that we can conflate 107*c8dee2aaSAndroid Build Coastguard Worker * coverage and color, so the actual values written to pixels with partial coverage may still 108*c8dee2aaSAndroid Build Coastguard Worker * not seem constant, even if this function returns true. 109*c8dee2aaSAndroid Build Coastguard Worker */ 110*c8dee2aaSAndroid Build Coastguard Worker bool isConstantBlendedColor(SkPMColor4f* constantColor) const; 111*c8dee2aaSAndroid Build Coastguard Worker 112*c8dee2aaSAndroid Build Coastguard Worker /** 113*c8dee2aaSAndroid Build Coastguard Worker * A trivial paint is one that uses src-over and has no fragment processors. 114*c8dee2aaSAndroid Build Coastguard Worker * It may have variable sRGB settings. 115*c8dee2aaSAndroid Build Coastguard Worker **/ isTrivial()116*c8dee2aaSAndroid Build Coastguard Worker bool isTrivial() const { return fTrivial; } 117*c8dee2aaSAndroid Build Coastguard Worker assert_alive(GrPaint & p)118*c8dee2aaSAndroid Build Coastguard Worker friend void assert_alive(GrPaint& p) { 119*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(p.fAlive); 120*c8dee2aaSAndroid Build Coastguard Worker } 121*c8dee2aaSAndroid Build Coastguard Worker 122*c8dee2aaSAndroid Build Coastguard Worker private: 123*c8dee2aaSAndroid Build Coastguard Worker // Since paint copying is expensive if there are fragment processors, we require going through 124*c8dee2aaSAndroid Build Coastguard Worker // the Clone() method. 125*c8dee2aaSAndroid Build Coastguard Worker GrPaint(const GrPaint&); 126*c8dee2aaSAndroid Build Coastguard Worker GrPaint& operator=(const GrPaint&) = delete; 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker friend class GrProcessorSet; 129*c8dee2aaSAndroid Build Coastguard Worker 130*c8dee2aaSAndroid Build Coastguard Worker const GrXPFactory* fXPFactory = nullptr; 131*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> fColorFragmentProcessor; 132*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrFragmentProcessor> fCoverageFragmentProcessor; 133*c8dee2aaSAndroid Build Coastguard Worker bool fTrivial = true; 134*c8dee2aaSAndroid Build Coastguard Worker SkPMColor4f fColor = SK_PMColor4fWHITE; 135*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(bool fAlive = true;) // Set false after moved from. 136*c8dee2aaSAndroid Build Coastguard Worker }; 137*c8dee2aaSAndroid Build Coastguard Worker 138*c8dee2aaSAndroid Build Coastguard Worker #endif 139