michael@0: /* michael@0: * Copyright 2012 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef GrTextureAccess_DEFINED michael@0: #define GrTextureAccess_DEFINED michael@0: michael@0: #include "SkRefCnt.h" michael@0: #include "SkShader.h" michael@0: #include "SkTypes.h" michael@0: michael@0: class GrTexture; michael@0: michael@0: /** michael@0: * Represents the filtering and tile modes used to access a texture. It is mostly used with michael@0: * GrTextureAccess (defined below). Also, some of the texture cache methods require knowledge about michael@0: * filtering and tiling to perform a cache lookup. If it wasn't for this latter usage this would michael@0: * be folded into GrTextureAccess. The default is clamp tile modes and no filtering. michael@0: */ michael@0: class GrTextureParams { michael@0: public: michael@0: GrTextureParams() { michael@0: this->reset(); michael@0: } michael@0: michael@0: enum FilterMode { michael@0: kNone_FilterMode, michael@0: kBilerp_FilterMode, michael@0: kMipMap_FilterMode michael@0: }; michael@0: michael@0: GrTextureParams(SkShader::TileMode tileXAndY, FilterMode filterMode) { michael@0: this->reset(tileXAndY, filterMode); michael@0: } michael@0: michael@0: GrTextureParams(const SkShader::TileMode tileModes[2], FilterMode filterMode) { michael@0: this->reset(tileModes, filterMode); michael@0: } michael@0: michael@0: GrTextureParams(const GrTextureParams& params) { michael@0: *this = params; michael@0: } michael@0: michael@0: GrTextureParams& operator= (const GrTextureParams& params) { michael@0: fTileModes[0] = params.fTileModes[0]; michael@0: fTileModes[1] = params.fTileModes[1]; michael@0: fFilterMode = params.fFilterMode; michael@0: return *this; michael@0: } michael@0: michael@0: void reset() { michael@0: this->reset(SkShader::kClamp_TileMode, kNone_FilterMode); michael@0: } michael@0: michael@0: void reset(SkShader::TileMode tileXAndY, FilterMode filterMode) { michael@0: fTileModes[0] = fTileModes[1] = tileXAndY; michael@0: fFilterMode = filterMode; michael@0: } michael@0: michael@0: void reset(const SkShader::TileMode tileModes[2], FilterMode filterMode) { michael@0: fTileModes[0] = tileModes[0]; michael@0: fTileModes[1] = tileModes[1]; michael@0: fFilterMode = filterMode; michael@0: } michael@0: michael@0: void setClampNoFilter() { michael@0: fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode; michael@0: fFilterMode = kNone_FilterMode; michael@0: } michael@0: michael@0: void setClamp() { michael@0: fTileModes[0] = fTileModes[1] = SkShader::kClamp_TileMode; michael@0: } michael@0: michael@0: void setFilterMode(FilterMode filterMode) { fFilterMode = filterMode; } michael@0: michael@0: void setTileModeX(const SkShader::TileMode tm) { fTileModes[0] = tm; } michael@0: void setTileModeY(const SkShader::TileMode tm) { fTileModes[1] = tm; } michael@0: void setTileModeXAndY(const SkShader::TileMode tm) { fTileModes[0] = fTileModes[1] = tm; } michael@0: michael@0: SkShader::TileMode getTileModeX() const { return fTileModes[0]; } michael@0: michael@0: SkShader::TileMode getTileModeY() const { return fTileModes[1]; } michael@0: michael@0: bool isTiled() const { michael@0: return SkShader::kClamp_TileMode != fTileModes[0] || michael@0: SkShader::kClamp_TileMode != fTileModes[1]; michael@0: } michael@0: michael@0: FilterMode filterMode() const { return fFilterMode; } michael@0: michael@0: bool operator== (const GrTextureParams& other) const { michael@0: return fTileModes[0] == other.fTileModes[0] && michael@0: fTileModes[1] == other.fTileModes[1] && michael@0: fFilterMode == other.fFilterMode; michael@0: } michael@0: michael@0: bool operator!= (const GrTextureParams& other) const { return !(*this == other); } michael@0: michael@0: private: michael@0: michael@0: SkShader::TileMode fTileModes[2]; michael@0: FilterMode fFilterMode; michael@0: }; michael@0: michael@0: /** A class representing the swizzle access pattern for a texture. Note that if the texture is michael@0: * an alpha-only texture then the alpha channel is substituted for other components. Any mangling michael@0: * to handle the r,g,b->a conversions for alpha textures is automatically included in the stage michael@0: * key. However, if a GrEffect uses different swizzles based on its input then it must michael@0: * consider that variation in its key-generation. michael@0: */ michael@0: class GrTextureAccess : public SkNoncopyable { michael@0: public: michael@0: /** michael@0: * A default GrTextureAccess must have reset() called on it in a GrEffect subclass's michael@0: * constructor if it will be accessible via GrEffect::textureAccess(). michael@0: */ michael@0: GrTextureAccess(); michael@0: michael@0: /** michael@0: * Uses the default swizzle, "rgba". michael@0: */ michael@0: GrTextureAccess(GrTexture*, const GrTextureParams&); michael@0: explicit GrTextureAccess(GrTexture*, michael@0: GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode, michael@0: SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode); michael@0: michael@0: /** michael@0: * swizzle must be a string between one and four (inclusive) characters containing only 'r', michael@0: * 'g', 'b', and/or 'a'. michael@0: */ michael@0: GrTextureAccess(GrTexture*, const char* swizzle, const GrTextureParams&); michael@0: GrTextureAccess(GrTexture*, michael@0: const char* swizzle, michael@0: GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode, michael@0: SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode); michael@0: michael@0: void reset(GrTexture*, const GrTextureParams&); michael@0: void reset(GrTexture*, michael@0: GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode, michael@0: SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode); michael@0: void reset(GrTexture*, const char* swizzle, const GrTextureParams&); michael@0: void reset(GrTexture*, michael@0: const char* swizzle, michael@0: GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode, michael@0: SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode); michael@0: michael@0: bool operator== (const GrTextureAccess& other) const { michael@0: #ifdef SK_DEBUG michael@0: // below assumes all chars in fSwizzle are initialized even if string is < 4 chars long. michael@0: SkASSERT(memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1) == michael@0: strcmp(fSwizzle, other.fSwizzle)); michael@0: #endif michael@0: return fParams == other.fParams && michael@0: (fTexture.get() == other.fTexture.get()) && michael@0: (0 == memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1)); michael@0: } michael@0: michael@0: bool operator!= (const GrTextureAccess& other) const { return !(*this == other); } michael@0: michael@0: GrTexture* getTexture() const { return fTexture.get(); } michael@0: michael@0: /** michael@0: * Returns a string representing the swizzle. The string is is null-terminated. michael@0: */ michael@0: const char* getSwizzle() const { return fSwizzle; } michael@0: michael@0: /** Returns a mask indicating which components are referenced in the swizzle. The return michael@0: is a bitfield of GrColorComponentFlags. */ michael@0: uint32_t swizzleMask() const { return fSwizzleMask; } michael@0: michael@0: const GrTextureParams& getParams() const { return fParams; } michael@0: michael@0: private: michael@0: void setSwizzle(const char*); michael@0: michael@0: GrTextureParams fParams; michael@0: SkAutoTUnref fTexture; michael@0: uint32_t fSwizzleMask; michael@0: char fSwizzle[5]; michael@0: michael@0: typedef SkNoncopyable INHERITED; michael@0: }; michael@0: michael@0: #endif