Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrDrawState.h
index 19ea4df..97516e8 100644 (file)
@@ -8,21 +8,23 @@
 #ifndef GrDrawState_DEFINED
 #define GrDrawState_DEFINED
 
+
 #include "GrBlend.h"
 #include "GrDrawTargetCaps.h"
+#include "GrGeometryProcessor.h"
 #include "GrGpuResourceRef.h"
-#include "GrRODrawState.h"
+#include "GrProcessorStage.h"
+#include "GrRenderTarget.h"
+#include "GrStencil.h"
+#include "SkMatrix.h"
 #include "effects/GrSimpleTextureEffect.h"
 
+class GrDrawTargetCaps;
 class GrOptDrawState;
+class GrPaint;
+class GrTexture;
 
-/**
- * Modifiable subclass derived from GrRODrawState. The majority of the data that represents a draw
- * state is stored in the parent class. GrDrawState contains methods for setting, adding to, etc.
- * various data members of the draw state. This class is used to configure the state used when
- * issuing draws via GrDrawTarget.
- */
-class GrDrawState : public GrRODrawState {
+class GrDrawState : public SkRefCnt {
 public:
     SK_DECLARE_INST_COUNT(GrDrawState)
 
@@ -70,6 +72,31 @@ public:
     /// @name Vertex Attributes
     ////
 
+    enum {
+        kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
+    };
+
+    const GrVertexAttrib* getVertexAttribs() const { return fVAPtr; }
+    int getVertexAttribCount() const { return fVACount; }
+
+    size_t getVertexStride() const { return fVAStride; }
+
+    bool hasLocalCoordAttribute() const {
+        return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
+    }
+    bool hasColorVertexAttribute() const {
+        return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
+    }
+    bool hasCoverageVertexAttribute() const {
+        return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
+    }
+
+    const int* getFixedFunctionVertexAttribIndices() const {
+        return fFixedFunctionVertexAttribIndices;
+    }
+
+    bool validateVertexAttribs() const;
+
    /**
      * The format of vertices is represented as an array of GrVertexAttribs, with each representing
      * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
@@ -127,12 +154,19 @@ public:
      */
     bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
 
+    /**
+     * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
+     */
+    bool hasSolidCoverage() const;
+
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
     /// @name Color
     ////
 
+    GrColor getColor() const { return fColor; }
+
     /**
      *  Sets color for next draw to a premultiplied-alpha color.
      *
@@ -159,6 +193,12 @@ public:
     /// @name Coverage
     ////
 
+    uint8_t getCoverage() const { return fCoverage; }
+
+    GrColor getCoverageColor() const {
+        return GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
+    }
+
     /**
      * Sets a constant fractional coverage to be applied to the draw. The
      * initial value (after construction or reset()) is 0xff. The constant
@@ -182,7 +222,7 @@ public:
     const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
         SkASSERT(geometryProcessor);
         SkASSERT(!this->hasGeometryProcessor());
-        fGeometryProcessor.reset(new GrGeometryStage(geometryProcessor));
+        fGeometryProcessor.reset(SkRef(geometryProcessor));
         this->invalidateOptState();
         return geometryProcessor;
     }
@@ -207,6 +247,23 @@ public:
     /// the color / coverage distinction.
     ////
 
+    int numColorStages() const { return fColorStages.count(); }
+    int numCoverageStages() const { return fCoverageStages.count(); }
+    int numTotalStages() const {
+         return this->numColorStages() + this->numCoverageStages() +
+                 (this->hasGeometryProcessor() ? 1 : 0);
+    }
+
+    bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
+    const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
+    const GrFragmentStage& getColorStage(int idx) const { return fColorStages[idx]; }
+    const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
+
+    /**
+     * Checks whether any of the effects will read the dst pixel color.
+     */
+    bool willEffectReadDstColor() const;
+
     const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
         SkASSERT(effect);
         SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
@@ -289,12 +346,58 @@ public:
         int             fCoverageEffectCnt;
     };
 
+    /**
+     * AutoRestoreStencil
+     *
+     * This simple struct saves and restores the stencil settings
+     */
+    class AutoRestoreStencil : public ::SkNoncopyable {
+    public:
+        AutoRestoreStencil() : fDrawState(NULL) {}
+
+        AutoRestoreStencil(GrDrawState* ds) : fDrawState(NULL) { this->set(ds); }
+
+        ~AutoRestoreStencil() { this->set(NULL); }
+
+        void set(GrDrawState* ds) {
+            if (fDrawState) {
+                fDrawState->setStencil(fStencilSettings);
+            }
+            fDrawState = ds;
+            if (ds) {
+                fStencilSettings = ds->getStencil();
+            }
+        }
+
+        bool isSet() const { return SkToBool(fDrawState); }
+
+    private:
+        GrDrawState*       fDrawState;
+        GrStencilSettings  fStencilSettings;
+    };
+
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
     /// @name Blending
     ////
 
+    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
+    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
+
+    /**
+     * Retrieves the last value set by setBlendConstant()
+     * @return the blending constant value
+     */
+    GrColor getBlendConstant() const { return fBlendConstant; }
+
+    /**
+     * Determines whether multiplying the computed per-pixel color by the pixel's fractional
+     * coverage before the blend will give the correct final destination color. In general it
+     * will not as coverage is applied after blending.
+     */
+    bool canTweakAlphaForCoverage() const;
+
     /**
      * Sets the blending function coefficients.
      *
@@ -316,10 +419,10 @@ public:
         }
     #ifdef SK_DEBUG
         if (GrBlendCoeffRefsDst(dstCoeff)) {
-            GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
+            SkDebugf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
         }
         if (GrBlendCoeffRefsSrc(srcCoeff)) {
-            GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
+            SkDebugf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
         }
     #endif
     }
@@ -348,6 +451,32 @@ public:
     ////
 
     /**
+     * Retrieves the current view matrix
+     * @return the current view matrix.
+     */
+    const SkMatrix& getViewMatrix() const { return fViewMatrix; }
+
+    /**
+     *  Retrieves the inverse of the current view matrix.
+     *
+     *  If the current view matrix is invertible, return true, and if matrix
+     *  is non-null, copy the inverse into it. If the current view matrix is
+     *  non-invertible, return false and ignore the matrix parameter.
+     *
+     * @param matrix if not null, will receive a copy of the current inverse.
+     */
+    bool getViewInverse(SkMatrix* matrix) const {
+        SkMatrix inverse;
+        if (fViewMatrix.invert(&inverse)) {
+            if (matrix) {
+                *matrix = inverse;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Sets the view matrix to identity and updates any installed effects to compensate for the
      * coord system change.
      */
@@ -387,8 +516,7 @@ public:
         GrDrawState*                                           fDrawState;
         SkMatrix                                               fViewMatrix;
         int                                                    fNumColorStages;
-        bool                                                   fHasGeometryProcessor;
-        SkAutoSTArray<8, GrProcessorStage::SavedCoordChange>   fSavedCoordChanges;
+        SkAutoSTArray<8, GrFragmentStage::SavedCoordChange>    fSavedCoordChanges;
     };
 
     /// @}
@@ -398,12 +526,19 @@ public:
     ////
 
     /**
+     * Retrieves the currently set render-target.
+     *
+     * @return    The currently set render target.
+     */
+    GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
+
+    /**
      * Sets the render-target used at the next drawing call
      *
      * @param target  The render target to set.
      */
     void setRenderTarget(GrRenderTarget* target) {
-        fRenderTarget.set(SkSafeRef(target), GrIORef::kWrite_IOType);
+        fRenderTarget.set(SkSafeRef(target), kWrite_GrIOType);
         this->invalidateOptState();
     }
 
@@ -413,6 +548,8 @@ public:
     /// @name Stencil
     ////
 
+    const GrStencilSettings& getStencil() const { return fStencilSettings; }
+
     /**
      * Sets the stencil settings to use for the next draw.
      * Changing the clip has the side-effect of possibly zeroing
@@ -445,6 +582,51 @@ public:
     /// @name State Flags
     ////
 
+    /**
+     *  Flags that affect rendering. Controlled using enable/disableState(). All
+     *  default to disabled.
+     */
+    enum StateBits {
+        /**
+         * Perform dithering. TODO: Re-evaluate whether we need this bit
+         */
+        kDither_StateBit        = 0x01,
+        /**
+         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
+         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
+         * the 3D API.
+         */
+        kHWAntialias_StateBit   = 0x02,
+        /**
+         * Draws will respect the clip, otherwise the clip is ignored.
+         */
+        kClip_StateBit          = 0x04,
+        /**
+         * Disables writing to the color buffer. Useful when performing stencil
+         * operations.
+         */
+        kNoColorWrites_StateBit = 0x08,
+
+        /**
+         * Usually coverage is applied after color blending. The color is blended using the coeffs
+         * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
+         * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
+         * this case there is no distinction between coverage and color and the caller needs direct
+         * control over the blend coeffs. When set, there will be a single blend step controlled by
+         * setBlendFunc() which will use coverage*color as the src color.
+         */
+         kCoverageDrawing_StateBit = 0x10,
+         kLast_StateBit = kCoverageDrawing_StateBit,
+    };
+
+    uint32_t getFlagBits() const { return fFlagBits; }
+
+    bool isStateFlagEnabled(uint32_t stateBit) const { return 0 != (stateBit & fFlagBits); }
+
+    bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
+    bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
+    bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
+
     void resetStateFlags() {
         if (0 != fFlagBits) {
             fFlagBits = 0;
@@ -496,6 +678,21 @@ public:
     /// @name Face Culling
     ////
 
+    enum DrawFace {
+        kInvalid_DrawFace = -1,
+
+        kBoth_DrawFace,
+        kCCW_DrawFace,
+        kCW_DrawFace,
+    };
+
+    /**
+     * Gets whether the target is drawing clockwise, counterclockwise,
+     * or both faces.
+     * @return the current draw face(s).
+     */
+    DrawFace getDrawFace() const { return fDrawFace; }
+
     /**
      * Controls whether clockwise, counterclockwise, or both faces are drawn.
      * @param face  the face(s) to draw.
@@ -512,8 +709,15 @@ public:
     /// Hints that when provided can enable optimizations.
     ////
 
+    enum Hints {
+        kVertexColorsAreOpaque_Hint = 0x1,
+        kLast_Hint = kVertexColorsAreOpaque_Hint
+    };
+
     void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
 
+    bool vertexColorsAreOpaque() const { return kVertexColorsAreOpaque_Hint & fHints; }
+
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
@@ -539,15 +743,72 @@ public:
 
     GrDrawState& operator= (const GrDrawState& that);
 
+private:
     /**
-     * Returns a snapshot of the current optimized state. If the current drawState has a valid
-     * cached optimiezed state it will simply return a pointer to it otherwise it will create a new
-     * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
-     * caller.
+     * Converts refs on GrGpuResources owned directly or indirectly by this GrDrawState into
+     * pending reads and writes. This should be called when a GrDrawState is recorded into
+     * a GrDrawTarget for later execution. Subclasses of GrDrawState may add setters. However,
+     * once this call has been made the GrDrawState is immutable. It is also no longer copyable.
+     * In the future this conversion will automatically happen when converting a GrDrawState into
+     * an optimized draw state.
      */
-    GrOptDrawState* createOptState(const GrDrawTargetCaps&) const;
+    void convertToPendingExec();
+
+    friend class GrDrawTarget;
+
+    bool isEqual(const GrDrawState& that) const;
+
+    /**
+     * Optimizations for blending / coverage to that can be applied based on the current state.
+     */
+    enum BlendOptFlags {
+        /**
+         * No optimization
+         */
+        kNone_BlendOpt                  = 0,
+        /**
+         * Don't draw at all
+         */
+        kSkipDraw_BlendOptFlag          = 0x1,
+        /**
+         * The coverage value does not have to be computed separately from alpha, the the output
+         * color can be the modulation of the two.
+         */
+        kCoverageAsAlpha_BlendOptFlag   = 0x2,
+        /**
+         * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
+         * "don't cares".
+         */
+        kEmitCoverage_BlendOptFlag      = 0x4,
+        /**
+         * Emit transparent black instead of the src color, no need to compute coverage.
+         */
+        kEmitTransBlack_BlendOptFlag    = 0x8,
+    };
+    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
+
+    /**
+     * Determines what optimizations can be applied based on the blend. The coefficients may have
+     * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
+     * params that receive the tweaked coefficients. Normally the function looks at the current
+     * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
+     * determine the blend optimizations that would be used if there was partial pixel coverage.
+     *
+     * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
+     * playback) must call this function and respect the flags that replace the output color.
+     *
+     * If the cached BlendOptFlags does not have the invalidate bit set, then getBlendOpts will
+     * simply returned the cached flags and coefficients. Otherwise it will calculate the values. 
+     */
+    BlendOptFlags getBlendOpts(bool forceCoverage = false,
+                               GrBlendCoeff* srcCoeff = NULL,
+                               GrBlendCoeff* dstCoeff = NULL) const;
+
+    /**
+     * Determines whether src alpha is guaranteed to be one for all src pixels
+     */
+    bool srcAlphaWillBeOne() const;
 
-private:
     void invalidateOptState() const;
 
     void onReset(const SkMatrix* initialViewMatrix);
@@ -558,10 +819,42 @@ private:
 
     void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride);
 
+    typedef GrTGpuResourceRef<GrRenderTarget> ProgramRenderTarget;
+    // These fields are roughly sorted by decreasing likelihood of being different in op==
+    ProgramRenderTarget                 fRenderTarget;
+    GrColor                             fColor;
+    SkMatrix                            fViewMatrix;
+    GrColor                             fBlendConstant;
+    uint32_t                            fFlagBits;
+    const GrVertexAttrib*               fVAPtr;
+    int                                 fVACount;
+    size_t                              fVAStride;
+    GrStencilSettings                   fStencilSettings;
+    uint8_t                             fCoverage;
+    DrawFace                            fDrawFace;
+    GrBlendCoeff                        fSrcBlend;
+    GrBlendCoeff                        fDstBlend;
+
+    typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
+    typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
+    ProgramGeometryProcessor            fGeometryProcessor;
+    FragmentStageArray                  fColorStages;
+    FragmentStageArray                  fCoverageStages;
+
+    uint32_t                            fHints;
+
+    // This is simply a different representation of info in fVertexAttribs and thus does
+    // not need to be compared in op==.
+    int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
+
     mutable GrOptDrawState* fCachedOptState;
     mutable uint32_t fCachedCapsID;
 
-    typedef GrRODrawState INHERITED;
+    friend class GrOptDrawState;
+
+    typedef SkRefCnt INHERITED;
 };
 
+GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
+
 #endif