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