diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/Matrix.cpp | 158 | ||||
| -rw-r--r-- | libs/hwui/Matrix.h | 8 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 99 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 16 | ||||
| -rw-r--r-- | libs/hwui/shaders/drawColor.vert | 3 |
5 files changed, 161 insertions, 123 deletions
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp index c097d7f..59b7fef 100644 --- a/libs/hwui/Matrix.cpp +++ b/libs/hwui/Matrix.cpp @@ -30,95 +30,95 @@ namespace android { namespace uirenderer { void Matrix4::loadIdentity() { - mMat[0] = 1.0f; - mMat[1] = 0.0f; - mMat[2] = 0.0f; - mMat[3] = 0.0f; - - mMat[4] = 0.0f; - mMat[5] = 1.0f; - mMat[6] = 0.0f; - mMat[7] = 0.0f; - - mMat[8] = 0.0f; - mMat[9] = 0.0f; - mMat[10] = 1.0f; - mMat[11] = 0.0f; - - mMat[12] = 0.0f; - mMat[13] = 0.0f; - mMat[14] = 0.0f; - mMat[15] = 1.0f; + data[0] = 1.0f; + data[1] = 0.0f; + data[2] = 0.0f; + data[3] = 0.0f; + + data[4] = 0.0f; + data[5] = 1.0f; + data[6] = 0.0f; + data[7] = 0.0f; + + data[8] = 0.0f; + data[9] = 0.0f; + data[10] = 1.0f; + data[11] = 0.0f; + + data[12] = 0.0f; + data[13] = 0.0f; + data[14] = 0.0f; + data[15] = 1.0f; } void Matrix4::load(const float* v) { - memcpy(mMat, v, sizeof(mMat)); + memcpy(data, v, sizeof(data)); } void Matrix4::load(const Matrix4& v) { - memcpy(mMat, v.mMat, sizeof(mMat)); + memcpy(data, v.data, sizeof(data)); } void Matrix4::load(const SkMatrix& v) { - memset(mMat, 0, sizeof(mMat)); + memset(data, 0, sizeof(data)); - mMat[0] = v[SkMatrix::kMScaleX]; - mMat[4] = v[SkMatrix::kMSkewX]; - mMat[12] = v[SkMatrix::kMTransX]; + data[0] = v[SkMatrix::kMScaleX]; + data[4] = v[SkMatrix::kMSkewX]; + data[12] = v[SkMatrix::kMTransX]; - mMat[1] = v[SkMatrix::kMSkewY]; - mMat[5] = v[SkMatrix::kMScaleY]; - mMat[13] = v[SkMatrix::kMTransY]; + data[1] = v[SkMatrix::kMSkewY]; + data[5] = v[SkMatrix::kMScaleY]; + data[13] = v[SkMatrix::kMTransY]; - mMat[3] = v[SkMatrix::kMPersp0]; - mMat[7] = v[SkMatrix::kMPersp1]; - mMat[15] = v[SkMatrix::kMPersp2]; + data[3] = v[SkMatrix::kMPersp0]; + data[7] = v[SkMatrix::kMPersp1]; + data[15] = v[SkMatrix::kMPersp2]; - mMat[10] = 1.0f; + data[10] = 1.0f; } void Matrix4::copyTo(SkMatrix& v) const { v.reset(); - v.set(SkMatrix::kMScaleX, mMat[0]); - v.set(SkMatrix::kMSkewX, mMat[4]); - v.set(SkMatrix::kMTransX, mMat[12]); + v.set(SkMatrix::kMScaleX, data[0]); + v.set(SkMatrix::kMSkewX, data[4]); + v.set(SkMatrix::kMTransX, data[12]); - v.set(SkMatrix::kMSkewY, mMat[1]); - v.set(SkMatrix::kMScaleY, mMat[5]); - v.set(SkMatrix::kMTransY, mMat[13]); + v.set(SkMatrix::kMSkewY, data[1]); + v.set(SkMatrix::kMScaleY, data[5]); + v.set(SkMatrix::kMTransY, data[13]); - v.set(SkMatrix::kMPersp0, mMat[3]); - v.set(SkMatrix::kMPersp1, mMat[7]); - v.set(SkMatrix::kMPersp2, mMat[15]); + v.set(SkMatrix::kMPersp0, data[3]); + v.set(SkMatrix::kMPersp1, data[7]); + v.set(SkMatrix::kMPersp2, data[15]); } void Matrix4::copyTo(float* v) const { - memcpy(v, mMat, sizeof(mMat)); + memcpy(v, data, sizeof(data)); } void Matrix4::loadTranslate(float x, float y, float z) { loadIdentity(); - mMat[12] = x; - mMat[13] = y; - mMat[14] = z; + data[12] = x; + data[13] = y; + data[14] = z; } void Matrix4::loadScale(float sx, float sy, float sz) { loadIdentity(); - mMat[0] = sx; - mMat[5] = sy; - mMat[10] = sz; + data[0] = sx; + data[5] = sy; + data[10] = sz; } void Matrix4::loadRotate(float angle, float x, float y, float z) { - mMat[3] = 0.0f; - mMat[7] = 0.0f; - mMat[11] = 0.0f; - mMat[12] = 0.0f; - mMat[13] = 0.0f; - mMat[14] = 0.0f; - mMat[15] = 1.0f; + data[3] = 0.0f; + data[7] = 0.0f; + data[11] = 0.0f; + data[12] = 0.0f; + data[13] = 0.0f; + data[14] = 0.0f; + data[15] = 1.0f; angle *= float(M_PI / 180.0f); float c = cosf(angle); @@ -133,15 +133,15 @@ void Matrix4::loadRotate(float angle, float x, float y, float z) { const float ys = y * s; const float zs = z * s; - mMat[0] = x * x * nc + c; - mMat[4] = xy * nc - zs; - mMat[8] = zx * nc + ys; - mMat[1] = xy * nc + zs; - mMat[5] = y * y * nc + c; - mMat[9] = yz * nc - xs; - mMat[2] = zx * nc - ys; - mMat[6] = yz * nc + xs; - mMat[10] = z * z * nc + c; + data[0] = x * x * nc + c; + data[4] = xy * nc - zs; + data[8] = zx * nc + ys; + data[1] = xy * nc + zs; + data[5] = y * y * nc + c; + data[9] = yz * nc - xs; + data[2] = zx * nc - ys; + data[6] = yz * nc + xs; + data[10] = z * z * nc + c; } void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) { @@ -152,7 +152,7 @@ void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) { float w = 0; for (int j = 0 ; j < 4 ; j++) { - const float e = v.get(i,j); + const float e = v.get(i, j); x += u.get(j, 0) * e; y += u.get(j, 1) * e; z += u.get(j, 2) * e; @@ -168,22 +168,22 @@ void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) { void Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) { loadIdentity(); - mMat[0] = 2.0f / (right - left); - mMat[5] = 2.0f / (top - bottom); - mMat[10] = -2.0f / (far - near); - mMat[12] = -(right + left) / (right - left); - mMat[13] = -(top + bottom) / (top - bottom); - mMat[14] = -(far + near) / (far - near); + data[0] = 2.0f / (right - left); + data[5] = 2.0f / (top - bottom); + data[10] = -2.0f / (far - near); + data[12] = -(right + left) / (right - left); + data[13] = -(top + bottom) / (top - bottom); + data[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 sx = data[0]; + const float sy = data[5]; - const float tx = mMat[12]; - const float ty = mMat[13]; + const float tx = data[12]; + const float ty = data[13]; MUL_ADD_STORE(r.left, sx, tx); MUL_ADD_STORE(r.right, sx, tx); @@ -193,10 +193,10 @@ void Matrix4::mapRect(Rect& r) const { void Matrix4::dump() const { LOGD("Matrix4["); - LOGD(" %f %f %f %f", mMat[0], mMat[4], mMat[ 8], mMat[12]); - LOGD(" %f %f %f %f", mMat[1], mMat[5], mMat[ 9], mMat[13]); - LOGD(" %f %f %f %f", mMat[2], mMat[6], mMat[10], mMat[14]); - LOGD(" %f %f %f %f", mMat[3], mMat[7], mMat[11], mMat[15]); + LOGD(" %f %f %f %f", data[0], data[4], data[ 8], data[12]); + LOGD(" %f %f %f %f", data[1], data[5], data[ 9], data[13]); + LOGD(" %f %f %f %f", data[2], data[6], data[10], data[14]); + LOGD(" %f %f %f %f", data[3], data[7], data[11], data[15]); LOGD("]"); } diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h index 9bd289f..8fa5e4d 100644 --- a/libs/hwui/Matrix.h +++ b/libs/hwui/Matrix.h @@ -30,6 +30,8 @@ namespace uirenderer { class Matrix4 { public: + float data[16]; + Matrix4() { loadIdentity(); } @@ -92,14 +94,12 @@ public: private: inline float get(int i, int j) const { - return mMat[i * 4 + j]; + return data[i * 4 + j]; } inline void set(int i, int j, float v) { - mMat[i * 4 + j] = v; + data[i * 4 + j] = v; } - - float mMat[16]; }; // class Matrix4 /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 575bc20..2ebd7cd 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -27,6 +27,7 @@ #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> +#include <SkPaint.h> #include <SkXfermode.h> #include "OpenGLRenderer.h" @@ -39,20 +40,20 @@ namespace uirenderer { // Defines /////////////////////////////////////////////////////////////////////////////// -#define SOLID_WHITE { 1.0f, 1.0f, 1.0f, 1.0f } - -#define P(x, y) { x, y } +#define V(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 } +const SimpleVertex gDrawColorVertices[] = { + V(0.0f, 0.0f), + V(1.0f, 0.0f), + V(0.0f, 1.0f), + V(1.0f, 1.0f) }; +const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex); +const GLsizei gDrawColorVertexCount = 4; /////////////////////////////////////////////////////////////////////////////// // Shaders @@ -142,6 +143,15 @@ DrawColorProgram::DrawColorProgram(): 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); } /////////////////////////////////////////////////////////////////////////////// @@ -179,7 +189,7 @@ void OpenGLRenderer::setViewport(int width, int height) { glViewport(0, 0, width, height); mat4 ortho; - ortho.loadOrtho(0, width, height, 0, 0, 1); + ortho.loadOrtho(0, width, height, 0, -1, 1); ortho.copyTo(mOrthoMatrix); mWidth = width; @@ -196,6 +206,7 @@ void OpenGLRenderer::prepare() { glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_SCISSOR_TEST); + glScissor(0, 0, mWidth, mHeight); mSnapshot->clipRect.set(0.0f, 0.0f, mWidth, mHeight); } @@ -291,13 +302,31 @@ void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { void OpenGLRenderer::setScissorFromClip() { const Rect& clip = mSnapshot->getMappedClip(); - glScissor(clip.left, clip.top, clip.getWidth(), clip.getHeight()); + glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight()); } const Rect& OpenGLRenderer::getClipBounds() { return mSnapshot->clipRect; } +bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { + /* + * The documentation of quickReject() indicates that the specified rect + * is transformed before being compared to the clip rect. However, the + * clip rect is not stored transformed in the snapshot and can thus be + * compared directly + * + * The following code can be used instead to performed a mapped comparison: + * + * mSnapshot->transform.mapRect(r); + * const Rect& clip = mSnapshot->getMappedClip(); + * return !clip.intersects(r); + */ + + Rect r(left, top, right, bottom); + return !mSnapshot->clipRect.intersects(r); +} + bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) { bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom); if (clipped) { @@ -312,40 +341,38 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { - 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); + // TODO: Set the transfer mode + const Rect& clip = mSnapshot->clipRect; + drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color); +} - float matrix[16]; - modelView.copyTo(matrix); - // TODO Optimize this section +void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* paint) { + // TODO Support more than just color + // TODO: Set the transfer mode + drawColorRect(left, top, right, bottom, paint->getColor()); +} - mDrawColorShader->use(); +void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, int 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; - glUniformMatrix4fv(mDrawColorShader->projection, 1, GL_FALSE, &mOrthoMatrix[0]); - glUniformMatrix4fv(mDrawColorShader->modelView, 1, GL_FALSE, &matrix[0]); + mModelView.loadTranslate(left, top, 0.0f); + mModelView.scale(right - left, bottom - top, 1.0f); - glEnableVertexAttribArray(mDrawColorShader->position); + mDrawColorShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); - GLsizei stride = sizeof(Vertex); - const GLvoid* p = &gDrawColorVertices[0].position[0]; + const GLvoid* p = &gDrawColorVertices[0].position[0]; - glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE, stride, p); - glVertexAttrib4f(mDrawColorShader->color, r, g, b, a); + glEnableVertexAttribArray(mDrawColorShader->position); + glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE, + gDrawColorVertexStride, p); + glVertexAttrib4f(mDrawColorShader->color, r, g, b, a); - GLsizei vertexCount = sizeof(gDrawColorVertices) / sizeof(Vertex); - glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount); + glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount); - glDisableVertexAttribArray(mDrawColorShader->position); - glDisableVertexAttribArray(mDrawColorShader->color); + glDisableVertexAttribArray(mDrawColorShader->position); } }; // namespace uirenderer diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 88cbc1c..bef4193 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -72,10 +72,9 @@ private: Rect mappedClip; }; // class Snapshot -struct Vertex { +struct SimpleVertex { float position[2]; - float color[4]; -}; // struct Vertex +}; // struct SimpleVertex typedef char* shader; @@ -112,11 +111,15 @@ class DrawColorProgram: public Program { public: DrawColorProgram(); + void use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix, + const GLfloat* transformMatrix); + int position; int color; int projection; int modelView; + int transform; }; /////////////////////////////////////////////////////////////////////////////// @@ -145,9 +148,11 @@ public: void concatMatrix(SkMatrix* matrix); const Rect& getClipBounds(); + bool quickReject(float left, float top, float right, float bottom); bool clipRect(float left, float top, float right, float bottom); void drawColor(int color, SkXfermode::Mode mode); + void drawRect(float left, float top, float right, float bottom, SkPaint* paint); private: int saveSnapshot(); @@ -155,12 +160,17 @@ private: void setScissorFromClip(); + void drawColorRect(float left, float top, float right, float bottom, int color); + // Dimensions of the drawing surface int mWidth, mHeight; // Matrix used for ortho projection in shaders float mOrthoMatrix[16]; + // Model-view matrix used to position/size objects + mat4 mModelView; + // Number of saved states int mSaveCount; // Base state diff --git a/libs/hwui/shaders/drawColor.vert b/libs/hwui/shaders/drawColor.vert index fd3cb45..4b7f883 100644 --- a/libs/hwui/shaders/drawColor.vert +++ b/libs/hwui/shaders/drawColor.vert @@ -5,12 +5,13 @@ attribute vec4 color; uniform mat4 projection; uniform mat4 modelView; +uniform mat4 transform; varying vec4 outColor; void main(void) { outColor = color; - gl_Position = projection * modelView * position; + gl_Position = projection * transform * modelView * position; } ); |
