Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2011 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 #ifndef GrPaint_DEFINED
     11 #define GrPaint_DEFINED
     12 
     13 #include "GrTexture.h"
     14 #include "GrColor.h"
     15 #include "GrSamplerState.h"
     16 
     17 #include "SkXfermode.h"
     18 
     19 /**
     20  * The paint describes how pixels are colored when the context draws to
     21  * them. TODO: Make this a "real" class with getters and setters, default
     22  * values, and documentation.
     23  */
     24 class GrPaint {
     25 public:
     26     enum {
     27         kMaxTextures = 1,
     28         kMaxMasks    = 1,
     29     };
     30 
     31     // All the paint fields are public except textures/samplers
     32     GrBlendCoeff                fSrcBlendCoeff;
     33     GrBlendCoeff                fDstBlendCoeff;
     34     bool                        fAntiAlias;
     35     bool                        fDither;
     36     bool                        fColorMatrixEnabled;
     37 
     38     GrColor                     fColor;
     39     uint8_t                     fCoverage;
     40 
     41     GrColor                     fColorFilterColor;
     42     SkXfermode::Mode            fColorFilterXfermode;
     43     float                       fColorMatrix[20];
     44 
     45     void setTexture(int i, GrTexture* texture) {
     46         GrAssert((unsigned)i < kMaxTextures);
     47         GrSafeRef(texture);
     48         GrSafeUnref(fTextures[i]);
     49         fTextures[i] = texture;
     50     }
     51 
     52     GrTexture* getTexture(int i) const {
     53         GrAssert((unsigned)i < kMaxTextures);
     54         return fTextures[i];
     55     }
     56 
     57     GrSamplerState* textureSampler(int i) {
     58         GrAssert((unsigned)i < kMaxTextures);
     59         return fTextureSamplers + i;
     60     }
     61 
     62     const GrSamplerState& getTextureSampler(int i) const {
     63         GrAssert((unsigned)i < kMaxTextures);
     64         return fTextureSamplers[i];
     65     }
     66 
     67     // The mask can be alpha-only or per channel. It is applied
     68     // after the colorfilter
     69     void setMask(int i, GrTexture* mask) {
     70         GrAssert((unsigned)i < kMaxMasks);
     71         GrSafeRef(mask);
     72         GrSafeUnref(fMaskTextures[i]);
     73         fMaskTextures[i] = mask;
     74     }
     75 
     76     GrTexture* getMask(int i) const {
     77         GrAssert((unsigned)i < kMaxMasks);
     78         return fMaskTextures[i];
     79     }
     80 
     81     // mask's sampler matrix is always applied to the positions
     82     // (i.e. no explicit texture coordinates)
     83     GrSamplerState* maskSampler(int i) {
     84         GrAssert((unsigned)i < kMaxMasks);
     85         return fMaskSamplers + i;
     86     }
     87 
     88     const GrSamplerState& getMaskSampler(int i) const {
     89         GrAssert((unsigned)i < kMaxMasks);
     90         return fMaskSamplers[i];
     91     }
     92 
     93     // pre-concats sampler matrices for non-NULL textures and masks
     94     void preConcatActiveSamplerMatrices(const GrMatrix& matrix) {
     95         for (int i = 0; i < kMaxTextures; ++i) {
     96             fTextureSamplers[i].preConcatMatrix(matrix);
     97         }
     98         for (int i = 0; i < kMaxMasks; ++i) {
     99             fMaskSamplers[i].preConcatMatrix(matrix);
    100         }
    101     }
    102 
    103     // uninitialized
    104     GrPaint() {
    105         for (int i = 0; i < kMaxTextures; ++i) {
    106             fTextures[i] = NULL;
    107         }
    108         for (int i = 0; i < kMaxMasks; ++i) {
    109             fMaskTextures[i] = NULL;
    110         }
    111     }
    112 
    113     GrPaint(const GrPaint& paint) {
    114         for (int i = 0; i < kMaxTextures; ++i) {
    115             fTextures[i] = NULL;
    116         }
    117         for (int i = 0; i < kMaxMasks; ++i) {
    118             fMaskTextures[i] = NULL;
    119         }
    120         *this = paint;
    121     }
    122 
    123     GrPaint& operator=(const GrPaint& paint) {
    124         fSrcBlendCoeff = paint.fSrcBlendCoeff;
    125         fDstBlendCoeff = paint.fDstBlendCoeff;
    126         fAntiAlias = paint.fAntiAlias;
    127         fDither = paint.fDither;
    128 
    129         fColor = paint.fColor;
    130         fCoverage = paint.fCoverage;
    131 
    132         fColorFilterColor = paint.fColorFilterColor;
    133         fColorFilterXfermode = paint.fColorFilterXfermode;
    134         memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
    135         fColorMatrixEnabled = paint.fColorMatrixEnabled;
    136 
    137         for (int i = 0; i < kMaxTextures; ++i) {
    138             GrSafeUnref(fTextures[i]);
    139             fTextureSamplers[i] = paint.fTextureSamplers[i];
    140             fTextures[i] = paint.fTextures[i];
    141             GrSafeRef(fTextures[i]);
    142         }
    143         for (int i = 0; i < kMaxMasks; ++i) {
    144             GrSafeUnref(fMaskTextures[i]);
    145             fMaskSamplers[i] = paint.fMaskSamplers[i];
    146             fMaskTextures[i] = paint.fMaskTextures[i];
    147             GrSafeRef(fMaskTextures[i]);
    148         }
    149         return *this;
    150     }
    151 
    152     ~GrPaint() {
    153         for (int i = 0; i < kMaxTextures; ++i) {
    154             GrSafeUnref(fTextures[i]);
    155         }
    156         for (int i = 0; i < kMaxMasks; ++i) {
    157             GrSafeUnref(fMaskTextures[i]);
    158         }
    159     }
    160 
    161     // sets paint to src-over, solid white, no texture, no mask
    162     void reset() {
    163         this->resetBlend();
    164         this->resetOptions();
    165         this->resetColor();
    166         this->resetCoverage();
    167         this->resetTextures();
    168         this->resetColorFilter();
    169         this->resetMasks();
    170     }
    171 
    172     void resetColorFilter() {
    173         fColorFilterXfermode = SkXfermode::kDst_Mode;
    174         fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
    175         memset(fColorMatrix, 0, sizeof(fColorMatrix));
    176         fColorMatrixEnabled = false;
    177     }
    178 
    179     bool hasTexture() const {
    180         return 0 != this->getActiveTextureStageMask();
    181     }
    182 
    183     bool hasMask() const {
    184         return 0 != this->getActiveMaskStageMask();
    185     }
    186 
    187     bool hasTextureOrMask() const {
    188         return this->hasTexture() || this->hasMask();
    189     }
    190 
    191     // helpers for GrContext, GrTextContext
    192     int getActiveTextureStageMask() const {
    193         int mask = 0;
    194         for (int i = 0; i < kMaxTextures; ++i) {
    195             if (NULL != fTextures[i]) {
    196                 mask |= 1 << (i + kFirstTextureStage);
    197             }
    198         }
    199         return mask;
    200     }
    201 
    202     int getActiveMaskStageMask() const {
    203         int mask = 0;
    204         for (int i = 0; i < kMaxMasks; ++i) {
    205             if (NULL != fMaskTextures[i]) {
    206                 mask |= 1 << (i + kFirstMaskStage);
    207             }
    208         }
    209         return mask;
    210     }
    211 
    212     int getActiveStageMask() const {
    213         return this->getActiveTextureStageMask() |
    214                 this->getActiveMaskStageMask();
    215     }
    216 
    217     // internal use
    218     // GrPaint's textures and masks map to the first N stages
    219     // of GrDrawTarget in that order (textures followed by masks)
    220     enum {
    221         kFirstTextureStage = 0,
    222         kFirstMaskStage = kMaxTextures,
    223         kTotalStages = kMaxTextures + kMaxMasks,
    224     };
    225 
    226 private:
    227 
    228     GrSamplerState              fTextureSamplers[kMaxTextures];
    229     GrSamplerState              fMaskSamplers[kMaxMasks];
    230 
    231     GrTexture*      fTextures[kMaxTextures];
    232     GrTexture*      fMaskTextures[kMaxMasks];
    233 
    234     void resetBlend() {
    235         fSrcBlendCoeff = kOne_BlendCoeff;
    236         fDstBlendCoeff = kZero_BlendCoeff;
    237     }
    238 
    239     void resetOptions() {
    240         fAntiAlias = false;
    241         fDither = false;
    242     }
    243 
    244     void resetColor() {
    245         fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
    246     }
    247 
    248     void resetCoverage() {
    249         fCoverage = 0xff;
    250     }
    251 
    252     void resetTextures() {
    253         for (int i = 0; i < kMaxTextures; ++i) {
    254             this->setTexture(i, NULL);
    255             fTextureSamplers[i].reset();
    256         }
    257     }
    258 
    259     void resetMasks() {
    260         for (int i = 0; i < kMaxMasks; ++i) {
    261             this->setMask(i, NULL);
    262             fMaskSamplers[i].reset();
    263         }
    264     }
    265 };
    266 
    267 #endif
    268