/**
* Copyright 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
package com.jogamp.opengl.test.junit.jogl.acore;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.GLPixelStorageModes;
import com.jogamp.opengl.test.junit.util.NEWTGLContext;
import com.jogamp.opengl.test.junit.util.UITestCase;
import java.io.IOException;
import java.nio.ByteBuffer;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GL2GL3;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLDrawable;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
import org.junit.Assert;
import org.junit.Test;
import org.junit.FixMethodOrder;
import org.junit.runners.MethodSorters;
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestGPUMemSec01NEWT extends UITestCase {
static String hexString(final int i) {
return "0x"+Integer.toHexString(i);
}
static String exceptionMsg(final String pre, final int format, final int type, final int components, final int width, final int height, final int rl1, final int rl4, final int rl8) {
return pre +
": fmt "+hexString(format)+", type "+hexString(type)+", comps "+components+
", "+width+"x"+height+
", rowlenA1 "+rl1+", rowlenA4 "+rl4+", rowlenA8 "+rl8;
}
static NEWTGLContext.WindowContext createCurrentGLOffscreenWindow(final GLProfile glp, final int width, final int height) throws GLException, InterruptedException {
final GLCapabilities caps = new GLCapabilities(glp);
caps.setOnscreen(false);
final NEWTGLContext.WindowContext winctx = NEWTGLContext.createWindow(
caps, width, height, true);
final GL gl = winctx.context.getGL();
// System.err.println("Pre GL Error: 0x"+Integer.toHexString(gl.glGetError()));
// System.err.println(winctx.drawable);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
// misc GL setup
gl.glClearColor(1, 1, 1, 1);
gl.glEnable(GL.GL_DEPTH_TEST);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
gl.glViewport(0, 0, width, height);
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
return winctx;
}
static int readPixelsCheck(final GL gl, final int format, final int type, final int components, final int width, final int height) throws InterruptedException {
int expectedExceptions = 0;
final int rowlenA1 = width * components;
final int rowlenA4 = ( ( width * components + 3 ) / 4 ) * 4 ;
Assert.assertTrue(rowlenA4 % 4 == 0);
final int rowlenA8 = ( ( width * components + 7 ) / 8 ) * 8 ;
Assert.assertTrue(rowlenA8 % 8 == 0);
final GLPixelStorageModes psm = new GLPixelStorageModes();
psm.setPackAlignment(gl, 1);
Exception ee = null;
// ok size !
try {
final ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1);
gl.glReadPixels(0, 0, width, height, format, type, bb);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
} catch(final IndexOutOfBoundsException e) {
ee = e;
}
Assert.assertNull(
exceptionMsg("Unexpected IndexOutOfBoundsException (size ok, alignment 1)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
ee = null;
// too small -10 !
try {
final ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1-10);
gl.glReadPixels(0, 0, width, height, format, type, bb);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
} catch(final IndexOutOfBoundsException e) {
ee = e;
System.err.println(
exceptionMsg("OK Expected IndexOutOfBoundsException (size-10 bytes)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8)+
": "+ee.getMessage());
expectedExceptions++;
}
Assert.assertNotNull(
exceptionMsg("Expected IndexOutOfBoundsException (size-10 bytes)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
ee = null;
// too small size/4 !
try {
final ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1/4);
gl.glReadPixels(0, 0, width, height, format, type, bb);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
} catch(final IndexOutOfBoundsException e) {
ee = e;
System.err.println(
exceptionMsg("OK Expected IndexOutOfBoundsException (size/4 bytes)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8)+
": "+ee.getMessage());
expectedExceptions++;
}
Assert.assertNotNull(
exceptionMsg("Expected IndexOutOfBoundsException (size/4 bytes)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
ee = null;
//
// Alignment test
//
psm.setPackAlignment(gl, 4);
// ok size !
try {
final ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA4);
gl.glReadPixels(0, 0, width, height, format, type, bb);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
} catch(final IndexOutOfBoundsException e) {
ee = e;
}
Assert.assertNull(
exceptionMsg("Unexpected IndexOutOfBoundsException (size ok, alignment 4)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
ee = null;
// too small if rowlenA1%4 > 0
try {
final ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1);
gl.glReadPixels(0, 0, width, height, format, type, bb);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
} catch(final IndexOutOfBoundsException e) {
ee = e;
if(rowlenA1%4>0) {
System.err.println(
exceptionMsg("OK Expected IndexOutOfBoundsException (alignment 4)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8)+
": "+ee.getMessage());
expectedExceptions++;
}
}
if(rowlenA1%4>0) {
Assert.assertNotNull(
exceptionMsg("Expected IndexOutOfBoundsException (alignment 4)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
} else {
Assert.assertNull(
exceptionMsg("Unexpected IndexOutOfBoundsException (alignment 4)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
}
ee = null;
psm.setPackAlignment(gl, 8);
// ok size !
try {
final ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA8);
gl.glReadPixels(0, 0, width, height, format, type, bb);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
} catch(final IndexOutOfBoundsException e) {
ee = e;
}
Assert.assertNull(
exceptionMsg("Unexpected IndexOutOfBoundsException (size ok, alignment 8)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
ee = null;
// too small if rowlenA1%8 > 0
try {
final ByteBuffer bb = Buffers.newDirectByteBuffer(height*rowlenA1);
gl.glReadPixels(0, 0, width, height, format, type, bb);
Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
} catch(final IndexOutOfBoundsException e) {
ee = e;
if(rowlenA1%8>0) {
System.err.println(
exceptionMsg("OK Expected IndexOutOfBoundsException (alignment 8)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8)+
": "+ee.getMessage());
expectedExceptions++;
}
}
if(rowlenA1%8>0) {
Assert.assertNotNull(
exceptionMsg("Expected IndexOutOfBoundsException (alignment 8)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
} else {
Assert.assertNull(
exceptionMsg("Unexpected IndexOutOfBoundsException (alignment 8)",
format, type, components, width, height, rowlenA1, rowlenA4, rowlenA8), ee);
}
ee = null;
psm.restore(gl);
return expectedExceptions;
}
@Test
public void testReadPixelsGL_640x480xRGBAxUB() throws InterruptedException {
final GLProfile glp = GLProfile.getDefault();
final int width = 640;
final int height= 480;
// preset ..
final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(glp, width, height);
final GLDrawable drawable = winctx.context.getGLDrawable();
final GL gl = winctx.context.getGL();
// 2 x too small - 0 x alignment
Assert.assertEquals(2, readPixelsCheck(gl, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, 4, width, height));
drawable.swapBuffers();
Thread.sleep(50);
NEWTGLContext.destroyWindow(winctx);
}
@Test
public void testReadPixelsGL_99x100xRGBxUB() throws InterruptedException {
final GLProfile glp = GLProfile.getGL2ES2();
final int wwidth = 640;
final int wheight= 480;
final int rwidth = 99;
final int rheight= 100;
// preset ..
final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(glp, wwidth, wheight);
final GLDrawable drawable = winctx.context.getGLDrawable();
final GL gl = winctx.context.getGL();
// 2 x too small - 1 x alignment
Assert.assertEquals(3, readPixelsCheck(gl, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, 4, rwidth, rheight));
drawable.swapBuffers();
Thread.sleep(50);
NEWTGLContext.destroyWindow(winctx);
}
@Test
public void testReadPixelsGL2GL3_640x480xRGBxUB() throws InterruptedException {
final GLProfile glp = GLProfile.getGL2ES2();
if(!glp.isGL2ES3()) {
System.err.println("GL2ES3 n/a skip test");
return;
}
final int width = 640;
final int height= 480;
// preset ..
final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(glp, width, height);
final GLDrawable drawable = winctx.context.getGLDrawable();
final GL gl = winctx.context.getGL();
// 2 x too small - 0 x alignment
Assert.assertEquals(2, readPixelsCheck(gl, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, 3, width, height));
drawable.swapBuffers();
Thread.sleep(50);
NEWTGLContext.destroyWindow(winctx);
}
@Test
public void testReadPixelsGL2GL3_99x100xRGBxUB() throws InterruptedException {
final GLProfile glp = GLProfile.getGL2ES2();
if(!glp.isGL2ES3()) {
System.err.println("GL2ES3 n/a skip test");
return;
}
final int wwidth = 640;
final int wheight= 480;
final int rwidth = 99;
final int rheight= 100;
// preset ..
final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(glp, wwidth, wheight);
final GLDrawable drawable = winctx.context.getGLDrawable();
final GL gl = winctx.context.getGL();
// 2 x too small - 2 x alignment
Assert.assertEquals(4, readPixelsCheck(gl, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, 3, rwidth, rheight));
drawable.swapBuffers();
Thread.sleep(50);
NEWTGLContext.destroyWindow(winctx);
}
@Test
public void testReadPixelsGL2GL3_640x480xREDxUB() throws InterruptedException {
final GLProfile glp = GLProfile.getGL2ES2();
if(!glp.isGL2ES3()) {
System.err.println("GL2ES3 n/a skip test");
return;
}
final int width = 640;
final int height= 480;
// preset ..
final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(glp, width, height);
final GLDrawable drawable = winctx.context.getGLDrawable();
final GL2GL3 gl = winctx.context.getGL().getGL2GL3();
// 2 x too small - 0 x alignment
Assert.assertEquals(2, readPixelsCheck(gl, GL2ES2.GL_RED, GL.GL_UNSIGNED_BYTE, 1, width, height));
drawable.swapBuffers();
Thread.sleep(50);
NEWTGLContext.destroyWindow(winctx);
}
@Test
public void testReadPixelsGL2GL3_102x100xREDxUB() throws InterruptedException {
final GLProfile glp = GLProfile.getGL2ES2();
if(!glp.isGL2ES3()) {
System.err.println("GL2ES3 n/a skip test");
return;
}
final int wwidth = 640;
final int wheight= 480;
final int rwidth = 102;
final int rheight= 100;
// preset ..
final NEWTGLContext.WindowContext winctx = createCurrentGLOffscreenWindow(glp, wwidth, wheight);
final GLDrawable drawable = winctx.context.getGLDrawable();
final GL2GL3 gl = winctx.context.getGL().getGL2GL3();
// 2 x too small - 2 x alignment
Assert.assertEquals(4, readPixelsCheck(gl, GL2ES2.GL_RED, GL.GL_UNSIGNED_BYTE, 1, rwidth, rheight));
drawable.swapBuffers();
Thread.sleep(50);
NEWTGLContext.destroyWindow(winctx);
}
public static void main(final String args[]) throws IOException {
final String tstname = TestGPUMemSec01NEWT.class.getName();
org.junit.runner.JUnitCore.main(tstname);
}
}