From 307479391f955a5bd611b4ad4db6f53e097d15c5 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 24 Feb 2023 22:15:20 +0100 Subject: Graph Region: Address overflow issue using GL2ES3 integer indices (WIP...); Ease GLArrayData* buffer growth. Using integer indices, i.e. GL_UNSIGNED_INT, requires us to pass a GLProfile 'hint' to the GLRegion ctor. Region.max_indices is computed in this regard and used in Region.addOutlineShape(). TODO: If exceeding max_indices, the code path needs some work. Buffer growth is eased via GLArrayData using its golden growth ratio and manually triggering growth before processing all triangles in Region.addOutlineShape(). +++ TextRegionUtil static drawText() won't clear passed Region anymore, caller has to do this if so intended. --- .../classes/com/jogamp/graph/curve/Region.java | 50 ++++++--- .../com/jogamp/graph/curve/opengl/GLRegion.java | 41 ++++++-- .../jogamp/graph/curve/opengl/TextRegionUtil.java | 15 +-- .../graph/curve/opengl/VBORegion2PMSAAES2.java | 46 ++++++++- .../graph/curve/opengl/VBORegion2PVBAAES2.java | 55 ++++++++-- .../jogamp/graph/curve/opengl/VBORegionSPES2.java | 43 +++++++- .../test/junit/graph/TestTextRendererNEWT00.java | 115 ++++++++++++--------- .../test/junit/graph/TestTextRendererNEWT10.java | 14 +-- .../test/junit/graph/TestTextRendererNEWT20.java | 10 +- .../junit/graph/demos/GPURegionGLListener00.java | 7 +- .../junit/graph/demos/GPURegionGLListener01.java | 2 +- .../junit/graph/demos/GPURegionGLListener10.java | 7 +- .../junit/graph/demos/GPUTextGLListener0A.java | 6 +- .../test/junit/graph/demos/GPUTextNewtDemo.java | 2 +- .../graph/demos/GPUTextRendererListenerBase01.java | 15 +-- .../junit/graph/demos/GPUUISceneGLListener02.java | 9 -- .../junit/graph/demos/GPUUISceneGLListener04.java | 7 -- .../junit/graph/demos/GPUUISceneGLListener0A.java | 11 -- .../test/junit/graph/demos/GPUUISceneNewtDemo.java | 2 +- .../test/junit/graph/demos/UITypeDemo01.java | 2 +- .../junit/graph/demos/ui/TextureSeqButton.java | 6 +- .../opengl/test/junit/graph/demos/ui/UIShape.java | 7 +- .../test/junit/jogl/acore/GLReadBuffer00Base.java | 10 +- .../jogl/acore/TestGLReadBuffer01GLCanvasAWT.java | 7 +- .../jogl/acore/TestGLReadBuffer01GLJPanelAWT.java | 7 +- .../jogl/acore/TestGLReadBuffer01GLWindowNEWT.java | 2 +- .../test/junit/jogl/demos/es2/av/MovieCube.java | 8 +- .../junit/jogl/demos/es2/av/MovieSBSStereo.java | 10 +- .../test/junit/jogl/demos/es2/av/MovieSimple.java | 9 +- 29 files changed, 352 insertions(+), 173 deletions(-) delete mode 100644 src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener02.java delete mode 100644 src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneGLListener04.java (limited to 'src') diff --git a/src/jogl/classes/com/jogamp/graph/curve/Region.java b/src/jogl/classes/com/jogamp/graph/curve/Region.java index 264b00b92..8843188b4 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/Region.java +++ b/src/jogl/classes/com/jogamp/graph/curve/Region.java @@ -27,6 +27,7 @@ */ package com.jogamp.graph.curve; +import java.io.PrintStream; import java.util.ArrayList; import java.util.List; @@ -35,7 +36,9 @@ import jogamp.opengl.Debug; import com.jogamp.graph.geom.Triangle; import com.jogamp.graph.geom.Vertex; import com.jogamp.graph.geom.plane.AffineTransform; +import com.jogamp.common.nio.Buffers; import com.jogamp.graph.curve.opengl.GLRegion; +import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.opengl.math.geom.Frustum; import com.jogamp.opengl.util.texture.TextureSequence; @@ -110,6 +113,8 @@ public abstract class Region { protected static final int DIRTY_STATE = 1 << 1 ; private final int renderModes; + private final boolean use_int32_idx; + private final int max_indices; private int quality; private int dirty = DIRTY_SHAPE | DIRTY_STATE; private int numVertices = 0; @@ -168,19 +173,33 @@ public abstract class Region { } } - protected Region(final int regionRenderModes) { + protected Region(final int regionRenderModes, final boolean use_int32_idx) { this.renderModes = regionRenderModes; + this.use_int32_idx = use_int32_idx; + if( use_int32_idx ) { + this.max_indices = GL_INT32_MAX / Buffers.SIZEOF_INT; // byte-size int32_t limit + } else { + this.max_indices = GL_UINT16_MAX; + } this.quality = MAX_QUALITY; } - // FIXME: Better handling of impl. buffer growth .. ! - // protected abstract void setupInitialComponentCount(int attributeCount, int indexCount); + /** Print implementation buffer stats like detailed and total size and capacity in bytes etc */ + public abstract void printBufferStats(PrintStream out); + + /** + * Returns true if implementation uses `int32_t` sized indices implying at least a {@link GLProfile#isGL2ES3()} alike context. + * Otherwise method returns false on {@link GLProfile#isGLES2()} using `uint16_t` sized indices. + */ + public final boolean usesI32Idx() { return this.use_int32_idx; } + + protected abstract void growBufferSize(int verticeCount, int indexCount); protected abstract void pushVertex(final float[] coords, final float[] texParams, float[] rgba); protected abstract void pushIndex(int idx); /** - * Return bit-field of render modes, see {@link GLRegion#create(int, TextureSequence)}. + * Return bit-field of render modes, see {@link GLRegion#create(GLProfile, int, TextureSequence)}. */ public final int getRenderModes() { return renderModes; } @@ -269,6 +288,9 @@ public abstract class Region { private final AABBox tmpBox = new AABBox(); + protected static final int GL_UINT16_MAX = 0xffff; // 65,535 + protected static final int GL_INT32_MAX = 0x7fffffff; // 2,147,483,647 + /** * Add the given {@link OutlineShape} to this region with the given optional {@link AffineTransform}. *

