LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu - GrXferProcessor.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 44 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 GrXferProcessor_DEFINED
       9             : #define GrXferProcessor_DEFINED
      10             : 
      11             : #include "GrBlend.h"
      12             : #include "GrColor.h"
      13             : #include "GrNonAtomicRef.h"
      14             : #include "GrProcessor.h"
      15             : #include "GrProcessorSet.h"
      16             : #include "GrTexture.h"
      17             : #include "GrTypes.h"
      18             : 
      19             : class GrShaderCaps;
      20             : class GrGLSLXferProcessor;
      21             : 
      22             : /**
      23             :  * Barriers for blending. When a shader reads the dst directly, an Xfer barrier is sometimes
      24             :  * required after a pixel has been written, before it can be safely read again.
      25             :  */
      26             : enum GrXferBarrierType {
      27             :     kNone_GrXferBarrierType = 0, //<! No barrier is required
      28             :     kTexture_GrXferBarrierType,  //<! Required when a shader reads and renders to the same texture.
      29             :     kBlend_GrXferBarrierType,    //<! Required by certain blend extensions.
      30             : };
      31             : /** Should be able to treat kNone as false in boolean expressions */
      32             : GR_STATIC_ASSERT(SkToBool(kNone_GrXferBarrierType) == false);
      33             : 
      34             : /**
      35             :  * GrXferProcessor is responsible for implementing the xfer mode that blends the src color and dst
      36             :  * color, and for applying any coverage. It does this by emitting fragment shader code and
      37             :  * controlling the fixed-function blend state. When dual-source blending is available, it may also
      38             :  * write a seconday fragment shader output color. GrXferProcessor has two modes of operation:
      39             :  *
      40             :  * Dst read: When allowed by the backend API, or when supplied a texture of the destination, the
      41             :  * GrXferProcessor may read the destination color. While operating in this mode, the subclass only
      42             :  * provides shader code that blends the src and dst colors, and the base class applies coverage.
      43             :  *
      44             :  * No dst read: When not performing a dst read, the subclass is given full control of the fixed-
      45             :  * function blend state and/or secondary output, and is responsible to apply coverage on its own.
      46             :  *
      47             :  * A GrXferProcessor is never installed directly into our draw state, but instead is created from a
      48             :  * GrXPFactory once we have finalized the state of our draw.
      49             :  */
      50           0 : class GrXferProcessor : public GrProcessor, public GrNonAtomicRef<GrXferProcessor> {
      51             : public:
      52             :     /**
      53             :      * A texture that contains the dst pixel values and an integer coord offset from device space
      54             :      * to the space of the texture. Depending on GPU capabilities a DstTexture may be used by a
      55             :      * GrXferProcessor for blending in the fragment shader.
      56             :      */
      57           0 :     class DstTexture {
      58             :     public:
      59           0 :         DstTexture() { fOffset.set(0, 0); }
      60             : 
      61           0 :         DstTexture(const DstTexture& other) {
      62           0 :             *this = other;
      63           0 :         }
      64             : 
      65             :         DstTexture(GrTexture* texture, const SkIPoint& offset)
      66             :                 : fTexture(SkSafeRef(texture)), fOffset(texture ? offset : SkIPoint{0, 0}) {}
      67             : 
      68           0 :         DstTexture& operator=(const DstTexture& other) {
      69           0 :             fTexture = other.fTexture;
      70           0 :             fOffset = other.fOffset;
      71           0 :             return *this;
      72             :         }
      73             : 
      74           0 :         bool operator==(const DstTexture& that) const {
      75           0 :             return fTexture == that.fTexture && fOffset == that.fOffset;
      76             :         }
      77           0 :         bool operator!=(const DstTexture& that) const { return !(*this == that); }
      78             : 
      79           0 :         const SkIPoint& offset() const { return fOffset; }
      80             : 
      81           0 :         void setOffset(const SkIPoint& offset) { fOffset = offset; }
      82           0 :         void setOffset(int ox, int oy) { fOffset.set(ox, oy); }
      83             : 
      84           0 :         GrTexture* texture() const { return fTexture.get(); }
      85             : 
      86           0 :         void setTexture(sk_sp<GrTexture> texture) {
      87           0 :             fTexture = std::move(texture);
      88           0 :             if (!fTexture) {
      89           0 :                 fOffset = {0, 0};
      90             :             }
      91           0 :         }
      92             : 
      93             :     private:
      94             :         sk_sp<GrTexture> fTexture;
      95             :         SkIPoint         fOffset;
      96             :     };
      97             : 
      98             :     /**
      99             :      * Sets a unique key on the GrProcessorKeyBuilder calls onGetGLSLProcessorKey(...) to get the
     100             :      * specific subclass's key.
     101             :      */
     102             :     void getGLSLProcessorKey(const GrShaderCaps&,
     103             :                              GrProcessorKeyBuilder*,
     104             :                              const GrSurfaceOrigin* originIfDstTexture) const;
     105             : 
     106             :     /** Returns a new instance of the appropriate *GL* implementation class
     107             :         for the given GrXferProcessor; caller is responsible for deleting
     108             :         the object. */
     109             :     virtual GrGLSLXferProcessor* createGLSLInstance() const = 0;
     110             : 
     111             :     /**
     112             :      * Returns the barrier type, if any, that this XP will require. Note that the possibility
     113             :      * that a kTexture type barrier is required is handled by the GrPipeline and need not be
     114             :      * considered by subclass overrides of this function.
     115             :      */
     116           0 :     virtual GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
     117           0 :         return kNone_GrXferBarrierType;
     118             :     }
     119             : 
     120             :     struct BlendInfo {
     121           0 :         void reset() {
     122           0 :             fEquation = kAdd_GrBlendEquation;
     123           0 :             fSrcBlend = kOne_GrBlendCoeff;
     124           0 :             fDstBlend = kZero_GrBlendCoeff;
     125           0 :             fBlendConstant = 0;
     126           0 :             fWriteColor = true;
     127           0 :         }
     128             : 
     129             :         SkDEBUGCODE(SkString dump() const;)
     130             : 
     131             :         GrBlendEquation fEquation;
     132             :         GrBlendCoeff    fSrcBlend;
     133             :         GrBlendCoeff    fDstBlend;
     134             :         GrColor         fBlendConstant;
     135             :         bool            fWriteColor;
     136             :     };
     137             : 
     138             :     void getBlendInfo(BlendInfo* blendInfo) const;
     139             : 
     140           0 :     bool willReadDstColor() const { return fWillReadDstColor; }
     141             : 
     142             :     /**
     143             :      * If we are performing a dst read, returns whether the base class will use mixed samples to
     144             :      * antialias the shader's final output. If not doing a dst read, the subclass is responsible
     145             :      * for antialiasing and this returns false.
     146             :      */
     147           0 :     bool dstReadUsesMixedSamples() const { return fDstReadUsesMixedSamples; }
     148             : 
     149             :     /**
     150             :      * Returns whether or not this xferProcossor will set a secondary output to be used with dual
     151             :      * source blending.
     152             :      */
     153             :     bool hasSecondaryOutput() const;
     154             : 
     155             :     /** Returns true if this and other processor conservatively draw identically. It can only return
     156             :         true when the two processor are of the same subclass (i.e. they return the same object from
     157             :         from getFactory()).
     158             : 
     159             :         A return value of true from isEqual() should not be used to test whether the processor would
     160             :         generate the same shader code. To test for identical code generation use getGLSLProcessorKey
     161             :       */
     162             :     
     163           0 :     bool isEqual(const GrXferProcessor& that) const {
     164           0 :         if (this->classID() != that.classID()) {
     165           0 :             return false;
     166             :         }
     167           0 :         if (this->fWillReadDstColor != that.fWillReadDstColor) {
     168           0 :             return false;
     169             :         }
     170           0 :         if (this->fDstReadUsesMixedSamples != that.fDstReadUsesMixedSamples) {
     171           0 :             return false;
     172             :         }
     173           0 :         return this->onIsEqual(that);
     174             :     }
     175             : 
     176             : protected:
     177             :     GrXferProcessor();
     178             :     GrXferProcessor(bool willReadDstColor, bool hasMixedSamples);
     179             : 
     180             : private:
     181             :     /**
     182             :      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
     183             :      * processor's GL backend implementation.
     184             :      */
     185             :     virtual void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
     186             : 
     187             :     /**
     188             :      * If we are not performing a dst read, returns whether the subclass will set a secondary
     189             :      * output. When using dst reads, the base class controls the secondary output and this method
     190             :      * will not be called.
     191             :      */
     192           0 :     virtual bool onHasSecondaryOutput() const { return false; }
     193             : 
     194             :     /**
     195             :      * If we are not performing a dst read, retrieves the fixed-function blend state required by the
     196             :      * subclass. When using dst reads, the base class controls the fixed-function blend state and
     197             :      * this method will not be called. The BlendInfo struct comes initialized to "no blending".
     198             :      */
     199           0 :     virtual void onGetBlendInfo(BlendInfo*) const {}
     200             : 
     201             :     virtual bool onIsEqual(const GrXferProcessor&) const = 0;
     202             : 
     203             :     bool                    fWillReadDstColor;
     204             :     bool                    fDstReadUsesMixedSamples;
     205             : 
     206             :     typedef GrFragmentProcessor INHERITED;
     207             : };
     208             : 
     209             : /**
     210             :  * We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is
     211             :  * known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the
     212             :  * draw opaque, etc.). Once the state of the draw is finalized, we use the XPF along with all the
     213             :  * draw information to create a GrXferProcessor (XP) which can implement the desired blending for
     214             :  * the draw.
     215             :  *
     216             :  * Before the XP is created, the XPF is able to answer queries about what functionality the XPs it
     217             :  * creates will have. For example, can it create an XP that supports RGB coverage or will the XP
     218             :  * blend with the destination color.
     219             :  *
     220             :  * GrXPFactories are intended to be static immutable objects. We pass them around as raw pointers
     221             :  * and expect the pointers to always be valid and for the factories to be reusable and thread safe.
     222             :  * Equality is tested for using pointer comparison. GrXPFactory destructors must be no-ops.
     223             :  */
     224             : 
     225             : // In order to construct GrXPFactory subclass instances as constexpr the subclass, and therefore
     226             : // GrXPFactory, must be a literal type. One requirement is having a trivial destructor. This is ok
     227             : // since these objects have no need for destructors. However, GCC and clang throw a warning when a
     228             : // class has virtual functions and a non-virtual destructor. We suppress that warning here and
     229             : // for the subclasses.
     230             : #if defined(__GNUC__) || defined(__clang)
     231             : #pragma GCC diagnostic push
     232             : #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
     233             : #endif
     234             : class GrXPFactory {
     235             : public:
     236             :     typedef GrXferProcessor::DstTexture DstTexture;
     237             : 
     238             :     enum class AnalysisProperties : unsigned {
     239             :         kNone = 0x0,
     240             :         /**
     241             :          * The fragment shader will require the destination color.
     242             :          */
     243             :         kReadsDstInShader = 0x1,
     244             :         /**
     245             :          * The op may apply coverage as alpha and still blend correctly.
     246             :          */
     247             :         kCompatibleWithAlphaAsCoverage = 0x2,
     248             :         /**
     249             :          * The color input to the GrXferProcessor will be ignored.
     250             :          */
     251             :         kIgnoresInputColor = 0x4,
     252             :         /**
     253             :          * If set overlapping stencil and cover operations can be replaced by a combined stencil
     254             :          * followed by a combined cover.
     255             :          */
     256             :         kCanCombineOverlappedStencilAndCover = 0x8,
     257             :         /**
     258             :          * The destination color will be provided to the fragment processor using a texture. This is
     259             :          * additional information about the implementation of kReadsDstInShader.
     260             :          */
     261             :         kRequiresDstTexture = 0x10,
     262             :         /**
     263             :          * If set overlapping draws may not be combined because a barrier must be inserted between
     264             :          * them.
     265             :          */
     266             :         kRequiresBarrierBetweenOverlappingDraws = 0x20,
     267             :     };
     268             :     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(AnalysisProperties);
     269             : 
     270             :     static sk_sp<const GrXferProcessor> MakeXferProcessor(const GrXPFactory*,
     271             :                                                           const GrProcessorAnalysisColor&,
     272             :                                                           GrProcessorAnalysisCoverage,
     273             :                                                           bool hasMixedSamples,
     274             :                                                           const GrCaps& caps);
     275             : 
     276             :     static AnalysisProperties GetAnalysisProperties(const GrXPFactory*,
     277             :                                                     const GrProcessorAnalysisColor&,
     278             :                                                     const GrProcessorAnalysisCoverage&,
     279             :                                                     const GrCaps&);
     280             : 
     281             : protected:
     282             :     constexpr GrXPFactory() {}
     283             : 
     284             : private:
     285             :     virtual sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&,
     286             :                                                            GrProcessorAnalysisCoverage,
     287             :                                                            bool hasMixedSamples,
     288             :                                                            const GrCaps&) const = 0;
     289             : 
     290             :     /**
     291             :      * Subclass analysis implementation. This should not return kNeedsDstInTexture as that will be
     292             :      * inferred by the base class based on kReadsDstInShader and the caps.
     293             :      */
     294             :     virtual AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&,
     295             :                                                   const GrProcessorAnalysisCoverage&,
     296             :                                                   const GrCaps&) const = 0;
     297             : };
     298             : #if defined(__GNUC__) || defined(__clang)
     299             : #pragma GCC diagnostic pop
     300             : #endif
     301             : 
     302           0 : GR_MAKE_BITFIELD_CLASS_OPS(GrXPFactory::AnalysisProperties);
     303             : 
     304             : #endif

Generated by: LCOV version 1.13