summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Romain Guy <romainguy@google.com> 2010-07-27 17:39:27 -0700
committer Romain Guy <romainguy@google.com> 2010-07-27 19:52:29 -0700
commitac670c0433d19397d4e36ced2110475b6f54fe26 (patch)
tree10722cd4e465fc053f9536cc312c1125a694108a
parentbb2b2a996b2c0bea7e434136e20340f4f1b398ab (diff)
Generate shaders to cover all possible cases.
With this change, all the vertex and fragment shaders used by the GL renderer are now generated based on a program description supplied by the caller. This allows the renderer to generate a large number of shaders without having to write all the possible combinations by hand. The generated shaders are stored in a program cache. Change-Id: If54d286e77ae021c724d42090da476df12a18ebb
-rw-r--r--core/java/android/view/Window.java5
-rw-r--r--libs/hwui/Android.mk1
-rw-r--r--libs/hwui/OpenGLRenderer.cpp57
-rw-r--r--libs/hwui/OpenGLRenderer.h6
-rw-r--r--libs/hwui/Program.cpp11
-rw-r--r--libs/hwui/Program.h28
-rw-r--r--libs/hwui/ProgramCache.cpp332
-rw-r--r--libs/hwui/ProgramCache.h155
-rw-r--r--libs/hwui/Vertex.h8
-rw-r--r--libs/hwui/shaders/drawColor.vert11
-rw-r--r--libs/hwui/shaders/drawLinearGradient.vert2
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java3
12 files changed, 543 insertions, 76 deletions
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index ed02456ce807..b077b568efd6 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -56,11 +56,6 @@ public abstract class Window {
public static final int FEATURE_CONTEXT_MENU = 6;
/** Flag for custom title. You cannot combine this feature with other title features. */
public static final int FEATURE_CUSTOM_TITLE = 7;
- /** Flag for asking for an OpenGL enabled window.
- All 2D graphics will be handled by OpenGL ES.
- @hide
- */
- public static final int FEATURE_OPENGL = 8;
/**
* Flag for enabling the Action Bar.
* This is enabled by default for some devices. The Action Bar
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 172952a8f49d..a9714c7ab79b 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -10,6 +10,7 @@ LOCAL_SRC_FILES:= \
Patch.cpp \
PatchCache.cpp \
Program.cpp \
+ ProgramCache.cpp \
TextureCache.cpp
LOCAL_C_INCLUDES += \
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2e44e122ea39..0ed62768b899 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -45,32 +45,22 @@ namespace uirenderer {
#define MB(s) s * 1024 * 1024
// Generates simple and textured vertices
-#define SV(x, y) { { x, y } }
#define FV(x, y, u, v) { { x, y }, { u, v } }
///////////////////////////////////////////////////////////////////////////////
// Globals
///////////////////////////////////////////////////////////////////////////////
-static const SimpleVertex gDrawColorVertices[] = {
- SV(0.0f, 0.0f),
- SV(1.0f, 0.0f),
- SV(0.0f, 1.0f),
- SV(1.0f, 1.0f)
-};
-static const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex);
-static const GLsizei gDrawColorVertexCount = 4;
-
// This array is never used directly but used as a memcpy source in the
// OpenGLRenderer constructor
-static const TextureVertex gDrawTextureVertices[] = {
+static const TextureVertex gMeshVertices[] = {
FV(0.0f, 0.0f, 0.0f, 0.0f),
FV(1.0f, 0.0f, 1.0f, 0.0f),
FV(0.0f, 1.0f, 0.0f, 1.0f),
FV(1.0f, 1.0f, 1.0f, 1.0f)
};
-static const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex);
-static const GLsizei gDrawTextureVertexCount = 4;
+static const GLsizei gMeshStride = sizeof(TextureVertex);
+static const GLsizei gMeshCount = 4;
// In this array, the index of each Blender equals the value of the first
// entry. For instance, gBlends[1] == gBlends[SkXfermode::kSrc_Mode]
@@ -143,7 +133,18 @@ OpenGLRenderer::OpenGLRenderer():
mLastTexture = 0;
- memcpy(mDrawTextureVertices, gDrawTextureVertices, sizeof(gDrawTextureVertices));
+ memcpy(mMeshVertices, gMeshVertices, sizeof(gMeshVertices));
+
+ ProgramDescription d;
+ mProgramCache.get(d);
+ d.hasTexture = true;
+ mProgramCache.get(d);
+ d.hasAlpha8Texture = true;
+ d.hasGradient = true;
+ d.hasBitmap = true;
+ d.shadersMode = SkXfermode::kDstOut_Mode;
+ d.colorOp = ProgramDescription::kColorMatrix;
+ mProgramCache.get(d);
}
OpenGLRenderer::~OpenGLRenderer() {
@@ -650,9 +651,13 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot
mModelView.scale(right - left, bottom - top, 1.0f);
if (!useProgram(mDrawColorProgram)) {
- const GLvoid* p = &gDrawColorVertices[0].position[0];
+ const GLvoid* vertices = &mMeshVertices[0].position[0];
+ const GLvoid* texCoords = &mMeshVertices[0].texture[0];
+
glVertexAttribPointer(mDrawColorProgram->position, 2, GL_FLOAT, GL_FALSE,
- gDrawColorVertexStride, p);
+ gMeshStride, vertices);
+ glVertexAttribPointer(mDrawColorProgram->texCoords, 2, GL_FLOAT, GL_FALSE,
+ gMeshStride, texCoords);
}
if (!ignoreTransform) {
@@ -664,7 +669,7 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot
glUniform4f(mDrawColorProgram->color, r, g, b, a);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
}
void OpenGLRenderer::drawLinearGradientShader(float left, float top, float right, float bottom,
@@ -717,9 +722,9 @@ void OpenGLRenderer::drawLinearGradientShader(float left, float top, float right
&screenSpace.data[0]);
glVertexAttribPointer(mDrawLinearGradientProgram->position, 2, GL_FLOAT, GL_FALSE,
- gDrawTextureVertexStride, &mDrawTextureVertices[0].position[0]);
+ gMeshStride, &mMeshVertices[0].position[0]);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawTextureVertexCount);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
}
void OpenGLRenderer::drawBitmapShader(float left, float top, float right, float bottom,
@@ -757,7 +762,7 @@ void OpenGLRenderer::drawBitmapShader(float left, float top, float right, float
resetDrawTextureTexCoords(u1, v1, u2, v2);
drawTextureMesh(left, top, right, bottom, texture->id, alpha, mode, texture->blend,
- &mDrawTextureVertices[0].position[0], &mDrawTextureVertices[0].texture[0], NULL);
+ &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], NULL);
resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
}
@@ -769,13 +774,13 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b
getAlphaAndMode(paint, &alpha, &mode);
drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend,
- &mDrawTextureVertices[0].position[0], &mDrawTextureVertices[0].texture[0], NULL);
+ &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], NULL);
}
void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
GLuint texture, float alpha, SkXfermode::Mode mode, bool blend) {
drawTextureMesh(left, top, right, bottom, texture, alpha, mode, blend,
- &mDrawTextureVertices[0].position[0], &mDrawTextureVertices[0].texture[0], NULL);
+ &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0], NULL);
}
void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom,
@@ -794,12 +799,12 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b
glUniform4f(mDrawTextureProgram->color, alpha, alpha, alpha, alpha);
glVertexAttribPointer(mDrawTextureProgram->position, 2, GL_FLOAT, GL_FALSE,
- gDrawTextureVertexStride, vertices);
+ gMeshStride, vertices);
glVertexAttribPointer(mDrawTextureProgram->texCoords, 2, GL_FLOAT, GL_FALSE,
- gDrawTextureVertexStride, texCoords);
+ gMeshStride, texCoords);
if (!indices) {
- glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawTextureVertexCount);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
} else {
glDrawElements(GL_TRIANGLES, elementsCount, GL_UNSIGNED_SHORT, indices);
}
@@ -842,7 +847,7 @@ bool OpenGLRenderer::useProgram(const sp<Program>& program) {
}
void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) {
- TextureVertex* v = &mDrawTextureVertices[0];
+ TextureVertex* v = &mMeshVertices[0];
TextureVertex::setUV(v++, u1, v1);
TextureVertex::setUV(v++, u2, v1);
TextureVertex::setUV(v++, u1, v2);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 248c9c3c1b6d..975be056b15f 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -41,6 +41,7 @@
#include "PatchCache.h"
#include "Vertex.h"
#include "FontRenderer.h"
+#include "ProgramCache.h"
namespace android {
namespace uirenderer {
@@ -268,7 +269,7 @@ private:
SkXfermode::Mode mode);
/**
- * Resets the texture coordinates stored in mDrawTextureVertices. Setting the values
+ * Resets the texture coordinates stored in mMeshVertices. Setting the values
* back to default is achieved by calling:
*
* resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
@@ -337,7 +338,7 @@ private:
sp<DrawLinearGradientProgram> mDrawLinearGradientProgram;
// Used to draw textured quads
- TextureVertex mDrawTextureVertices[4];
+ TextureVertex mMeshVertices[4];
// Current texture state
GLuint mLastTexture;
@@ -372,6 +373,7 @@ private:
TextureCache mTextureCache;
LayerCache mLayerCache;
GradientCache mGradientCache;
+ ProgramCache mProgramCache;
PatchCache mPatchCache;
}; // class OpenGLRenderer
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 6e608084f5bb..86fc154bb9c2 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -27,7 +27,6 @@ namespace uirenderer {
#define SHADER_SOURCE(name, source) const char* name = #source
-#include "shaders/drawColor.vert"
#include "shaders/drawColor.frag"
#include "shaders/drawTexture.vert"
@@ -127,7 +126,7 @@ GLuint Program::buildShader(const char* source, GLenum type) {
///////////////////////////////////////////////////////////////////////////////
DrawColorProgram::DrawColorProgram():
- Program(gDrawColorVertexShader, gDrawColorFragmentShader) {
+ Program(gDrawTextureVertexShader, gDrawColorFragmentShader) {
getAttribsAndUniforms();
}
@@ -138,6 +137,7 @@ DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment):
void DrawColorProgram::getAttribsAndUniforms() {
position = addAttrib("position");
+ texCoords = addAttrib("texCoords");
color = addUniform("color");
transform = addUniform("transform");
}
@@ -154,11 +154,13 @@ void DrawColorProgram::set(const mat4& projectionMatrix, const mat4& modelViewMa
void DrawColorProgram::use() {
Program::use();
glEnableVertexAttribArray(position);
+ glEnableVertexAttribArray(texCoords);
}
void DrawColorProgram::remove() {
Program::remove();
glDisableVertexAttribArray(position);
+ glDisableVertexAttribArray(texCoords);
}
///////////////////////////////////////////////////////////////////////////////
@@ -167,26 +169,21 @@ void DrawColorProgram::remove() {
DrawTextureProgram::DrawTextureProgram():
DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) {
- texCoords = addAttrib("texCoords");
sampler = addUniform("sampler");
}
DrawTextureProgram::DrawTextureProgram(const char* vertex, const char* fragment):
DrawColorProgram(vertex, fragment) {
- texCoords = addAttrib("texCoords");
sampler = addUniform("sampler");
}
void DrawTextureProgram::use() {
DrawColorProgram::use();
- glActiveTexture(GL_TEXTURE0);
glUniform1i(sampler, 0);
- glEnableVertexAttribArray(texCoords);
}
void DrawTextureProgram::remove() {
DrawColorProgram::remove();
- glDisableVertexAttribArray(texCoords);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 824aa0525e44..2cdd90512d95 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -53,6 +53,16 @@ public:
virtual void remove();
/**
+ * Returns the OpenGL name of the specified attribute.
+ */
+ int getAttrib(const char* name);
+
+ /**
+ * Returns the OpenGL name of the specified uniform.
+ */
+ int getUniform(const char* name);
+
+ /**
* Indicates whether this program is currently in use with
* the GL context.
*/
@@ -67,10 +77,6 @@ protected:
* @return The OpenGL name of the attribute.
*/
int addAttrib(const char* name);
- /**
- * Returns the OpenGL name of the specified attribute.
- */
- int getAttrib(const char* name);
/**
* Adds a uniform with the specified name.
@@ -78,10 +84,6 @@ protected:
* @return The OpenGL name of the uniform.
*/
int addUniform(const char* name);
- /**
- * Returns the OpenGL name of the specified uniform.
- */
- int getUniform(const char* name);
private:
/**
@@ -145,6 +147,11 @@ public:
int position;
/**
+ * Name of the texture coordinates attribute.
+ */
+ int texCoords;
+
+ /**
* Name of the color uniform.
*/
int color;
@@ -184,11 +191,6 @@ public:
* Name of the texture sampler uniform.
*/
int sampler;
-
- /**
- * Name of the texture coordinates attribute.
- */
- int texCoords;
};
class DrawTextProgram: public DrawTextureProgram {
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
new file mode 100644
index 000000000000..5a89eb6a3a1a
--- /dev/null
+++ b/libs/hwui/ProgramCache.cpp
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <utils/String8.h>
+
+#include "ProgramCache.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Vertex shaders snippets
+///////////////////////////////////////////////////////////////////////////////
+
+// TODO: Implement BitmapShader, implement repeat/mirror for npot
+
+const char* gVS_Header_Attributes =
+ "attribute vec4 position;\n";
+const char* gVS_Header_Attributes_TexCoords =
+ "attribute vec2 texCoords;\n";
+const char* gVS_Header_Uniforms =
+ "uniform mat4 transform;\n";
+const char* gVS_Header_Uniforms_HasGradient =
+ "uniform float gradientLength;\n"
+ "uniform vec2 gradient;\n"
+ "uniform vec2 gradientStart;\n"
+ "uniform mat4 screenSpace;\n";
+const char* gVS_Header_Varyings_HasTexture =
+ "varying vec2 outTexCoords;\n";
+const char* gVS_Header_Varyings_HasBitmap =
+ "varying vec2 outBitmapTexCoords;\n";
+const char* gVS_Header_Varyings_HasGradient =
+ "varying float index;\n";
+const char* gVS_Main =
+ "\nvoid main(void) {\n";
+const char* gVS_Main_OutTexCoords =
+ " outTexCoords = texCoords;\n";
+const char* gVS_Main_OutGradientIndex =
+ " vec4 location = screenSpace * position;\n"
+ " index = dot(location.xy - gradientStart, gradient) * gradientLength;\n";
+const char* gVS_Main_Position =
+ " gl_Position = transform * position;\n";
+const char* gVS_Footer =
+ "}\n\n";
+
+///////////////////////////////////////////////////////////////////////////////
+// Fragment shaders snippets
+///////////////////////////////////////////////////////////////////////////////
+
+const char* gFS_Header =
+ "precision mediump float;\n\n";
+const char* gFS_Uniforms_Color =
+ "uniform vec4 color;\n";
+const char* gFS_Uniforms_TextureSampler =
+ "uniform sampler2D sampler;\n";
+const char* gFS_Uniforms_GradientSampler =
+ "uniform sampler2D gradientSampler;\n";
+const char* gFS_Uniforms_BitmapSampler =
+ "uniform sampler2D bitmapSampler;\n";
+const char* gFS_Uniforms_ColorOp[4] = {
+ // None
+ "",
+ // Matrix
+ "uniform mat4 colorMatrix;\n"
+ "uniform vec4 colorMatrixVector;\n",
+ // Lighting
+ "uniform float lightingMul;\n"
+ "uniform float lightingAdd;\n",
+ // PorterDuff
+ "uniform vec4 colorBLend;\n"
+};
+const char* gFS_Main =
+ "\nvoid main(void) {\n"
+ " vec4 fragColor;\n";
+const char* gFS_Main_FetchColor =
+ " fragColor = color;\n";
+const char* gFS_Main_FetchTexture =
+ " fragColor = color * texture2D(sampler, outTexCoords);\n";
+const char* gFS_Main_FetchA8Texture =
+ " fragColor = color * texture2D(sampler, outTexCoords).a;\n";
+const char* gFS_Main_FetchGradient =
+ " vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n";
+const char* gFS_Main_FetchBitmap =
+ " vec4 bitmapColor = texture2D(bitmapSampler, outBitmapTexCoords);\n";
+const char* gFS_Main_BlendShadersBG =
+ " fragColor = blendShaders(bitmapColor, gradientColor)";
+const char* gFS_Main_BlendShadersGB =
+ " fragColor = blendShaders(gradientColor, bitmapColor)";
+const char* gFS_Main_BlendShaders_Modulate =
+ " * fragColor.a;\n";
+const char* gFS_Main_FragColor =
+ " gl_FragColor = fragColor;\n";
+const char* gFS_Main_ApplyColorOp[4] = {
+ // None
+ "",
+ // Matrix
+ " fragColor *= colorMatrix;\n"
+ " fragColor += colorMatrixVector;\n",
+ // Lighting
+ " fragColor *= lightingMul;\n"
+ " fragColor += lightingAdd;\n",
+ // PorterDuff
+ " fragColor = blendColors(colorBlend, fragColor);\n"
+};
+const char* gFS_Footer =
+ "}\n\n";
+
+///////////////////////////////////////////////////////////////////////////////
+// PorterDuff snippets
+///////////////////////////////////////////////////////////////////////////////
+
+const char* gPorterDuff[12] = {
+ // Clear
+ "return vec4(0.0, 0.0, 0.0, 0.0);\n",
+ // Src
+ "return src;\n",
+ // Dst
+ "return dst;\n",
+ // SrcOver
+ "return vec4(src.rgb + (1.0 - src.a) * dst.rgb, src.a + dst.a - src.a * dst.a);\n",
+ // DstOver
+ "return vec4(dst.rgb + (1.0 - dst.a) * src.rgb, src.a + dst.a - src.a * dst.a);\n",
+ // SrcIn
+ "return vec4(src.rgb * dst.a, src.a * dst.a);\n",
+ // DstIn
+ "return vec4(dst.rgb * src.a, src.a * dst.a);\n",
+ // SrcOut
+ "return vec4(src.rgb * (1.0 - dst.a), src.a * (1.0 - dst.a));\n",
+ // DstOut
+ "return vec4(dst.rgb * (1.0 - src.a), dst.a * (1.0 - src.a));\n",
+ // SrcAtop
+ "return vec4(src.rgb * dst.a + (1.0 - src.a) * dst.rgb, dst.a);\n",
+ // DstAtop
+ "return vec4(dst.rgb * src.a + (1.0 - dst.a) * src.rgb, src.a);\n",
+ // Xor
+ "return vec4(src.rgb * (1.0 - dst.a) + (1.0 - src.a) * dst.rgb, "
+ "src.a + dst.a - 2.0 * src.a * dst.a);\n",
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructors/destructors
+///////////////////////////////////////////////////////////////////////////////
+
+ProgramCache::ProgramCache() {
+}
+
+ProgramCache::~ProgramCache() {
+ clear();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Cache management
+///////////////////////////////////////////////////////////////////////////////
+
+void ProgramCache::clear() {
+ size_t count = mCache.size();
+ for (size_t i = 0; i < count; i++) {
+ delete mCache.valueAt(i);
+ }
+ mCache.clear();
+}
+
+Program* ProgramCache::get(const ProgramDescription& description) {
+ programid key = description.key();
+ ssize_t index = mCache.indexOfKey(key);
+ Program* program = NULL;
+ if (index < 0) {
+ PROGRAM_LOGD("Could not find program with key 0x%x", key);
+ program = generateProgram(description, key);
+ mCache.add(key, program);
+ } else {
+ program = mCache.valueAt(index);
+ }
+ return program;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Program generation
+///////////////////////////////////////////////////////////////////////////////
+
+Program* ProgramCache::generateProgram(const ProgramDescription& description, programid key) {
+ String8 vertexShader = generateVertexShader(description);
+ String8 fragmentShader = generateFragmentShader(description);
+
+ Program* program = new Program(vertexShader.string(), fragmentShader.string());
+ return program;
+}
+
+String8 ProgramCache::generateVertexShader(const ProgramDescription& description) {
+ // Add attributes
+ String8 shader(gVS_Header_Attributes);
+ if (description.hasTexture || description.hasBitmap) {
+ shader.append(gVS_Header_Attributes_TexCoords);
+ }
+ // Uniforms
+ shader.append(gVS_Header_Uniforms);
+ if (description.hasGradient) {
+ shader.append(gVS_Header_Uniforms_HasGradient);
+ }
+ // Varyings
+ if (description.hasTexture) {
+ shader.append(gVS_Header_Varyings_HasTexture);
+ }
+ if (description.hasGradient) {
+ shader.append(gVS_Header_Varyings_HasGradient);
+ }
+ if (description.hasBitmap) {
+ shader.append(gVS_Header_Varyings_HasBitmap);
+ }
+
+ // Begin the shader
+ shader.append(gVS_Main); {
+ if (description.hasTexture) {
+ shader.append(gVS_Main_OutTexCoords);
+ }
+ if (description.hasGradient) {
+ shader.append(gVS_Main_OutGradientIndex);
+ }
+ // Output transformed position
+ shader.append(gVS_Main_Position);
+ }
+ // End the shader
+ shader.append(gVS_Footer);
+
+ PROGRAM_LOGD("*** Generated vertex shader:\n\n%s", shader.string());
+
+ return shader;
+}
+
+String8 ProgramCache::generateFragmentShader(const ProgramDescription& description) {
+ // Set the default precision
+ String8 shader(gFS_Header);
+
+ // Varyings
+ if (description.hasTexture) {
+ shader.append(gVS_Header_Varyings_HasTexture);
+ }
+ if (description.hasGradient) {
+ shader.append(gVS_Header_Varyings_HasGradient);
+ }
+ if (description.hasBitmap) {
+ shader.append(gVS_Header_Varyings_HasBitmap);
+ }
+
+
+ // Uniforms
+ shader.append(gFS_Uniforms_Color);
+ if (description.hasTexture) {
+ shader.append(gFS_Uniforms_TextureSampler);
+ }
+ if (description.hasGradient) {
+ shader.append(gFS_Uniforms_GradientSampler);
+ }
+ if (description.hasBitmap) {
+ shader.append(gFS_Uniforms_BitmapSampler);
+ }
+ shader.append(gFS_Uniforms_ColorOp[description.colorOp]);
+
+ // Generate required functions
+ if (description.hasGradient && description.hasBitmap) {
+ generatePorterDuffBlend(shader, "blendShaders", description.shadersMode);
+ }
+ if (description.colorOp == ProgramDescription::kColorBlend) {
+ generatePorterDuffBlend(shader, "blendColors", description.colorMode);
+ }
+
+ // Begin the shader
+ shader.append(gFS_Main); {
+ // Stores the result in fragColor directly
+ if (description.hasTexture) {
+ if (description.hasAlpha8Texture) {
+ shader.append(gFS_Main_FetchA8Texture);
+ } else {
+ shader.append(gFS_Main_FetchTexture);
+ }
+ } else {
+ shader.append(gFS_Main_FetchColor);
+ }
+ if (description.hasGradient) {
+ shader.append(gFS_Main_FetchGradient);
+ }
+ if (description.hasBitmap) {
+ shader.append(gFS_Main_FetchBitmap);
+ }
+ // Case when we have two shaders set
+ if (description.hasGradient && description.hasBitmap) {
+ if (description.isBitmapFirst) {
+ shader.append(gFS_Main_BlendShadersBG);
+ } else {
+ shader.append(gFS_Main_BlendShadersGB);
+ }
+ shader.append(gFS_Main_BlendShaders_Modulate);
+ }
+ // Apply the color op if needed
+ shader.append(gFS_Main_ApplyColorOp[description.colorOp]);
+ // Output the fragment
+ shader.append(gFS_Main_FragColor);
+ }
+ // End the shader
+ shader.append(gFS_Footer);
+
+ PROGRAM_LOGD("*** Generated fragment shader:\n\n%s", shader.string());
+ return shader;
+}
+
+void ProgramCache::generatePorterDuffBlend(String8& shader, const char* name,
+ SkXfermode::Mode mode) {
+ shader.append("\nvec4 ");
+ shader.append(name);
+ shader.append("(vec4 src, vec4 dst) {\n");
+ shader.append(" ");
+ shader.append(gPorterDuff[mode]);
+ shader.append("}\n");
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
new file mode 100644
index 000000000000..7f2f5faf33e8
--- /dev/null
+++ b/libs/hwui/ProgramCache.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_PROGRAM_CACHE_H
+#define ANDROID_UI_PROGRAM_CACHE_H
+
+#include <utils/KeyedVector.h>
+#include <utils/Log.h>
+
+#include <SkXfermode.h>
+
+#include "Program.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+// Debug
+#define DEBUG_PROGRAM_CACHE 0
+
+// Debug
+#if DEBUG_PROGRAM_CACHE
+ #define PROGRAM_LOGD(...) LOGD(__VA_ARGS__)
+#else
+ #define PROGRAM_LOGD(...)
+#endif
+
+#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
+
+// Support only the 12 Porter-Duff modes for now
+#define PROGRAM_MAX_XFERMODE 0xC
+#define PROGRAM_XFERMODE_SHADER_SHIFT 24
+#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
+
+///////////////////////////////////////////////////////////////////////////////
+// Types
+///////////////////////////////////////////////////////////////////////////////
+
+typedef uint32_t programid;
+
+///////////////////////////////////////////////////////////////////////////////
+// Cache
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * 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
+ };
+
+ ProgramDescription():
+ hasTexture(false), hasAlpha8Texture(false),
+ hasBitmap(false), hasGradient(false), shadersMode(SkXfermode::kClear_Mode),
+ colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode) {
+ }
+
+ // Texturing
+ bool hasTexture;
+ bool hasAlpha8Texture;
+
+ // Shaders
+ bool hasBitmap;
+ bool hasGradient;
+ SkXfermode::Mode shadersMode;
+ bool isBitmapFirst;
+
+ // Color operations
+ int colorOp;
+ SkXfermode::Mode colorMode;
+
+ 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 (hasGradient) key |= PROGRAM_KEY_GRADIENT;
+ 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;
+ }
+ return key;
+ }
+}; // struct ProgramDescription
+
+/**
+ * Generates and caches program. Programs are generated based on
+ * ProgramDescriptions.
+ */
+class ProgramCache {
+public:
+ ProgramCache();
+ ~ProgramCache();
+
+ Program* get(const ProgramDescription& description);
+
+ void clear();
+
+private:
+ Program* generateProgram(const ProgramDescription& description, programid key);
+ String8 generateVertexShader(const ProgramDescription& description);
+ String8 generateFragmentShader(const ProgramDescription& description);
+ void generatePorterDuffBlend(String8& shader, const char* name, SkXfermode::Mode mode);
+
+ KeyedVector<programid, Program*> mCache;
+
+}; // class ProgramCache
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_PROGRAM_CACHE_H
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index ffd063384846..1f540864f17f 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -21,14 +21,6 @@ namespace android {
namespace uirenderer {
/**
- * Simple structure to describe a vertex with a position.
- * This is used to draw filled rectangles without a texture.
- */
-struct SimpleVertex {
- float position[2];
-}; // struct SimpleVertex
-
-/**
* Simple structure to describe a vertex with a position and a texture.
*/
struct TextureVertex {
diff --git a/libs/hwui/shaders/drawColor.vert b/libs/hwui/shaders/drawColor.vert
deleted file mode 100644
index 20e26363e1e4..000000000000
--- a/libs/hwui/shaders/drawColor.vert
+++ /dev/null
@@ -1,11 +0,0 @@
-SHADER_SOURCE(gDrawColorVertexShader,
-
-attribute vec4 position;
-
-uniform mat4 transform;
-
-void main(void) {
- gl_Position = transform * position;
-}
-
-);
diff --git a/libs/hwui/shaders/drawLinearGradient.vert b/libs/hwui/shaders/drawLinearGradient.vert
index f5c669b0607e..d2f857d4d958 100644
--- a/libs/hwui/shaders/drawLinearGradient.vert
+++ b/libs/hwui/shaders/drawLinearGradient.vert
@@ -2,10 +2,10 @@ SHADER_SOURCE(gDrawLinearGradientVertexShader,
attribute vec4 position;
+uniform mat4 transform;
uniform float gradientLength;
uniform vec2 gradient;
uniform vec2 start;
-uniform mat4 transform;
uniform mat4 screenSpace;
varying float index;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 5771e8568ff4..2976e3eeda89 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -196,9 +196,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
/* Custom title feature is enabled and the user is trying to enable another feature */
throw new AndroidRuntimeException("You cannot combine custom titles with other title features");
}
- if (featureId == FEATURE_OPENGL) {
- getAttributes().memoryType = WindowManager.LayoutParams.MEMORY_TYPE_GPU;
- }
return super.requestFeature(featureId);
}