aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-09-08 15:13:00 +0200
committerSven Gothel <[email protected]>2013-09-08 15:13:00 +0200
commit8313200af6da93f83bc70a645e79bfdeb22f05d4 (patch)
tree7d5618c9d3face58de56a8a08fdbfa660e845a8b
parent78b65d52385f4a15e4357d0444ea9daec54fb173 (diff)
TileRenderer*: Fix pre-swap and post-swap in regards to endTile(..), i.e. pre-swap only for FBO && MSAA. See TileRendererBase.reqPreSwapBuffers(..) API doc.
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java12
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java62
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2NEWT.java72
4 files changed, 122 insertions, 36 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
index 55b31b692..afc57fa30 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
@@ -126,19 +126,21 @@ public class RandomTileRenderer extends TileRendererBase {
// be sure OpenGL rendering is finished
gl.glFlush();
- if( DEBUG ) {
- System.err.println("TileRenderer.end.0: "+this.toString());
- }
-
// save current glPixelStore values
psm.save(gl);
psm.setPackAlignment(gl, 1);
final GL2ES3 gl2es3;
+ final int readBuffer;
if( gl.isGL2ES3() ) {
gl2es3 = gl.getGL2ES3();
- gl2es3.glReadBuffer(gl2es3.getDefaultReadBuffer());
+ readBuffer = gl2es3.getDefaultReadBuffer();
+ gl2es3.glReadBuffer(readBuffer);
} else {
gl2es3 = null;
+ readBuffer = 0; // undef. probably default: GL_FRONT (single buffering) GL_BACK (double buffering)
+ }
+ if( DEBUG ) {
+ System.err.println("TileRenderer.end.0: readBuffer 0x"+Integer.toHexString(readBuffer)+", "+this.toString());
}
final int tmp[] = new int[1];
diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
index e24fa9706..bb6cf70f4 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
@@ -314,20 +314,22 @@ public class TileRenderer extends TileRendererBase {
// be sure OpenGL rendering is finished
gl.glFlush();
-
- if( DEBUG ) {
- System.err.println("TileRenderer.end.0: "+this.toString());
- }
// save current glPixelStore values
psm.save(gl);
psm.setPackAlignment(gl, 1);
final GL2ES3 gl2es3;
+ final int readBuffer;
if( gl.isGL2ES3() ) {
gl2es3 = gl.getGL2ES3();
- gl2es3.glReadBuffer(gl2es3.getDefaultReadBuffer());
+ readBuffer = gl2es3.getDefaultReadBuffer();
+ gl2es3.glReadBuffer(readBuffer);
} else {
gl2es3 = null;
+ readBuffer = 0; // undef. probably default: GL_FRONT (single buffering) GL_BACK (double buffering)
+ }
+ if( DEBUG ) {
+ System.err.println("TileRenderer.end.0: readBuffer 0x"+Integer.toHexString(readBuffer)+", "+this.toString());
}
final int tmp[] = new int[1];
diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java
index 70e68b97f..411d33881 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java
@@ -41,10 +41,11 @@ import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES3;
import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
-
+import javax.media.opengl.GLFBODrawable;
import jogamp.opengl.Debug;
/**
@@ -138,6 +139,7 @@ public abstract class TileRendererBase {
protected int currentTileWidth;
protected int currentTileHeight;
protected GLAutoDrawable glad;
+ protected boolean gladRequiresPreSwap;
protected boolean gladAutoSwapBufferMode = true;
protected GLEventListener[] listeners;
protected boolean[] listenersInit;
@@ -156,7 +158,7 @@ public abstract class TileRendererBase {
sb.append("tile[");
tileDetails(sb);
sb.append("], image[size "+imageSize+", buffer "+hashStr(imageBuffer)+"], glad["+
- gladListenerCount+" listener, pre "+(null!=glEventListenerPre)+", post "+(null!=glEventListenerPost)+"]");
+ gladListenerCount+" listener, pre "+(null!=glEventListenerPre)+", post "+(null!=glEventListenerPost)+", preSwap "+gladRequiresPreSwap+"]");
return sb;
}
public String toString() {
@@ -271,9 +273,9 @@ public abstract class TileRendererBase {
* Must be called after rendering the scene,
* see {@link #beginTile(GL)}.
* <p>
- * Is is highly recommended to perform {@link GLDrawable#swapBuffers() swapBuffers()} before calling this method.<br>
- * This is especially true in regards to multisampling offscreen FBO drawables,
- * where {@link GLDrawable#swapBuffers() swapBuffers()} triggers the <i>downsampling</i> to the readable sampling sink.
+ * Please consider {@link #reqPreSwapBuffers(GLCapabilitiesImmutable)} to determine
+ * whether you need to perform {@link GLDrawable#swapBuffers() swap-buffers} before or after
+ * calling this method!
* </p>
* <p>
* User has to comply with the <a href="#glprequirement">GL profile requirement</a>.
@@ -286,6 +288,29 @@ public abstract class TileRendererBase {
public abstract void endTile( GL gl ) throws IllegalStateException, GLException;
/**
+ * Determines whether the chosen {@link GLCapabilitiesImmutable}
+ * requires a <i>pre-{@link GLDrawable#swapBuffers() swap-buffers}</i>
+ * before accessing the results, i.e. before {@link #endTile(GL)}.
+ * <p>
+ * Usually one uses the {@link GL#getDefaultReadBuffer() default-read-buffer}, i.e.
+ * {@link GL#GL_FRONT} for single-buffer and {@link GL#GL_BACK} for double-buffer {@link GLDrawable}s
+ * and {@link GL#GL_COLOR_ATTACHMENT0} for offscreen framebuffer objects.<br>
+ * Here {@link GLDrawable#swapBuffers() swap-buffers} shall happen <b>after</b> calling {@link #endTile(GL)}, the default.
+ * </p>
+ * <p>
+ * However, <i>multisampling</i> offscreen {@link GLFBODrawable}s
+ * utilize {@link GLDrawable#swapBuffers() swap-buffers} to <i>downsample</i>
+ * the multisamples into the readable sampling sink.
+ * In this case, we require a {@link GLDrawable#swapBuffers() swap-buffers} <b>before</b> calling {@link #endTile(GL)}.
+ * </p>
+ * @param chosenCaps the chosen {@link GLCapabilitiesImmutable}
+ * @return chosenCaps.isFBO() && chosenCaps.getSampleBuffers()
+ */
+ public final boolean reqPreSwapBuffers(GLCapabilitiesImmutable chosenCaps) {
+ return chosenCaps.isFBO() && chosenCaps.getSampleBuffers();
+ }
+
+ /**
* Attaches this renderer to the {@link GLAutoDrawable}.
* <p>
* The {@link GLAutoDrawable}'s original {@link GLEventListener} are moved to this tile renderer.<br>
@@ -295,7 +320,8 @@ public abstract class TileRendererBase {
* </p>
* <p>
* The {@link GLAutoDrawable}'s {@link GLAutoDrawable#getAutoSwapBufferMode() auto-swap mode} is cached
- * and set to <code>false</code>, since {@link GLAutoDrawable#swapBuffers() swapBuffers()} must be issued before {@link #endTile(GL)}.
+ * and set to <code>false</code>, since {@link GLAutoDrawable#swapBuffers() swapBuffers()} maybe issued before {@link #endTile(GL)},
+ * see {@link #reqPreSwapBuffers(GLCapabilitiesImmutable)}.
* </p>
* <p>
* This tile renderer's {@link GLEventListener} is then added to handle the tile rendering,
@@ -309,8 +335,9 @@ public abstract class TileRendererBase {
* <li>{@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int) reshape(0, 0, tile-width, tile-height)}</li>
* <li>{@link GLEventListener#display(GLAutoDrawable) display(autoDrawable)}</li>
* </ul></li>
- * <li>{@link GLAutoDrawable#swapBuffers() swapBuffers()}</li>
+ * <li>if ( {@link #reqPreSwapBuffers(GLCapabilitiesImmutable) pre-swap} ) { {@link GLAutoDrawable#swapBuffers() swapBuffers()} }</li>
* <li>{@link #endTile(GL)}</li>
+ * <li>if ( !{@link #reqPreSwapBuffers(GLCapabilitiesImmutable) pre-swap} ) { {@link GLAutoDrawable#swapBuffers() swapBuffers()} }</li>
* <li>Optional {@link #setGLEventListener(GLEventListener, GLEventListener) post-glel}.{@link GLEventListener#display(GLAutoDrawable) display(..)}</li>
* </ul>
* </p>
@@ -357,7 +384,12 @@ public abstract class TileRendererBase {
}
glad.addGLEventListener(tiledGLEL);
gladAutoSwapBufferMode = glad.getAutoSwapBufferMode();
+ gladRequiresPreSwap = this.reqPreSwapBuffers(glad.getChosenGLCapabilities());
glad.setAutoSwapBufferMode(false);
+ if( DEBUG ) {
+ System.err.println("TileRenderer: attached: "+glad);
+ System.err.println("TileRenderer: preSwap "+gladRequiresPreSwap+", "+glad.getChosenGLCapabilities()+", cached "+listeners.length+" listener");
+ }
}
/**
@@ -384,6 +416,10 @@ public abstract class TileRendererBase {
glad.setGLEventListenerInitState(l, listenersInit[i]);
}
glad.setAutoSwapBufferMode(gladAutoSwapBufferMode);
+ if( DEBUG ) {
+ System.err.println("TileRenderer: detached: "+glad);
+ System.err.println("TileRenderer: "+glad.getChosenGLCapabilities());
+ }
listeners = null;
listenersInit = null;
@@ -459,9 +495,15 @@ public abstract class TileRendererBase {
listeners[i].reshape(drawable, 0, 0, currentTileWidth, currentTileHeight);
listeners[i].display(drawable);
}
- glad.swapBuffers();
-
- endTile(gl);
+
+ if( gladRequiresPreSwap ) {
+ glad.swapBuffers();
+ endTile(gl);
+ } else {
+ endTile(gl);
+ glad.swapBuffers();
+ }
+
if( null != glEventListenerPost ) {
glEventListenerPost.display(drawable);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2NEWT.java
index be209412e..26ac34d5a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2NEWT.java
@@ -27,6 +27,7 @@
*/
package com.jogamp.opengl.test.junit.jogl.tile;
+import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -44,7 +45,6 @@ import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLEventListener;
-import javax.media.opengl.GLOffscreenAutoDrawable;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
@@ -91,49 +91,89 @@ public class TestTiledRendering2NEWT extends UITestCase {
}
@Test
- public void test01_gl2___aa0() throws IOException {
+ public void test001_off_gl2___aa0() throws IOException {
GLProfile glp = getGLProfile(GLProfile.GL2);
if( null == glp ) {
return;
}
- doTest(new Gears(), glp, 0);
+ doTest(false, new Gears(), glp, 0);
}
@Test
- public void test02_gl2___aa8() throws IOException {
+ public void test002_off_gl2___aa8() throws IOException {
GLProfile glp = getGLProfile(GLProfile.GL2);
if( null == glp ) {
return;
}
- doTest(new Gears(), glp, 8);
+ doTest(false, new Gears(), glp, 8);
}
@Test
- public void test11_gl2es3_aa0() throws IOException {
+ public void test011_off_gl2es3_aa0() throws IOException {
GLProfile glp = getGL2ES3();
if( null == glp ) {
return;
}
- doTest(new GearsES2(), glp, 0);
+ doTest(false, new GearsES2(), glp, 0);
}
@Test
- public void test12_gl2es3_aa8() throws IOException {
+ public void test012_off_gl2es3_aa8() throws IOException {
GLProfile glp = getGL2ES3();
if( null == glp ) {
return;
}
- doTest(new GearsES2(), glp, 8);
+ doTest(false, new GearsES2(), glp, 8);
+ }
+ @Test
+ public void test101_on__gl2___aa0() throws IOException {
+ GLProfile glp = getGLProfile(GLProfile.GL2);
+ if( null == glp ) {
+ return;
+ }
+ doTest(true, new Gears(), glp, 0);
+ }
+ @Test
+ public void test102_on__gl2___aa8() throws IOException {
+ GLProfile glp = getGLProfile(GLProfile.GL2);
+ if( null == glp ) {
+ return;
+ }
+ doTest(true, new Gears(), glp, 8);
+ }
+ @Test
+ public void test111_on__gl2es3_aa0() throws IOException {
+ GLProfile glp = getGL2ES3();
+ if( null == glp ) {
+ return;
+ }
+ doTest(true, new GearsES2(), glp, 0);
+ }
+ @Test
+ public void test112_on__gl2es3_aa8() throws IOException {
+ GLProfile glp = getGL2ES3();
+ if( null == glp ) {
+ return;
+ }
+ doTest(true, new GearsES2(), glp, 8);
}
- void doTest(final GLEventListener demo, GLProfile glp, final int msaaCount) throws IOException {
- GLCapabilities caps = new GLCapabilities(glp);
- caps.setDoubleBuffered(false);
+ void doTest(boolean onscreen, final GLEventListener demo, GLProfile glp, final int msaaCount) throws IOException {
+ GLCapabilities caps = new GLCapabilities(glp);
+ caps.setDoubleBuffered(onscreen);
if( msaaCount > 0 ) {
caps.setSampleBuffers(true);
caps.setNumSamples(msaaCount);
}
final int maxTileSize = 256;
- final GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
- final GLOffscreenAutoDrawable glad = factory.createOffscreenAutoDrawable(null, caps, null, maxTileSize, maxTileSize, null);
+ final GLAutoDrawable glad;
+ if( onscreen ) {
+ final GLWindow glWin = GLWindow.create(caps);
+ glWin.setSize(maxTileSize, maxTileSize);
+ glWin.setVisible(true);
+ glad = glWin;
+ } else {
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
+ glad = factory.createOffscreenAutoDrawable(null, caps, null, maxTileSize, maxTileSize, null);
+ }
glad.addGLEventListener( demo );
@@ -192,8 +232,6 @@ public class TestTiledRendering2NEWT extends UITestCase {
}
});
- glad.destroy();
-
final GLPixelBuffer imageBuffer = renderer.getImageBuffer();
final TextureData textureData = new TextureData(
caps.getGLProfile(),
@@ -207,6 +245,8 @@ public class TestTiledRendering2NEWT extends UITestCase {
null /* Flusher */);
TextureIO.write(textureData, file);
+
+ glad.destroy();
}
public static void main(String args[]) {