| |
| /* |
| * Copyright 2010 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| |
| |
| #ifndef GrSamplerState_DEFINED |
| #define GrSamplerState_DEFINED |
| |
| #include "GrCustomStage.h" |
| #include "GrMatrix.h" |
| #include "GrTypes.h" |
| |
| #include "SkShader.h" |
| |
| class GrTextureParams { |
| public: |
| GrTextureParams() { |
| this->reset(); |
| } |
| |
| GrTextureParams(const GrTextureParams& params) { |
| *this = params; |
| } |
| |
| GrTextureParams& operator =(const GrTextureParams& params) { |
| fTileModes[0] = params.fTileModes[0]; |
| fTileModes[1] = params.fTileModes[1]; |
| fBilerp = params.fBilerp; |
| return *this; |
| } |
| |
| void reset() { |
| this->reset(SkShader::kClamp_TileMode, false); |
| } |
| |
| void reset(SkShader::TileMode tileXAndY, bool filter) { |
| fTileModes[0] = fTileModes[1] = tileXAndY; |
| fBilerp = filter; |
| } |
| void reset(SkShader::TileMode tileModes[2], bool filter) { |
| fTileModes[0] = tileModes[0]; |
| fTileModes[1] = tileModes[1]; |
| fBilerp = filter; |
| } |
| |
| void setClampNoFilter() { |
| fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode; |
| fBilerp = false; |
| } |
| |
| void setClamp() { |
| fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode; |
| } |
| |
| void setBilerp(bool bilerp) { fBilerp = bilerp; } |
| |
| void setTileModeX(const SkShader::TileMode tm) { fTileModes[0] = tm; } |
| void setTileModeY(const SkShader::TileMode tm) { fTileModes[1] = tm; } |
| void setTileModeXAndY(const SkShader::TileMode tm) { fTileModes[0] = fTileModes[1] = tm; } |
| |
| SkShader::TileMode getTileModeX() const { return fTileModes[0]; } |
| |
| SkShader::TileMode getTileModeY() const { return fTileModes[1]; } |
| |
| bool isTiled() const { |
| return SkShader::kClamp_TileMode != fTileModes[0] || |
| SkShader::kClamp_TileMode != fTileModes[1]; |
| } |
| |
| bool isBilerp() const { return fBilerp; } |
| |
| private: |
| |
| SkShader::TileMode fTileModes[2]; |
| bool fBilerp; |
| }; |
| |
| class GrSamplerState { |
| public: |
| static const bool kBilerpDefault = false; |
| |
| static const SkShader::TileMode kTileModeDefault = SkShader::kClamp_TileMode; |
| |
| /** |
| * Default sampler state is set to clamp, use normal sampling mode, be |
| * unfiltered, and use identity matrix. |
| */ |
| GrSamplerState() |
| : fCustomStage (NULL) { |
| memset(this, 0, sizeof(GrSamplerState)); |
| this->reset(); |
| } |
| |
| ~GrSamplerState() { |
| GrSafeUnref(fCustomStage); |
| } |
| |
| bool operator ==(const GrSamplerState& s) const { |
| /* We must be bit-identical as far as the CustomStage; |
| there may be multiple CustomStages that will produce |
| the same shader code and so are equivalent. |
| Can't take the address of fWrapX because it's :8 */ |
| int bitwiseRegion = (intptr_t) &fCustomStage - (intptr_t) this; |
| GrAssert(sizeof(GrSamplerState) == |
| bitwiseRegion + sizeof(fCustomStage)); |
| return !memcmp(this, &s, bitwiseRegion) && |
| ((fCustomStage == s.fCustomStage) || |
| (fCustomStage && s.fCustomStage && |
| (fCustomStage->getFactory() == |
| s.fCustomStage->getFactory()) && |
| fCustomStage->isEqual(*s.fCustomStage))); |
| } |
| bool operator !=(const GrSamplerState& s) const { return !(*this == s); } |
| |
| GrSamplerState& operator =(const GrSamplerState& s) { |
| // memcpy() breaks refcounting |
| fTextureParams = s.fTextureParams; |
| fMatrix = s.fMatrix; |
| fSwapRAndB = s.fSwapRAndB; |
| |
| GrSafeAssign(fCustomStage, s.fCustomStage); |
| |
| return *this; |
| } |
| |
| const GrMatrix& getMatrix() const { return fMatrix; } |
| bool swapsRAndB() const { return fSwapRAndB; } |
| bool premultiply() const { return fPremultiply; } |
| |
| GrTextureParams* textureParams() { return &fTextureParams; } |
| const GrTextureParams& getTextureParams() const { return fTextureParams; } |
| /** |
| * Access the sampler's matrix. See SampleMode for explanation of |
| * relationship between the matrix and sample mode. |
| */ |
| GrMatrix* matrix() { return &fMatrix; } |
| |
| /** |
| * Swaps the R and B components when reading from the texture. Has no effect |
| * if the texture is alpha only. |
| */ |
| void setRAndBSwap(bool swap) { fSwapRAndB = swap; } |
| |
| /** |
| * If the texture is RGBA/BGRA 8888 config then its rgb components will be |
| * multiplied by its a component after the texture read. |
| **/ |
| void setPremultiply(bool premul) { fPremultiply = premul; } |
| |
| /** |
| * Multiplies the current sampler matrix a matrix |
| * |
| * After this call M' = M*m where M is the old matrix, m is the parameter |
| * to this function, and M' is the new matrix. (We consider points to |
| * be column vectors so tex cood vector t is transformed by matrix X as |
| * t' = X*t.) |
| * |
| * @param matrix the matrix used to modify the matrix. |
| */ |
| void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); } |
| |
| void reset(SkShader::TileMode tileXAndY, |
| bool filter, |
| const GrMatrix& matrix) { |
| fTextureParams.reset(tileXAndY, filter); |
| fMatrix = matrix; |
| fSwapRAndB = false; |
| fPremultiply = false; |
| GrSafeSetNull(fCustomStage); |
| } |
| void reset(SkShader::TileMode wrapXAndY, bool filter) { |
| this->reset(wrapXAndY, filter, GrMatrix::I()); |
| } |
| void reset(const GrMatrix& matrix) { |
| this->reset(kTileModeDefault, kBilerpDefault, matrix); |
| } |
| void reset() { |
| this->reset(kTileModeDefault, kBilerpDefault, GrMatrix::I()); |
| } |
| |
| GrCustomStage* setCustomStage(GrCustomStage* stage) { |
| GrSafeAssign(fCustomStage, stage); |
| return stage; |
| } |
| const GrCustomStage* getCustomStage() const { return fCustomStage; } |
| |
| private: |
| GrTextureParams fTextureParams; |
| bool fSwapRAndB; |
| bool fPremultiply; // temporary, will be replaced soon by a custom stage. |
| GrMatrix fMatrix; |
| |
| GrCustomStage* fCustomStage; |
| }; |
| |
| #endif |
| |