diff options
author | Romain Guy <romainguy@google.com> | 2010-06-24 19:30:36 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2010-06-24 19:30:36 -0700 |
commit | 9d5316e3f56d138504565ff311145ac01621dff4 (patch) | |
tree | 40c79ba098de4624fbe38cb400c6ac4fe7340673 /libs/hwui/OpenGLRenderer.cpp | |
parent | a18dbdf420fabebb83e7403d000384a8d98daffa (diff) | |
download | frameworks_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.cpp | 177 |
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 |