Sure!
It doesn't really do very much, just a wrapper around a buffer.
frame_reset() is called once each frame.

public class DynamicBuffer {
        private static final int BUFFER_SIZE = 32*1024;
        private static final int SCRATCH_SIZE = 32*1024;
        private static int _p = 0;
        public static FloatBuffer _buffer;
        public static float _scratch[] = new float[SCRATCH_SIZE];


        static {
                _buffer = Util.create_floatbuffer(BUFFER_SIZE);
        }

        public static int allocate(int size) {
                int r = _p;
                _p += size;
                if(_p > BUFFER_SIZE)
                        throw new RuntimeException("Dynamic buffer overflow");

                return r;
        }

        // will only deallocate the last consecutive sequence of allocated
blocks
        public static void deallocate(int size) {
                _p -= size;
                if(_p < 0)
                        throw new RuntimeException("Dynamic buffer underflow");
        }

        // write to dynamic buffer at offset off (returned by allocate())
contents of buf at [buf_off,buf_off+buf_len)
        public static void put(int off, float[] buf, int buf_off, int
buf_len) {
                _buffer.position(off);
                _buffer.put(buf, buf_off, buf_len);
        }

        public static void frame_reset() {
                _p = 0;
        }
}

public class Util {
...
        public static FloatBuffer create_floatbuffer(int size) {
                ByteBuffer bb = ByteBuffer.allocateDirect(size*4);
                bb.order(ByteOrder.nativeOrder());
                FloatBuffer fb = bb.asFloatBuffer();
                return fb;
        }
...
}

On 26 Feb, 00:49, Robert Green <rbgrn....@gmail.com> wrote:
> Viktor,
>
> Would you be willing to show a bit of your DynamicBuffer code so I can
> see what it's doing?  It's hard for me to help when there's a black
> box in the middle.
>
> On Feb 25, 1:41 pm, Viktor Linder <linder.vik...@gmail.com> wrote:
>
> > 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 <rbgrn....@gmail.com> 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 <rbgrn....@gmail.com> 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 <r...@acm.org> 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 <tomslic...@gmail.com> 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 <rbgrn....@gmail.com> 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 <tob...@googlemail.com> 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 <linder.vik...@gmail.com> 
> > > > > > > > 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 <rbgrn....@gmail.com> 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 =
>
> > ...
>
> > read more »

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

Reply via email to