@@ -297,15 +319,17 @@ public abstract class Region { } final List trisIn = shape.getTriangles(OutlineShape.VerticesState.QUADRATIC_NURBS); final ArrayList vertsIn = shape.getVertices(); - if(DEBUG_INSTANCE) { + { final int addedVerticeCount = shape.getAddedVerticeCount(); final int verticeCount = vertsIn.size() + addedVerticeCount; final int indexCount = trisIn.size() * 3; - System.err.println("Region.addOutlineShape().0: tris: "+trisIn.size()+", verts "+vertsIn.size()+", transform "+t); - System.err.println("Region.addOutlineShape().0: VerticeCount "+vertsIn.size()+" + "+addedVerticeCount+" = "+verticeCount); - System.err.println("Region.addOutlineShape().0: IndexCount "+indexCount); + if(DEBUG_INSTANCE) { + System.err.println("Region.addOutlineShape().0: tris: "+trisIn.size()+", verts "+vertsIn.size()+", transform "+t); + System.err.println("Region.addOutlineShape().0: VerticeCount "+vertsIn.size()+" + "+addedVerticeCount+" = "+verticeCount); + System.err.println("Region.addOutlineShape().0: IndexCount "+indexCount); + } + growBufferSize(verticeCount, indexCount); } - // setupInitialComponentCount(verticeCount, indexCount); // FIXME: Use it ? final int idxOffset = numVertices; int vertsVNewIdxCount = 0, vertsTMovIdxCount = 0, vertsTNewIdxCount = 0, tris = 0; @@ -330,7 +354,7 @@ public abstract class Region { // triangles.add( triEx ); final Vertex[] triInVertices = triIn.getVertices(); final int tv0Idx = triInVertices[0].getId(); - if( Integer.MAX_VALUE-idxOffset > tv0Idx ) { // Integer.MAX_VALUE != i0 // FIXME: renderer uses SHORT! + if ( max_indices - idxOffset > tv0Idx ) { // valid 'known' idx - move by offset if(Region.DEBUG_INSTANCE) { System.err.println("T["+i+"]: Moved "+tv0Idx+" + "+idxOffset+" -> "+(tv0Idx+idxOffset)); @@ -340,7 +364,7 @@ public abstract class Region { pushIndex(triInVertices[2].getId()+idxOffset); vertsTMovIdxCount+=3; } else { - // invalid idx - generate new one + // FIXME: Invalid idx - generate new one if(Region.DEBUG_INSTANCE) { System.err.println("T["+i+"]: New Idx "+numVertices); } @@ -353,12 +377,13 @@ public abstract class Region { } } if(DEBUG_INSTANCE) { - System.err.println("Region.addOutlineShape().X: idxOffset "+idxOffset+", tris: "+tris+", verts [idx "+vertsTNewIdxCount+", add "+vertsTNewIdxCount+" = "+(vertsVNewIdxCount+vertsTNewIdxCount)+"]"); + System.err.println("Region.addOutlineShape().X: idx[ui32 "+usesI32Idx()+", offset "+idxOffset+"], tris: "+tris+", verts [idx "+vertsTNewIdxCount+", add "+vertsTNewIdxCount+" = "+(vertsVNewIdxCount+vertsTNewIdxCount)+"]"); System.err.println("Region.addOutlineShape().X: verts: idx[v-new "+vertsVNewIdxCount+", t-new "+vertsTNewIdxCount+" = "+(vertsVNewIdxCount+vertsTNewIdxCount)+"]"); System.err.println("Region.addOutlineShape().X: verts: idx t-moved "+vertsTMovIdxCount+", numVertices "+numVertices); System.err.println("Region.addOutlineShape().X: verts: v-dups "+vertsDupCountV+", t-dups "+vertsDupCountT+", t-known "+vertsKnownMovedT); // int vertsDupCountV = 0, vertsDupCountT = 0; System.err.println("Region.addOutlineShape().X: box "+box); + printBufferStats(System.err); } markShapeDirty(); } @@ -405,6 +430,7 @@ public abstract class Region { } protected final int getDirtyBits() { return dirty; } + @Override public String toString() { return "Region["+getRenderModeString(this.renderModes)+", q "+quality+", dirty "+dirty+", vertices "+numVertices+", box "+box+"]"; } diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java index d924fa9c8..69638f60e 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java @@ -29,6 +29,8 @@ package com.jogamp.graph.curve.opengl; import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; +import com.jogamp.opengl.GLArrayData; +import com.jogamp.opengl.GLProfile; import jogamp.graph.curve.opengl.VBORegion2PMSAAES2; import jogamp.graph.curve.opengl.VBORegion2PVBAAES2; @@ -37,6 +39,10 @@ import jogamp.graph.curve.opengl.VBORegionSPES2; import com.jogamp.opengl.util.PMVMatrix; import com.jogamp.opengl.util.texture.TextureSequence; import com.jogamp.graph.curve.Region; + +import java.io.PrintStream; + +import com.jogamp.common.nio.Buffers; import com.jogamp.graph.curve.OutlineShape; /** A GLRegion is the OGL binding of one or more OutlineShapes @@ -57,31 +63,36 @@ public abstract class GLRegion extends Region { * *

In case {@link Region#VBAA_RENDERING_BIT} is being requested the default texture unit * {@link Region#DEFAULT_TWO_PASS_TEXTURE_UNIT} is being used.

+ * @param glp intended GLProfile to use. Instance may use higher OpenGL features if indicated by GLProfile. * @param renderModes bit-field of modes, e.g. {@link Region#VARWEIGHT_RENDERING_BIT}, {@link Region#VBAA_RENDERING_BIT} * @param colorTexSeq optional {@link TextureSequence} for {@link Region#COLORTEXTURE_RENDERING_BIT} rendering mode. */ - public static GLRegion create(int renderModes, final TextureSequence colorTexSeq) { + public static GLRegion create(final GLProfile glp, int renderModes, final TextureSequence colorTexSeq) { if( null != colorTexSeq ) { renderModes |= Region.COLORTEXTURE_RENDERING_BIT; } else if( Region.hasColorTexture(renderModes) ) { throw new IllegalArgumentException("COLORTEXTURE_RENDERING_BIT set but null TextureSequence"); } if( isVBAA(renderModes) ) { - return new VBORegion2PVBAAES2(renderModes, colorTexSeq, Region.DEFAULT_TWO_PASS_TEXTURE_UNIT); + return new VBORegion2PVBAAES2(glp, renderModes, colorTexSeq, Region.DEFAULT_TWO_PASS_TEXTURE_UNIT); } else if( isMSAA(renderModes) ) { - return new VBORegion2PMSAAES2(renderModes, colorTexSeq, Region.DEFAULT_TWO_PASS_TEXTURE_UNIT); + return new VBORegion2PMSAAES2(glp, renderModes, colorTexSeq, Region.DEFAULT_TWO_PASS_TEXTURE_UNIT); } else { - return new VBORegionSPES2(renderModes, colorTexSeq); + return new VBORegionSPES2(glp, renderModes, colorTexSeq); } } + private final int gl_idx_type; protected final TextureSequence colorTexSeq; - protected GLRegion(final int renderModes, final TextureSequence colorTexSeq) { - super(renderModes); + protected GLRegion(final GLProfile glp, final int renderModes, final TextureSequence colorTexSeq) { + super(renderModes, glp.isGL2ES3() /* use_int32_idx */); + this.gl_idx_type = usesI32Idx() ? GL.GL_UNSIGNED_INT : GL.GL_UNSIGNED_SHORT; this.colorTexSeq = colorTexSeq; } + protected final int glIdxType() { return this.gl_idx_type; } + /** * Updates a graph region by updating the ogl related * objects for use in rendering if {@link #isShapeDirty()}. @@ -94,12 +105,28 @@ public abstract class GLRegion extends Region { protected abstract void clearImpl(final GL2ES2 gl); + protected static void printAndCount(final PrintStream out, final String name, final GLArrayData data, final int[] size, final int[] capacity) { + out.print(name+"["); + if( null != data ) { + data.printStats(out); + size[0] += data.getSizeInBytes(); + capacity[0] += data.getCapacityInBytes(); + out.print("]"); + } else { + out.print("null]"); + } + } + /** * Clears all data, i.e. triangles, vertices etc. + * + * @param gl the current {@link GL2ES2} object + * @return this {@link GLRegion} for chaining. */ - public void clear(final GL2ES2 gl) { + public GLRegion clear(final GL2ES2 gl) { clearImpl(gl); clearImpl(); + return this; } /** diff --git a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java index 88e972bdc..547a07fba 100644 --- a/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java +++ b/src/jogl/classes/com/jogamp/graph/curve/opengl/TextRegionUtil.java @@ -144,7 +144,7 @@ public class TextRegionUtil { GLRegion region = getCachedRegion(font, str); AABBox res; if(null == region) { - region = GLRegion.create(renderModes, null); + region = GLRegion.create(gl.getGLProfile(), renderModes, null); res = addStringToRegion(region, font, null, str, rgbaColor, tempT1, tempT2); addCachedRegion(gl, font, str, region); } else { @@ -185,7 +185,7 @@ public class TextRegionUtil { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } - final GLRegion region = GLRegion.create(renderModes, null); + final GLRegion region = GLRegion.create(gl.getGLProfile(), renderModes, null); final AABBox res = addStringToRegion(region, font, null, str, rgbaColor); region.draw(gl, renderer, sampleCount); region.destroy(gl); @@ -193,8 +193,10 @@ public class TextRegionUtil { } /** - * Render the string in 3D space w.r.t. the font in font em-size [0..1] at the end of the given {@link GLRegion}, - * which will {@link GLRegion#clear(GL2ES2) cleared} beforehand. + * Render the string in 3D space w.r.t. the font in font em-size [0..1] at the end of the given {@link GLRegion}. + *

+ * User might want to {@link GLRegion#clear(GL2ES2)} the region before calling this method. + *

*

* The shapes added to the GLRegion are in font em-size [0..1]. *

@@ -202,6 +204,8 @@ public class TextRegionUtil { * Origin of rendered text is 0/0 at bottom left. *

* @param gl the current GL state + * @param region + * @param renderer * @param font {@link Font} to be used * @param str text to be rendered * @param rgbaColor if {@link Region#hasColorChannel()} RGBA color must be passed, otherwise value is ignored. @@ -216,14 +220,13 @@ public class TextRegionUtil { if(!renderer.isInitialized()){ throw new GLException("TextRendererImpl01: not initialized!"); } - region.clear(gl); final AABBox res = addStringToRegion(region, font, null, str, rgbaColor); region.draw(gl, renderer, sampleCount); return res; } /** - * Clear all cached {@link GLRegions}. + * Clear all cached {@link GLRegions} and mapped values. */ public void clear(final GL2ES2 gl) { // fluchCache(gl) already called diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java index 798d77b8f..4d88479ea 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java @@ -27,9 +27,12 @@ */ package jogamp.graph.curve.opengl; +import java.io.PrintStream; import java.nio.FloatBuffer; import com.jogamp.opengl.GL2ES2; +import com.jogamp.opengl.GLArrayData; +import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.GL; import com.jogamp.opengl.GLUniformData; @@ -43,6 +46,7 @@ import com.jogamp.opengl.FBObject; import com.jogamp.opengl.FBObject.Attachment; import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.opengl.util.GLArrayDataClient; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.glsl.ShaderProgram; import com.jogamp.opengl.util.texture.Texture; @@ -134,15 +138,16 @@ public class VBORegion2PMSAAES2 extends GLRegion { } } - public VBORegion2PMSAAES2(final int renderModes, final TextureSequence colorTexSeq, final int pass2TexUnit) { - super(renderModes, colorTexSeq); + public VBORegion2PMSAAES2(final GLProfile glp, final int renderModes, final TextureSequence colorTexSeq, final int pass2TexUnit) { + super(glp, renderModes, colorTexSeq); rsLocal = new RenderState.ProgramLocal(); final int initialElementCount = 256; + // We leave GLArrayDataClient.DEFAULT_GROWTH_FACTOR intact for avg +19% size, but 15% less CPU overhead compared to 1.2 (19% total) // Pass 1: - indicesBuffer = GLArrayDataServer.createData(3, GL.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + indicesBuffer = GLArrayDataServer.createData(3, glIdxType(), initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); gca_VerticesAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL.GL_FLOAT, false, initialElementCount, GL.GL_STATIC_DRAW); @@ -173,7 +178,7 @@ public class VBORegion2PMSAAES2 extends GLRegion { // Pass 2: gcu_FboTexUnit = new GLUniformData(UniformNames.gcu_FboTexUnit, pass2TexUnit); - indicesFbo = GLArrayDataServer.createData(3, GL.GL_SHORT, 2, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + indicesFbo = GLArrayDataServer.createData(3, GL.GL_UNSIGNED_SHORT, 2, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); indicesFbo.puts((short) 0); indicesFbo.puts((short) 1); indicesFbo.puts((short) 3); indicesFbo.puts((short) 1); indicesFbo.puts((short) 2); indicesFbo.puts((short) 3); indicesFbo.seal(true); @@ -190,6 +195,16 @@ public class VBORegion2PMSAAES2 extends GLRegion { false, 4, GL.GL_STATIC_DRAW); } + @Override + protected void growBufferSize(final int verticeCount, final int indexCount) { + indicesBuffer.growIfNeeded(indexCount); + gca_VerticesAttr.growIfNeeded(verticeCount * gca_VerticesAttr.getCompsPerElem()); + gca_CurveParamsAttr.growIfNeeded(verticeCount * gca_CurveParamsAttr.getCompsPerElem()); + if( null != gca_ColorsAttr ) { + gca_ColorsAttr.growIfNeeded(verticeCount * gca_ColorsAttr.getCompsPerElem()); + } + } + @Override protected final void clearImpl(final GL2ES2 gl) { if( null != indicesBuffer ) { @@ -207,6 +222,23 @@ public class VBORegion2PMSAAES2 extends GLRegion { fboDirty = true; } + @Override + protected void printBufferStats(final PrintStream out) { + final int[] size= { 0 }, capacity= { 0 }; + out.println("VBORegion2PMSAAES2:"); + printAndCount(out, " indices ", indicesBuffer, size, capacity); + out.println(); + printAndCount(out, " vertices ", gca_VerticesAttr, size, capacity); + out.println(); + printAndCount(out, " params ", gca_CurveParamsAttr, size, capacity); + out.println(); + printAndCount(out, " color ", gca_ColorsAttr, size, capacity); + final float filled = (float)size[0]/(float)capacity[0]; + out.println(); + out.printf(" total [bytes %,d / %,d], filled %.1f%%, left %.1f%%]%n", + size[0], capacity[0], filled*100f, (1f-filled)*100f); + } + @Override protected final void pushVertex(final float[] coords, final float[] texParams, final float[] rgba) { gca_VerticesAttr.putf(coords[0]); @@ -231,7 +263,11 @@ public class VBORegion2PMSAAES2 extends GLRegion { @Override protected final void pushIndex(final int idx) { - indicesBuffer.puts((short)idx); + if( usesI32Idx() ) { + indicesBuffer.puti(idx); + } else { + indicesBuffer.puts((short)idx); + } } @Override diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java index a5af67e0c..7e8d76127 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PVBAAES2.java @@ -27,9 +27,11 @@ */ package jogamp.graph.curve.opengl; +import java.io.PrintStream; import java.nio.FloatBuffer; import com.jogamp.opengl.GL2ES2; +import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.GL; import com.jogamp.opengl.GLUniformData; @@ -47,6 +49,7 @@ import com.jogamp.opengl.FBObject.Attachment; import com.jogamp.opengl.FBObject.TextureAttachment; import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.math.geom.AABBox; +import com.jogamp.opengl.util.GLArrayDataClient; import com.jogamp.opengl.util.GLArrayDataServer; import com.jogamp.opengl.util.glsl.ShaderProgram; import com.jogamp.opengl.util.texture.Texture; @@ -171,24 +174,31 @@ public class VBORegion2PVBAAES2 extends GLRegion { } } - public VBORegion2PVBAAES2(final int renderModes, final TextureSequence colorTexSeq, final int pass2TexUnit) { - super(renderModes, colorTexSeq); + public VBORegion2PVBAAES2(final GLProfile glp, final int renderModes, final TextureSequence colorTexSeq, final int pass2TexUnit) { + super(glp, renderModes, colorTexSeq); rsLocal = new RenderState.ProgramLocal(); final int initialElementCount = 256; + // final float growthFactor = 1.2f; // avg +5% size but 15% more overhead (34% total) + final float growthFactor = GLArrayDataClient.DEFAULT_GROWTH_FACTOR; // avg +20% size, but 15% less CPU overhead compared to 1.2 (19% total) // Pass 1: - indicesBuffer = GLArrayDataServer.createData(3, GL.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + indicesBuffer = GLArrayDataServer.createData(3, glIdxType(), initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + indicesBuffer.setGrowthFactor(growthFactor); gca_VerticesAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL.GL_FLOAT, - false, initialElementCount, GL.GL_STATIC_DRAW); + false, initialElementCount, GL.GL_STATIC_DRAW); + gca_VerticesAttr.setGrowthFactor(growthFactor); gca_CurveParamsAttr = GLArrayDataServer.createGLSL(AttributeNames.CURVEPARAMS_ATTR_NAME, 3, GL.GL_FLOAT, - false, initialElementCount, GL.GL_STATIC_DRAW); + false, initialElementCount, GL.GL_STATIC_DRAW); + gca_CurveParamsAttr.setGrowthFactor(growthFactor); + if( hasColorChannel() ) { gca_ColorsAttr = GLArrayDataServer.createGLSL(AttributeNames.COLOR_ATTR_NAME, 4, GL.GL_FLOAT, false, initialElementCount, GL.GL_STATIC_DRAW); + gca_ColorsAttr.setGrowthFactor(growthFactor); } else { gca_ColorsAttr = null; } @@ -210,7 +220,7 @@ public class VBORegion2PVBAAES2 extends GLRegion { gcu_FboTexUnit = new GLUniformData(UniformNames.gcu_FboTexUnit, pass2TexUnit); gcu_FboTexSize = new GLUniformData(UniformNames.gcu_FboTexSize, 2, FloatBuffer.wrap(new float[2])); - indicesFbo = GLArrayDataServer.createData(3, GL.GL_SHORT, 2, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + indicesFbo = GLArrayDataServer.createData(3, GL.GL_UNSIGNED_SHORT, 2, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); indicesFbo.puts((short) 0); indicesFbo.puts((short) 1); indicesFbo.puts((short) 3); indicesFbo.puts((short) 1); indicesFbo.puts((short) 2); indicesFbo.puts((short) 3); indicesFbo.seal(true); @@ -227,6 +237,16 @@ public class VBORegion2PVBAAES2 extends GLRegion { false, 4, GL.GL_STATIC_DRAW); } + @Override + protected void growBufferSize(final int verticeCount, final int indexCount) { + indicesBuffer.growIfNeeded(indexCount); + gca_VerticesAttr.growIfNeeded(verticeCount * gca_VerticesAttr.getCompsPerElem()); + gca_CurveParamsAttr.growIfNeeded(verticeCount * gca_CurveParamsAttr.getCompsPerElem()); + if( null != gca_ColorsAttr ) { + gca_ColorsAttr.growIfNeeded(verticeCount * gca_ColorsAttr.getCompsPerElem()); + } + } + @Override protected final void clearImpl(final GL2ES2 gl) { if(DEBUG_INSTANCE) { @@ -248,6 +268,23 @@ public class VBORegion2PVBAAES2 extends GLRegion { fboDirty = true; } + @Override + protected void printBufferStats(final PrintStream out) { + final int[] size= { 0 }, capacity= { 0 }; + out.println("VBORegion2PVBAAES2:"); + printAndCount(out, " indices ", indicesBuffer, size, capacity); + out.println(); + printAndCount(out, " vertices ", gca_VerticesAttr, size, capacity); + out.println(); + printAndCount(out, " params ", gca_CurveParamsAttr, size, capacity); + out.println(); + printAndCount(out, " color ", gca_ColorsAttr, size, capacity); + final float filled = (float)size[0]/(float)capacity[0]; + out.println(); + out.printf(" total [bytes %,d / %,d], filled %.1f%%, left %.1f%%]%n", + size[0], capacity[0], filled*100f, (1f-filled)*100f); + } + @Override protected final void pushVertex(final float[] coords, final float[] texParams, final float[] rgba) { gca_VerticesAttr.putf(coords[0]); @@ -272,7 +309,11 @@ public class VBORegion2PVBAAES2 extends GLRegion { @Override protected final void pushIndex(final int idx) { - indicesBuffer.puts((short)idx); + if( usesI32Idx() ) { + indicesBuffer.puti(idx); + } else { + indicesBuffer.puts((short)idx); + } } @Override diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java index 5b0d38929..73f9acb34 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegionSPES2.java @@ -27,10 +27,12 @@ */ package jogamp.graph.curve.opengl; +import java.io.PrintStream; import java.nio.FloatBuffer; import com.jogamp.opengl.GL; import com.jogamp.opengl.GL2ES2; +import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.GLUniformData; import jogamp.graph.curve.opengl.shader.AttributeNames; @@ -58,13 +60,15 @@ public class VBORegionSPES2 extends GLRegion { private final GLUniformData gcu_ColorTexBBox; private ShaderProgram spPass1 = null; - public VBORegionSPES2(final int renderModes, final TextureSequence colorTexSeq) { - super(renderModes, colorTexSeq); + public VBORegionSPES2(final GLProfile glp, final int renderModes, final TextureSequence colorTexSeq) { + super(glp, renderModes, colorTexSeq); rsLocal = new RenderState.ProgramLocal(); final int initialElementCount = 256; - indicesBuffer = GLArrayDataServer.createData(3, GL.GL_SHORT, initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); + // We leave GLArrayDataClient.DEFAULT_GROWTH_FACTOR intact for avg +19% size, but 15% less CPU overhead compared to 1.2 (19% total) + + indicesBuffer = GLArrayDataServer.createData(3, glIdxType(), initialElementCount, GL.GL_STATIC_DRAW, GL.GL_ELEMENT_ARRAY_BUFFER); gca_VerticesAttr = GLArrayDataServer.createGLSL(AttributeNames.VERTEX_ATTR_NAME, 3, GL.GL_FLOAT, false, initialElementCount, GL.GL_STATIC_DRAW); @@ -89,6 +93,16 @@ public class VBORegionSPES2 extends GLRegion { } } + @Override + protected void growBufferSize(final int verticeCount, final int indexCount) { + indicesBuffer.growIfNeeded(indexCount); + gca_VerticesAttr.growIfNeeded(verticeCount * gca_VerticesAttr.getCompsPerElem()); + gca_CurveParamsAttr.growIfNeeded(verticeCount * gca_CurveParamsAttr.getCompsPerElem()); + if( null != gca_ColorsAttr ) { + gca_ColorsAttr.growIfNeeded(verticeCount * gca_ColorsAttr.getCompsPerElem()); + } + } + @Override protected final void clearImpl(final GL2ES2 gl) { if(DEBUG_INSTANCE) { @@ -108,6 +122,23 @@ public class VBORegionSPES2 extends GLRegion { } } + @Override + protected void printBufferStats(final PrintStream out) { + final int[] size= { 0 }, capacity= { 0 }; + out.println("VBORegionSPES2:"); + printAndCount(out, " indices ", indicesBuffer, size, capacity); + out.println(); + printAndCount(out, " vertices ", gca_VerticesAttr, size, capacity); + out.println(); + printAndCount(out, " params ", gca_CurveParamsAttr, size, capacity); + out.println(); + printAndCount(out, " color ", gca_ColorsAttr, size, capacity); + final float filled = (float)size[0]/(float)capacity[0]; + out.println(); + out.printf(" total [bytes %,d / %,d], filled %.1f%%, left %.1f%%]%n", + size[0], capacity[0], filled*100f, (1f-filled)*100f); + } + @Override protected final void pushVertex(final float[] coords, final float[] texParams, final float[] rgba) { gca_VerticesAttr.putf(coords[0]); @@ -132,7 +163,11 @@ public class VBORegionSPES2 extends GLRegion { @Override protected final void pushIndex(final int idx) { - indicesBuffer.puts((short)idx); + if( usesI32Idx() ) { + indicesBuffer.puti(idx); + } else { + indicesBuffer.puts((short)idx); + } } @Override diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java index a3733022f..add4b52dd 100644 --- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java +++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT00.java @@ -56,6 +56,7 @@ import com.jogamp.graph.font.FontFactory; import com.jogamp.graph.font.FontSet; import com.jogamp.graph.geom.SVertex; import com.jogamp.graph.geom.plane.AffineTransform; +import com.jogamp.junit.util.JunitTracer; import com.jogamp.opengl.math.geom.AABBox; import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.NEWTGLContext; @@ -84,6 +85,7 @@ public class TestTextRendererNEWT00 extends UITestCase { static boolean useMSAA = true; static int win_width = 1280; static int win_height = 720; + static boolean loop_inf = false; static Font font; static float fontSize = 24; // in pixel @@ -103,6 +105,7 @@ public class TestTextRendererNEWT00 extends UITestCase { } public static void main(final String args[]) throws IOException { + boolean wait = false; mainRun = true; for(int i=0; i