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