diff options
author | Owen Lin <owenlin@google.com> | 2011-08-17 22:07:43 +0800 |
---|---|---|
committer | Owen Lin <owenlin@google.com> | 2011-08-18 13:33:50 +0800 |
commit | a2fba687d4d2dbb3b2db8866b054ecb0e42871b2 (patch) | |
tree | dacc5a60ed945fe989aebf1f227f72bc90ebc4b8 /tests/src/com/android/gallery3d/ui | |
parent | a053a3179cfee3d2bb666eff5f4f03a96b092e04 (diff) | |
download | android_packages_apps_Snap-a2fba687d4d2dbb3b2db8866b054ecb0e42871b2.tar.gz android_packages_apps_Snap-a2fba687d4d2dbb3b2db8866b054ecb0e42871b2.tar.bz2 android_packages_apps_Snap-a2fba687d4d2dbb3b2db8866b054ecb0e42871b2.zip |
Initial code for Gallery2.
fix: 5176434
Change-Id: I041e282b9c7b34ceb1db8b033be2b853bb3a992c
Diffstat (limited to 'tests/src/com/android/gallery3d/ui')
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLCanvasMock.java | 68 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLCanvasStub.java | 79 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLCanvasTest.java | 778 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLMock.java | 195 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLRootMock.java | 37 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLRootStub.java | 30 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLStub.java | 1490 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLViewMock.java | 85 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/GLViewTest.java | 424 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/PointerInfo.java | 222 | ||||
-rw-r--r-- | tests/src/com/android/gallery3d/ui/TextureTest.java | 208 |
11 files changed, 3616 insertions, 0 deletions
diff --git a/tests/src/com/android/gallery3d/ui/GLCanvasMock.java b/tests/src/com/android/gallery3d/ui/GLCanvasMock.java new file mode 100644 index 000000000..f8100ddf6 --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLCanvasMock.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import javax.microedition.khronos.opengles.GL11; + +public class GLCanvasMock extends GLCanvasStub { + // fillRect + int mFillRectCalled; + float mFillRectWidth; + float mFillRectHeight; + int mFillRectColor; + // drawMixed + int mDrawMixedCalled; + float mDrawMixedRatio; + // drawTexture; + int mDrawTextureCalled; + + private GL11 mGL; + + public GLCanvasMock(GL11 gl) { + mGL = gl; + } + + public GLCanvasMock() { + mGL = new GLStub(); + } + + @Override + public GL11 getGLInstance() { + return mGL; + } + + @Override + public void fillRect(float x, float y, float width, float height, int color) { + mFillRectCalled++; + mFillRectWidth = width; + mFillRectHeight = height; + mFillRectColor = color; + } + + @Override + public void drawTexture( + BasicTexture texture, int x, int y, int width, int height) { + mDrawTextureCalled++; + } + + @Override + public void drawMixed(BasicTexture from, BasicTexture to, + float ratio, int x, int y, int w, int h) { + mDrawMixedCalled++; + mDrawMixedRatio = ratio; + } +} diff --git a/tests/src/com/android/gallery3d/ui/GLCanvasStub.java b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java new file mode 100644 index 000000000..f1663f4bd --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLCanvasStub.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import android.graphics.RectF; + +import javax.microedition.khronos.opengles.GL11; + +public class GLCanvasStub implements GLCanvas { + public void setSize(int width, int height) {} + public void clearBuffer() {} + public void setCurrentAnimationTimeMillis(long time) {} + public long currentAnimationTimeMillis() { + throw new UnsupportedOperationException(); + } + public void setAlpha(float alpha) {} + public float getAlpha() { + throw new UnsupportedOperationException(); + } + public void multiplyAlpha(float alpha) {} + public void translate(float x, float y, float z) {} + 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) { + throw new UnsupportedOperationException(); + } + public int save() { + throw new UnsupportedOperationException(); + } + public int save(int saveFlags) { + throw new UnsupportedOperationException(); + } + public void setBlendEnabled(boolean enabled) {} + public void restore() {} + public void drawLine(float x1, float y1, float x2, float y2, GLPaint paint) {} + public void drawRect(float x1, float y1, float x2, float y2, GLPaint paint) {} + public void fillRect(float x, float y, float width, float height, int color) {} + public void drawTexture( + BasicTexture texture, int x, int y, int width, int height) {} + public void drawMesh(BasicTexture tex, int x, int y, int xyBuffer, + int uvBuffer, int indexBuffer, int indexCount) {} + public void drawTexture(BasicTexture texture, + int x, int y, int width, int height, float alpha) {} + public void drawTexture(BasicTexture texture, RectF source, RectF target) {} + public void drawMixed(BasicTexture from, BasicTexture to, + float ratio, int x, int y, int w, int h) {} + public void drawMixed(BasicTexture from, int to, + float ratio, int x, int y, int w, int h) {} + public void drawMixed(BasicTexture from, BasicTexture to, + float ratio, int x, int y, int width, int height, float alpha) {} + public BasicTexture copyTexture(int x, int y, int width, int height) { + throw new UnsupportedOperationException(); + } + public GL11 getGLInstance() { + throw new UnsupportedOperationException(); + } + public boolean unloadTexture(BasicTexture texture) { + throw new UnsupportedOperationException(); + } + public void deleteBuffer(int bufferId) { + throw new UnsupportedOperationException(); + } + public void deleteRecycledResources() {} + public void multiplyMatrix(float[] mMatrix, int offset) {} +} diff --git a/tests/src/com/android/gallery3d/ui/GLCanvasTest.java b/tests/src/com/android/gallery3d/ui/GLCanvasTest.java new file mode 100644 index 000000000..528b04f67 --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLCanvasTest.java @@ -0,0 +1,778 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; + +import junit.framework.TestCase; + +import java.util.Arrays; + +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +@SmallTest +public class GLCanvasTest extends TestCase { + private static final String TAG = "GLCanvasTest"; + + private static GLPaint newColorPaint(int color) { + GLPaint paint = new GLPaint(); + paint.setColor(color); + return paint; + } + + @SmallTest + public void testSetSize() { + GL11 glStub = new GLStub(); + GLCanvas canvas = new GLCanvasImpl(glStub); + canvas.setSize(100, 200); + canvas.setSize(1000, 100); + try { + canvas.setSize(-1, 100); + fail(); + } catch (Throwable ex) { + // expected. + } + } + + @SmallTest + public void testClearBuffer() { + new ClearBufferTest().run(); + } + + private static class ClearBufferTest extends GLMock { + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + assertEquals(0, mGLClearCalled); + canvas.clearBuffer(); + assertEquals(GL10.GL_COLOR_BUFFER_BIT, mGLClearMask); + assertEquals(1, mGLClearCalled); + } + } + + @SmallTest + public void testAnimationTime() { + GL11 glStub = new GLStub(); + GLCanvas canvas = new GLCanvasImpl(glStub); + + long[] testData = {0, 1, 2, 1000, 10000, Long.MAX_VALUE}; + + for (long v : testData) { + canvas.setCurrentAnimationTimeMillis(v); + assertEquals(v, canvas.currentAnimationTimeMillis()); + } + + try { + canvas.setCurrentAnimationTimeMillis(-1); + fail(); + } catch (Throwable ex) { + // expected. + } + } + + @SmallTest + public void testSetColor() { + new SetColorTest().run(); + } + + // This test assumes we use pre-multipled alpha blending and should + // set the blending function and color correctly. + private static class SetColorTest extends GLMock { + void run() { + int[] testColors = new int[] { + 0, 0xFFFFFFFF, 0xFF000000, 0x00FFFFFF, 0x80FF8001, + 0x7F010101, 0xFEFEFDFC, 0x017F8081, 0x027F8081, 0x2ADE4C4D + }; + + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(400, 300); + // Test one color to make sure blend function is set. + assertEquals(0, mGLColorCalled); + canvas.drawLine(0, 0, 1, 1, newColorPaint(0x7F804020)); + assertEquals(1, mGLColorCalled); + assertEquals(0x7F402010, mGLColor); + assertPremultipliedBlending(this); + + // Test other colors to make sure premultiplication is right + for (int c : testColors) { + float a = (c >>> 24) / 255f; + float r = ((c >> 16) & 0xff) / 255f; + float g = ((c >> 8) & 0xff) / 255f; + float b = (c & 0xff) / 255f; + int pre = makeColor4f(a * r, a * g, a * b, a); + + mGLColorCalled = 0; + canvas.drawLine(0, 0, 1, 1, newColorPaint(c)); + assertEquals(1, mGLColorCalled); + assertEquals(pre, mGLColor); + } + } + } + + @SmallTest + public void testSetGetMultiplyAlpha() { + GL11 glStub = new GLStub(); + GLCanvas canvas = new GLCanvasImpl(glStub); + + canvas.setAlpha(1f); + assertEquals(1f, canvas.getAlpha()); + + canvas.setAlpha(0f); + assertEquals(0f, canvas.getAlpha()); + + canvas.setAlpha(0.5f); + assertEquals(0.5f, canvas.getAlpha()); + + canvas.multiplyAlpha(0.5f); + assertEquals(0.25f, canvas.getAlpha()); + + canvas.multiplyAlpha(0f); + assertEquals(0f, canvas.getAlpha()); + + try { + canvas.setAlpha(-0.01f); + fail(); + } catch (Throwable ex) { + // expected. + } + + try { + canvas.setAlpha(1.01f); + fail(); + } catch (Throwable ex) { + // expected. + } + } + + @SmallTest + public void testAlpha() { + new AlphaTest().run(); + } + + private static class AlphaTest extends GLMock { + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(400, 300); + + assertEquals(0, mGLColorCalled); + canvas.setAlpha(0.48f); + canvas.drawLine(0, 0, 1, 1, newColorPaint(0xFF804020)); + assertPremultipliedBlending(this); + assertEquals(1, mGLColorCalled); + assertEquals(0x7A3D1F0F, mGLColor); + } + } + + @SmallTest + public void testDrawLine() { + new DrawLineTest().run(); + } + + // This test assumes the drawLine() function use glDrawArrays() with + // GL_LINE_STRIP mode to draw the line and the input coordinates are used + // directly. + private static class DrawLineTest extends GLMock { + private int mDrawArrayCalled = 0; + private final int[] mResult = new int[4]; + + @Override + public void glDrawArrays(int mode, int first, int count) { + assertNotNull(mGLVertexPointer); + assertEquals(GL10.GL_LINE_STRIP, mode); + assertEquals(2, count); + mGLVertexPointer.bindByteBuffer(); + + double[] coord = new double[4]; + mGLVertexPointer.getArrayElement(first, coord); + mResult[0] = (int) coord[0]; + mResult[1] = (int) coord[1]; + mGLVertexPointer.getArrayElement(first + 1, coord); + mResult[2] = (int) coord[0]; + mResult[3] = (int) coord[1]; + mDrawArrayCalled++; + } + + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(400, 300); + canvas.drawLine(2, 7, 1, 8, newColorPaint(0) /* color */); + assertTrue(mGLVertexArrayEnabled); + assertEquals(1, mDrawArrayCalled); + + Log.v(TAG, "result = " + Arrays.toString(mResult)); + int[] answer = new int[] {2, 7, 1, 8}; + for (int i = 0; i < answer.length; i++) { + assertEquals(answer[i], mResult[i]); + } + } + } + + @SmallTest + public void testFillRect() { + new FillRectTest().run(); + } + + // This test assumes the drawLine() function use glDrawArrays() with + // GL_TRIANGLE_STRIP mode to draw the line and the input coordinates + // are used directly. + private static class FillRectTest extends GLMock { + private int mDrawArrayCalled = 0; + private final int[] mResult = new int[8]; + + @Override + public void glDrawArrays(int mode, int first, int count) { + assertNotNull(mGLVertexPointer); + assertEquals(GL10.GL_TRIANGLE_STRIP, mode); + assertEquals(4, count); + mGLVertexPointer.bindByteBuffer(); + + double[] coord = new double[4]; + for (int i = 0; i < 4; i++) { + mGLVertexPointer.getArrayElement(first + i, coord); + mResult[i * 2 + 0] = (int) coord[0]; + mResult[i * 2 + 1] = (int) coord[1]; + } + + mDrawArrayCalled++; + } + + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(400, 300); + canvas.fillRect(2, 7, 1, 8, 0 /* color */); + assertTrue(mGLVertexArrayEnabled); + assertEquals(1, mDrawArrayCalled); + Log.v(TAG, "result = " + Arrays.toString(mResult)); + + // These are the four vertics that should be used. + int[] answer = new int[] { + 2, 7, + 3, 7, + 3, 15, + 2, 15}; + int count[] = new int[4]; + + // Count the number of appearances for each vertex. + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (answer[i * 2] == mResult[j * 2] && + answer[i * 2 + 1] == mResult[j * 2 + 1]) { + count[i]++; + } + } + } + + // Each vertex should appear exactly once. + for (int i = 0; i < 4; i++) { + assertEquals(1, count[i]); + } + } + } + + @SmallTest + public void testTransform() { + new TransformTest().run(); + } + + // This test assumes glLoadMatrixf is used to load the model view matrix, + // and glOrthof is used to load the projection matrix. + // + // The projection matrix is set to an orthogonal projection which is the + // inverse of viewport transform. So the model view matrix maps input + // directly to screen coordinates (default no scaling, and the y-axis is + // reversed). + // + // The matrix here are all listed in column major order. + // + private static class TransformTest extends GLMock { + private final float[] mModelViewMatrixUsed = new float[16]; + private final float[] mProjectionMatrixUsed = new float[16]; + + @Override + public void glDrawArrays(int mode, int first, int count) { + copy(mModelViewMatrixUsed, mGLModelViewMatrix); + copy(mProjectionMatrixUsed, mGLProjectionMatrix); + } + + private void copy(float[] dest, float[] src) { + System.arraycopy(src, 0, dest, 0, 16); + } + + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(40, 50); + int color = 0; + + // Initial matrix + canvas.drawLine(0, 0, 1, 1, newColorPaint(color)); + assertMatrixEq(new float[] { + 1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, 1, 0, + 0, 50, 0, 1 + }, mModelViewMatrixUsed); + + assertMatrixEq(new float[] { + 2f / 40, 0, 0, 0, + 0, 2f / 50, 0, 0, + 0, 0, -1, 0, + -1, -1, 0, 1 + }, mProjectionMatrixUsed); + + // Translation + canvas.translate(3, 4, 5); + canvas.drawLine(0, 0, 1, 1, newColorPaint(color)); + assertMatrixEq(new float[] { + 1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, 1, 0, + 3, 46, 5, 1 + }, mModelViewMatrixUsed); + canvas.save(); + + // Scaling + canvas.scale(0.7f, 0.6f, 0.5f); + canvas.drawLine(0, 0, 1, 1, newColorPaint(color)); + assertMatrixEq(new float[] { + 0.7f, 0, 0, 0, + 0, -0.6f, 0, 0, + 0, 0, 0.5f, 0, + 3, 46, 5, 1 + }, mModelViewMatrixUsed); + + // Rotation + canvas.rotate(90, 0, 0, 1); + canvas.drawLine(0, 0, 1, 1, newColorPaint(color)); + assertMatrixEq(new float[] { + 0, -0.6f, 0, 0, + -0.7f, 0, 0, 0, + 0, 0, 0.5f, 0, + 3, 46, 5, 1 + }, mModelViewMatrixUsed); + canvas.restore(); + + // After restoring to the point just after translation, + // do rotation again. + canvas.rotate(180, 1, 0, 0); + canvas.drawLine(0, 0, 1, 1, newColorPaint(color)); + assertMatrixEq(new float[] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, -1, 0, + 3, 46, 5, 1 + }, mModelViewMatrixUsed); + } + } + + @SmallTest + public void testClipRect() { + // The test is currently broken, waiting for the fix + // new ClipRectTest().run(); + } + + private static class ClipRectTest extends GLStub { + int mX, mY, mWidth, mHeight; + + @Override + public void glScissor(int x, int y, int width, int height) { + mX = x; + mY = 100 - y - height; // flip in Y direction + mWidth = width; + mHeight = height; + } + + private void assertClipRect(int x, int y, int width, int height) { + assertEquals(x, mX); + assertEquals(y, mY); + assertEquals(width, mWidth); + assertEquals(height, mHeight); + } + + private void assertEmptyClipRect() { + assertEquals(0, mWidth); + assertEquals(0, mHeight); + } + + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(100, 100); + canvas.save(); + assertClipRect(0, 0, 100, 100); + + assertTrue(canvas.clipRect(10, 10, 70, 70)); + canvas.save(); + assertClipRect(10, 10, 60, 60); + + assertTrue(canvas.clipRect(30, 30, 90, 90)); + canvas.save(); + assertClipRect(30, 30, 40, 40); + + assertTrue(canvas.clipRect(40, 40, 60, 90)); + assertClipRect(40, 40, 20, 30); + + assertFalse(canvas.clipRect(30, 30, 70, 40)); + assertEmptyClipRect(); + assertFalse(canvas.clipRect(0, 0, 100, 100)); + assertEmptyClipRect(); + + canvas.restore(); + assertClipRect(30, 30, 40, 40); + + canvas.restore(); + assertClipRect(10, 10, 60, 60); + + canvas.restore(); + assertClipRect(0, 0, 100, 100); + + canvas.translate(10, 20, 30); + assertTrue(canvas.clipRect(10, 10, 70, 70)); + canvas.save(); + assertClipRect(20, 30, 60, 60); + } + } + + @SmallTest + public void testSaveRestore() { + new SaveRestoreTest().run(); + } + + private static class SaveRestoreTest extends GLStub { + int mX, mY, mWidth, mHeight; + + @Override + public void glScissor(int x, int y, int width, int height) { + mX = x; + mY = 100 - y - height; // flip in Y direction + mWidth = width; + mHeight = height; + } + + private void assertClipRect(int x, int y, int width, int height) { + assertEquals(x, mX); + assertEquals(y, mY); + assertEquals(width, mWidth); + assertEquals(height, mHeight); + } + + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(100, 100); + + canvas.setAlpha(0.7f); + assertTrue(canvas.clipRect(10, 10, 70, 70)); + + canvas.save(canvas.SAVE_FLAG_CLIP); + canvas.setAlpha(0.6f); + assertTrue(canvas.clipRect(30, 30, 90, 90)); + + canvas.save(canvas.SAVE_FLAG_CLIP | canvas.SAVE_FLAG_ALPHA); + canvas.setAlpha(0.5f); + assertTrue(canvas.clipRect(40, 40, 60, 90)); + + assertEquals(0.5f, canvas.getAlpha()); + assertClipRect(40, 40, 20, 30); + + canvas.restore(); // now both clipping rect and alpha are restored. + assertEquals(0.6f, canvas.getAlpha()); + assertClipRect(30, 30, 40, 40); + + canvas.restore(); // now only clipping rect is restored. + + canvas.save(0); + canvas.save(0); + canvas.restore(); + canvas.restore(); + + assertEquals(0.6f, canvas.getAlpha()); + assertTrue(canvas.clipRect(10, 10, 60, 60)); + } + } + + @SmallTest + public void testDrawTexture() { + new DrawTextureTest().run(); + new DrawTextureMixedTest().run(); + } + + private static class MyTexture extends BasicTexture { + boolean mIsOpaque; + int mBindCalled; + + MyTexture(GLCanvas canvas, int id, boolean isOpaque) { + super(canvas, id, STATE_LOADED); + setSize(1, 1); + mIsOpaque = isOpaque; + } + + @Override + protected boolean onBind(GLCanvas canvas) { + mBindCalled++; + return true; + } + + public boolean isOpaque() { + return mIsOpaque; + } + } + + private static class DrawTextureTest extends GLMock { + int mDrawTexiOESCalled; + int mDrawArrayCalled; + int[] mResult = new int[4]; + + @Override + public void glDrawTexiOES(int x, int y, int z, + int width, int height) { + mDrawTexiOESCalled++; + } + + @Override + public void glDrawArrays(int mode, int first, int count) { + assertNotNull(mGLVertexPointer); + assertEquals(GL10.GL_TRIANGLE_STRIP, mode); + assertEquals(4, count); + mGLVertexPointer.bindByteBuffer(); + + double[] coord = new double[4]; + mGLVertexPointer.getArrayElement(first, coord); + mResult[0] = (int) coord[0]; + mResult[1] = (int) coord[1]; + mGLVertexPointer.getArrayElement(first + 1, coord); + mResult[2] = (int) coord[0]; + mResult[3] = (int) coord[1]; + mDrawArrayCalled++; + } + + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(400, 300); + MyTexture texture = new MyTexture(canvas, 42, false); // non-opaque + MyTexture texture_o = new MyTexture(canvas, 47, true); // opaque + + // Draw a non-opaque texture + canvas.drawTexture(texture, 100, 200, 300, 400); + assertEquals(42, mGLBindTextureId); + assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE_ENV_MODE)); + assertPremultipliedBlending(this); + assertFalse(mGLStencilEnabled); + + // Draw an opaque texture + canvas.drawTexture(texture_o, 100, 200, 300, 400); + assertEquals(47, mGLBindTextureId); + assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE_ENV_MODE)); + assertFalse(mGLBlendEnabled); + + // Draw a non-opaque texture with alpha = 0.5 + canvas.setAlpha(0.5f); + canvas.drawTexture(texture, 100, 200, 300, 400); + assertEquals(42, mGLBindTextureId); + assertEquals(0x80808080, mGLColor); + assertEquals(GL_MODULATE, getTexEnvi(GL_TEXTURE_ENV_MODE)); + assertPremultipliedBlending(this); + assertFalse(mGLStencilEnabled); + + // Draw an non-opaque texture with overriden alpha = 1 + canvas.drawTexture(texture, 100, 200, 300, 400, 1f); + assertEquals(42, mGLBindTextureId); + assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE_ENV_MODE)); + assertPremultipliedBlending(this); + + // Draw an opaque texture with overriden alpha = 1 + canvas.drawTexture(texture_o, 100, 200, 300, 400, 1f); + assertEquals(47, mGLBindTextureId); + assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE_ENV_MODE)); + assertFalse(mGLBlendEnabled); + + // Draw an opaque texture with overridden alpha = 0.25 + canvas.drawTexture(texture_o, 100, 200, 300, 400, 0.25f); + assertEquals(47, mGLBindTextureId); + assertEquals(0x40404040, mGLColor); + assertEquals(GL_MODULATE, getTexEnvi(GL_TEXTURE_ENV_MODE)); + assertPremultipliedBlending(this); + + // Draw an opaque texture with overridden alpha = 0.125 + // but with some rotation so it will use DrawArray. + canvas.save(); + canvas.rotate(30, 0, 0, 1); + canvas.drawTexture(texture_o, 100, 200, 300, 400, 0.125f); + canvas.restore(); + assertEquals(47, mGLBindTextureId); + assertEquals(0x20202020, mGLColor); + assertEquals(GL_MODULATE, getTexEnvi(GL_TEXTURE_ENV_MODE)); + assertPremultipliedBlending(this); + + // We have drawn seven textures above. + assertEquals(1, mDrawArrayCalled); + assertEquals(6, mDrawTexiOESCalled); + + // translate and scale does not affect whether we + // can use glDrawTexiOES, but rotate may. + canvas.translate(10, 20, 30); + canvas.drawTexture(texture, 100, 200, 300, 400); + assertEquals(7, mDrawTexiOESCalled); + + canvas.scale(10, 20, 30); + canvas.drawTexture(texture, 100, 200, 300, 400); + assertEquals(8, mDrawTexiOESCalled); + + canvas.rotate(90, 1, 2, 3); + canvas.drawTexture(texture, 100, 200, 300, 400); + assertEquals(8, mDrawTexiOESCalled); + + canvas.rotate(-90, 1, 2, 3); + canvas.drawTexture(texture, 100, 200, 300, 400); + assertEquals(9, mDrawTexiOESCalled); + + canvas.rotate(180, 0, 0, 1); + canvas.drawTexture(texture, 100, 200, 300, 400); + assertEquals(9, mDrawTexiOESCalled); + + canvas.rotate(180, 0, 0, 1); + canvas.drawTexture(texture, 100, 200, 300, 400); + assertEquals(10, mDrawTexiOESCalled); + + assertEquals(3, mDrawArrayCalled); + + assertTrue(texture.isLoaded(canvas)); + texture.recycle(); + assertFalse(texture.isLoaded(canvas)); + canvas.deleteRecycledResources(); + + assertTrue(texture_o.isLoaded(canvas)); + texture_o.recycle(); + assertFalse(texture_o.isLoaded(canvas)); + } + } + + private static class DrawTextureMixedTest extends GLMock { + + boolean mTexture2DEnabled0, mTexture2DEnabled1; + int mBindTexture0; + int mBindTexture1; + + @Override + public void glEnable(int cap) { + if (cap == GL_TEXTURE_2D) { + texture2DEnable(true); + } + } + + @Override + public void glDisable(int cap) { + if (cap == GL_TEXTURE_2D) { + texture2DEnable(false); + } + } + + private void texture2DEnable(boolean enable) { + if (mGLActiveTexture == GL_TEXTURE0) { + mTexture2DEnabled0 = enable; + } else if (mGLActiveTexture == GL_TEXTURE1) { + mTexture2DEnabled1 = enable; + } else { + fail(); + } + } + + @Override + public void glTexEnvfv(int target, int pname, float[] params, int offset) { + if (target == GL_TEXTURE_ENV && pname == GL_TEXTURE_ENV_COLOR) { + assertEquals(0.5f, params[offset + 3]); + } + } + + @Override + public void glBindTexture(int target, int texture) { + if (target == GL_TEXTURE_2D) { + if (mGLActiveTexture == GL_TEXTURE0) { + mBindTexture0 = texture; + } else if (mGLActiveTexture == GL_TEXTURE1) { + mBindTexture1 = texture; + } else { + fail(); + } + } + } + + void run() { + GLCanvas canvas = new GLCanvasImpl(this); + canvas.setSize(400, 300); + MyTexture from = new MyTexture(canvas, 42, false); // non-opaque + MyTexture to = new MyTexture(canvas, 47, true); // opaque + + canvas.drawMixed(from, to, 0.5f, 100, 200, 300, 400); + assertEquals(42, mBindTexture0); + assertEquals(47, mBindTexture1); + assertTrue(mTexture2DEnabled0); + assertFalse(mTexture2DEnabled1); + + assertEquals(GL_COMBINE, getTexEnvi(GL_TEXTURE1, GL_TEXTURE_ENV_MODE)); + assertEquals(GL_INTERPOLATE, getTexEnvi(GL_TEXTURE1, GL_COMBINE_RGB)); + assertEquals(GL_INTERPOLATE, getTexEnvi(GL_TEXTURE1, GL_COMBINE_ALPHA)); + assertEquals(GL_CONSTANT, getTexEnvi(GL_TEXTURE1, GL_SRC2_RGB)); + assertEquals(GL_CONSTANT, getTexEnvi(GL_TEXTURE1, GL_SRC2_ALPHA)); + assertEquals(GL_SRC_ALPHA, getTexEnvi(GL_TEXTURE1, GL_OPERAND2_RGB)); + assertEquals(GL_SRC_ALPHA, getTexEnvi(GL_TEXTURE1, GL_OPERAND2_ALPHA)); + + assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE0, GL_TEXTURE_ENV_MODE)); + + assertFalse(mGLBlendEnabled); + + canvas.drawMixed(from, to, 0, 100, 200, 300, 400); + assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE0, GL_TEXTURE_ENV_MODE)); + assertEquals(42, mBindTexture0); + + canvas.drawMixed(from, to, 1, 100, 200, 300, 400); + assertEquals(GL_REPLACE, getTexEnvi(GL_TEXTURE0, GL_TEXTURE_ENV_MODE)); + assertEquals(47, mBindTexture0); + } + } + + @SmallTest + public void testGetGLInstance() { + GL11 glStub = new GLStub(); + GLCanvas canvas = new GLCanvasImpl(glStub); + assertSame(glStub, canvas.getGLInstance()); + } + + private static void assertPremultipliedBlending(GLMock mock) { + assertTrue(mock.mGLBlendFuncCalled > 0); + assertTrue(mock.mGLBlendEnabled); + assertEquals(GL11.GL_ONE, mock.mGLBlendFuncSFactor); + assertEquals(GL11.GL_ONE_MINUS_SRC_ALPHA, mock.mGLBlendFuncDFactor); + } + + private static void assertMatrixEq(float[] expected, float[] actual) { + try { + for (int i = 0; i < 16; i++) { + assertFloatEq(expected[i], actual[i]); + } + } catch (Throwable t) { + Log.v(TAG, "expected = " + Arrays.toString(expected) + + ", actual = " + Arrays.toString(actual)); + fail(); + } + } + + public static void assertFloatEq(float expected, float actual) { + if (Math.abs(actual - expected) > 1e-6) { + Log.v(TAG, "expected: " + expected + ", actual: " + actual); + fail(); + } + } +} diff --git a/tests/src/com/android/gallery3d/ui/GLMock.java b/tests/src/com/android/gallery3d/ui/GLMock.java new file mode 100644 index 000000000..c1fe53c62 --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLMock.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import java.nio.Buffer; +import java.util.HashMap; +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; + +public class GLMock extends GLStub { + @SuppressWarnings("unused") + private static final String TAG = "GLMock"; + + // glClear + int mGLClearCalled; + int mGLClearMask; + // glBlendFunc + int mGLBlendFuncCalled; + int mGLBlendFuncSFactor; + int mGLBlendFuncDFactor; + // glColor4[fx] + int mGLColorCalled; + int mGLColor; + // glEnable, glDisable + boolean mGLBlendEnabled; + boolean mGLStencilEnabled; + // glEnableClientState + boolean mGLVertexArrayEnabled; + // glVertexPointer + PointerInfo mGLVertexPointer; + // glMatrixMode + int mGLMatrixMode = GL10.GL_MODELVIEW; + // glLoadMatrixf + float[] mGLModelViewMatrix = new float[16]; + float[] mGLProjectionMatrix = new float[16]; + // glBindTexture + int mGLBindTextureId; + // glTexEnvf + HashMap<Integer, Float> mGLTexEnv0 = new HashMap<Integer, Float>(); + HashMap<Integer, Float> mGLTexEnv1 = new HashMap<Integer, Float>(); + // glActiveTexture + int mGLActiveTexture = GL11.GL_TEXTURE0; + + @Override + public void glClear(int mask) { + mGLClearCalled++; + mGLClearMask = mask; + } + + @Override + public void glBlendFunc(int sfactor, int dfactor) { + mGLBlendFuncSFactor = sfactor; + mGLBlendFuncDFactor = dfactor; + mGLBlendFuncCalled++; + } + + @Override + public void glColor4f(float red, float green, float blue, + float alpha) { + mGLColorCalled++; + mGLColor = makeColor4f(red, green, blue, alpha); + } + + @Override + public void glColor4x(int red, int green, int blue, int alpha) { + mGLColorCalled++; + mGLColor = makeColor4x(red, green, blue, alpha); + } + + @Override + public void glEnable(int cap) { + if (cap == GL11.GL_BLEND) { + mGLBlendEnabled = true; + } else if (cap == GL11.GL_STENCIL_TEST) { + mGLStencilEnabled = true; + } + } + + @Override + public void glDisable(int cap) { + if (cap == GL11.GL_BLEND) { + mGLBlendEnabled = false; + } else if (cap == GL11.GL_STENCIL_TEST) { + mGLStencilEnabled = false; + } + } + + @Override + public void glEnableClientState(int array) { + if (array == GL10.GL_VERTEX_ARRAY) { + mGLVertexArrayEnabled = true; + } + } + + @Override + public void glVertexPointer(int size, int type, int stride, Buffer pointer) { + mGLVertexPointer = new PointerInfo(size, type, stride, pointer); + } + + @Override + public void glMatrixMode(int mode) { + mGLMatrixMode = mode; + } + + @Override + public void glLoadMatrixf(float[] m, int offset) { + if (mGLMatrixMode == GL10.GL_MODELVIEW) { + System.arraycopy(m, offset, mGLModelViewMatrix, 0, 16); + } else if (mGLMatrixMode == GL10.GL_PROJECTION) { + System.arraycopy(m, offset, mGLProjectionMatrix, 0, 16); + } + } + + @Override + public void glOrthof( + float left, float right, float bottom, float top, + float zNear, float zFar) { + float tx = -(right + left) / (right - left); + float ty = -(top + bottom) / (top - bottom); + float tz = - (zFar + zNear) / (zFar - zNear); + float[] m = new float[] { + 2 / (right - left), 0, 0, 0, + 0, 2 / (top - bottom), 0, 0, + 0, 0, -2 / (zFar - zNear), 0, + tx, ty, tz, 1 + }; + glLoadMatrixf(m, 0); + } + + @Override + public void glBindTexture(int target, int texture) { + if (target == GL11.GL_TEXTURE_2D) { + mGLBindTextureId = texture; + } + } + + @Override + public void glTexEnvf(int target, int pname, float param) { + if (target == GL11.GL_TEXTURE_ENV) { + if (mGLActiveTexture == GL11.GL_TEXTURE0) { + mGLTexEnv0.put(pname, param); + } else if (mGLActiveTexture == GL11.GL_TEXTURE1) { + mGLTexEnv1.put(pname, param); + } else { + throw new AssertionError(); + } + } + } + + public int getTexEnvi(int pname) { + return getTexEnvi(mGLActiveTexture, pname); + } + + public int getTexEnvi(int activeTexture, int pname) { + if (activeTexture == GL11.GL_TEXTURE0) { + return (int) mGLTexEnv0.get(pname).floatValue(); + } else if (activeTexture == GL11.GL_TEXTURE1) { + return (int) mGLTexEnv1.get(pname).floatValue(); + } else { + throw new AssertionError(); + } + } + + @Override + public void glActiveTexture(int texture) { + mGLActiveTexture = texture; + } + + public static int makeColor4f(float red, float green, float blue, + float alpha) { + return (Math.round(alpha * 255) << 24) | + (Math.round(red * 255) << 16) | + (Math.round(green * 255) << 8) | + Math.round(blue * 255); + } + + public static int makeColor4x(int red, int green, int blue, int alpha) { + final float X = 65536f; + return makeColor4f(red / X, green / X, blue / X, alpha / X); + } +} diff --git a/tests/src/com/android/gallery3d/ui/GLRootMock.java b/tests/src/com/android/gallery3d/ui/GLRootMock.java new file mode 100644 index 000000000..c83e94342 --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLRootMock.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import com.android.gallery3d.anim.CanvasAnimation; + +public class GLRootMock implements GLRoot { + int mRequestRenderCalled; + int mRequestLayoutContentPaneCalled; + + public void addOnGLIdleListener(OnGLIdleListener listener) {} + public void registerLaunchedAnimation(CanvasAnimation animation) {} + public void requestRender() { + mRequestRenderCalled++; + } + public void requestLayoutContentPane() { + mRequestLayoutContentPaneCalled++; + } + public boolean hasStencil() { return true; } + public void lockRenderThread() {} + public void unlockRenderThread() {} + public void setContentPane(GLView content) {} +} diff --git a/tests/src/com/android/gallery3d/ui/GLRootStub.java b/tests/src/com/android/gallery3d/ui/GLRootStub.java new file mode 100644 index 000000000..d6bc678d4 --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLRootStub.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import com.android.gallery3d.anim.CanvasAnimation; + +public class GLRootStub implements GLRoot { + public void addOnGLIdleListener(OnGLIdleListener listener) {} + public void registerLaunchedAnimation(CanvasAnimation animation) {} + public void requestRender() {} + public void requestLayoutContentPane() {} + public boolean hasStencil() { return true; } + public void lockRenderThread() {} + public void unlockRenderThread() {} + public void setContentPane(GLView content) {} +} diff --git a/tests/src/com/android/gallery3d/ui/GLStub.java b/tests/src/com/android/gallery3d/ui/GLStub.java new file mode 100644 index 000000000..2af73f905 --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLStub.java @@ -0,0 +1,1490 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import javax.microedition.khronos.opengles.GL; +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL10Ext; +import javax.microedition.khronos.opengles.GL11; +import javax.microedition.khronos.opengles.GL11Ext; + +public class GLStub implements GL, GL10, GL10Ext, GL11, GL11Ext { + @SuppressWarnings("unused") + private static final String TAG = "GLStub"; + + public void glActiveTexture( + int texture + ){} + + public void glAlphaFunc( + int func, + float ref + ){} + + public void glAlphaFuncx( + int func, + int ref + ){} + + public void glBindTexture( + int target, + int texture + ){} + + public void glBlendFunc( + int sfactor, + int dfactor + ){} + + public void glClear( + int mask + ){} + + public void glClearColor( + float red, + float green, + float blue, + float alpha + ){} + + public void glClearColorx( + int red, + int green, + int blue, + int alpha + ){} + + public void glClearDepthf( + float depth + ){} + + public void glClearDepthx( + int depth + ){} + + public void glClearStencil( + int s + ){} + + public void glClientActiveTexture( + int texture + ){} + + public void glColor4f( + float red, + float green, + float blue, + float alpha + ){} + + public void glColor4x( + int red, + int green, + int blue, + int alpha + ){} + + public void glColorMask( + boolean red, + boolean green, + boolean blue, + boolean alpha + ){} + + public void glColorPointer( + int size, + int type, + int stride, + java.nio.Buffer pointer + ){} + + public void glCompressedTexImage2D( + int target, + int level, + int internalformat, + int width, + int height, + int border, + int imageSize, + java.nio.Buffer data + ){} + + public void glCompressedTexSubImage2D( + int target, + int level, + int xoffset, + int yoffset, + int width, + int height, + int format, + int imageSize, + java.nio.Buffer data + ){} + + public void glCopyTexImage2D( + int target, + int level, + int internalformat, + int x, + int y, + int width, + int height, + int border + ){} + + public void glCopyTexSubImage2D( + int target, + int level, + int xoffset, + int yoffset, + int x, + int y, + int width, + int height + ){} + + public void glCullFace( + int mode + ){} + + public void glDeleteTextures( + int n, + int[] textures, + int offset + ){} + + public void glDeleteTextures( + int n, + java.nio.IntBuffer textures + ){} + + public void glDepthFunc( + int func + ){} + + public void glDepthMask( + boolean flag + ){} + + public void glDepthRangef( + float zNear, + float zFar + ){} + + public void glDepthRangex( + int zNear, + int zFar + ){} + + public void glDisable( + int cap + ){} + + public void glDisableClientState( + int array + ){} + + public void glDrawArrays( + int mode, + int first, + int count + ){} + + public void glDrawElements( + int mode, + int count, + int type, + java.nio.Buffer indices + ){} + + public void glEnable( + int cap + ){} + + public void glEnableClientState( + int array + ){} + + public void glFinish( + ){} + + public void glFlush( + ){} + + public void glFogf( + int pname, + float param + ){} + + public void glFogfv( + int pname, + float[] params, + int offset + ){} + + public void glFogfv( + int pname, + java.nio.FloatBuffer params + ){} + + public void glFogx( + int pname, + int param + ){} + + public void glFogxv( + int pname, + int[] params, + int offset + ){} + + public void glFogxv( + int pname, + java.nio.IntBuffer params + ){} + + public void glFrontFace( + int mode + ){} + + public void glFrustumf( + float left, + float right, + float bottom, + float top, + float zNear, + float zFar + ){} + + public void glFrustumx( + int left, + int right, + int bottom, + int top, + int zNear, + int zFar + ){} + + public void glGenTextures( + int n, + int[] textures, + int offset + ){} + + public void glGenTextures( + int n, + java.nio.IntBuffer textures + ){} + + public int glGetError( + ){ throw new UnsupportedOperationException(); } + + public void glGetIntegerv( + int pname, + int[] params, + int offset + ){} + + public void glGetIntegerv( + int pname, + java.nio.IntBuffer params + ){} + + public String glGetString( + int name + ){ throw new UnsupportedOperationException(); } + + public void glHint( + int target, + int mode + ){} + + public void glLightModelf( + int pname, + float param + ){} + + public void glLightModelfv( + int pname, + float[] params, + int offset + ){} + + public void glLightModelfv( + int pname, + java.nio.FloatBuffer params + ){} + + public void glLightModelx( + int pname, + int param + ){} + + public void glLightModelxv( + int pname, + int[] params, + int offset + ){} + + public void glLightModelxv( + int pname, + java.nio.IntBuffer params + ){} + + public void glLightf( + int light, + int pname, + float param + ){} + + public void glLightfv( + int light, + int pname, + float[] params, + int offset + ){} + + public void glLightfv( + int light, + int pname, + java.nio.FloatBuffer params + ){} + + public void glLightx( + int light, + int pname, + int param + ){} + + public void glLightxv( + int light, + int pname, + int[] params, + int offset + ){} + + public void glLightxv( + int light, + int pname, + java.nio.IntBuffer params + ){} + + public void glLineWidth( + float width + ){} + + public void glLineWidthx( + int width + ){} + + public void glLoadIdentity( + ){} + + public void glLoadMatrixf( + float[] m, + int offset + ){} + + public void glLoadMatrixf( + java.nio.FloatBuffer m + ){} + + public void glLoadMatrixx( + int[] m, + int offset + ){} + + public void glLoadMatrixx( + java.nio.IntBuffer m + ){} + + public void glLogicOp( + int opcode + ){} + + public void glMaterialf( + int face, + int pname, + float param + ){} + + public void glMaterialfv( + int face, + int pname, + float[] params, + int offset + ){} + + public void glMaterialfv( + int face, + int pname, + java.nio.FloatBuffer params + ){} + + public void glMaterialx( + int face, + int pname, + int param + ){} + + public void glMaterialxv( + int face, + int pname, + int[] params, + int offset + ){} + + public void glMaterialxv( + int face, + int pname, + java.nio.IntBuffer params + ){} + + public void glMatrixMode( + int mode + ){} + + public void glMultMatrixf( + float[] m, + int offset + ){} + + public void glMultMatrixf( + java.nio.FloatBuffer m + ){} + + public void glMultMatrixx( + int[] m, + int offset + ){} + + public void glMultMatrixx( + java.nio.IntBuffer m + ){} + + public void glMultiTexCoord4f( + int target, + float s, + float t, + float r, + float q + ){} + + public void glMultiTexCoord4x( + int target, + int s, + int t, + int r, + int q + ){} + + public void glNormal3f( + float nx, + float ny, + float nz + ){} + + public void glNormal3x( + int nx, + int ny, + int nz + ){} + + public void glNormalPointer( + int type, + int stride, + java.nio.Buffer pointer + ){} + + public void glOrthof( + float left, + float right, + float bottom, + float top, + float zNear, + float zFar + ){} + + public void glOrthox( + int left, + int right, + int bottom, + int top, + int zNear, + int zFar + ){} + + public void glPixelStorei( + int pname, + int param + ){} + + public void glPointSize( + float size + ){} + + public void glPointSizex( + int size + ){} + + public void glPolygonOffset( + float factor, + float units + ){} + + public void glPolygonOffsetx( + int factor, + int units + ){} + + public void glPopMatrix( + ){} + + public void glPushMatrix( + ){} + + public void glReadPixels( + int x, + int y, + int width, + int height, + int format, + int type, + java.nio.Buffer pixels + ){} + + public void glRotatef( + float angle, + float x, + float y, + float z + ){} + + public void glRotatex( + int angle, + int x, + int y, + int z + ){} + + public void glSampleCoverage( + float value, + boolean invert + ){} + + public void glSampleCoveragex( + int value, + boolean invert + ){} + + public void glScalef( + float x, + float y, + float z + ){} + + public void glScalex( + int x, + int y, + int z + ){} + + public void glScissor( + int x, + int y, + int width, + int height + ){} + + public void glShadeModel( + int mode + ){} + + public void glStencilFunc( + int func, + int ref, + int mask + ){} + + public void glStencilMask( + int mask + ){} + + public void glStencilOp( + int fail, + int zfail, + int zpass + ){} + + public void glTexCoordPointer( + int size, + int type, + int stride, + java.nio.Buffer pointer + ){} + + public void glTexEnvf( + int target, + int pname, + float param + ){} + + public void glTexEnvfv( + int target, + int pname, + float[] params, + int offset + ){} + + public void glTexEnvfv( + int target, + int pname, + java.nio.FloatBuffer params + ){} + + public void glTexEnvx( + int target, + int pname, + int param + ){} + + public void glTexEnvxv( + int target, + int pname, + int[] params, + int offset + ){} + + public void glTexEnvxv( + int target, + int pname, + java.nio.IntBuffer params + ){} + + public void glTexImage2D( + int target, + int level, + int internalformat, + int width, + int height, + int border, + int format, + int type, + java.nio.Buffer pixels + ){} + + public void glTexParameterf( + int target, + int pname, + float param + ){} + + public void glTexParameterx( + int target, + int pname, + int param + ){} + + public void glTexSubImage2D( + int target, + int level, + int xoffset, + int yoffset, + int width, + int height, + int format, + int type, + java.nio.Buffer pixels + ){} + + public void glTranslatef( + float x, + float y, + float z + ){} + + public void glTranslatex( + int x, + int y, + int z + ){} + + public void glVertexPointer( + int size, + int type, + int stride, + java.nio.Buffer pointer + ){} + + public void glViewport( + int x, + int y, + int width, + int height + ){} + + public int glQueryMatrixxOES( + int[] mantissa, + int mantissaOffset, + int[] exponent, + int exponentOffset + ){ throw new UnsupportedOperationException(); } + + public int glQueryMatrixxOES( + java.nio.IntBuffer mantissa, + java.nio.IntBuffer exponent + ){ throw new UnsupportedOperationException(); } + + public void glGetPointerv(int pname, java.nio.Buffer[] params){} + public void glBindBuffer( + int target, + int buffer + ){} + + public void glBufferData( + int target, + int size, + java.nio.Buffer data, + int usage + ){} + + public void glBufferSubData( + int target, + int offset, + int size, + java.nio.Buffer data + ){} + + public void glClipPlanef( + int plane, + float[] equation, + int offset + ){} + + public void glClipPlanef( + int plane, + java.nio.FloatBuffer equation + ){} + + public void glClipPlanex( + int plane, + int[] equation, + int offset + ){} + + public void glClipPlanex( + int plane, + java.nio.IntBuffer equation + ){} + + public void glColor4ub( + byte red, + byte green, + byte blue, + byte alpha + ){} + + public void glColorPointer( + int size, + int type, + int stride, + int offset + ){} + + public void glDeleteBuffers( + int n, + int[] buffers, + int offset + ){} + + public void glDeleteBuffers( + int n, + java.nio.IntBuffer buffers + ){} + + public void glDrawElements( + int mode, + int count, + int type, + int offset + ){} + + public void glGenBuffers( + int n, + int[] buffers, + int offset + ){} + + public void glGenBuffers( + int n, + java.nio.IntBuffer buffers + ){} + + public void glGetBooleanv( + int pname, + boolean[] params, + int offset + ){} + + public void glGetBooleanv( + int pname, + java.nio.IntBuffer params + ){} + + public void glGetBufferParameteriv( + int target, + int pname, + int[] params, + int offset + ){} + + public void glGetBufferParameteriv( + int target, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetClipPlanef( + int pname, + float[] eqn, + int offset + ){} + + public void glGetClipPlanef( + int pname, + java.nio.FloatBuffer eqn + ){} + + public void glGetClipPlanex( + int pname, + int[] eqn, + int offset + ){} + + public void glGetClipPlanex( + int pname, + java.nio.IntBuffer eqn + ){} + + public void glGetFixedv( + int pname, + int[] params, + int offset + ){} + + public void glGetFixedv( + int pname, + java.nio.IntBuffer params + ){} + + public void glGetFloatv( + int pname, + float[] params, + int offset + ){} + + public void glGetFloatv( + int pname, + java.nio.FloatBuffer params + ){} + + public void glGetLightfv( + int light, + int pname, + float[] params, + int offset + ){} + + public void glGetLightfv( + int light, + int pname, + java.nio.FloatBuffer params + ){} + + public void glGetLightxv( + int light, + int pname, + int[] params, + int offset + ){} + + public void glGetLightxv( + int light, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetMaterialfv( + int face, + int pname, + float[] params, + int offset + ){} + + public void glGetMaterialfv( + int face, + int pname, + java.nio.FloatBuffer params + ){} + + public void glGetMaterialxv( + int face, + int pname, + int[] params, + int offset + ){} + + public void glGetMaterialxv( + int face, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetTexEnviv( + int env, + int pname, + int[] params, + int offset + ){} + + public void glGetTexEnviv( + int env, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetTexEnvxv( + int env, + int pname, + int[] params, + int offset + ){} + + public void glGetTexEnvxv( + int env, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetTexParameterfv( + int target, + int pname, + float[] params, + int offset + ){} + + public void glGetTexParameterfv( + int target, + int pname, + java.nio.FloatBuffer params + ){} + + public void glGetTexParameteriv( + int target, + int pname, + int[] params, + int offset + ){} + + public void glGetTexParameteriv( + int target, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetTexParameterxv( + int target, + int pname, + int[] params, + int offset + ){} + + public void glGetTexParameterxv( + int target, + int pname, + java.nio.IntBuffer params + ){} + + public boolean glIsBuffer( + int buffer + ){ throw new UnsupportedOperationException(); } + + public boolean glIsEnabled( + int cap + ){ throw new UnsupportedOperationException(); } + + public boolean glIsTexture( + int texture + ){ throw new UnsupportedOperationException(); } + + public void glNormalPointer( + int type, + int stride, + int offset + ){} + + public void glPointParameterf( + int pname, + float param + ){} + + public void glPointParameterfv( + int pname, + float[] params, + int offset + ){} + + public void glPointParameterfv( + int pname, + java.nio.FloatBuffer params + ){} + + public void glPointParameterx( + int pname, + int param + ){} + + public void glPointParameterxv( + int pname, + int[] params, + int offset + ){} + + public void glPointParameterxv( + int pname, + java.nio.IntBuffer params + ){} + + public void glPointSizePointerOES( + int type, + int stride, + java.nio.Buffer pointer + ){} + + public void glTexCoordPointer( + int size, + int type, + int stride, + int offset + ){} + + public void glTexEnvi( + int target, + int pname, + int param + ){} + + public void glTexEnviv( + int target, + int pname, + int[] params, + int offset + ){} + + public void glTexEnviv( + int target, + int pname, + java.nio.IntBuffer params + ){} + + public void glTexParameterfv( + int target, + int pname, + float[] params, + int offset + ){} + + public void glTexParameterfv( + int target, + int pname, + java.nio.FloatBuffer params + ){} + + public void glTexParameteri( + int target, + int pname, + int param + ){} + + public void glTexParameteriv( + int target, + int pname, + int[] params, + int offset + ){} + + public void glTexParameteriv( + int target, + int pname, + java.nio.IntBuffer params + ){} + + public void glTexParameterxv( + int target, + int pname, + int[] params, + int offset + ){} + + public void glTexParameterxv( + int target, + int pname, + java.nio.IntBuffer params + ){} + + public void glVertexPointer( + int size, + int type, + int stride, + int offset + ){} + + public void glCurrentPaletteMatrixOES( + int matrixpaletteindex + ){} + + public void glDrawTexfOES( + float x, + float y, + float z, + float width, + float height + ){} + + public void glDrawTexfvOES( + float[] coords, + int offset + ){} + + public void glDrawTexfvOES( + java.nio.FloatBuffer coords + ){} + + public void glDrawTexiOES( + int x, + int y, + int z, + int width, + int height + ){} + + public void glDrawTexivOES( + int[] coords, + int offset + ){} + + public void glDrawTexivOES( + java.nio.IntBuffer coords + ){} + + public void glDrawTexsOES( + short x, + short y, + short z, + short width, + short height + ){} + + public void glDrawTexsvOES( + short[] coords, + int offset + ){} + + public void glDrawTexsvOES( + java.nio.ShortBuffer coords + ){} + + public void glDrawTexxOES( + int x, + int y, + int z, + int width, + int height + ){} + + public void glDrawTexxvOES( + int[] coords, + int offset + ){} + + public void glDrawTexxvOES( + java.nio.IntBuffer coords + ){} + + public void glLoadPaletteFromModelViewMatrixOES( + ){} + + public void glMatrixIndexPointerOES( + int size, + int type, + int stride, + java.nio.Buffer pointer + ){} + + public void glMatrixIndexPointerOES( + int size, + int type, + int stride, + int offset + ){} + + public void glWeightPointerOES( + int size, + int type, + int stride, + java.nio.Buffer pointer + ){} + + public void glWeightPointerOES( + int size, + int type, + int stride, + int offset + ){} + + public void glBindFramebufferOES( + int target, + int framebuffer + ){} + + public void glBindRenderbufferOES( + int target, + int renderbuffer + ){} + + public void glBlendEquation( + int mode + ){} + + public void glBlendEquationSeparate( + int modeRGB, + int modeAlpha + ){} + + public void glBlendFuncSeparate( + int srcRGB, + int dstRGB, + int srcAlpha, + int dstAlpha + ){} + + public int glCheckFramebufferStatusOES( + int target + ){ throw new UnsupportedOperationException(); } + + public void glDeleteFramebuffersOES( + int n, + int[] framebuffers, + int offset + ){} + + public void glDeleteFramebuffersOES( + int n, + java.nio.IntBuffer framebuffers + ){} + + public void glDeleteRenderbuffersOES( + int n, + int[] renderbuffers, + int offset + ){} + + public void glDeleteRenderbuffersOES( + int n, + java.nio.IntBuffer renderbuffers + ){} + + public void glFramebufferRenderbufferOES( + int target, + int attachment, + int renderbuffertarget, + int renderbuffer + ){} + + public void glFramebufferTexture2DOES( + int target, + int attachment, + int textarget, + int texture, + int level + ){} + + public void glGenerateMipmapOES( + int target + ){} + + public void glGenFramebuffersOES( + int n, + int[] framebuffers, + int offset + ){} + + public void glGenFramebuffersOES( + int n, + java.nio.IntBuffer framebuffers + ){} + + public void glGenRenderbuffersOES( + int n, + int[] renderbuffers, + int offset + ){} + + public void glGenRenderbuffersOES( + int n, + java.nio.IntBuffer renderbuffers + ){} + + public void glGetFramebufferAttachmentParameterivOES( + int target, + int attachment, + int pname, + int[] params, + int offset + ){} + + public void glGetFramebufferAttachmentParameterivOES( + int target, + int attachment, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetRenderbufferParameterivOES( + int target, + int pname, + int[] params, + int offset + ){} + + public void glGetRenderbufferParameterivOES( + int target, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetTexGenfv( + int coord, + int pname, + float[] params, + int offset + ){} + + public void glGetTexGenfv( + int coord, + int pname, + java.nio.FloatBuffer params + ){} + + public void glGetTexGeniv( + int coord, + int pname, + int[] params, + int offset + ){} + + public void glGetTexGeniv( + int coord, + int pname, + java.nio.IntBuffer params + ){} + + public void glGetTexGenxv( + int coord, + int pname, + int[] params, + int offset + ){} + + public void glGetTexGenxv( + int coord, + int pname, + java.nio.IntBuffer params + ){} + + public boolean glIsFramebufferOES( + int framebuffer + ){ throw new UnsupportedOperationException(); } + + public boolean glIsRenderbufferOES( + int renderbuffer + ){ throw new UnsupportedOperationException(); } + + public void glRenderbufferStorageOES( + int target, + int internalformat, + int width, + int height + ){} + + public void glTexGenf( + int coord, + int pname, + float param + ){} + + public void glTexGenfv( + int coord, + int pname, + float[] params, + int offset + ){} + + public void glTexGenfv( + int coord, + int pname, + java.nio.FloatBuffer params + ){} + + public void glTexGeni( + int coord, + int pname, + int param + ){} + + public void glTexGeniv( + int coord, + int pname, + int[] params, + int offset + ){} + + public void glTexGeniv( + int coord, + int pname, + java.nio.IntBuffer params + ){} + + public void glTexGenx( + int coord, + int pname, + int param + ){} + + public void glTexGenxv( + int coord, + int pname, + int[] params, + int offset + ){} + + public void glTexGenxv( + int coord, + int pname, + java.nio.IntBuffer params + ){} +} diff --git a/tests/src/com/android/gallery3d/ui/GLViewMock.java b/tests/src/com/android/gallery3d/ui/GLViewMock.java new file mode 100644 index 000000000..7b941daad --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLViewMock.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +class GLViewMock extends GLView { + // onAttachToRoot + int mOnAttachCalled; + GLRoot mRoot; + // onDetachFromRoot + int mOnDetachCalled; + // onVisibilityChanged + int mOnVisibilityChangedCalled; + // onLayout + int mOnLayoutCalled; + boolean mOnLayoutChangeSize; + // renderBackground + int mRenderBackgroundCalled; + // onMeasure + int mOnMeasureCalled; + int mOnMeasureWidthSpec; + int mOnMeasureHeightSpec; + + @Override + public void onAttachToRoot(GLRoot root) { + mRoot = root; + mOnAttachCalled++; + super.onAttachToRoot(root); + } + + @Override + public void onDetachFromRoot() { + mRoot = null; + mOnDetachCalled++; + super.onDetachFromRoot(); + } + + @Override + protected void onVisibilityChanged(int visibility) { + mOnVisibilityChangedCalled++; + } + + @Override + protected void onLayout(boolean changeSize, int left, int top, + int right, int bottom) { + mOnLayoutCalled++; + mOnLayoutChangeSize = changeSize; + // call children's layout. + for (int i = 0, n = getComponentCount(); i < n; ++i) { + GLView item = getComponent(i); + item.layout(left, top, right, bottom); + } + } + + @Override + protected void onMeasure(int widthSpec, int heightSpec) { + mOnMeasureCalled++; + mOnMeasureWidthSpec = widthSpec; + mOnMeasureHeightSpec = heightSpec; + // call children's measure. + for (int i = 0, n = getComponentCount(); i < n; ++i) { + GLView item = getComponent(i); + item.measure(widthSpec, heightSpec); + } + setMeasuredSize(widthSpec, heightSpec); + } + + @Override + protected void renderBackground(GLCanvas view) { + mRenderBackgroundCalled++; + } +} diff --git a/tests/src/com/android/gallery3d/ui/GLViewTest.java b/tests/src/com/android/gallery3d/ui/GLViewTest.java new file mode 100644 index 000000000..a9377bfee --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/GLViewTest.java @@ -0,0 +1,424 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import android.graphics.Rect; +import android.test.suitebuilder.annotation.SmallTest; +import android.view.MotionEvent; + +import junit.framework.TestCase; + +@SmallTest +public class GLViewTest extends TestCase { + @SuppressWarnings("unused") + private static final String TAG = "GLViewTest"; + + @SmallTest + public void testVisibility() { + GLViewMock a = new GLViewMock(); + assertEquals(GLView.VISIBLE, a.getVisibility()); + assertEquals(0, a.mOnVisibilityChangedCalled); + a.setVisibility(GLView.INVISIBLE); + assertEquals(GLView.INVISIBLE, a.getVisibility()); + assertEquals(1, a.mOnVisibilityChangedCalled); + a.setVisibility(GLView.VISIBLE); + assertEquals(GLView.VISIBLE, a.getVisibility()); + assertEquals(2, a.mOnVisibilityChangedCalled); + } + + @SmallTest + public void testComponents() { + GLView view = new GLView(); + assertEquals(0, view.getComponentCount()); + try { + view.getComponent(0); + fail(); + } catch (IndexOutOfBoundsException ex) { + // expected + } + + GLView x = new GLView(); + GLView y = new GLView(); + view.addComponent(x); + view.addComponent(y); + assertEquals(2, view.getComponentCount()); + assertSame(x, view.getComponent(0)); + assertSame(y, view.getComponent(1)); + view.removeComponent(x); + assertSame(y, view.getComponent(0)); + try { + view.getComponent(1); + fail(); + } catch (IndexOutOfBoundsException ex) { + // expected + } + try { + view.addComponent(y); + fail(); + } catch (IllegalStateException ex) { + // expected + } + view.addComponent(x); + view.removeAllComponents(); + assertEquals(0, view.getComponentCount()); + } + + @SmallTest + public void testBounds() { + GLView view = new GLView(); + + assertEquals(0, view.getWidth()); + assertEquals(0, view.getHeight()); + + Rect b = view.bounds(); + assertEquals(0, b.left); + assertEquals(0, b.top); + assertEquals(0, b.right); + assertEquals(0, b.bottom); + + view.layout(10, 20, 30, 100); + assertEquals(20, view.getWidth()); + assertEquals(80, view.getHeight()); + + b = view.bounds(); + assertEquals(10, b.left); + assertEquals(20, b.top); + assertEquals(30, b.right); + assertEquals(100, b.bottom); + } + + @SmallTest + public void testPaddings() { + GLView view = new GLView(); + + Rect p = view.getPaddings(); + assertEquals(0, p.left); + assertEquals(0, p.top); + assertEquals(0, p.right); + assertEquals(0, p.bottom); + + view.setPaddings(10, 20, 30, 100); + p = view.getPaddings(); + assertEquals(10, p.left); + assertEquals(20, p.top); + assertEquals(30, p.right); + assertEquals(100, p.bottom); + + p = new Rect(11, 22, 33, 104); + view.setPaddings(p); + p = view.getPaddings(); + assertEquals(11, p.left); + assertEquals(22, p.top); + assertEquals(33, p.right); + assertEquals(104, p.bottom); + } + + @SmallTest + public void testParent() { + GLView a = new GLView(); + GLView b = new GLView(); + assertNull(b.mParent); + a.addComponent(b); + assertSame(a, b.mParent); + a.removeComponent(b); + assertNull(b.mParent); + } + + @SmallTest + public void testRoot() { + GLViewMock a = new GLViewMock(); + GLViewMock b = new GLViewMock(); + GLRoot r = new GLRootStub(); + GLRoot r2 = new GLRootStub(); + a.addComponent(b); + + // Attach to root r + assertEquals(0, a.mOnAttachCalled); + assertEquals(0, b.mOnAttachCalled); + a.attachToRoot(r); + assertEquals(1, a.mOnAttachCalled); + assertEquals(1, b.mOnAttachCalled); + assertSame(r, a.getGLRoot()); + assertSame(r, b.getGLRoot()); + + // Detach from r + assertEquals(0, a.mOnDetachCalled); + assertEquals(0, b.mOnDetachCalled); + a.detachFromRoot(); + assertEquals(1, a.mOnDetachCalled); + assertEquals(1, b.mOnDetachCalled); + + // Attach to another root r2 + assertEquals(1, a.mOnAttachCalled); + assertEquals(1, b.mOnAttachCalled); + a.attachToRoot(r2); + assertEquals(2, a.mOnAttachCalled); + assertEquals(2, b.mOnAttachCalled); + assertSame(r2, a.getGLRoot()); + assertSame(r2, b.getGLRoot()); + + // Detach from r2 + assertEquals(1, a.mOnDetachCalled); + assertEquals(1, b.mOnDetachCalled); + a.detachFromRoot(); + assertEquals(2, a.mOnDetachCalled); + assertEquals(2, b.mOnDetachCalled); + } + + @SmallTest + public void testRoot2() { + GLView a = new GLViewMock(); + GLViewMock b = new GLViewMock(); + GLRoot r = new GLRootStub(); + + a.attachToRoot(r); + + assertEquals(0, b.mOnAttachCalled); + a.addComponent(b); + assertEquals(1, b.mOnAttachCalled); + + assertEquals(0, b.mOnDetachCalled); + a.removeComponent(b); + assertEquals(1, b.mOnDetachCalled); + } + + @SmallTest + public void testInvalidate() { + GLView a = new GLView(); + GLRootMock r = new GLRootMock(); + a.attachToRoot(r); + assertEquals(0, r.mRequestRenderCalled); + a.invalidate(); + assertEquals(1, r.mRequestRenderCalled); + } + + @SmallTest + public void testRequestLayout() { + GLView a = new GLView(); + GLView b = new GLView(); + GLRootMock r = new GLRootMock(); + a.attachToRoot(r); + a.addComponent(b); + assertEquals(0, r.mRequestLayoutContentPaneCalled); + b.requestLayout(); + assertEquals(1, r.mRequestLayoutContentPaneCalled); + } + + @SmallTest + public void testLayout() { + GLViewMock a = new GLViewMock(); + GLViewMock b = new GLViewMock(); + GLViewMock c = new GLViewMock(); + GLRootMock r = new GLRootMock(); + + a.attachToRoot(r); + a.addComponent(b); + a.addComponent(c); + + assertEquals(0, a.mOnLayoutCalled); + a.layout(10, 20, 60, 100); + assertEquals(1, a.mOnLayoutCalled); + assertEquals(1, b.mOnLayoutCalled); + assertEquals(1, c.mOnLayoutCalled); + assertTrue(a.mOnLayoutChangeSize); + assertTrue(b.mOnLayoutChangeSize); + assertTrue(c.mOnLayoutChangeSize); + + // same size should not trigger onLayout + a.layout(10, 20, 60, 100); + assertEquals(1, a.mOnLayoutCalled); + + // unless someone requested it, but only those on the path + // to the requester. + assertEquals(0, r.mRequestLayoutContentPaneCalled); + b.requestLayout(); + a.layout(10, 20, 60, 100); + assertEquals(1, r.mRequestLayoutContentPaneCalled); + assertEquals(2, a.mOnLayoutCalled); + assertEquals(2, b.mOnLayoutCalled); + assertEquals(1, c.mOnLayoutCalled); + } + + @SmallTest + public void testRender() { + GLViewMock a = new GLViewMock(); + GLViewMock b = new GLViewMock(); + + a.addComponent(b); + GLCanvasStub canvas = new GLCanvasStub(); + assertEquals(0, a.mRenderBackgroundCalled); + assertEquals(0, b.mRenderBackgroundCalled); + a.render(canvas); + assertEquals(1, a.mRenderBackgroundCalled); + assertEquals(1, b.mRenderBackgroundCalled); + } + + @SmallTest + public void testMeasure() { + GLViewMock a = new GLViewMock(); + GLViewMock b = new GLViewMock(); + GLViewMock c = new GLViewMock(); + GLRootMock r = new GLRootMock(); + + a.addComponent(b); + a.addComponent(c); + a.attachToRoot(r); + + assertEquals(0, a.mOnMeasureCalled); + a.measure(100, 200); + assertEquals(1, a.mOnMeasureCalled); + assertEquals(1, b.mOnMeasureCalled); + assertEquals(100, a.mOnMeasureWidthSpec); + assertEquals(200, a.mOnMeasureHeightSpec); + assertEquals(100, b.mOnMeasureWidthSpec); + assertEquals(200, b.mOnMeasureHeightSpec); + assertEquals(100, a.getMeasuredWidth()); + assertEquals(200, b.getMeasuredHeight()); + + // same spec should not trigger onMeasure + a.measure(100, 200); + assertEquals(1, a.mOnMeasureCalled); + + // unless someone requested it, but only those on the path + // to the requester. + b.requestLayout(); + a.measure(100, 200); + assertEquals(2, a.mOnMeasureCalled); + assertEquals(2, b.mOnMeasureCalled); + assertEquals(1, c.mOnMeasureCalled); + } + + class MyGLView extends GLView { + private int mWidth; + int mOnTouchCalled; + int mOnTouchX; + int mOnTouchY; + int mOnTouchAction; + + public MyGLView(int width) { + mWidth = width; + } + + @Override + protected void onLayout(boolean changeSize, int left, int top, + int right, int bottom) { + // layout children from left to right + // call children's layout. + int x = 0; + for (int i = 0, n = getComponentCount(); i < n; ++i) { + GLView item = getComponent(i); + item.measure(0, 0); + int w = item.getMeasuredWidth(); + int h = item.getMeasuredHeight(); + item.layout(x, 0, x + w, h); + x += w; + } + } + + @Override + protected void onMeasure(int widthSpec, int heightSpec) { + setMeasuredSize(mWidth, 100); + } + + @Override + protected boolean onTouch(MotionEvent event) { + mOnTouchCalled++; + mOnTouchX = (int) event.getX(); + mOnTouchY = (int) event.getY(); + mOnTouchAction = event.getAction(); + return true; + } + } + + private MotionEvent NewMotionEvent(int action, int x, int y) { + return MotionEvent.obtain(0, 0, action, x, y, 0); + } + + @SmallTest + public void testTouchEvent() { + // We construct a tree with four nodes. Only the x coordinate is used: + // A = [0..............................300) + // B = [0......100) + // C = [100......200) + // D = [100..150) + + MyGLView a = new MyGLView(300); + MyGLView b = new MyGLView(100); + MyGLView c = new MyGLView(100); + MyGLView d = new MyGLView(50); + GLRoot r = new GLRootStub(); + + a.addComponent(b); + a.addComponent(c); + c.addComponent(d); + a.attachToRoot(r); + a.layout(0, 0, 300, 100); + + int DOWN = MotionEvent.ACTION_DOWN; + int UP = MotionEvent.ACTION_UP; + int MOVE = MotionEvent.ACTION_MOVE; + int CANCEL = MotionEvent.ACTION_CANCEL; + + // simple case + assertEquals(0, a.mOnTouchCalled); + a.dispatchTouchEvent(NewMotionEvent(DOWN, 250, 0)); + assertEquals(DOWN, a.mOnTouchAction); + a.dispatchTouchEvent(NewMotionEvent(UP, 250, 0)); + assertEquals(UP, a.mOnTouchAction); + assertEquals(2, a.mOnTouchCalled); + + // pass to a child, check the location is offseted. + assertEquals(0, c.mOnTouchCalled); + a.dispatchTouchEvent(NewMotionEvent(DOWN, 175, 0)); + a.dispatchTouchEvent(NewMotionEvent(UP, 175, 0)); + assertEquals(75, c.mOnTouchX); + assertEquals(0, c.mOnTouchY); + assertEquals(2, c.mOnTouchCalled); + assertEquals(2, a.mOnTouchCalled); + + // motion target cancel event + assertEquals(0, d.mOnTouchCalled); + a.dispatchTouchEvent(NewMotionEvent(DOWN, 125, 0)); + assertEquals(1, d.mOnTouchCalled); + a.dispatchTouchEvent(NewMotionEvent(MOVE, 250, 0)); + assertEquals(2, d.mOnTouchCalled); + a.dispatchTouchEvent(NewMotionEvent(MOVE, 50, 0)); + assertEquals(3, d.mOnTouchCalled); + a.dispatchTouchEvent(NewMotionEvent(DOWN, 175, 0)); + assertEquals(4, d.mOnTouchCalled); + assertEquals(CANCEL, d.mOnTouchAction); + assertEquals(3, c.mOnTouchCalled); + assertEquals(DOWN, c.mOnTouchAction); + a.dispatchTouchEvent(NewMotionEvent(UP, 175, 0)); + + // motion target is removed + assertEquals(4, d.mOnTouchCalled); + a.dispatchTouchEvent(NewMotionEvent(DOWN, 125, 0)); + assertEquals(5, d.mOnTouchCalled); + a.removeComponent(c); + assertEquals(6, d.mOnTouchCalled); + assertEquals(CANCEL, d.mOnTouchAction); + + // invisible component should not get events + assertEquals(2, a.mOnTouchCalled); + assertEquals(0, b.mOnTouchCalled); + b.setVisibility(GLView.INVISIBLE); + a.dispatchTouchEvent(NewMotionEvent(DOWN, 50, 0)); + assertEquals(3, a.mOnTouchCalled); + assertEquals(0, b.mOnTouchCalled); + } +} diff --git a/tests/src/com/android/gallery3d/ui/PointerInfo.java b/tests/src/com/android/gallery3d/ui/PointerInfo.java new file mode 100644 index 000000000..6c78556e1 --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/PointerInfo.java @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.CharBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; + +import javax.microedition.khronos.opengles.GL10; + +public class PointerInfo { + + /** + * The number of coordinates per vertex. 1..4 + */ + public int mSize; + + /** + * The type of each coordinate. + */ + public int mType; + + /** + * The byte offset between consecutive vertices. 0 means mSize * + * sizeof(mType) + */ + public int mStride; + public Buffer mPointer; + public ByteBuffer mTempByteBuffer; + + public PointerInfo(int size, int type, int stride, Buffer pointer) { + mSize = size; + mType = type; + mStride = stride; + mPointer = pointer; + } + + private int getStride() { + return mStride > 0 ? mStride : sizeof(mType) * mSize; + } + + public void bindByteBuffer() { + mTempByteBuffer = mPointer == null ? null : toByteBuffer(-1, mPointer); + } + + public void unbindByteBuffer() { + mTempByteBuffer = null; + } + + private static int sizeof(int type) { + switch (type) { + case GL10.GL_UNSIGNED_BYTE: + return 1; + case GL10.GL_BYTE: + return 1; + case GL10.GL_SHORT: + return 2; + case GL10.GL_FIXED: + return 4; + case GL10.GL_FLOAT: + return 4; + default: + return 0; + } + } + + private static ByteBuffer toByteBuffer(int byteCount, Buffer input) { + ByteBuffer result = null; + boolean convertWholeBuffer = (byteCount < 0); + if (input instanceof ByteBuffer) { + ByteBuffer input2 = (ByteBuffer) input; + int position = input2.position(); + if (convertWholeBuffer) { + byteCount = input2.limit() - position; + } + result = ByteBuffer.allocate(byteCount).order(input2.order()); + for (int i = 0; i < byteCount; i++) { + result.put(input2.get()); + } + input2.position(position); + } else if (input instanceof CharBuffer) { + CharBuffer input2 = (CharBuffer) input; + int position = input2.position(); + if (convertWholeBuffer) { + byteCount = (input2.limit() - position) * 2; + } + result = ByteBuffer.allocate(byteCount).order(input2.order()); + CharBuffer result2 = result.asCharBuffer(); + for (int i = 0; i < byteCount / 2; i++) { + result2.put(input2.get()); + } + input2.position(position); + } else if (input instanceof ShortBuffer) { + ShortBuffer input2 = (ShortBuffer) input; + int position = input2.position(); + if (convertWholeBuffer) { + byteCount = (input2.limit() - position)* 2; + } + result = ByteBuffer.allocate(byteCount).order(input2.order()); + ShortBuffer result2 = result.asShortBuffer(); + for (int i = 0; i < byteCount / 2; i++) { + result2.put(input2.get()); + } + input2.position(position); + } else if (input instanceof IntBuffer) { + IntBuffer input2 = (IntBuffer) input; + int position = input2.position(); + if (convertWholeBuffer) { + byteCount = (input2.limit() - position) * 4; + } + result = ByteBuffer.allocate(byteCount).order(input2.order()); + IntBuffer result2 = result.asIntBuffer(); + for (int i = 0; i < byteCount / 4; i++) { + result2.put(input2.get()); + } + input2.position(position); + } else if (input instanceof FloatBuffer) { + FloatBuffer input2 = (FloatBuffer) input; + int position = input2.position(); + if (convertWholeBuffer) { + byteCount = (input2.limit() - position) * 4; + } + result = ByteBuffer.allocate(byteCount).order(input2.order()); + FloatBuffer result2 = result.asFloatBuffer(); + for (int i = 0; i < byteCount / 4; i++) { + result2.put(input2.get()); + } + input2.position(position); + } else if (input instanceof DoubleBuffer) { + DoubleBuffer input2 = (DoubleBuffer) input; + int position = input2.position(); + if (convertWholeBuffer) { + byteCount = (input2.limit() - position) * 8; + } + result = ByteBuffer.allocate(byteCount).order(input2.order()); + DoubleBuffer result2 = result.asDoubleBuffer(); + for (int i = 0; i < byteCount / 8; i++) { + result2.put(input2.get()); + } + input2.position(position); + } else if (input instanceof LongBuffer) { + LongBuffer input2 = (LongBuffer) input; + int position = input2.position(); + if (convertWholeBuffer) { + byteCount = (input2.limit() - position) * 8; + } + result = ByteBuffer.allocate(byteCount).order(input2.order()); + LongBuffer result2 = result.asLongBuffer(); + for (int i = 0; i < byteCount / 8; i++) { + result2.put(input2.get()); + } + input2.position(position); + } else { + throw new RuntimeException("Unimplemented Buffer subclass."); + } + result.rewind(); + // The OpenGL API will interpret the result in hardware byte order, + // so we better do that as well: + result.order(ByteOrder.nativeOrder()); + return result; + } + + public void getArrayElement(int index, double[] result) { + if (mTempByteBuffer == null) { + throw new IllegalArgumentException("undefined pointer"); + } + if (mStride < 0) { + throw new IllegalArgumentException("invalid stride"); + } + + int stride = getStride(); + ByteBuffer byteBuffer = mTempByteBuffer; + int size = mSize; + int type = mType; + int sizeofType = sizeof(type); + int byteOffset = stride * index; + + for (int i = 0; i < size; i++) { + switch (type) { + case GL10.GL_BYTE: + case GL10.GL_UNSIGNED_BYTE: + result[i] = byteBuffer.get(byteOffset); + break; + case GL10.GL_SHORT: + ShortBuffer shortBuffer = byteBuffer.asShortBuffer(); + result[i] = shortBuffer.get(byteOffset / 2); + break; + case GL10.GL_FIXED: + IntBuffer intBuffer = byteBuffer.asIntBuffer(); + result[i] = intBuffer.get(byteOffset / 4); + break; + case GL10.GL_FLOAT: + FloatBuffer floatBuffer = byteBuffer.asFloatBuffer(); + result[i] = floatBuffer.get(byteOffset / 4); + break; + default: + throw new UnsupportedOperationException("unknown type"); + } + byteOffset += sizeofType; + } + } +} diff --git a/tests/src/com/android/gallery3d/ui/TextureTest.java b/tests/src/com/android/gallery3d/ui/TextureTest.java new file mode 100644 index 000000000..fb26060bc --- /dev/null +++ b/tests/src/com/android/gallery3d/ui/TextureTest.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.ui; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.test.suitebuilder.annotation.SmallTest; + +import javax.microedition.khronos.opengles.GL11; + +import junit.framework.TestCase; + +@SmallTest +public class TextureTest extends TestCase { + @SuppressWarnings("unused") + private static final String TAG = "TextureTest"; + + class MyBasicTexture extends BasicTexture { + int mOnBindCalled; + int mOpaqueCalled; + + MyBasicTexture(GLCanvas canvas, int id) { + super(canvas, id, BasicTexture.STATE_UNLOADED); + } + + @Override + protected boolean onBind(GLCanvas canvas) { + mOnBindCalled++; + return true; + } + + public boolean isOpaque() { + mOpaqueCalled++; + return true; + } + + void upload() { + mState = STATE_LOADED; + } + } + + @SmallTest + public void testBasicTexture() { + GL11 glStub = new GLStub(); + GLCanvas canvas = new GLCanvasImpl(glStub); + MyBasicTexture texture = new MyBasicTexture(canvas, 47); + + assertEquals(47, texture.getId()); + texture.setSize(1, 1); + assertEquals(1, texture.getWidth()); + assertEquals(1, texture.getHeight()); + assertEquals(1, texture.getTextureWidth()); + assertEquals(1, texture.getTextureHeight()); + texture.setSize(3, 5); + assertEquals(3, texture.getWidth()); + assertEquals(5, texture.getHeight()); + assertEquals(4, texture.getTextureWidth()); + assertEquals(8, texture.getTextureHeight()); + + assertFalse(texture.isLoaded(canvas)); + texture.upload(); + assertTrue(texture.isLoaded(canvas)); + + // For a different GL, it's not loaded. + GLCanvas canvas2 = new GLCanvasImpl(new GLStub()); + assertFalse(texture.isLoaded(canvas2)); + + assertEquals(0, texture.mOnBindCalled); + assertEquals(0, texture.mOpaqueCalled); + texture.draw(canvas, 100, 200, 1, 1); + assertEquals(1, texture.mOnBindCalled); + assertEquals(1, texture.mOpaqueCalled); + texture.draw(canvas, 0, 0); + assertEquals(2, texture.mOnBindCalled); + assertEquals(2, texture.mOpaqueCalled); + } + + @SmallTest + public void testRawTexture() { + GL11 glStub = new GLStub(); + GLCanvas canvas = new GLCanvasImpl(glStub); + RawTexture texture = RawTexture.newInstance(canvas); + texture.onBind(canvas); + + GLCanvas canvas2 = new GLCanvasImpl(new GLStub()); + try { + texture.onBind(canvas2); + fail(); + } catch (RuntimeException ex) { + // expected. + } + + assertTrue(texture.isOpaque()); + } + + @SmallTest + public void testColorTexture() { + GLCanvasMock canvas = new GLCanvasMock(); + ColorTexture texture = new ColorTexture(0x12345678); + + texture.setSize(42, 47); + assertEquals(texture.getWidth(), 42); + assertEquals(texture.getHeight(), 47); + assertEquals(0, canvas.mFillRectCalled); + texture.draw(canvas, 0, 0); + assertEquals(1, canvas.mFillRectCalled); + assertEquals(0x12345678, canvas.mFillRectColor); + assertEquals(42f, canvas.mFillRectWidth); + assertEquals(47f, canvas.mFillRectHeight); + assertFalse(texture.isOpaque()); + assertTrue(new ColorTexture(0xFF000000).isOpaque()); + } + + private class MyUploadedTexture extends UploadedTexture { + int mGetCalled; + int mFreeCalled; + Bitmap mBitmap; + @Override + protected Bitmap onGetBitmap() { + mGetCalled++; + Config config = Config.ARGB_8888; + mBitmap = Bitmap.createBitmap(47, 42, config); + return mBitmap; + } + @Override + protected void onFreeBitmap(Bitmap bitmap) { + mFreeCalled++; + assertSame(mBitmap, bitmap); + mBitmap.recycle(); + mBitmap = null; + } + } + + @SmallTest + public void testUploadedTexture() { + GL11 glStub = new GLStub(); + GLCanvas canvas = new GLCanvasImpl(glStub); + MyUploadedTexture texture = new MyUploadedTexture(); + + // draw it and the bitmap should be fetched. + assertEquals(0, texture.mFreeCalled); + assertEquals(0, texture.mGetCalled); + texture.draw(canvas, 0, 0); + assertEquals(1, texture.mGetCalled); + assertTrue(texture.isLoaded(canvas)); + assertTrue(texture.isContentValid(canvas)); + + // invalidate content and it should be freed. + texture.invalidateContent(); + assertFalse(texture.isContentValid(canvas)); + assertEquals(1, texture.mFreeCalled); + assertTrue(texture.isLoaded(canvas)); // But it's still loaded + + // draw it again and the bitmap should be fetched again. + texture.draw(canvas, 0, 0); + assertEquals(2, texture.mGetCalled); + assertTrue(texture.isLoaded(canvas)); + assertTrue(texture.isContentValid(canvas)); + + // recycle the texture and it should be freed again. + texture.recycle(); + assertEquals(2, texture.mFreeCalled); + // TODO: these two are broken and waiting for fix. + //assertFalse(texture.isLoaded(canvas)); + //assertFalse(texture.isContentValid(canvas)); + } + + class MyTextureForMixed extends BasicTexture { + MyTextureForMixed(GLCanvas canvas, int id) { + super(canvas, id, BasicTexture.STATE_UNLOADED); + } + + @Override + protected boolean onBind(GLCanvas canvas) { + return true; + } + + public boolean isOpaque() { + return true; + } + } + + @SmallTest + public void testBitmapTexture() { + Config config = Config.ARGB_8888; + Bitmap bitmap = Bitmap.createBitmap(47, 42, config); + assertFalse(bitmap.isRecycled()); + BitmapTexture texture = new BitmapTexture(bitmap); + texture.recycle(); + assertFalse(bitmap.isRecycled()); + bitmap.recycle(); + assertTrue(bitmap.isRecycled()); + } +} |