No vertex buffers, glBindBufferARB wants int?

As far as I understand, you need to add finalizer to buffer object explicitly if you want to get native memory cleared (through PhantomRef probably). I have not found finalize method anywhere in Buffer source and I hope it is not there - finalization would KILL any hopes for performance. While normal garbage is only bad, objects with finalizers are major offense - for me, acceptable only for critical, long-lived resources (like open files, graphic context etc).

[quote]I have not found finalize method anywhere in Buffer source and I hope it is not there - finalization would KILL any hopes for performance.
[/quote]
Unfortunately the hidden class DirectByteBuffer (which is what is created from the JNI call NewDirectByteBuffer) does in fact have a finalizer.

We’ll have to fully implement the new map primitives and work around this problem if it in fact arises. One possibility would be to keep around a HashMap from the Long address to the ByteBuffer which points to it, since the buffers are unlikely to move in memory.

I have done some measurements for finalizer overhead. Allocating object in tight loop (so they are clearly in eden space only and available for gc umpteen creations after their own), shows following data (jdk141 server after dry run, I’ll retest with 1.4.2 at home)

Allocating and collecting 1.000.000 objects without finalizer (with static x++ in constructor) - 50ms. Doing the same for object with x++ instruction moved to finalizer - 8400ms (this is after substracting overhead for loops and x++, which is around 16ms).

While 50ms is too small number to tell anything, it can give a feeling about order of magnitude of difference between objects with and without finalizer. We are talking here about 1 obj with finalizer = 150 objects without one. This also means that you can allocate and trash only around 100 finalizable objects per ms. Given 5ms per frame as estimate, with 500 direct buffers of garbage you will have no time left for any rendering/ai/anything.

IF we want to go Buffer route, caching is a must - only question is if it should be done at library side or application side. Most apps can easily put a wrapper object around vertex buffer and cache offset buffer there. Certainly, caching ‘zero pointer’ at library would be helpful, for the rest - maybe it is better to leave it to app.

I would just like to ask you to reconsider going plain int route - I know, that this way we are adding amount of manual intervention to api, but on the other hand, int as offset is a lot easier to grasp, manage and a gives no problems with performance.

Although I normally dislike the "me too"s…

Me too! :wink:

We recently went the int route, including the hard parts - manually tracking the VBO state in the library and only allowing Buffer arguments when VBO is disabled and only allowing int offset arguments otherwise. It is ugly to track VBO, but at least it can be done behind the application’s back, and it actually gives extra security over the buffer-only implementation.

  • elias

Vertex_buffer_object support has just been checked in to the JOGL source tree. It deals exclusively with Buffers (no ints/longs exposed) and performs caching of the mapped Buffer objects based on their base address and capacity. The VertexArrayRange demo has been ported to VertexBufferObject and works, though the relative speedup from the system memory version to the vertex buffer object version is currently less than with the original VAR demo. I think the geometry needs to be retesselated to have longer quad strips in order to be more effective; additionally the element arrays could be moved into fast RAM. I’ll try to rebuild on all platforms and post a new set of binaries tonight.

Great, thanks! ;D

So basically, to send the offset, I can just use ANY buffer that has it’s .position() set to the offset I want?
Or am I reading you wrong?

[quote]So basically, to send the offset, I can just use ANY buffer that has it’s .position() set to the offset I want?
[/quote]
You need to use the new net.java.games.jogl.util.BufferUtils.bufferOffset() API, which returns a ByteBuffer representing the desired offset. Please see the source code for the new VertexBufferObject demo (in the jogl-demos source tree) for an example. This demo hasn’t been tuned yet but does show one way of using the APIs.

Shouldn’t ARBVBOKey class have hashCode and equals method implemented ? I do not understand how they work as a key in HashMap at the moment.

Second question - is ‘if (!BufferFactory.isDirect(pointer))’
check really needed ? I think it would fit in DebugGL more than in default implementation.

And finally - BufferUtil does not cache buffers, does it ? For the offsets, we still need to do caching at app level ?

[quote]Shouldn’t ARBVBOKey class have hashCode and equals method implemented ? I do not understand how they work as a key in HashMap at the moment.
[/quote]
Good point, I hadn’t thought clearly through the fact that hashCode() would be broken. Both hashCode() and equals() are now overridden.

[quote]Second question - is ‘if (!BufferFactory.isDirect(pointer))’
check really needed ? I think it would fit in DebugGL more than in default implementation.
[/quote]
The old check used to be in the C code and was present in the default implementation. Range checks are also done by default for passed arrays where the expected size of the array is known. I’m open to moving them into DebugGL but doing so would need to be done by giving GlueGen a .cfg file option to elide the checks and then have them produced by BuildComposablePipeline. If you want to change GlueGen and BuildComposablePipeline to be able to move the checks into DebugGL (while leaving them in by default in GlueGen’s generated code) then please send in a patch. I think however that there isn’t enough information available to BuildComposablePipeline to reconstitute these checks.

[quote]And finally - BufferUtil does not cache buffers, does it ? For the offsets, we still need to do caching at app level ?
[/quote]
Thanks for the suggestion, I’ve added this caching to BufferUtils.