Loading core/java/android/view/GLES20Canvas.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -186,10 +186,11 @@ class GLES20Canvas extends Canvas { @Override @Override public boolean getClipBounds(Rect bounds) { public boolean getClipBounds(Rect bounds) { // TODO: Implement return nGetClipBounds(mRenderer, bounds); return false; } } private native boolean nGetClipBounds(int renderer, Rect bounds); @Override @Override public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) { public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) { // TODO: Implement // TODO: Implement Loading core/jni/android_view_GLES20Canvas.cpp +39 −0 Original line number Original line Diff line number Diff line Loading @@ -22,9 +22,22 @@ #include <SkXfermode.h> #include <SkXfermode.h> #include <OpenGLRenderer.h> #include <OpenGLRenderer.h> #include <Rect.h> #include <ui/Rect.h> namespace android { namespace android { using namespace uirenderer; // ---------------------------------------------------------------------------- // Java APIs // ---------------------------------------------------------------------------- static struct { jclass clazz; jmethodID set; } gRectClassInfo; // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Constructors // Constructors // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -90,6 +103,17 @@ static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas, return renderer->clipRect(float(left), float(top), float(right), float(bottom)); return renderer->clipRect(float(left), float(top), float(right), float(bottom)); } } static bool android_view_GLES20Renderer_getClipBounds(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jobject rect) { const android::uirenderer::Rect& bounds(renderer->getClipBounds()); env->CallVoidMethod(rect, gRectClassInfo.set, int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); return !bounds.isEmpty(); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Transforms // Transforms // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -153,6 +177,9 @@ static JNINativeMethod gMethods[] = { { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF }, { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF }, { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect }, { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect }, { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z", (void*) android_view_GLES20Renderer_getClipBounds }, { "nTranslate", "(IFF)V", (void*) android_view_GLES20Renderer_translate }, { "nTranslate", "(IFF)V", (void*) android_view_GLES20Renderer_translate }, { "nRotate", "(IF)V", (void*) android_view_GLES20Renderer_rotate }, { "nRotate", "(IF)V", (void*) android_view_GLES20Renderer_rotate }, { "nScale", "(IFF)V", (void*) android_view_GLES20Renderer_scale }, { "nScale", "(IFF)V", (void*) android_view_GLES20Renderer_scale }, Loading @@ -164,7 +191,19 @@ static JNINativeMethod gMethods[] = { { "nDrawColor", "(III)V", (void*) android_view_GLES20Renderer_drawColor }, { "nDrawColor", "(III)V", (void*) android_view_GLES20Renderer_drawColor }, }; }; #define FIND_CLASS(var, className) \ var = env->FindClass(className); \ LOG_FATAL_IF(! var, "Unable to find class " className); \ var = jclass(env->NewGlobalRef(var)); #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ var = env->GetMethodID(clazz, methodName, methodDescriptor); \ LOG_FATAL_IF(! var, "Unable to find method " methodName); int register_android_view_GLES20Canvas(JNIEnv* env) { int register_android_view_GLES20Canvas(JNIEnv* env) { FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect"); GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V"); return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); } } Loading libs/hwui/Matrix.cpp +19 −2 Original line number Original line Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. * limitations under the License. */ */ #define LOG_TAG "UIMatrix" #define LOG_TAG "Matrix" #include <math.h> #include <math.h> #include <stdlib.h> #include <stdlib.h> Loading @@ -27,6 +27,7 @@ #include "Matrix.h" #include "Matrix.h" namespace android { namespace android { namespace uirenderer { void Matrix4::loadIdentity() { void Matrix4::loadIdentity() { mMat[0] = 1.0f; mMat[0] = 1.0f; Loading Loading @@ -175,6 +176,21 @@ void Matrix4::loadOrtho(float left, float right, float bottom, float top, float mMat[14] = -(far + near) / (far - near); mMat[14] = -(far + near) / (far - near); } } #define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c) void Matrix4::mapRect(Rect& r) const { const float sx = mMat[0]; const float sy = mMat[5]; const float tx = mMat[12]; const float ty = mMat[13]; MUL_ADD_STORE(r.left, sx, tx); MUL_ADD_STORE(r.right, sx, tx); MUL_ADD_STORE(r.top, sy, ty); MUL_ADD_STORE(r.bottom, sy, ty); } void Matrix4::dump() const { void Matrix4::dump() const { LOGD("Matrix4["); LOGD("Matrix4["); LOGD(" %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]); LOGD(" %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]); Loading @@ -184,4 +200,5 @@ void Matrix4::dump() const { LOGD("]"); LOGD("]"); } } }; }; // namespace uirenderer }; // namespace android libs/hwui/Matrix.h +9 −3 Original line number Original line Diff line number Diff line Loading @@ -14,12 +14,15 @@ * limitations under the License. * limitations under the License. */ */ #ifndef ANDROID_MATRIX_H #ifndef ANDROID_UI_MATRIX_H #define ANDROID_MATRIX_H #define ANDROID_UI_MATRIX_H #include <SkMatrix.h> #include <SkMatrix.h> #include "Rect.h" namespace android { namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Classes // Classes Loading Loading @@ -83,6 +86,8 @@ public: void copyTo(float* v) const; void copyTo(float* v) const; void copyTo(SkMatrix& v) const; void copyTo(SkMatrix& v) const; void mapRect(Rect& r) const; void dump() const; void dump() const; private: private: Loading @@ -103,6 +108,7 @@ private: typedef Matrix4 mat4; typedef Matrix4 mat4; }; // namespace uirenderer }; // namespace android }; // namespace android #endif // ANDROID_MATRIX_H #endif // ANDROID_UI_MATRIX_H libs/hwui/OpenGLRenderer.cpp +172 −5 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <sys/types.h> #include <sys/types.h> #include <utils/Errors.h> #include <utils/Errors.h> #include <utils/KeyedVector.h> #include <utils/Log.h> #include <utils/Log.h> #include <GLES2/gl2.h> #include <GLES2/gl2.h> Loading @@ -32,6 +33,129 @@ #include "Matrix.h" #include "Matrix.h" namespace android { 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 // Constructors/destructor Loading @@ -39,6 +163,8 @@ namespace android { OpenGLRenderer::OpenGLRenderer() { OpenGLRenderer::OpenGLRenderer() { LOGD("Create OpenGLRenderer"); LOGD("Create OpenGLRenderer"); mDrawColorShader = new DrawColorProgram; } } OpenGLRenderer::~OpenGLRenderer() { OpenGLRenderer::~OpenGLRenderer() { Loading Loading @@ -114,7 +240,6 @@ int OpenGLRenderer::saveSnapshot() { } } bool OpenGLRenderer::restoreSnapshot() { bool OpenGLRenderer::restoreSnapshot() { // TODO: handle local transformations bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; mSaveCount--; mSaveCount--; Loading @@ -132,18 +257,22 @@ bool OpenGLRenderer::restoreSnapshot() { void OpenGLRenderer::translate(float dx, float dy) { void OpenGLRenderer::translate(float dx, float dy) { mSnapshot->transform.translate(dx, dy, 0.0f); mSnapshot->transform.translate(dx, dy, 0.0f); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } void OpenGLRenderer::rotate(float degrees) { void OpenGLRenderer::rotate(float degrees) { mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f); mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } void OpenGLRenderer::scale(float sx, float sy) { void OpenGLRenderer::scale(float sx, float sy) { mSnapshot->transform.scale(sx, sy, 1.0f); mSnapshot->transform.scale(sx, sy, 1.0f); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } void OpenGLRenderer::setMatrix(SkMatrix* matrix) { void OpenGLRenderer::setMatrix(SkMatrix* matrix) { mSnapshot->transform.load(*matrix); mSnapshot->transform.load(*matrix); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } void OpenGLRenderer::getMatrix(SkMatrix* matrix) { void OpenGLRenderer::getMatrix(SkMatrix* matrix) { Loading @@ -153,6 +282,7 @@ void OpenGLRenderer::getMatrix(SkMatrix* matrix) { void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { mat4 m(*matrix); mat4 m(*matrix); mSnapshot->transform.multiply(m); mSnapshot->transform.multiply(m); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// Loading @@ -160,12 +290,15 @@ void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::setScissorFromClip() { void OpenGLRenderer::setScissorFromClip() { Rect* clip = &(mSnapshot->clipRect); const Rect& clip = mSnapshot->getMappedClip(); glScissor(clip->left, clip->top, clip->getWidth(), clip->getHeight()); 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) { 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); bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom); if (clipped) { if (clipped) { mSnapshot->flags |= Snapshot::kFlagClipSet; mSnapshot->flags |= Snapshot::kFlagClipSet; Loading @@ -179,7 +312,41 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { 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 }; // namespace android Loading
core/java/android/view/GLES20Canvas.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -186,10 +186,11 @@ class GLES20Canvas extends Canvas { @Override @Override public boolean getClipBounds(Rect bounds) { public boolean getClipBounds(Rect bounds) { // TODO: Implement return nGetClipBounds(mRenderer, bounds); return false; } } private native boolean nGetClipBounds(int renderer, Rect bounds); @Override @Override public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) { public boolean quickReject(float left, float top, float right, float bottom, EdgeType type) { // TODO: Implement // TODO: Implement Loading
core/jni/android_view_GLES20Canvas.cpp +39 −0 Original line number Original line Diff line number Diff line Loading @@ -22,9 +22,22 @@ #include <SkXfermode.h> #include <SkXfermode.h> #include <OpenGLRenderer.h> #include <OpenGLRenderer.h> #include <Rect.h> #include <ui/Rect.h> namespace android { namespace android { using namespace uirenderer; // ---------------------------------------------------------------------------- // Java APIs // ---------------------------------------------------------------------------- static struct { jclass clazz; jmethodID set; } gRectClassInfo; // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Constructors // Constructors // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -90,6 +103,17 @@ static bool android_view_GLES20Renderer_clipRect(JNIEnv* env, jobject canvas, return renderer->clipRect(float(left), float(top), float(right), float(bottom)); return renderer->clipRect(float(left), float(top), float(right), float(bottom)); } } static bool android_view_GLES20Renderer_getClipBounds(JNIEnv* env, jobject canvas, OpenGLRenderer* renderer, jobject rect) { const android::uirenderer::Rect& bounds(renderer->getClipBounds()); env->CallVoidMethod(rect, gRectClassInfo.set, int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom)); return !bounds.isEmpty(); } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Transforms // Transforms // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- Loading Loading @@ -153,6 +177,9 @@ static JNINativeMethod gMethods[] = { { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF }, { "nClipRect", "(IFFFF)Z", (void*) android_view_GLES20Renderer_clipRectF }, { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect }, { "nClipRect", "(IIIII)Z", (void*) android_view_GLES20Renderer_clipRect }, { "nGetClipBounds", "(ILandroid/graphics/Rect;)Z", (void*) android_view_GLES20Renderer_getClipBounds }, { "nTranslate", "(IFF)V", (void*) android_view_GLES20Renderer_translate }, { "nTranslate", "(IFF)V", (void*) android_view_GLES20Renderer_translate }, { "nRotate", "(IF)V", (void*) android_view_GLES20Renderer_rotate }, { "nRotate", "(IF)V", (void*) android_view_GLES20Renderer_rotate }, { "nScale", "(IFF)V", (void*) android_view_GLES20Renderer_scale }, { "nScale", "(IFF)V", (void*) android_view_GLES20Renderer_scale }, Loading @@ -164,7 +191,19 @@ static JNINativeMethod gMethods[] = { { "nDrawColor", "(III)V", (void*) android_view_GLES20Renderer_drawColor }, { "nDrawColor", "(III)V", (void*) android_view_GLES20Renderer_drawColor }, }; }; #define FIND_CLASS(var, className) \ var = env->FindClass(className); \ LOG_FATAL_IF(! var, "Unable to find class " className); \ var = jclass(env->NewGlobalRef(var)); #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ var = env->GetMethodID(clazz, methodName, methodDescriptor); \ LOG_FATAL_IF(! var, "Unable to find method " methodName); int register_android_view_GLES20Canvas(JNIEnv* env) { int register_android_view_GLES20Canvas(JNIEnv* env) { FIND_CLASS(gRectClassInfo.clazz, "android/graphics/Rect"); GET_METHOD_ID(gRectClassInfo.set, gRectClassInfo.clazz, "set", "(IIII)V"); return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods)); } } Loading
libs/hwui/Matrix.cpp +19 −2 Original line number Original line Diff line number Diff line Loading @@ -14,7 +14,7 @@ * limitations under the License. * limitations under the License. */ */ #define LOG_TAG "UIMatrix" #define LOG_TAG "Matrix" #include <math.h> #include <math.h> #include <stdlib.h> #include <stdlib.h> Loading @@ -27,6 +27,7 @@ #include "Matrix.h" #include "Matrix.h" namespace android { namespace android { namespace uirenderer { void Matrix4::loadIdentity() { void Matrix4::loadIdentity() { mMat[0] = 1.0f; mMat[0] = 1.0f; Loading Loading @@ -175,6 +176,21 @@ void Matrix4::loadOrtho(float left, float right, float bottom, float top, float mMat[14] = -(far + near) / (far - near); mMat[14] = -(far + near) / (far - near); } } #define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c) void Matrix4::mapRect(Rect& r) const { const float sx = mMat[0]; const float sy = mMat[5]; const float tx = mMat[12]; const float ty = mMat[13]; MUL_ADD_STORE(r.left, sx, tx); MUL_ADD_STORE(r.right, sx, tx); MUL_ADD_STORE(r.top, sy, ty); MUL_ADD_STORE(r.bottom, sy, ty); } void Matrix4::dump() const { void Matrix4::dump() const { LOGD("Matrix4["); LOGD("Matrix4["); LOGD(" %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]); LOGD(" %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]); Loading @@ -184,4 +200,5 @@ void Matrix4::dump() const { LOGD("]"); LOGD("]"); } } }; }; // namespace uirenderer }; // namespace android
libs/hwui/Matrix.h +9 −3 Original line number Original line Diff line number Diff line Loading @@ -14,12 +14,15 @@ * limitations under the License. * limitations under the License. */ */ #ifndef ANDROID_MATRIX_H #ifndef ANDROID_UI_MATRIX_H #define ANDROID_MATRIX_H #define ANDROID_UI_MATRIX_H #include <SkMatrix.h> #include <SkMatrix.h> #include "Rect.h" namespace android { namespace android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Classes // Classes Loading Loading @@ -83,6 +86,8 @@ public: void copyTo(float* v) const; void copyTo(float* v) const; void copyTo(SkMatrix& v) const; void copyTo(SkMatrix& v) const; void mapRect(Rect& r) const; void dump() const; void dump() const; private: private: Loading @@ -103,6 +108,7 @@ private: typedef Matrix4 mat4; typedef Matrix4 mat4; }; // namespace uirenderer }; // namespace android }; // namespace android #endif // ANDROID_MATRIX_H #endif // ANDROID_UI_MATRIX_H
libs/hwui/OpenGLRenderer.cpp +172 −5 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <sys/types.h> #include <sys/types.h> #include <utils/Errors.h> #include <utils/Errors.h> #include <utils/KeyedVector.h> #include <utils/Log.h> #include <utils/Log.h> #include <GLES2/gl2.h> #include <GLES2/gl2.h> Loading @@ -32,6 +33,129 @@ #include "Matrix.h" #include "Matrix.h" namespace android { 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 // Constructors/destructor Loading @@ -39,6 +163,8 @@ namespace android { OpenGLRenderer::OpenGLRenderer() { OpenGLRenderer::OpenGLRenderer() { LOGD("Create OpenGLRenderer"); LOGD("Create OpenGLRenderer"); mDrawColorShader = new DrawColorProgram; } } OpenGLRenderer::~OpenGLRenderer() { OpenGLRenderer::~OpenGLRenderer() { Loading Loading @@ -114,7 +240,6 @@ int OpenGLRenderer::saveSnapshot() { } } bool OpenGLRenderer::restoreSnapshot() { bool OpenGLRenderer::restoreSnapshot() { // TODO: handle local transformations bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; mSaveCount--; mSaveCount--; Loading @@ -132,18 +257,22 @@ bool OpenGLRenderer::restoreSnapshot() { void OpenGLRenderer::translate(float dx, float dy) { void OpenGLRenderer::translate(float dx, float dy) { mSnapshot->transform.translate(dx, dy, 0.0f); mSnapshot->transform.translate(dx, dy, 0.0f); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } void OpenGLRenderer::rotate(float degrees) { void OpenGLRenderer::rotate(float degrees) { mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f); mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } void OpenGLRenderer::scale(float sx, float sy) { void OpenGLRenderer::scale(float sx, float sy) { mSnapshot->transform.scale(sx, sy, 1.0f); mSnapshot->transform.scale(sx, sy, 1.0f); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } void OpenGLRenderer::setMatrix(SkMatrix* matrix) { void OpenGLRenderer::setMatrix(SkMatrix* matrix) { mSnapshot->transform.load(*matrix); mSnapshot->transform.load(*matrix); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } void OpenGLRenderer::getMatrix(SkMatrix* matrix) { void OpenGLRenderer::getMatrix(SkMatrix* matrix) { Loading @@ -153,6 +282,7 @@ void OpenGLRenderer::getMatrix(SkMatrix* matrix) { void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { mat4 m(*matrix); mat4 m(*matrix); mSnapshot->transform.multiply(m); mSnapshot->transform.multiply(m); mSnapshot->flags |= Snapshot::kFlagDirtyTransform; } } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// Loading @@ -160,12 +290,15 @@ void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::setScissorFromClip() { void OpenGLRenderer::setScissorFromClip() { Rect* clip = &(mSnapshot->clipRect); const Rect& clip = mSnapshot->getMappedClip(); glScissor(clip->left, clip->top, clip->getWidth(), clip->getHeight()); 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) { 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); bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom); if (clipped) { if (clipped) { mSnapshot->flags |= Snapshot::kFlagClipSet; mSnapshot->flags |= Snapshot::kFlagClipSet; Loading @@ -179,7 +312,41 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { 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 }; // namespace android