To clarify, in the original example, no buffer is allocated. The call
to "DynamicBuffer.allocate()" simply moves a position in a previously
allocated buffer which is filled each frame - ie. an "arena
allocator". DynamicBuffer.deallocate_last(size) simply moves the
position back without destroying any memory.

So it is not a gc issue. Also, while the buffer might get filled with
"junk" it will still be valid floats of some sort, since the array is
only written to from java.

Best regards,
Viktor Linder

On 25 Feb, 20:08, Robert Green <[email protected]> wrote:
> Actually, let me clear something technical up.  I just realized that
> the OpenGL native side is using GetPrimitiveArrayCritical and not
> GetDirectBufferAddress.  I'm not sure why they decided to take that
> route but I'm sure there was a good reason for it.  The fact of the
> matter is that while GPAC doesn't guarantee the actual array address
> (it has the option to make a copy), it's most likely that it won't
> make a copy and will instead hand over the actual array address.  This
> of course depends on the VM's implementation.  The could have easily
> implemented it to always use the actual address.  Someone from that
> camp would have to comment because I'm not going to dig through
> Dalvik's source :)
>
> Read more about it 
> here:http://java.sun.com/j2se/1.3/docs/guide/jni/jni-12.html#GetPrimitiveA...
>
> That being said - all of what I talked about still stands.  It's just
> a different JNI function to get to it.
>
> On Feb 25, 12:39 pm, Robert Green <[email protected]> wrote:
>
> > Let me explain something.  Using directly allocated NIO buffers is a
> > DIRECT LINK between Java and native.  The pointer you get from (void
> > *)GetDirectBufferAddress points to the exact memory that the Java
> > buffer is using.  The memory is not managed in Java on the heap like
> > everything else.  This is one of the few cases where you can write to
> > natively accessible code that does not need to be copied to work on
> > like an array does.
>
> > It's not a copy.  It's the original buffer data that the native side
> > sees.  That memory will be freed when the Buffer's java object is GCed
> > (from no more references.)  It's safe to use that address so long as
> > you're still holding on to a reference to the Buffer (in Java, not
> > native.  That native pointer is only as good as the java
> > counterpart).  In the context of OpenGL, the memory is needed during
> > the GL bufferdata or GL array call and most likely during the draw
> > call (As that normally needs to read from system memory, particularly
> > with arrays) but I don't know if it needs it all the way to the end of
> > the flush.  One would have to ask why you'd be allocating/deallocating
> > memory in a real time simulation, though :)  Preallocation throughout
> > the sim would be the ideal solution and that wouldn't have issues with
> > invalidating memory before it's done being used.
>
> > Like Bob said, don't be creating new buffers all the time.  In a
> > dynamic system (where you don't know how many triangles you'll be
> > drawing until visibility checks are done), make one the biggest buffer
> > it ever needs to be and use however much of it you need to use for
> > that draw.  Most systems are relatively static, though, so all you
> > need to do is preallocate for each unique 3d object and use transforms
> > to do the dirty work.
>
> > I have a dynamic system for animations so I end up recalcing vertex
> > positions, but that's a fixed size buffer so I never need to
> > reallocate.  I just process it in native code and it really works
> > great.
>
> > On Feb 25, 11:30 am, Bob Kerns <[email protected]> wrote:
>
> > > This would be a bug in the JNI code, which is responsible for
> > > protecting from the GC any and all memory which it is using. Only it
> > > can do so, because only it knows when it is done.
>
> > > That's unlikely, though. The the JNI API makes it impossible to get
> > > your JNI code to get its hands on the data without protecting it from
> > > the GC -- and even then, you may only get a copy, if the system feels
> > > like doing that instead. Bugs ARE still possible -- you can free it an
> > > then hang onto the data you no longer have rights to.
>
> > > But really, the only impact of holding onto a buffer on the Java side,
> > > only to discard it next frame, is to make the GC work harder.  If you
> > > were to REUSE that buffer, however, you'd avoiding extra GC work.
>
> > > On Feb 25, 12:45 am, Twisted Ware <[email protected]> wrote:
>
> > > > Robert has a very good point, but I also think you can expect the GL
> > > > implementation to allow the buffers to get garbage collected before
> > > > they have been used.
>
> > > > You allocate the buffer in a scope and then pass that buffer pointer
> > > > into the GL system - and then toss the memory away. Unless you flush
> > > > the GL queue, there is no guarantee the graphics system has done
> > > > anything with the data you've passed. The point of the direct buffers
> > > > is to prevent copying data around all the time during these calls, so
> > > > the GL system could be using the memory directly much later than you
> > > > expect. You should probably not deallocate the buffer until the next
> > > > frame comes around, when you know the system is done with the data.
>
> > > > On Feb 24, 2:50 pm, Robert Green <[email protected]> wrote:
>
> > > > > The OpenGL wrappers take the data pointer passed in by those sorts of
> > > > > methods using native GetDirectBufferAddress of the corresponding type
> > > > > (int or float) and pass that pointer into the native gl method.  That
> > > > > only works correctly if it's a direct buffer.
>
> > > > > I just checked android_opengl_GLES10.cpp and GLES11.cpp and found that
> > > > > glTexImage2D and glBufferData use the same getPointer() method to get
> > > > > to the data.  That means that behavior should be the same.
> > > > > Ultimately, the data comes from:
>
> > > > > *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
> > > > >             getBaseArrayID, buffer);
> > > > >     offset = _env->CallStaticIntMethod(nioAccessClass,
> > > > >             getBaseArrayOffsetID, buffer);
> > > > >     data = _env->GetPrimitiveArrayCritical(*array, (jboolean *)
> > > > > 0);
> > > > >     return (void *) ((char *) data + offset);
>
> > > > > then the gl method is called, then the pointer is released.
>
> > > > > Always use direct buffers when working with any aspect of OpenGL on
> > > > > Android.
>
> > > > > On Feb 24, 4:01 am, Clankrieger <[email protected]> wrote:
>
> > > > > > As what I am aware of, VBOs do not need direct buffers (and indirect
> > > > > > buffers might be handled faster), but this is just a detail. I also
> > > > > > tried GL_FIXED but it did not make much difference for me. I assume
> > > > > > that it gives performance gains only if you have a) static data that
> > > > > > is converted to fixed format once and then re-rendered or b) do all
> > > > > > calculations with fixed number precision (which is making things a 
> > > > > > lot
> > > > > > more complicated and less readable when you need to update data). 
> > > > > > So I
> > > > > > switched back to Float because I hat to convert most values to fixed
> > > > > > before uploading them in GL calls.
>
> > > > > > I wonder if your offsets are correct? Is _pos_size_bytes the correct
> > > > > > offset? For safety, I would stick to non-interleaved arrays for
> > > > > > testing. Also I'm not sure when to array-copying in the bufferdata
> > > > > > call takes place - have you tried a glFlush call or a buffer rebind
> > > > > > (bind VBO to 0 and the ID again) after all the buffering? Somebody
> > > > > > with knowledge about the native part of of this buffering could help
> > > > > > you better with this, I guess.
>
> > > > > > T.
>
> > > > > > On Feb 16, 8:43 pm, Viktor Linder <[email protected]> wrote:
>
> > > > > > > As you say, the most likely explanation is that I have a bad 
> > > > > > > pointer
> > > > > > > being used somewhere. The thing is I have gone over this code a 
> > > > > > > bunch
> > > > > > > of times and tried lots of different checks and I just can't find
> > > > > > > what's wrong.
> > > > > > > Do you have any pointers on ways to debug the crash in the GL 
> > > > > > > library?
>
> > > > > > > I forgot to mention: I bind the array buffer to 0 after the call 
> > > > > > > to
> > > > > > > glDrawElements(), so any future draw calls that are not using VBOs
> > > > > > > will not break. Also, I am not using VBOs for all draw calls.
>
> > > > > > > You keep a different VBO for each channel; is using a single VBO 
> > > > > > > for
> > > > > > > several channels not allowed?
>
> > > > > > > If its possible to use a single buffer that would reduce the 
> > > > > > > needed
> > > > > > > calls to glBindBuffer() and allowed interleaved data which would
> > > > > > > improve cache locality.
>
> > > > > > > Curious; did using GL_FIXED give a large performance gain?
>
> > > > > > > Thanks for your help.
>
> > > > > > > /Viktor
> > > > > > > On 16 Feb, 21:25, Robert Green <[email protected]> wrote:
>
> > > > > > > > You're probably pointing something to some bad memory location
> > > > > > > > somewhere.  I know you didn't post all of your real code so I 
> > > > > > > > can't
> > > > > > > > really say for sure but it looks to me like you may be doing 
> > > > > > > > something
> > > > > > > > wrong with your buffers.  Here's how I do it:
>
> > > > > > > > -- Load --
> > > > > > > >                         GL11 gl11 = (GL11) gl;
> > > > > > > >                         if (modelData.normals != null) {
> > > > > > > >                                 int[] vboIds = new int[5];
> > > > > > > >                                 gl11.glGenBuffers(5, vboIds, 0);
> > > > > > > >                                 vertexVBOId = vboIds[0];
> > > > > > > >                                 texVBOId = vboIds[1];
> > > > > > > >                                 normalVBOId = vboIds[2];
> > > > > > > >                                 indexVBOId = vboIds[3];
> > > > > > > >                                 lightmapVBOId = vboIds[4];
> > > > > > > >                         } else {
> > > > > > > >                                 int[] vboIds = new int[4];
> > > > > > > >                                 gl11.glGenBuffers(4, vboIds, 0);
> > > > > > > >                                 vertexVBOId = vboIds[0];
> > > > > > > >                                 texVBOId = vboIds[1];
> > > > > > > >                                 indexVBOId = vboIds[2];
> > > > > > > >                                
>
> ...
>
> läs mer »

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to