From 3f43ecbb1b7c8f24c9a6e3d6b9807a1d0ef2f2ab Mon Sep 17 00:00:00 2001 From: Chih-Chung Chang Date: Thu, 16 Feb 2012 07:27:03 +0800 Subject: Make GLCanvas a bit faster. (1) make a faster version of translate(x, y). (2) make mapPoints() faster. (3) avoid calling canvas.rotate() when it is not needed. Change-Id: I364e2aa3fc9ee81c43f42f3af8b2d30a1241b482 --- src/com/android/gallery3d/ui/GLCanvas.java | 1 + src/com/android/gallery3d/ui/GLCanvasImpl.java | 68 +++++++++++++--------- src/com/android/gallery3d/ui/GLView.java | 4 +- src/com/android/gallery3d/ui/PhotoView.java | 4 +- src/com/android/gallery3d/ui/ProgressSpinner.java | 2 +- src/com/android/gallery3d/ui/SlideshowView.java | 2 +- src/com/android/gallery3d/ui/SlotView.java | 12 ++-- src/com/android/gallery3d/ui/TileImageView.java | 4 +- .../src/com/android/gallery3d/ui/GLCanvasStub.java | 1 + 9 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/com/android/gallery3d/ui/GLCanvas.java b/src/com/android/gallery3d/ui/GLCanvas.java index 88c02f3b5..fea95092e 100644 --- a/src/com/android/gallery3d/ui/GLCanvas.java +++ b/src/com/android/gallery3d/ui/GLCanvas.java @@ -54,6 +54,7 @@ public interface GLCanvas { // Change the current transform matrix. public void translate(float x, float y, float z); + public void translate(float x, float y); public void scale(float sx, float sy, float sz); public void rotate(float angle, float x, float y, float z); public void multiplyMatrix(float[] mMatrix, int offset); diff --git a/src/com/android/gallery3d/ui/GLCanvasImpl.java b/src/com/android/gallery3d/ui/GLCanvasImpl.java index 612c7c4f2..b8961f9d1 100644 --- a/src/com/android/gallery3d/ui/GLCanvasImpl.java +++ b/src/com/android/gallery3d/ui/GLCanvasImpl.java @@ -51,8 +51,9 @@ public class GLCanvasImpl implements GLCanvas { private final float mMatrixValues[] = new float[16]; private final float mTextureMatrixValues[] = new float[16]; - // mapPoints needs 10 input and output numbers. - private final float mMapPointsBuffer[] = new float[10]; + // The results of mapPoints are stored in this buffer, and the order is + // x1, y1, x2, y2. + private final float mMapPointsBuffer[] = new float[4]; private final float mTextureColor[] = new float[4]; @@ -171,7 +172,7 @@ public class GLCanvasImpl implements GLCanvas { mGLState.setLineSmooth(paint.getAntiAlias()); saveTransform(); - translate(x, y, 0); + translate(x, y); scale(width, height, 1); gl.glLoadMatrixf(mMatrixValues, 0); @@ -189,7 +190,7 @@ public class GLCanvasImpl implements GLCanvas { mGLState.setLineSmooth(paint.getAntiAlias()); saveTransform(); - translate(x1, y1, 0); + translate(x1, y1); scale(x2 - x1, y2 - y1, 1); gl.glLoadMatrixf(mMatrixValues, 0); @@ -204,7 +205,7 @@ public class GLCanvasImpl implements GLCanvas { GL11 gl = mGL; saveTransform(); - translate(x, y, 0); + translate(x, y); scale(width, height, 1); gl.glLoadMatrixf(mMatrixValues, 0); @@ -218,6 +219,17 @@ public class GLCanvasImpl implements GLCanvas { Matrix.translateM(mMatrixValues, 0, x, y, z); } + // This is a faster version of translate(x, y, z) because + // (1) we knows z = 0, (2) we inline the Matrix.translateM call, + // (3) we unroll the loop + public void translate(float x, float y) { + float[] m = mMatrixValues; + m[12] += m[0] * x + m[4] * y; + m[13] += m[1] * x + m[5] * y; + m[14] += m[2] * x + m[6] * y; + m[15] += m[3] * x + m[7] * y; + } + public void scale(float sx, float sy, float sz) { Matrix.scaleM(mMatrixValues, 0, sx, sy, sz); } @@ -239,7 +251,7 @@ public class GLCanvasImpl implements GLCanvas { GL11 gl = mGL; saveTransform(); - translate(x, y, 0); + translate(x, y); scale(width, height, 1); gl.glLoadMatrixf(mMatrixValues, 0); @@ -263,7 +275,7 @@ public class GLCanvasImpl implements GLCanvas { setTextureCoords(0, 0, 1, 1); saveTransform(); - translate(x, y, 0); + translate(x, y); mGL.glLoadMatrixf(mMatrixValues, 0); @@ -285,28 +297,26 @@ public class GLCanvasImpl implements GLCanvas { mCountDrawMesh++; } - private float[] mapPoints(float matrix[], int x1, int y1, int x2, int y2) { - float[] point = mMapPointsBuffer; - int srcOffset = 6; - point[srcOffset] = x1; - point[srcOffset + 1] = y1; - point[srcOffset + 2] = 0; - point[srcOffset + 3] = 1; - - int resultOffset = 0; - Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset); - point[resultOffset] /= point[resultOffset + 3]; - point[resultOffset + 1] /= point[resultOffset + 3]; - - // map the second point - point[srcOffset] = x2; - point[srcOffset + 1] = y2; - resultOffset = 2; - Matrix.multiplyMV(point, resultOffset, matrix, 0, point, srcOffset); - point[resultOffset] /= point[resultOffset + 3]; - point[resultOffset + 1] /= point[resultOffset + 3]; - - return point; + // Transforms two points by the given matrix m. The result + // {x1', y1', x2', y2'} are stored in mMapPointsBuffer and also returned. + private float[] mapPoints(float m[], int x1, int y1, int x2, int y2) { + float[] r = mMapPointsBuffer; + + // Multiply m and (x1 y1 0 1) to produce (x3 y3 z3 w3). z3 is unused. + float x3 = m[0] * x1 + m[4] * y1 + m[12]; + float y3 = m[1] * x1 + m[5] * y1 + m[13]; + float w3 = m[3] * x1 + m[7] * y1 + m[15]; + r[0] = x3 / w3; + r[1] = y3 / w3; + + // Same for x2 y2. + float x4 = m[0] * x2 + m[4] * y2 + m[12]; + float y4 = m[1] * x2 + m[5] * y2 + m[13]; + float w4 = m[3] * x2 + m[7] * y2 + m[15]; + r[2] = x4 / w4; + r[3] = y4 / w4; + + return r; } public boolean clipRect(int left, int top, int right, int bottom) { diff --git a/src/com/android/gallery3d/ui/GLView.java b/src/com/android/gallery3d/ui/GLView.java index 7491a6ffb..b4af9bcdd 100644 --- a/src/com/android/gallery3d/ui/GLView.java +++ b/src/com/android/gallery3d/ui/GLView.java @@ -229,7 +229,7 @@ public class GLView { int xoffset = component.mBounds.left - mScrollX; int yoffset = component.mBounds.top - mScrollY; - canvas.translate(xoffset, yoffset, 0); + canvas.translate(xoffset, yoffset); CanvasAnimation anim = component.mAnimation; if (anim != null) { @@ -243,7 +243,7 @@ public class GLView { } component.render(canvas); if (anim != null) canvas.restore(); - canvas.translate(-xoffset, -yoffset, 0); + canvas.translate(-xoffset, -yoffset); } protected boolean onTouch(MotionEvent event) { diff --git a/src/com/android/gallery3d/ui/PhotoView.java b/src/com/android/gallery3d/ui/PhotoView.java index 08665b893..aa84d5393 100644 --- a/src/com/android/gallery3d/ui/PhotoView.java +++ b/src/com/android/gallery3d/ui/PhotoView.java @@ -738,9 +738,9 @@ public class PhotoView extends GLView { if (mTexture != null) { if (mRotation != 0) { canvas.save(GLCanvas.SAVE_FLAG_MATRIX); - canvas.translate(x, y, 0); + canvas.translate(x, y); canvas.rotate(mRotation, 0, 0, 1); //mRotation - canvas.translate(-x, -y, 0); + canvas.translate(-x, -y); } mTexture.draw(canvas, x - mDrawWidth / 2, y - mDrawHeight / 2, mDrawWidth, mDrawHeight); diff --git a/src/com/android/gallery3d/ui/ProgressSpinner.java b/src/com/android/gallery3d/ui/ProgressSpinner.java index e4d60242b..22ca3572a 100644 --- a/src/com/android/gallery3d/ui/ProgressSpinner.java +++ b/src/com/android/gallery3d/ui/ProgressSpinner.java @@ -68,7 +68,7 @@ public class ProgressSpinner { canvas.save(GLCanvas.SAVE_FLAG_MATRIX); - canvas.translate(x + mWidth / 2, y + mHeight / 2, 0); + canvas.translate(x + mWidth / 2, y + mHeight / 2); canvas.rotate(mInnerDegree, 0, 0, 1); mOuter.draw(canvas, -mOuter.getWidth() / 2, -mOuter.getHeight() / 2); canvas.rotate(mOuterDegree - mInnerDegree, 0, 0, 1); diff --git a/src/com/android/gallery3d/ui/SlideshowView.java b/src/com/android/gallery3d/ui/SlideshowView.java index 79a6bf080..1bd700b69 100644 --- a/src/com/android/gallery3d/ui/SlideshowView.java +++ b/src/com/android/gallery3d/ui/SlideshowView.java @@ -148,7 +148,7 @@ public class SlideshowView extends GLView { float centerX = viewWidth / 2 + mMovingVector.x * mProgress; float centerY = viewHeight / 2 + mMovingVector.y * mProgress; - canvas.translate(centerX, centerY, 0); + canvas.translate(centerX, centerY); canvas.scale(scale, scale, 0); } diff --git a/src/com/android/gallery3d/ui/SlotView.java b/src/com/android/gallery3d/ui/SlotView.java index 16040b7a2..f1c261b97 100644 --- a/src/com/android/gallery3d/ui/SlotView.java +++ b/src/com/android/gallery3d/ui/SlotView.java @@ -286,9 +286,9 @@ public class SlotView extends GLView { } if (WIDE) { - canvas.translate(-mScrollX, 0, 0); + canvas.translate(-mScrollX, 0); } else { - canvas.translate(0, -mScrollY, 0); + canvas.translate(0, -mScrollY); } LinkedNode.List list = mItemList; @@ -320,9 +320,9 @@ public class SlotView extends GLView { } if (WIDE) { - canvas.translate(mScrollX, 0, 0); + canvas.translate(mScrollX, 0); } else { - canvas.translate(0, mScrollY, 0); + canvas.translate(0, mScrollY); } if (more) invalidate(); @@ -363,7 +363,9 @@ public class SlotView extends GLView { } else { canvas.translate(position.x, position.y, position.z); } - canvas.rotate(position.theta, 0, 0, 1); + if (position.theta != 0) { + canvas.rotate(position.theta, 0, 0, 1); + } int more = entry.item.render(canvas, pass); canvas.restore(); return more; diff --git a/src/com/android/gallery3d/ui/TileImageView.java b/src/com/android/gallery3d/ui/TileImageView.java index 151022d30..1f2108d43 100644 --- a/src/com/android/gallery3d/ui/TileImageView.java +++ b/src/com/android/gallery3d/ui/TileImageView.java @@ -375,9 +375,9 @@ public class TileImageView extends GLView { if (rotation != 0) { canvas.save(GLCanvas.SAVE_FLAG_MATRIX); int centerX = getWidth() / 2, centerY = getHeight() / 2; - canvas.translate(centerX, centerY, 0); + canvas.translate(centerX, centerY); canvas.rotate(rotation, 0, 0, 1); - canvas.translate(-centerX, -centerY, 0); + canvas.translate(-centerX, -centerY); } try { if (level != mLevelCount) { diff --git a/tests/src/com/android/gallery3d/ui/GLCanvasStub.java b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java index f1663f4bd..17d520daf 100644 --- a/tests/src/com/android/gallery3d/ui/GLCanvasStub.java +++ b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java @@ -33,6 +33,7 @@ public class GLCanvasStub implements GLCanvas { } public void multiplyAlpha(float alpha) {} public void translate(float x, float y, float z) {} + public void translate(float x, float y) {} public void scale(float sx, float sy, float sz) {} public void rotate(float angle, float x, float y, float z) {} public boolean clipRect(int left, int top, int right, int bottom) { -- cgit v1.2.3