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 #ifndef GrPipeline_DEFINED
      9 #define GrPipeline_DEFINED
     10 
     11 #include "GrColor.h"
     12 #include "GrFragmentProcessor.h"
     13 #include "GrNonAtomicRef.h"
     14 #include "GrPendingProgramElement.h"
     15 #include "GrProcessorSet.h"
     16 #include "GrProgramDesc.h"
     17 #include "GrRect.h"
     18 #include "GrRenderTargetProxy.h"
     19 #include "GrScissorState.h"
     20 #include "GrUserStencilSettings.h"
     21 #include "GrWindowRectsState.h"
     22 #include "SkMatrix.h"
     23 #include "SkRefCnt.h"
     24 #include "effects/GrCoverageSetOpXP.h"
     25 #include "effects/GrDisableColorXP.h"
     26 #include "effects/GrPorterDuffXferProcessor.h"
     27 #include "effects/GrSimpleTextureEffect.h"
     28 
     29 class GrAppliedClip;
     30 class GrDeviceCoordTexture;
     31 class GrOp;
     32 class GrRenderTargetContext;
     33 
     34 /**
     35  * This immutable object contains information needed to set build a shader program and set API
     36  * state for a draw. It is used along with a GrPrimitiveProcessor and a source of geometric
     37  * data (GrMesh or GrPath) to draw.
     38  */
     39 class GrPipeline {
     40 public:
     41     ///////////////////////////////////////////////////////////////////////////
     42     /// @name Creation
     43 
     44     enum Flags {
     45         /**
     46          * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
     47          * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
     48          * the 3D API.
     49          */
     50         kHWAntialias_Flag = 0x1,
     51         /**
     52          * Modifies the vertex shader so that vertices will be positioned at pixel centers.
     53          */
     54         kSnapVerticesToPixelCenters_Flag = 0x2,
     55         /** Disables conversion to sRGB from linear when writing to a sRGB destination. */
     56         kDisableOutputConversionToSRGB_Flag = 0x4,
     57         /** Allows conversion from sRGB to linear when reading from processor's sRGB texture. */
     58         kAllowSRGBInputs_Flag = 0x8,
     59     };
     60 
     61     static uint32_t SRGBFlagsFromPaint(const GrPaint& paint) {
     62         uint32_t flags = 0;
     63         if (paint.getAllowSRGBInputs()) {
     64             flags |= kAllowSRGBInputs_Flag;
     65         }
     66         if (paint.getDisableOutputConversionToSRGB()) {
     67             flags |= kDisableOutputConversionToSRGB_Flag;
     68         }
     69         return flags;
     70     }
     71 
     72     enum ScissorState : bool {
     73         kEnabled = true,
     74         kDisabled = false
     75     };
     76 
     77     struct InitArgs {
     78         uint32_t fFlags = 0;
     79         const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
     80         GrRenderTargetProxy* fProxy = nullptr;
     81         const GrCaps* fCaps = nullptr;
     82         GrResourceProvider* fResourceProvider = nullptr;
     83         GrXferProcessor::DstProxy fDstProxy;
     84     };
     85 
     86     /**
     87      *  Graphics state that can change dynamically without creating a new pipeline.
     88      **/
     89     struct DynamicState {
     90         // Overrides the scissor rectangle (if scissor is enabled in the pipeline).
     91         // TODO: eventually this should be the only way to specify a scissor rectangle, as is the
     92         // case with the simple constructor.
     93         SkIRect fScissorRect;
     94     };
     95 
     96     /**
     97      * Creates a simple pipeline with default settings and no processors. The provided blend mode
     98      * must be "Porter Duff" (<= kLastCoeffMode). If using ScissorState::kEnabled, the caller must
     99      * specify a scissor rectangle through the DynamicState struct.
    100      **/
    101     GrPipeline(GrRenderTargetProxy*, ScissorState, SkBlendMode);
    102 
    103     GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
    104 
    105     GrPipeline(const GrPipeline&) = delete;
    106     GrPipeline& operator=(const GrPipeline&) = delete;
    107 
    108     /// @}
    109 
    110     ///////////////////////////////////////////////////////////////////////////
    111     /// @name GrFragmentProcessors
    112 
    113     // Make the renderTargetContext's GrOpList be dependent on any GrOpLists in this pipeline
    114     void addDependenciesTo(GrOpList* recipient, const GrCaps&) const;
    115 
    116     int numColorFragmentProcessors() const { return fNumColorProcessors; }
    117     int numCoverageFragmentProcessors() const {
    118         return fFragmentProcessors.count() - fNumColorProcessors;
    119     }
    120     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
    121 
    122     const GrXferProcessor& getXferProcessor() const {
    123         if (fXferProcessor) {
    124             return *fXferProcessor.get();
    125         } else {
    126             // A null xp member means the common src-over case. GrXferProcessor's ref'ing
    127             // mechanism is not thread safe so we do not hold a ref on this global.
    128             return GrPorterDuffXPFactory::SimpleSrcOverXP();
    129         }
    130     }
    131 
    132     /**
    133      * If the GrXferProcessor uses a texture to access the dst color, then this returns that
    134      * texture and the offset to the dst contents within that texture.
    135      */
    136     GrTextureProxy* dstTextureProxy(SkIPoint* offset = nullptr) const {
    137         if (offset) {
    138             *offset = fDstTextureOffset;
    139         }
    140         return fDstTextureProxy.get();
    141     }
    142 
    143     GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
    144         if (GrTextureProxy* dstProxy = this->dstTextureProxy(offset)) {
    145             return dstProxy->priv().peekTexture();
    146         }
    147 
    148         return nullptr;
    149     }
    150 
    151     const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
    152         SkASSERT(idx < this->numColorFragmentProcessors());
    153         return *fFragmentProcessors[idx].get();
    154     }
    155 
    156     const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
    157         SkASSERT(idx < this->numCoverageFragmentProcessors());
    158         return *fFragmentProcessors[fNumColorProcessors + idx].get();
    159     }
    160 
    161     const GrFragmentProcessor& getFragmentProcessor(int idx) const {
    162         return *fFragmentProcessors[idx].get();
    163     }
    164 
    165     /// @}
    166 
    167     /**
    168      * Retrieves the currently set render-target.
    169      *
    170      * @return    The currently set render target.
    171      */
    172     GrRenderTargetProxy* proxy() const { return fProxy.get(); }
    173     GrRenderTarget* renderTarget() const { return fProxy.get()->priv().peekRenderTarget(); }
    174 
    175     const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
    176 
    177     const GrScissorState& getScissorState() const { return fScissorState; }
    178 
    179     const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
    180 
    181     bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAntialias_Flag); }
    182     bool snapVerticesToPixelCenters() const {
    183         return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag);
    184     }
    185     bool getDisableOutputConversionToSRGB() const {
    186         return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
    187     }
    188     bool getAllowSRGBInputs() const {
    189         return SkToBool(fFlags & kAllowSRGBInputs_Flag);
    190     }
    191     bool hasStencilClip() const {
    192         return SkToBool(fFlags & kHasStencilClip_Flag);
    193     }
    194     bool isStencilEnabled() const {
    195         return SkToBool(fFlags & kStencilEnabled_Flag);
    196     }
    197     bool isBad() const { return SkToBool(fFlags & kIsBad_Flag); }
    198 
    199     GrXferBarrierType xferBarrierType(const GrCaps& caps) const;
    200 
    201     static SkString DumpFlags(uint32_t flags) {
    202         if (flags) {
    203             SkString result;
    204             if (flags & GrPipeline::kSnapVerticesToPixelCenters_Flag) {
    205                 result.append("Snap vertices to pixel center.\n");
    206             }
    207             if (flags & GrPipeline::kHWAntialias_Flag) {
    208                 result.append("HW Antialiasing enabled.\n");
    209             }
    210             if (flags & GrPipeline::kDisableOutputConversionToSRGB_Flag) {
    211                 result.append("Disable output conversion to sRGB.\n");
    212             }
    213             if (flags & GrPipeline::kAllowSRGBInputs_Flag) {
    214                 result.append("Allow sRGB Inputs.\n");
    215             }
    216             return result;
    217         }
    218         return SkString("No pipeline flags\n");
    219     }
    220 
    221 private:
    222     void markAsBad() { fFlags |= kIsBad_Flag; }
    223 
    224     /** This is a continuation of the public "Flags" enum. */
    225     enum PrivateFlags {
    226         kHasStencilClip_Flag = 0x10,
    227         kStencilEnabled_Flag = 0x20,
    228         kIsBad_Flag = 0x40,
    229     };
    230 
    231     using RenderTargetProxy = GrPendingIOResource<GrRenderTargetProxy, kWrite_GrIOType>;
    232     using DstTextureProxy = GrPendingIOResource<GrTextureProxy, kRead_GrIOType>;
    233     using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>;
    234 
    235     DstTextureProxy fDstTextureProxy;
    236     SkIPoint fDstTextureOffset;
    237     // MDB TODO: do we still need the destination proxy here?
    238     RenderTargetProxy fProxy;
    239     GrScissorState fScissorState;
    240     GrWindowRectsState fWindowRectsState;
    241     const GrUserStencilSettings* fUserStencilSettings;
    242     uint16_t fFlags;
    243     sk_sp<const GrXferProcessor> fXferProcessor;
    244     FragmentProcessorArray fFragmentProcessors;
    245 
    246     // This value is also the index in fFragmentProcessors where coverage processors begin.
    247     int fNumColorProcessors;
    248 
    249     typedef SkRefCnt INHERITED;
    250 };
    251 
    252 #endif
    253