summaryrefslogtreecommitdiffstats
path: root/libs/hwui/Program.h
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2011-12-12 20:35:21 -0800
committerRomain Guy <romainguy@google.com>2011-12-12 20:35:21 -0800
commitf3a910b423db7ad79cf61518bdd9278c048ad0d8 (patch)
treea0ae14d597ee14202ec6ca60cedfb446ff470379 /libs/hwui/Program.h
parentd71dd367af604571c7d00ca473184a1b9240eca2 (diff)
downloadframeworks_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.h257
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;