diff options
author | Romain Guy <romainguy@google.com> | 2011-12-12 20:35:21 -0800 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2011-12-12 20:35:21 -0800 |
commit | f3a910b423db7ad79cf61518bdd9278c048ad0d8 (patch) | |
tree | a0ae14d597ee14202ec6ca60cedfb446ff470379 /libs/hwui/Program.h | |
parent | d71dd367af604571c7d00ca473184a1b9240eca2 (diff) | |
download | frameworks_base-f3a910b423db7ad79cf61518bdd9278c048ad0d8.zip frameworks_base-f3a910b423db7ad79cf61518bdd9278c048ad0d8.tar.gz frameworks_base-f3a910b423db7ad79cf61518bdd9278c048ad0d8.tar.bz2 |
Optimize state changes
Change-Id: Iae59bc8dfd6427d0967472462cc1994987092827
Diffstat (limited to 'libs/hwui/Program.h')
-rw-r--r-- | libs/hwui/Program.h | 257 |
1 files changed, 255 insertions, 2 deletions
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index 9e59621..559c717 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -17,16 +17,264 @@ #ifndef ANDROID_HWUI_PROGRAM_H #define ANDROID_HWUI_PROGRAM_H +#include <utils/KeyedVector.h> + #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> -#include <utils/KeyedVector.h> +#include <SkXfermode.h> #include "Matrix.h" +#include "Properties.h" namespace android { namespace uirenderer { +/////////////////////////////////////////////////////////////////////////////// +// Defines +/////////////////////////////////////////////////////////////////////////////// + +// Debug +#if DEBUG_PROGRAMS + #define PROGRAM_LOGD(...) LOGD(__VA_ARGS__) +#else + #define PROGRAM_LOGD(...) +#endif + +#define COLOR_COMPONENT_THRESHOLD (1.0f - (0.5f / PANEL_BIT_DEPTH)) +#define COLOR_COMPONENT_INV_THRESHOLD (0.5f / PANEL_BIT_DEPTH) + +#define PROGRAM_KEY_TEXTURE 0x1 +#define PROGRAM_KEY_A8_TEXTURE 0x2 +#define PROGRAM_KEY_BITMAP 0x4 +#define PROGRAM_KEY_GRADIENT 0x8 +#define PROGRAM_KEY_BITMAP_FIRST 0x10 +#define PROGRAM_KEY_COLOR_MATRIX 0x20 +#define PROGRAM_KEY_COLOR_LIGHTING 0x40 +#define PROGRAM_KEY_COLOR_BLEND 0x80 +#define PROGRAM_KEY_BITMAP_NPOT 0x100 +#define PROGRAM_KEY_SWAP_SRC_DST 0x2000 + +#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600 +#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800 + +// Encode the xfermodes on 6 bits +#define PROGRAM_MAX_XFERMODE 0x1f +#define PROGRAM_XFERMODE_SHADER_SHIFT 26 +#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20 +#define PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT 14 + +#define PROGRAM_BITMAP_WRAPS_SHIFT 9 +#define PROGRAM_BITMAP_WRAPT_SHIFT 11 + +#define PROGRAM_GRADIENT_TYPE_SHIFT 33 +#define PROGRAM_MODULATE_SHIFT 35 + +#define PROGRAM_IS_POINT_SHIFT 36 + +#define PROGRAM_HAS_AA_SHIFT 37 + +#define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 38 +#define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 39 + +/////////////////////////////////////////////////////////////////////////////// +// Types +/////////////////////////////////////////////////////////////////////////////// + +typedef uint64_t programid; + +/////////////////////////////////////////////////////////////////////////////// +// Program description +/////////////////////////////////////////////////////////////////////////////// + +/** + * Describe the features required for a given program. The features + * determine the generation of both the vertex and fragment shaders. + * A ProgramDescription must be used in conjunction with a ProgramCache. + */ +struct ProgramDescription { + enum ColorModifier { + kColorNone, + kColorMatrix, + kColorLighting, + kColorBlend + }; + + enum Gradient { + kGradientLinear, + kGradientCircular, + kGradientSweep + }; + + ProgramDescription() { + reset(); + } + + // Texturing + bool hasTexture; + bool hasAlpha8Texture; + bool hasExternalTexture; + bool hasTextureTransform; + + // Modulate, this should only be set when setColor() return true + bool modulate; + + // Shaders + bool hasBitmap; + bool isBitmapNpot; + + bool isAA; + + bool hasGradient; + Gradient gradientType; + + SkXfermode::Mode shadersMode; + + bool isBitmapFirst; + GLenum bitmapWrapS; + GLenum bitmapWrapT; + + // Color operations + ColorModifier colorOp; + SkXfermode::Mode colorMode; + + // Framebuffer blending (requires Extensions.hasFramebufferFetch()) + // Ignored for all values < SkXfermode::kPlus_Mode + SkXfermode::Mode framebufferMode; + bool swapSrcDst; + + bool isPoint; + float pointSize; + + /** + * Resets this description. All fields are reset back to the default + * values they hold after building a new instance. + */ + void reset() { + hasTexture = false; + hasAlpha8Texture = false; + hasExternalTexture = false; + hasTextureTransform = false; + + isAA = false; + + modulate = false; + + hasBitmap = false; + isBitmapNpot = false; + + hasGradient = false; + gradientType = kGradientLinear; + + shadersMode = SkXfermode::kClear_Mode; + + isBitmapFirst = false; + bitmapWrapS = GL_CLAMP_TO_EDGE; + bitmapWrapT = GL_CLAMP_TO_EDGE; + + colorOp = kColorNone; + colorMode = SkXfermode::kClear_Mode; + + framebufferMode = SkXfermode::kClear_Mode; + swapSrcDst = false; + + isPoint = false; + pointSize = 0.0f; + } + + /** + * Indicates, for a given color, whether color modulation is required in + * the fragment shader. When this method returns true, the program should + * be provided with a modulation color. + */ + bool setColor(const float r, const float g, const float b, const float a) { + modulate = a < COLOR_COMPONENT_THRESHOLD || r < COLOR_COMPONENT_THRESHOLD || + g < COLOR_COMPONENT_THRESHOLD || b < COLOR_COMPONENT_THRESHOLD; + return modulate; + } + + /** + * Indicates, for a given color, whether color modulation is required in + * the fragment shader. When this method returns true, the program should + * be provided with a modulation color. + */ + bool setAlpha8Color(const float r, const float g, const float b, const float a) { + modulate = a < COLOR_COMPONENT_THRESHOLD || r > COLOR_COMPONENT_INV_THRESHOLD || + g > COLOR_COMPONENT_INV_THRESHOLD || b > COLOR_COMPONENT_INV_THRESHOLD; + return modulate; + } + + /** + * Computes the unique key identifying this program. + */ + programid key() const { + programid key = 0; + if (hasTexture) key |= PROGRAM_KEY_TEXTURE; + if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE; + if (hasBitmap) { + key |= PROGRAM_KEY_BITMAP; + if (isBitmapNpot) { + key |= PROGRAM_KEY_BITMAP_NPOT; + key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT; + key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT; + } + } + if (hasGradient) key |= PROGRAM_KEY_GRADIENT; + key |= programid(gradientType) << PROGRAM_GRADIENT_TYPE_SHIFT; + if (isBitmapFirst) key |= PROGRAM_KEY_BITMAP_FIRST; + if (hasBitmap && hasGradient) { + key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT; + } + switch (colorOp) { + case kColorMatrix: + key |= PROGRAM_KEY_COLOR_MATRIX; + break; + case kColorLighting: + key |= PROGRAM_KEY_COLOR_LIGHTING; + break; + case kColorBlend: + key |= PROGRAM_KEY_COLOR_BLEND; + key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT; + break; + case kColorNone: + break; + } + key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT; + if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST; + if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT; + if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT; + if (isAA) key |= programid(0x1) << PROGRAM_HAS_AA_SHIFT; + if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT; + if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT; + return key; + } + + /** + * Logs the specified message followed by the key identifying this program. + */ + void log(const char* message) const { +#if DEBUG_PROGRAMS + programid k = key(); + PROGRAM_LOGD("%s (key = 0x%.8x%.8x)", message, uint32_t(k >> 32), + uint32_t(k & 0xffffffff)); +#endif + } + +private: + inline uint32_t getEnumForWrap(GLenum wrap) const { + switch (wrap) { + case GL_CLAMP_TO_EDGE: + return 0; + case GL_REPEAT: + return 1; + case GL_MIRRORED_REPEAT: + return 2; + } + return 0; + } + +}; // struct ProgramDescription + /** * A program holds a vertex and a fragment shader. It offers several utility * methods to query attributes and uniforms. @@ -42,7 +290,7 @@ public: * Creates a new program with the specified vertex and fragment * shaders sources. */ - Program(const char* vertex, const char* fragment); + Program(const ProgramDescription& description, const char* vertex, const char* fragment); virtual ~Program(); /** @@ -99,6 +347,11 @@ public: int position; /** + * Name of the texCoords attribute if it exists, -1 otherwise. + */ + int texCoords; + + /** * Name of the transform uniform. */ int transform; |