From 4965923722fe44dfcf7eaff16cd5449707773123 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Sat, 7 Sep 2013 19:47:28 +0200
Subject: TileRenderer*: Fix FBO MSAA use-case, i.e. call swapBuffers() before
 endTile(); Enhance unit tests for MSAA, also add
 TileRendererBase.TileRendererNotify to GearsES2

GL[Auto]Drawable.swapBuffers() must be called before endTile().

This is especially important if using multisampling offscreen FBO drawables,
where swapBuffers() triggers the <i>downsampling</i> to the readable sampling sink.

Otherwise, we will be 'one tile behind' !
---
 .../com/jogamp/opengl/util/RandomTileRenderer.java |  9 ++++++
 .../com/jogamp/opengl/util/TileRenderer.java       | 20 ++++++--------
 .../com/jogamp/opengl/util/TileRendererBase.java   | 32 ++++++++++++++++++++--
 3 files changed, 47 insertions(+), 14 deletions(-)

(limited to 'src/jogl/classes/com/jogamp')

diff --git a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
index 2b698d2f5..55b31b692 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
@@ -104,6 +104,11 @@ public class RandomTileRenderer extends TileRendererBase {
         validateGL(gl);
         
         gl.glViewport( 0, 0, currentTileWidth, currentTileHeight );
+        
+        if( DEBUG ) {
+            System.err.println("TileRenderer.begin.X: "+this.toString());
+        }
+                
         // Do not forget to issue:
         //    reshape( 0, 0, tW, tH );
         // which shall reflect tile renderer fileds: currentTileXPos, currentTileYPos and imageSize
@@ -121,6 +126,10 @@ 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);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
index 46a1e2452..e24fa9706 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
@@ -104,7 +104,6 @@ public class TileRenderer extends TileRendererBase {
      */
     public static final int TR_BOTTOM_TO_TOP = 16;
 
-    private static final boolean DEBUG = true;
     private static final int DEFAULT_TILE_WIDTH = 256;
     private static final int DEFAULT_TILE_HEIGHT = 256;
     private static final int DEFAULT_TILE_BORDER = 0;
@@ -259,9 +258,6 @@ public class TileRenderer extends TileRendererBase {
             setup();
         }
 
-        final int preRow = currentRow;
-        final int preColumn = currentColumn;
-
         /* which tile (by row and column) we're about to render */
         if (rowOrder == TR_BOTTOM_TO_TOP) {
             currentRow = currentTile / columns;
@@ -293,20 +289,16 @@ public class TileRenderer extends TileRendererBase {
         currentTileXPos = currentColumn * tileSizeNB.getWidth() + offsetX;
         currentTileYPos = currentRow * tileSizeNB.getHeight() + offsetY;
 
-        final int preTileWidth = currentTileWidth;
-        final int preTileHeight = currentTileHeight;
-
         /* Save tile size, with border */
         currentTileWidth = tW;
         currentTileHeight = tH;
 
+        gl.glViewport( 0, 0, tW, tH );
+        
         if( DEBUG ) {
-            System.err.println("Tile["+currentTile+"]: off "+offsetX+"/"+offsetX+", ["+preColumn+"]["+preRow+"] "+preTileWidth+"x"+preTileHeight+
-                    " -> ["+currentColumn+"]["+currentRow+"] "+currentTileXPos+"/"+currentTileYPos+", "+tW+"x"+tH+
-                    ", image "+imageSize.getWidth()+"x"+imageSize.getHeight());
+            System.err.println("TileRenderer.begin.X: "+this.toString());
         }
-
-        gl.glViewport( 0, 0, tW, tH );
+        
         // Do not forget to issue:
         //    reshape( 0, 0, tW, tH );
         // which shall reflect tile renderer fileds: currentTileXPos, currentTileYPos and imageSize
@@ -323,6 +315,10 @@ 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);
diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java
index e7296ab0a..70e68b97f 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java
@@ -41,9 +41,12 @@ 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.GLDrawable;
 import javax.media.opengl.GLEventListener;
 import javax.media.opengl.GLException;
 
+import jogamp.opengl.Debug;
+
 /**
  * A fairly direct port of Brian Paul's tile rendering library, found
  * at <a href = "http://www.mesa3d.org/brianp/TR.html">
@@ -111,6 +114,8 @@ public abstract class TileRendererBase {
      */
     public static final int TR_CURRENT_TILE_HEIGHT = 6;
     
+    /* pp */ static final boolean DEBUG = Debug.debug("TileRenderer");
+    
     /** 
      * Notifies {@link GLEventListener} implementing this interface
      * that the owning {@link GLAutoDrawable} is {@link TileRendererBase#attachToAutoDrawable(GLAutoDrawable) attached} 
@@ -133,6 +138,7 @@ public abstract class TileRendererBase {
     protected int currentTileWidth;
     protected int currentTileHeight;
     protected GLAutoDrawable glad;
+    protected boolean gladAutoSwapBufferMode = true;
     protected GLEventListener[] listeners;
     protected boolean[] listenersInit;
     protected GLEventListener glEventListenerPre = null;
@@ -180,6 +186,9 @@ public abstract class TileRendererBase {
      */
     public final void setTileBuffer(GLPixelBuffer buffer) {
         tileBuffer = buffer;
+        if( DEBUG ) {
+            System.err.println("TileRenderer: tile-buffer "+tileBuffer);
+        }
     }
 
     /** @see #setTileBuffer(GLPixelBuffer) */
@@ -206,6 +215,9 @@ public abstract class TileRendererBase {
      */
     public final void setImageBuffer(GLPixelBuffer buffer) {
         imageBuffer = buffer;
+        if( DEBUG ) {
+            System.err.println("TileRenderer: image-buffer "+imageBuffer);
+        }
     }
 
     /** @see #setImageBuffer(GLPixelBuffer) */
@@ -259,6 +271,11 @@ 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.
+     * </p>
+     * <p>
      * User has to comply with the <a href="#glprequirement">GL profile requirement</a>.
      * </p>
      * 
@@ -277,8 +294,13 @@ public abstract class TileRendererBase {
      * about this event.
      * </p>
      * <p>
-     * This tile renderer's {@link GLEventListener} is then added to handle the tile rendering
-     * for the original {@link GLEventListener}, i.e. it's {@link GLEventListener#display(GLAutoDrawable) display} issues:
+     * 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)}.  
+     * </p>
+     * <p>
+     * This tile renderer's {@link GLEventListener} is then added to handle the tile rendering,
+     * replacing the original {@link GLEventListener}.<br>
+     * This {@link GLEventListener#display(GLAutoDrawable) display} implementations issues:
      * <ul>
      *   <li>Optional {@link #setGLEventListener(GLEventListener, GLEventListener) pre-glel}.{@link GLEventListener#display(GLAutoDrawable) display(..)}</li>
      *   <li>{@link #beginTile(GL)}</li>
@@ -287,6 +309,7 @@ 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>{@link #endTile(GL)}</li>
      *   <li>Optional {@link #setGLEventListener(GLEventListener, GLEventListener) post-glel}.{@link GLEventListener#display(GLAutoDrawable) display(..)}</li>
      * </ul>
@@ -333,6 +356,8 @@ public abstract class TileRendererBase {
             }
         }
         glad.addGLEventListener(tiledGLEL);
+        gladAutoSwapBufferMode = glad.getAutoSwapBufferMode();
+        glad.setAutoSwapBufferMode(false);
     }
 
     /**
@@ -358,6 +383,8 @@ public abstract class TileRendererBase {
                 glad.addGLEventListener(l);
                 glad.setGLEventListenerInitState(l, listenersInit[i]);
             }
+            glad.setAutoSwapBufferMode(gladAutoSwapBufferMode);
+            
             listeners = null;
             listenersInit = null;
             glad = null;
@@ -432,6 +459,7 @@ public abstract class TileRendererBase {
                 listeners[i].reshape(drawable, 0, 0, currentTileWidth, currentTileHeight);
                 listeners[i].display(drawable);
             }
+            glad.swapBuffers();
 
             endTile(gl);
             if( null != glEventListenerPost ) {
-- 
cgit v1.2.3