From 2634ce35031be322cb355e4d6055aace6a2c0619 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 12 Oct 2013 19:00:15 +0200 Subject: Bug 859: Let TileRenderer detect zero columns and rows in eot() where beginTile() throws an EOT IllegalStateException to avoid division by zero --- .../com/jogamp/opengl/util/RandomTileRenderer.java | 23 +++++- .../com/jogamp/opengl/util/TileRenderer.java | 95 ++++++++++++++++------ .../com/jogamp/opengl/util/TileRendererBase.java | 41 +++++++++- .../classes/javax/media/opengl/awt/GLCanvas.java | 32 +++++--- .../classes/javax/media/opengl/awt/GLJPanel.java | 29 ++++--- 5 files changed, 171 insertions(+), 49 deletions(-) (limited to 'src/jogl') diff --git a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java index 8fc7916c7..a2b7ba343 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java @@ -96,7 +96,28 @@ public class RandomTileRenderer extends TileRendererBase { /** * {@inheritDoc} - * @throws IllegalStateException if image-size or tileRect has not been set + * + *

+ * end of tiling is never reached w/ {@link RandomRileRenderer}, + * i.e. method always returns false. + *

+ */ + @Override + public final boolean eot() { return false; } + + /** + * {@inheritDoc} + * + * Reset internal states of {@link RandomTileRenderer} are: none. + */ + @Override + public final void reset() { } + + /** + * {@inheritDoc} + * + * @throws IllegalStateException if {@link #setImageSize(int, int) image-size} has not been set or + * {@link #setTileRect(int, int, int, int) tile-rect} has not been set. */ @Override public final void beginTile(GL gl) throws IllegalStateException, GLException { diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java index f126eb7f5..deab8bc3e 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java @@ -101,7 +101,7 @@ public class TileRenderer extends TileRendererBase { */ public static final int TR_COLUMNS = 15; /** - * The current tile number. See {@link #getParam(int)}. + * The current tile number. Has value -1 if {@link #eot()}. See {@link #getParam(int)}. */ public static final int TR_CURRENT_TILE_NUM = 16; /** @@ -132,12 +132,13 @@ public class TileRenderer extends TileRendererBase { private final Dimension tileSize = new Dimension(DEFAULT_TILE_WIDTH, DEFAULT_TILE_HEIGHT); private final Dimension tileSizeNB = new Dimension(DEFAULT_TILE_WIDTH - 2 * DEFAULT_TILE_BORDER, DEFAULT_TILE_HEIGHT - 2 * DEFAULT_TILE_BORDER); - protected Dimension imageClippingDim = null; // not set - default + private boolean isInit = false; + private Dimension imageClippingDim = null; // not set - default private int tileBorder = DEFAULT_TILE_BORDER; private int rowOrder = TR_BOTTOM_TO_TOP; private int rows; private int columns; - private int currentTile = -1; + private int currentTile = 0; private int currentRow; private int currentColumn; private int offsetX; @@ -157,6 +158,18 @@ public class TileRenderer extends TileRendererBase { super(); } + /** + * {@inheritDoc} + *

+ * Implementation {@link #reset()} internal states. + *

+ */ + @Override + public final void setImageSize(int width, int height) { + super.setImageSize(width, height); + reset(); + } + /** * Clips the image-size this tile-renderer iterates through, * which can be retrieved via {@link #getClippedImageSize()}. @@ -164,7 +177,7 @@ public class TileRenderer extends TileRendererBase { * Original image-size stored in this tile-renderer is unmodified. *

*

- * Method resets internal state and {@link #TR_ROWS} {@link #TR_COLUMNS} count. + * Implementation {@link #reset()} internal states. *

* * @param width The image-clipping.width @@ -178,7 +191,7 @@ public class TileRenderer extends TileRendererBase { imageClippingDim.setWidth(width); imageClippingDim.setHeight(height); } - setup(); + reset(); } /** @@ -210,7 +223,7 @@ public class TileRenderer extends TileRendererBase { * effective size of the tile depends on the border size, ie ( * width - 2*border ) * ( height - 2 * border ) *

- * Method resets internal state and {@link #TR_ROWS} {@link #TR_COLUMNS} count. + * Implementation {@link #reset()} internal states. *

* * @param width @@ -236,7 +249,7 @@ public class TileRenderer extends TileRendererBase { tileSize.setHeight( height ); tileSizeNB.setWidth( width - 2 * border ); tileSizeNB.setHeight( height - 2 * border ); - setup(); + reset(); } /** @@ -251,32 +264,43 @@ public class TileRenderer extends TileRendererBase { } /** - * Sets up the number of rows and columns needed + * {@inheritDoc} + * + * Reset internal states of {@link TileRenderer} are: + * */ - private final void setup() throws IllegalStateException { + @Override + public final void reset() { final DimensionImmutable clippedImageSize = getClippedImageSize(); columns = ( clippedImageSize.getWidth() + tileSizeNB.getWidth() - 1 ) / tileSizeNB.getWidth(); rows = ( clippedImageSize.getHeight() + tileSizeNB.getHeight() - 1 ) / tileSizeNB.getHeight(); + currentRow = 0; + currentColumn = 0; currentTile = 0; currentTileXPos = 0; currentTileYPos = 0; currentTileWidth = 0; currentTileHeight = 0; - currentRow = 0; - currentColumn = 0; assert columns >= 0; assert rows >= 0; + + beginCalled = false; + isInit = true; } /* pp */ final int getCurrentTile() { return currentTile; } - /** - * Returns true if all tiles have been rendered or {@link #setup()} - * has not been called, otherwise false. - */ - public final boolean eot() { return 0 > currentTile; } - @Override public final int getParam(int pname) { switch (pname) { @@ -341,16 +365,41 @@ public class TileRenderer extends TileRendererBase { return 0 < imageSize.getWidth() && 0 < imageSize.getHeight(); } + /** + * {@inheritDoc} + * + *

+ * end of tiling is reached w/ {@link TileRenderer}, if at least one of the following is true: + *

+ *

+ */ + @Override + public final boolean eot() { + if ( !isInit ) { // ensure at least one reset-call + reset(); + } + return 0 > currentTile || 0 >= columns*rows; + } + + /** + * {@inheritDoc} + * + * @throws IllegalStateException if {@link #setImageSize(int, int) image-size} has not been set or + * {@link #eot() end-of-tiling} has been reached. + */ @Override public final void beginTile( GL gl ) throws IllegalStateException, GLException { if( !isSetup() ) { - throw new IllegalStateException("Image size has not been set"); + throw new IllegalStateException("Image size has not been set: "+this); } - validateGL(gl); - if (currentTile <= 0) { - setup(); + if ( eot() ) { + throw new IllegalStateException("EOT reached: "+this); } - + validateGL(gl); + /* which tile (by row and column) we're about to render */ if (rowOrder == TR_BOTTOM_TO_TOP) { currentRow = currentTile / columns; @@ -390,7 +439,7 @@ public class TileRenderer extends TileRendererBase { gl.glViewport( 0, 0, tW, tH ); if( DEBUG ) { - System.err.println("TileRenderer.begin.X: "+this.toString()); + System.err.println("TileRenderer.begin: "+this.toString()); } // Do not forget to issue: diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java index f15c79f68..d6c36aa14 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java +++ b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java @@ -241,6 +241,7 @@ public abstract class TileRendererBase { tileDetails(sb); sb.append("], image[size "+imageSize+", buffer "+hashStr(imageBuffer)+"], glad["+ gladListenerCount+" listener, pre "+(null!=glEventListenerPre)+", post "+(null!=glEventListenerPost)+", preSwap "+gladRequiresPreSwap+"]"); + sb.append(", isSetup "+isSetup()); return sb; } public String toString() { @@ -284,7 +285,7 @@ public abstract class TileRendererBase { * @param width The width of the final image * @param height The height of the final image */ - public final void setImageSize(int width, int height) { + public void setImageSize(int width, int height) { imageSize.setWidth(width); imageSize.setHeight(height); } @@ -320,6 +321,27 @@ public abstract class TileRendererBase { */ public abstract boolean isSetup(); + /** + * Returns true if end of tiling has been reached, otherwise false. + *

+ * end of tiling criteria is implementation specific and may never be reached. + *

+ *

+ * User needs to {@link #reset()} tiling after reaching end of tiling + * before calling {@link #beginTile(GL)} again. + *

+ */ + public abstract boolean eot(); + + /** + * Method resets implementation's internal state to start of tiling + * as required for {@link #beginTile(GL)} if {@link #eot() end of tiling} has been reached. + *

+ * Implementation is a nop where {@link #eot() end of tiling} is never reached. + *

+ */ + public abstract void reset(); + /** * Begins rendering a tile. *

@@ -351,10 +373,19 @@ public abstract class TileRendererBase { *

* User has to comply with the GL profile requirement. *

+ *

+ * If {@link #eot() end of tiling} has been reached, + * user needs to {@link #reset()} tiling before calling this method. + *

* * @param gl The gl context - * @throws IllegalStateException if image-size has not been set + * @throws IllegalStateException if {@link #setImageSize(int, int) image-size} is undefined, + * an {@link #isSetup() implementation related setup} has not be performed + * or {@ link #eot()} has been reached. See implementing classes. * @throws GLException if {@link #setImageBuffer(GLPixelBuffer) image buffer} is used but gl instance is < {@link GL2ES3} + * @see #isSetup() + * @see #eot() + * @see #reset() */ public abstract void beginTile(GL gl) throws IllegalStateException, GLException; @@ -594,6 +625,12 @@ public abstract class TileRendererBase { } return; } + if( eot() ) { + if( DEBUG ) { + System.err.println("TileRenderer.glel.display: EOT: "+TileRendererBase.this); + } + return; + } final GL gl = drawable.getGL(); beginTile(gl); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index f86a6a347..20dd802fb 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -837,20 +837,26 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing final Graphics2D g2d = (Graphics2D)graphics; try { printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight()); - try { - final TileRenderer tileRenderer = printAWTTiles.renderer; - if( DEBUG ) { - System.err.println("AWT print.0: "+tileRenderer); - } - do { - if( printGLAD != GLCanvas.this ) { - tileRenderer.display(); - } else { - Threading.invoke(true, displayOnEDTAction, getTreeLock()); + final TileRenderer tileRenderer = printAWTTiles.renderer; + if( DEBUG ) { + System.err.println("AWT print.0: "+tileRenderer); + } + if( !tileRenderer.eot() ) { + try { + do { + if( printGLAD != GLCanvas.this ) { + tileRenderer.display(); + } else { + Threading.invoke(true, displayOnEDTAction, getTreeLock()); + } + } while ( !tileRenderer.eot() ); + if( DEBUG ) { + System.err.println("AWT print.1: "+printAWTTiles); } - } while ( !tileRenderer.eot() ); - } finally { - printAWTTiles.resetGraphics2D(); + } finally { + tileRenderer.reset(); + printAWTTiles.resetGraphics2D(); + } } } catch (NoninvertibleTransformException nte) { System.err.println("Catched: Inversion failed of: "+g2d.getTransform()); diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index fb39143b4..673f22aff 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -646,17 +646,26 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing final Graphics2D g2d = (Graphics2D)graphics; try { printAWTTiles.setupGraphics2DAndClipBounds(g2d, getWidth(), getHeight()); - try { - final TileRenderer tileRenderer = printAWTTiles.renderer; - do { - if( printGLAD != GLJPanel.this ) { - tileRenderer.display(); - } else { - backend.doPlainPaint(); + final TileRenderer tileRenderer = printAWTTiles.renderer; + if( DEBUG ) { + System.err.println("AWT print.0: "+tileRenderer); + } + if( !tileRenderer.eot() ) { + try { + do { + if( printGLAD != GLJPanel.this ) { + tileRenderer.display(); + } else { + backend.doPlainPaint(); + } + } while ( !tileRenderer.eot() ); + if( DEBUG ) { + System.err.println("AWT print.1: "+printAWTTiles); } - } while ( !tileRenderer.eot() ); - } finally { - printAWTTiles.resetGraphics2D(); + } finally { + tileRenderer.reset(); + printAWTTiles.resetGraphics2D(); + } } } catch (NoninvertibleTransformException nte) { System.err.println("Catched: Inversion failed of: "+g2d.getTransform()); -- cgit v1.2.3