Implement quickReject() and drawRect().
The OpenGL ES 2.0 renderer can now draw colored rectangles. At least there's
something on screen now.
Change-Id: I80a13ccc1dd56784edf74f2670a364f30700234a
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 uirenderer {
void Matrix4::loadIdentity() {
- mMat[0] = 1.0f;
- mMat[1] = 0.0f;
- mMat[2] = 0.0f;
- mMat[3] = 0.0f;
+ data[0] = 1.0f;
+ data[1] = 0.0f;
+ data[2] = 0.0f;
+ data[3] = 0.0f;
- mMat[4] = 0.0f;
- mMat[5] = 1.0f;
- mMat[6] = 0.0f;
- mMat[7] = 0.0f;
+ data[4] = 0.0f;
+ data[5] = 1.0f;
+ data[6] = 0.0f;
+ data[7] = 0.0f;
- mMat[8] = 0.0f;
- mMat[9] = 0.0f;
- mMat[10] = 1.0f;
- mMat[11] = 0.0f;
+ data[8] = 0.0f;
+ data[9] = 0.0f;
+ data[10] = 1.0f;
+ data[11] = 0.0f;
- mMat[12] = 0.0f;
- mMat[13] = 0.0f;
- mMat[14] = 0.0f;
- mMat[15] = 1.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 @@
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 @@
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::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::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 @@
class Matrix4 {
public:
+ float data[16];
+
Matrix4() {
loadIdentity();
}
@@ -92,14 +94,12 @@
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 @@
// 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 @@
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 @@
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 @@
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::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 @@
///////////////////////////////////////////////////////////////////////////////
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: Set the transfer mode
+ const Rect& clip = mSnapshot->clipRect;
+ drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color);
+}
- // TODO Optimize this section
- const Rect& clip = mSnapshot->getMappedClip();
+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());
+}
- mat4 modelView;
- modelView.loadScale(clip.getWidth(), clip.getHeight(), 1.0f);
- modelView.translate(clip.left, clip.top, 0.0f);
+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;
- float matrix[16];
- modelView.copyTo(matrix);
- // TODO Optimize this section
+ mModelView.loadTranslate(left, top, 0.0f);
+ mModelView.scale(right - left, bottom - top, 1.0f);
- mDrawColorShader->use();
+ mDrawColorShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]);
- glUniformMatrix4fv(mDrawColorShader->projection, 1, GL_FALSE, &mOrthoMatrix[0]);
- glUniformMatrix4fv(mDrawColorShader->modelView, 1, GL_FALSE, &matrix[0]);
+ const GLvoid* p = &gDrawColorVertices[0].position[0];
- glEnableVertexAttribArray(mDrawColorShader->position);
+ glEnableVertexAttribArray(mDrawColorShader->position);
+ glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE,
+ gDrawColorVertexStride, p);
+ glVertexAttrib4f(mDrawColorShader->color, r, g, b, a);
- GLsizei stride = sizeof(Vertex);
- const GLvoid* p = &gDrawColorVertices[0].position[0];
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount);
- 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);
+ 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 @@
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 @@
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 @@
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 @@
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 @@
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;
}
);