Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2010 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #ifndef GrEffectStage_DEFINED
     12 #define GrEffectStage_DEFINED
     13 
     14 #include "GrBackendEffectFactory.h"
     15 #include "GrEffect.h"
     16 #include "SkMatrix.h"
     17 #include "GrTypes.h"
     18 
     19 #include "SkShader.h"
     20 
     21 class GrEffectStage {
     22 public:
     23     GrEffectStage()
     24     : fEffectRef (NULL) {
     25         GR_DEBUGCODE(fSavedCoordChangeCnt = 0;)
     26     }
     27 
     28     ~GrEffectStage() {
     29         GrSafeUnref(fEffectRef);
     30         GrAssert(0 == fSavedCoordChangeCnt);
     31     }
     32 
     33     bool operator ==(const GrEffectStage& other) const {
     34         // first handle cases where one or the other has no effect
     35         if (NULL == fEffectRef) {
     36             return NULL == other.fEffectRef;
     37         } else if (NULL == other.fEffectRef) {
     38             return false;
     39         }
     40 
     41         if (!(*this->getEffect())->isEqual(*other.getEffect())) {
     42             return false;
     43         }
     44 
     45         return fCoordChangeMatrix == other.fCoordChangeMatrix;
     46     }
     47 
     48     bool operator !=(const GrEffectStage& s) const { return !(*this == s); }
     49 
     50     GrEffectStage& operator =(const GrEffectStage& other) {
     51         GrSafeAssign(fEffectRef, other.fEffectRef);
     52         if (NULL != fEffectRef) {
     53             fCoordChangeMatrix = other.fCoordChangeMatrix;
     54         }
     55         return *this;
     56     }
     57 
     58     /**
     59      * This is called when the coordinate system in which the geometry is specified will change.
     60      *
     61      * @param matrix    The transformation from the old coord system to the new one.
     62      */
     63     void preConcatCoordChange(const SkMatrix& matrix) { fCoordChangeMatrix.preConcat(matrix); }
     64 
     65     class SavedCoordChange {
     66     private:
     67         SkMatrix fCoordChangeMatrix;
     68         GR_DEBUGCODE(mutable SkAutoTUnref<const GrEffectRef> fEffectRef;)
     69 
     70         friend class GrEffectStage;
     71     };
     72 
     73     /**
     74      * This gets the current coordinate system change. It is the accumulation of
     75      * preConcatCoordChange calls since the effect was installed. It is used when then caller
     76      * wants to temporarily change the source geometry coord system, draw something, and then
     77      * restore the previous coord system (e.g. temporarily draw in device coords).
     78      */
     79     void saveCoordChange(SavedCoordChange* savedCoordChange) const {
     80         savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
     81         GrAssert(NULL == savedCoordChange->fEffectRef.get());
     82         GR_DEBUGCODE(GrSafeRef(fEffectRef);)
     83         GR_DEBUGCODE(savedCoordChange->fEffectRef.reset(fEffectRef);)
     84         GR_DEBUGCODE(++fSavedCoordChangeCnt);
     85     }
     86 
     87     /**
     88      * This balances the saveCoordChange call.
     89      */
     90     void restoreCoordChange(const SavedCoordChange& savedCoordChange) {
     91         fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
     92         GrAssert(savedCoordChange.fEffectRef.get() == fEffectRef);
     93         GR_DEBUGCODE(--fSavedCoordChangeCnt);
     94         GR_DEBUGCODE(savedCoordChange.fEffectRef.reset(NULL);)
     95     }
     96 
     97     /**
     98      * Used when storing a deferred GrDrawState. The DeferredStage allows resources owned by its
     99      * GrEffect to be recycled through the cache.
    100      */
    101     class DeferredStage {
    102     public:
    103         DeferredStage() : fEffect(NULL) {
    104             SkDEBUGCODE(fInitialized = false;)
    105         }
    106 
    107         ~DeferredStage() {
    108             if (NULL != fEffect) {
    109                 fEffect->decDeferredRefCounts();
    110             }
    111         }
    112 
    113         void saveFrom(const GrEffectStage& stage) {
    114             GrAssert(!fInitialized);
    115             if (NULL != stage.fEffectRef) {
    116                 stage.fEffectRef->get()->incDeferredRefCounts();
    117                 fEffect = stage.fEffectRef->get();
    118                 fCoordChangeMatrix = stage.fCoordChangeMatrix;
    119             }
    120             SkDEBUGCODE(fInitialized = true;)
    121         }
    122 
    123         void restoreTo(GrEffectStage* stage) {
    124             GrAssert(fInitialized);
    125             const GrEffectRef* oldEffectRef = stage->fEffectRef;
    126             if (NULL != fEffect) {
    127                 stage->fEffectRef = GrEffect::CreateEffectRef(fEffect);
    128                 stage->fCoordChangeMatrix = fCoordChangeMatrix;
    129             } else {
    130                 stage->fEffectRef = NULL;
    131             }
    132             SkSafeUnref(oldEffectRef);
    133         }
    134 
    135         bool isEqual(const GrEffectStage& stage) const {
    136             if (NULL == stage.fEffectRef) {
    137                 return NULL == fEffect;
    138             } else if (NULL == fEffect) {
    139                 return false;
    140             }
    141 
    142             if (!(*stage.getEffect())->isEqual(*fEffect)) {
    143                 return false;
    144             }
    145 
    146             return fCoordChangeMatrix == stage.fCoordChangeMatrix;
    147         }
    148 
    149     private:
    150         const GrEffect*               fEffect;
    151         SkMatrix                      fCoordChangeMatrix;
    152         SkDEBUGCODE(bool fInitialized;)
    153     };
    154 
    155     /**
    156      * Gets the matrix representing all changes of coordinate system since the GrEffect was
    157      * installed in the stage.
    158      */
    159     const SkMatrix& getCoordChangeMatrix() const { return fCoordChangeMatrix; }
    160 
    161     void reset() {
    162         GrSafeSetNull(fEffectRef);
    163     }
    164 
    165     const GrEffectRef* setEffect(const GrEffectRef* EffectRef) {
    166         GrAssert(0 == fSavedCoordChangeCnt);
    167         GrSafeAssign(fEffectRef, EffectRef);
    168         fCoordChangeMatrix.reset();
    169         return EffectRef;
    170     }
    171 
    172     const GrEffectRef* getEffect() const { return fEffectRef; }
    173 
    174 private:
    175     SkMatrix            fCoordChangeMatrix;
    176     const GrEffectRef*  fEffectRef;
    177 
    178     GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;)
    179 };
    180 
    181 #endif
    182