summaryrefslogtreecommitdiffstats
path: root/libs/hwui/OpenGLRenderer.cpp
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2010-06-24 19:30:36 -0700
committerRomain Guy <romainguy@google.com>2010-06-24 19:30:36 -0700
commit9d5316e3f56d138504565ff311145ac01621dff4 (patch)
tree40c79ba098de4624fbe38cb400c6ac4fe7340673 /libs/hwui/OpenGLRenderer.cpp
parenta18dbdf420fabebb83e7403d000384a8d98daffa (diff)
downloadframeworks_base-9d5316e3f56d138504565ff311145ac01621dff4.zip
frameworks_base-9d5316e3f56d138504565ff311145ac01621dff4.tar.gz
frameworks_base-9d5316e3f56d138504565ff311145ac01621dff4.tar.bz2
Add colored rectangles implementation in OpenGLRenderer.
Drawing two rectangles one after the other discards the second one because of Z buffering issues. This will be fixed in another changelist. Change-Id: Ida1b3cde8a78e60cacc07e477abc44def527ff67
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
-rw-r--r--libs/hwui/OpenGLRenderer.cpp177
1 files changed, 172 insertions, 5 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index e19795e..575bc20 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
#include <utils/Log.h>
#include <GLES2/gl2.h>
@@ -32,6 +33,129 @@
#include "Matrix.h"
namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+#define SOLID_WHITE { 1.0f, 1.0f, 1.0f, 1.0f }
+
+#define P(x, y) { x, y }
+
+///////////////////////////////////////////////////////////////////////////////
+// Globals
+///////////////////////////////////////////////////////////////////////////////
+
+const Vertex gDrawColorVertices[] = {
+ { P(0.0f, 0.0f), SOLID_WHITE },
+ { P(1.0f, 0.0f), SOLID_WHITE },
+ { P(0.0f, 1.0f), SOLID_WHITE },
+ { P(1.0f, 1.0f), SOLID_WHITE }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Shaders
+///////////////////////////////////////////////////////////////////////////////
+
+#define SHADER_SOURCE(name, source) const char* name = #source
+
+#include "shaders/drawColor.vert"
+#include "shaders/drawColor.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) {
+ position = addAttrib("position");
+ color = addAttrib("color");
+ projection = addUniform("projection");
+ modelView = addUniform("modelView");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Support
+///////////////////////////////////////////////////////////////////////////////
+
+const Rect& Snapshot::getMappedClip() {
+ if (flags & kFlagDirtyTransform) {
+ flags &= ~kFlagDirtyTransform;
+ mappedClip.set(clipRect);
+ transform.mapRect(mappedClip);
+ }
+ return mappedClip;
+}
///////////////////////////////////////////////////////////////////////////////
// Constructors/destructor
@@ -39,6 +163,8 @@ namespace android {
OpenGLRenderer::OpenGLRenderer() {
LOGD("Create OpenGLRenderer");
+
+ mDrawColorShader = new DrawColorProgram;
}
OpenGLRenderer::~OpenGLRenderer() {
@@ -114,7 +240,6 @@ int OpenGLRenderer::saveSnapshot() {
}
bool OpenGLRenderer::restoreSnapshot() {
- // TODO: handle local transformations
bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet;
mSaveCount--;
@@ -132,18 +257,22 @@ bool OpenGLRenderer::restoreSnapshot() {
void OpenGLRenderer::translate(float dx, float dy) {
mSnapshot->transform.translate(dx, dy, 0.0f);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::rotate(float degrees) {
mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::scale(float sx, float sy) {
mSnapshot->transform.scale(sx, sy, 1.0f);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
mSnapshot->transform.load(*matrix);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
@@ -153,6 +282,7 @@ void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
mat4 m(*matrix);
mSnapshot->transform.multiply(m);
+ mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
}
///////////////////////////////////////////////////////////////////////////////
@@ -160,12 +290,15 @@ void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::setScissorFromClip() {
- Rect* clip = &(mSnapshot->clipRect);
- glScissor(clip->left, clip->top, clip->getWidth(), clip->getHeight());
+ const Rect& clip = mSnapshot->getMappedClip();
+ glScissor(clip.left, clip.top, clip.getWidth(), clip.getHeight());
+}
+
+const Rect& OpenGLRenderer::getClipBounds() {
+ return mSnapshot->clipRect;
}
bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) {
- // TODO: take local translate transform into account
bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom);
if (clipped) {
mSnapshot->flags |= Snapshot::kFlagClipSet;
@@ -179,7 +312,41 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom)
///////////////////////////////////////////////////////////////////////////////
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
- LOGD("Drawing color");
+ GLfloat a = ((color >> 24) & 0xFF) / 255.0f;
+ GLfloat r = ((color >> 16) & 0xFF) / 255.0f;
+ GLfloat g = ((color >> 8) & 0xFF) / 255.0f;
+ GLfloat b = ((color ) & 0xFF) / 255.0f;
+
+ // TODO Optimize this section
+ const Rect& clip = mSnapshot->getMappedClip();
+
+ mat4 modelView;
+ modelView.loadScale(clip.getWidth(), clip.getHeight(), 1.0f);
+ modelView.translate(clip.left, clip.top, 0.0f);
+
+ float matrix[16];
+ modelView.copyTo(matrix);
+ // TODO Optimize this section
+
+ mDrawColorShader->use();
+
+ glUniformMatrix4fv(mDrawColorShader->projection, 1, GL_FALSE, &mOrthoMatrix[0]);
+ glUniformMatrix4fv(mDrawColorShader->modelView, 1, GL_FALSE, &matrix[0]);
+
+ glEnableVertexAttribArray(mDrawColorShader->position);
+
+ GLsizei stride = sizeof(Vertex);
+ const GLvoid* p = &gDrawColorVertices[0].position[0];
+
+ glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE, stride, p);
+ glVertexAttrib4f(mDrawColorShader->color, r, g, b, a);
+
+ GLsizei vertexCount = sizeof(gDrawColorVertices) / sizeof(Vertex);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount);
+
+ glDisableVertexAttribArray(mDrawColorShader->position);
+ glDisableVertexAttribArray(mDrawColorShader->color);
}
+}; // namespace uirenderer
}; // namespace android