Reduced the complexity of layers composition.
This change also refactors the code base a bit by moving classes out of
OpenGLRenderer into separate headers/implementations. This makes the code
more manageable.
This change also adds documentation for implementation methods. The
undocumented methods are simply Skia's Canvas methods.
Change-Id: I54c68b443580a0129251dddc1a7ac95813d5289e
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 54829a2d..fd76811 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -3,7 +3,8 @@
LOCAL_SRC_FILES:= \
Matrix.cpp \
- OpenGLRenderer.cpp
+ OpenGLRenderer.cpp \
+ Program.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index e9c7791..877d3bb 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "Matrix"
+#define LOG_TAG "OpenGLRenderer"
#include <math.h>
#include <stdlib.h>
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 786b927..e764778 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -20,19 +20,11 @@
#include <stdint.h>
#include <sys/types.h>
-#include <utils/Errors.h>
-#include <utils/KeyedVector.h>
+#include <SkCanvas.h>
+
#include <utils/Log.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <SkCanvas.h>
-#include <SkPaint.h>
-#include <SkXfermode.h>
-
#include "OpenGLRenderer.h"
-#include "Matrix.h"
namespace android {
namespace uirenderer {
@@ -57,7 +49,7 @@
const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex);
const GLsizei gDrawColorVertexCount = 4;
-const TextureVertex gDrawTextureVertices[] = {
+TextureVertex gDrawTextureVertices[] = {
FV(0.0f, 0.0f, 0.0f, 1.0f),
FV(1.0f, 0.0f, 1.0f, 1.0f),
FV(0.0f, 1.0f, 0.0f, 0.0f),
@@ -66,134 +58,15 @@
const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex);
const GLsizei gDrawTextureVertexCount = 4;
-///////////////////////////////////////////////////////////////////////////////
-// Shaders
-///////////////////////////////////////////////////////////////////////////////
-
-#define SHADER_SOURCE(name, source) const char* name = #source
-
-#include "shaders/drawColor.vert"
-#include "shaders/drawColor.frag"
-
-#include "shaders/drawTexture.vert"
-#include "shaders/drawTexture.frag"
-
-Program::Program(const char* vertex, const char* fragment) {
- vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
- fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
-
- id = glCreateProgram();
- glAttachShader(id, vertexShader);
- glAttachShader(id, fragmentShader);
- glLinkProgram(id);
-
- GLint status;
- glGetProgramiv(id, GL_LINK_STATUS, &status);
- if (status != GL_TRUE) {
- GLint infoLen = 0;
- glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
- if (infoLen > 1) {
- char* log = (char*) malloc(sizeof(char) * infoLen);
- glGetProgramInfoLog(id, infoLen, 0, log);
- LOGE("Error while linking shaders: %s", log);
- delete log;
- }
- glDeleteProgram(id);
- }
-}
-
-Program::~Program() {
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- glDeleteProgram(id);
-}
-
-void Program::use() {
- glUseProgram(id);
-}
-
-int Program::addAttrib(const char* name) {
- int slot = glGetAttribLocation(id, name);
- attributes.add(name, slot);
- return slot;
-}
-
-int Program::getAttrib(const char* name) {
- return attributes.valueFor(name);
-}
-
-int Program::addUniform(const char* name) {
- int slot = glGetUniformLocation(id, name);
- uniforms.add(name, slot);
- return slot;
-}
-
-int Program::getUniform(const char* name) {
- return uniforms.valueFor(name);
-}
-
-GLuint Program::buildShader(const char* source, GLenum type) {
- GLuint shader = glCreateShader(type);
- glShaderSource(shader, 1, &source, 0);
- glCompileShader(shader);
-
- GLint status;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- if (status != GL_TRUE) {
- // Some drivers return wrong values for GL_INFO_LOG_LENGTH
- // use a fixed size instead
- GLchar log[512];
- glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]);
- LOGE("Error while compiling shader: %s", log);
- glDeleteShader(shader);
- }
-
- return shader;
-}
-
-DrawColorProgram::DrawColorProgram():
- Program(gDrawColorVertexShader, gDrawColorFragmentShader) {
- getAttribsAndUniforms();
-}
-
-DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment):
- Program(vertex, fragment) {
- getAttribsAndUniforms();
-}
-
-void DrawColorProgram::getAttribsAndUniforms() {
- position = addAttrib("position");
- color = addAttrib("color");
- projection = addUniform("projection");
- modelView = addUniform("modelView");
- transform = addUniform("transform");
-}
-
-void DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
- const GLfloat* transformMatrix) {
- Program::use();
- glUniformMatrix4fv(projection, 1, GL_FALSE, projectionMatrix);
- glUniformMatrix4fv(modelView, 1, GL_FALSE, modelViewMatrix);
- glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix);
-}
-
-DrawTextureProgram::DrawTextureProgram():
- DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) {
- texCoords = addAttrib("texCoords");
- sampler = addUniform("sampler");
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Support
-///////////////////////////////////////////////////////////////////////////////
-
-const Rect& Snapshot::getMappedClip() {
- if (flags & kFlagDirtyTransform) {
- flags &= ~kFlagDirtyTransform;
- mappedClip.set(clipRect);
- transform.mapRect(mappedClip);
- }
- return mappedClip;
+static inline void resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) {
+ gDrawTextureVertices[0].texture[0] = u1;
+ gDrawTextureVertices[0].texture[1] = v2;
+ gDrawTextureVertices[1].texture[0] = u2;
+ gDrawTextureVertices[1].texture[1] = v2;
+ gDrawTextureVertices[2].texture[0] = u1;
+ gDrawTextureVertices[2].texture[1] = v1;
+ gDrawTextureVertices[3].texture[0] = u2;
+ gDrawTextureVertices[3].texture[1] = v1;
}
///////////////////////////////////////////////////////////////////////////////
@@ -292,11 +165,28 @@
// Most of the time, previous->fbo will be 0 to bind the default buffer
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
- const Rect& layer = current->layer;
- clipRect(layer.left, layer.top, layer.right, layer.bottom);
- mSnapshot->transform.loadIdentity();
+ // Restore the clip from the previous snapshot
+ const Rect& clip = previous->getMappedClip();
+ glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
- drawTextureRect(0.0f, 0.0f, mWidth, mHeight, current->texture, current->alpha);
+ // Compute the correct texture coordinates for the FBO texture
+ // The texture is currently as big as the window but drawn with
+ // a quad of the appropriate size
+ const Rect& layer = current->layer;
+ Rect texCoords(current->layer);
+ mSnapshot->transform.mapRect(texCoords);
+
+ const float u1 = texCoords.left / float(mWidth);
+ const float v1 = (mHeight - texCoords.top) / float(mHeight);
+ const float u2 = texCoords.right / float(mWidth);
+ const float v2 = (mHeight - texCoords.bottom) / float(mHeight);
+
+ resetDrawTextureTexCoords(u1, v1, u2, v1);
+
+ drawTextureRect(layer.left, layer.top, layer.right, layer.bottom,
+ current->texture, current->alpha);
+
+ resetDrawTextureTexCoords(0.0f, 1.0f, 1.0f, 0.0f);
glDeleteFramebuffers(1, ¤t->fbo);
glDeleteTextures(1, ¤t->texture);
@@ -337,11 +227,14 @@
// The FBO will not be scaled, so we can use lower quality filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// TODO ***** IMPORTANT *****
// Creating a texture-backed FBO works only if the texture is the same size
// as the original rendering buffer (in this case, mWidth and mHeight.)
// This is expensive and wasteful and must be fixed.
+ // TODO Additionally we should use an FBO cache
const GLsizei width = mWidth; //right - left;
const GLsizei height = mHeight; //bottom - right;
@@ -425,7 +318,6 @@
* const Rect& clip = mSnapshot->getMappedClip();
* return !clip.intersects(r);
*/
-
Rect r(left, top, right, bottom);
return !mSnapshot->clipRect.intersects(r);
}
@@ -485,7 +377,7 @@
mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]);
- // TODO Correctly set the blend function
+ // TODO Correctly set the blend function, based on texture format and xfermode
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 527bf3e..1e031b8 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -23,11 +23,12 @@
#include <SkMatrix.h>
#include <SkXfermode.h>
-#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include "Matrix.h"
+#include "Program.h"
#include "Rect.h"
+#include "Snapshot.h"
namespace android {
namespace uirenderer {
@@ -36,122 +37,30 @@
// Support
///////////////////////////////////////////////////////////////////////////////
-class Snapshot: public LightRefBase<Snapshot> {
-public:
- Snapshot() {
- }
-
- Snapshot(const sp<Snapshot> s):
- transform(s->transform),
- clipRect(s->clipRect),
- flags(kFlagDirtyTransform),
- previous(s),
- layer(0.0f, 0.0f, 0.0f, 0.0f),
- texture(0),
- fbo(0),
- alpha(255) {
- }
-
- enum Flags {
- kFlagClipSet = 0x1,
- kFlagDirtyTransform = 0x2,
- kFlagIsLayer = 0x4,
- };
-
- const Rect& getMappedClip();
-
- // Local transformations
- mat4 transform;
-
- // Clipping rectangle at the time of this snapshot
- Rect clipRect;
-
- // Dirty flags
- int flags;
-
- // Previous snapshot in the frames stack
- sp<Snapshot> previous;
-
- // Layer, only set if kFlagIsLayer is set
- Rect layer;
- GLuint texture;
- GLuint fbo;
- float alpha;
-
-private:
- // Clipping rectangle mapped with the transform
- Rect mappedClip;
-}; // class Snapshot
-
+/**
+ * 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 {
float position[2];
float texture[2];
}; // struct TextureVertex
-class Program: public LightRefBase<Program> {
-public:
- Program(const char* vertex, const char* fragment);
- ~Program();
-
- void use();
-
-protected:
- int addAttrib(const char* name);
- int getAttrib(const char* name);
-
- int addUniform(const char* name);
- int getUniform(const char* name);
-
-private:
- GLuint buildShader(const char* source, GLenum type);
-
- // Handle of the OpenGL program
- GLuint id;
-
- // Handles of the shaders
- GLuint vertexShader;
- GLuint fragmentShader;
-
- // Keeps track of attributes and uniforms slots
- KeyedVector<const char*, int> attributes;
- KeyedVector<const char*, int> uniforms;
-}; // class Program
-
-class DrawColorProgram: public Program {
-public:
- DrawColorProgram();
- DrawColorProgram(const char* vertex, const char* fragment);
-
- void use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
- const GLfloat* transformMatrix);
-
- int position;
- int color;
-
- int projection;
- int modelView;
- int transform;
-
-protected:
- void getAttribsAndUniforms();
-};
-
-class DrawTextureProgram: public DrawColorProgram {
-public:
- DrawTextureProgram();
-
- int sampler;
- int texCoords;
-};
-
///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////
+/**
+ * OpenGL renderer used to draw accelerated 2D graphics. The API is a
+ * simplified version of Skia's Canvas API.
+ */
class OpenGLRenderer {
public:
OpenGLRenderer();
@@ -184,12 +93,52 @@
void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
private:
+ /**
+ * Saves the current state of the renderer as a new snapshot.
+ * The new snapshot is saved in mSnapshot and the previous snapshot
+ * is linked from mSnapshot->previous.
+ *
+ * @return The new save count. This value can be passed to #restoreToCount()
+ */
int saveSnapshot();
+
+ /**
+ * Restores the current snapshot; mSnapshot becomes mSnapshot->previous.
+ *
+ * @return True if the clip should be also reapplied by calling
+ * #setScissorFromClip().
+ */
bool restoreSnapshot();
+ /**
+ * Sets the clipping rectangle using glScissor. The clip is defined by
+ * the current snapshot's clipRect member.
+ */
void setScissorFromClip();
+ /**
+ * Draws a colored rectangle with the specified color. The specified coordinates
+ * are transformed by the current snapshot's transform matrix.
+ *
+ * @param left The left coordinate of the rectangle
+ * @param top The top coordinate of the rectangle
+ * @param right The right coordinate of the rectangle
+ * @param bottom The bottom coordinate of the rectangle
+ * @param color The rectangle's ARGB color, defined as a packed 32 bits word
+ */
void drawColorRect(float left, float top, float right, float bottom, int color);
+
+ /**
+ * Draws a textured rectangle with the specified texture. The specified coordinates
+ * are transformed by the current snapshot's transform matrix.
+ *
+ * @param left The left coordinate of the rectangle
+ * @param top The top coordinate of the rectangle
+ * @param right The right coordinate of the rectangle
+ * @param bottom The bottom coordinate of the rectangle
+ * @param texture The texture name to map onto the rectangle
+ * @param alpha An additional translucency parameter, between 0.0f and 1.0f
+ */
void drawTextureRect(float left, float top, float right, float bottom, GLuint texture,
float alpha);
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
new file mode 100644
index 0000000..2acddfc
--- /dev/null
+++ b/libs/hwui/Program.cpp
@@ -0,0 +1,154 @@
+/*
+ * 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 "Program.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Shaders
+///////////////////////////////////////////////////////////////////////////////
+
+#define SHADER_SOURCE(name, source) const char* name = #source
+
+#include "shaders/drawColor.vert"
+#include "shaders/drawColor.frag"
+
+#include "shaders/drawTexture.vert"
+#include "shaders/drawTexture.frag"
+
+///////////////////////////////////////////////////////////////////////////////
+// Base program
+///////////////////////////////////////////////////////////////////////////////
+
+Program::Program(const char* vertex, const char* fragment) {
+ vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
+ fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
+
+ id = glCreateProgram();
+ glAttachShader(id, vertexShader);
+ glAttachShader(id, fragmentShader);
+ glLinkProgram(id);
+
+ GLint status;
+ glGetProgramiv(id, GL_LINK_STATUS, &status);
+ if (status != GL_TRUE) {
+ GLint infoLen = 0;
+ glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen > 1) {
+ char* log = (char*) malloc(sizeof(char) * infoLen);
+ glGetProgramInfoLog(id, infoLen, 0, log);
+ LOGE("Error while linking shaders: %s", log);
+ delete log;
+ }
+ glDeleteProgram(id);
+ }
+}
+
+Program::~Program() {
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ glDeleteProgram(id);
+}
+
+void Program::use() {
+ glUseProgram(id);
+}
+
+int Program::addAttrib(const char* name) {
+ int slot = glGetAttribLocation(id, name);
+ attributes.add(name, slot);
+ return slot;
+}
+
+int Program::getAttrib(const char* name) {
+ return attributes.valueFor(name);
+}
+
+int Program::addUniform(const char* name) {
+ int slot = glGetUniformLocation(id, name);
+ uniforms.add(name, slot);
+ return slot;
+}
+
+int Program::getUniform(const char* name) {
+ return uniforms.valueFor(name);
+}
+
+GLuint Program::buildShader(const char* source, GLenum type) {
+ GLuint shader = glCreateShader(type);
+ glShaderSource(shader, 1, &source, 0);
+ glCompileShader(shader);
+
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if (status != GL_TRUE) {
+ // Some drivers return wrong values for GL_INFO_LOG_LENGTH
+ // use a fixed size instead
+ GLchar log[512];
+ glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]);
+ LOGE("Error while compiling shader: %s", log);
+ glDeleteShader(shader);
+ }
+
+ return shader;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Draw color
+///////////////////////////////////////////////////////////////////////////////
+
+DrawColorProgram::DrawColorProgram():
+ Program(gDrawColorVertexShader, gDrawColorFragmentShader) {
+ getAttribsAndUniforms();
+}
+
+DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment):
+ Program(vertex, fragment) {
+ getAttribsAndUniforms();
+}
+
+void DrawColorProgram::getAttribsAndUniforms() {
+ position = addAttrib("position");
+ color = addAttrib("color");
+ projection = addUniform("projection");
+ modelView = addUniform("modelView");
+ transform = addUniform("transform");
+}
+
+void DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
+ const GLfloat* transformMatrix) {
+ Program::use();
+ glUniformMatrix4fv(projection, 1, GL_FALSE, projectionMatrix);
+ glUniformMatrix4fv(modelView, 1, GL_FALSE, modelViewMatrix);
+ glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Draw texture
+///////////////////////////////////////////////////////////////////////////////
+
+DrawTextureProgram::DrawTextureProgram():
+ DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) {
+ texCoords = addAttrib("texCoords");
+ sampler = addUniform("sampler");
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
new file mode 100644
index 0000000..ee16a92
--- /dev/null
+++ b/libs/hwui/Program.h
@@ -0,0 +1,156 @@
+/*
+ * 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_H
+#define ANDROID_UI_PROGRAM_H
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * A program holds a vertex and a fragment shader. It offers several utility
+ * methods to query attributes and uniforms.
+ */
+class Program: public LightRefBase<Program> {
+public:
+ /**
+ * Creates a new program with the specified vertex and fragment
+ * shaders sources.
+ */
+ Program(const char* vertex, const char* fragment);
+ ~Program();
+
+ /**
+ * Binds this program to the GL context.
+ */
+ void use();
+
+protected:
+ /**
+ * Adds an attribute with the specified name.
+ *
+ * @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.
+ *
+ * @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:
+ /**
+ * Compiles the specified shader of the specified type.
+ *
+ * @return The name of the compiled shader.
+ */
+ GLuint buildShader(const char* source, GLenum type);
+
+ // Name of the OpenGL program
+ GLuint id;
+
+ // Name of the shaders
+ GLuint vertexShader;
+ GLuint fragmentShader;
+
+ // Keeps track of attributes and uniforms slots
+ KeyedVector<const char*, int> attributes;
+ KeyedVector<const char*, int> uniforms;
+}; // class Program
+
+/**
+ * Program used to draw vertices with a simple color. The shaders must
+ * specify the following attributes:
+ * vec4 position, position of the vertex
+ * vec4 color, RGBA color of the vertex
+ *
+ * And the following uniforms:
+ * mat4 projection, the projection matrix
+ * mat4 modelView, the modelView matrix
+ * mat4 transform, an extra transformation matrix
+ */
+class DrawColorProgram: public Program {
+public:
+ DrawColorProgram();
+ DrawColorProgram(const char* vertex, const char* fragment);
+
+ /**
+ * Binds the program with the specified projection, modelView and
+ * transform matrices.
+ */
+ void use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
+ const GLfloat* transformMatrix);
+
+ /**
+ * Name of the position attribute.
+ */
+ int position;
+ /**
+ * Name of the color attribute.
+ */
+ int color;
+
+ /**
+ * Name of the projection uniform.
+ */
+ int projection;
+ /**
+ * Name of the modelView uniform.
+ */
+ int modelView;
+ /**
+ * Name of the transform uniform.
+ */
+ int transform;
+
+protected:
+ void getAttribsAndUniforms();
+};
+
+/**
+ * Program used to draw textured vertices. In addition to everything that the
+ * DrawColorProgram supports, the following two attributes must be specified:
+ * sampler2D sampler, the texture sampler
+ * vec2 texCoords, the texture coordinates of the vertex
+ */
+class DrawTextureProgram: public DrawColorProgram {
+public:
+ DrawTextureProgram();
+
+ int sampler;
+ int texCoords;
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_PROGRAM_H
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index b382dc3..ad57550 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_UI_RECT_H
#define ANDROID_UI_RECT_H
+#include <utils/Log.h>
+
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
new file mode 100644
index 0000000..9a9be2d
--- /dev/null
+++ b/libs/hwui/Snapshot.h
@@ -0,0 +1,145 @@
+/*
+ * 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_SNAPSHOT_H
+#define ANDROID_UI_SNAPSHOT_H
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <utils/RefBase.h>
+
+#include "Matrix.h"
+#include "Rect.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * A snapshot holds information about the current state of the rendering
+ * surface. A snapshot is usually created whenever the user calls save()
+ * and discarded when the user calls restore(). Once a snapshot is created,
+ * it can hold information for deferred rendering.
+ *
+ * Each snapshot has a link to a previous snapshot, indicating the previous
+ * state of the renderer.
+ */
+class Snapshot: public LightRefBase<Snapshot> {
+public:
+ Snapshot() {
+ }
+
+ /**
+ * Copies the specified snapshot. Only the transform and clip rectangle
+ * are copied. The layer information is set to 0 and the transform is
+ * assumed to be dirty. The specified snapshot is stored as the previous
+ * snapshot.
+ */
+ Snapshot(const sp<Snapshot> s):
+ transform(s->transform),
+ clipRect(s->clipRect),
+ flags(kFlagDirtyTransform),
+ previous(s),
+ layer(0.0f, 0.0f, 0.0f, 0.0f),
+ texture(0),
+ fbo(0),
+ alpha(255) {
+ }
+
+ /**
+ * Various flags set on #flags.
+ */
+ enum Flags {
+ /**
+ * Indicates that the clip region was modified. When this
+ * snapshot is restored so must the clip.
+ */
+ kFlagClipSet = 0x1,
+ /**
+ * Indicates that the snapshot holds new transform
+ * information.
+ */
+ kFlagDirtyTransform = 0x2,
+ /**
+ * Indicates that this snapshot was created when saving
+ * a new layer.
+ */
+ kFlagIsLayer = 0x4,
+ };
+
+ /**
+ * Returns the current clip region mapped by the current transform.
+ */
+ const Rect& getMappedClip() {
+ if (flags & kFlagDirtyTransform) {
+ flags &= ~kFlagDirtyTransform;
+ mappedClip.set(clipRect);
+ transform.mapRect(mappedClip);
+ }
+ return mappedClip;
+ }
+
+ /**
+ * Local transformation. Holds the current translation, scale and
+ * rotation values.
+ */
+ mat4 transform;
+
+ /**
+ * Current clip region.
+ */
+ Rect clipRect;
+
+ /**
+ * Dirty flags.
+ */
+ int flags;
+
+ /**
+ * Previous snapshot.
+ */
+ sp<Snapshot> previous;
+
+ /**
+ * Coordinates of the layer corresponding to this snapshot.
+ * Only set when the flag kFlagIsLayer is set.
+ */
+ Rect layer;
+ /**
+ * Name of the texture used to render the layer.
+ * Only set when the flag kFlagIsLayer is set.
+ */
+ GLuint texture;
+ /**
+ * Name of the FBO used to render the layer.
+ * Only set when the flag kFlagIsLayer is set.
+ */
+ GLuint fbo;
+ /**
+ * Opacity of the layer.
+ * Only set when the flag kFlagIsLayer is set.
+ */
+ float alpha;
+
+private:
+ // Clipping rectangle mapped with the transform
+ Rect mappedClip;
+}; // class Snapshot
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_SNAPSHOT_H