Interesting.. Thanks for your input Elliot.. I do want to clarify things as you allude that the byte order switch occurs on duplicate() and other methods is a specific regression with Honeycomb; is this correct?
Elliott: "allocate/allocateDirect/map/wrap/duplicate/slice always return a big- endian buffer." I had a feeling it was byte order related with the 65536 to 256 change. I ask because duplicate() on the desktop / J2SE 5.0 and the G2x / Android 2.2 maintain byte order and here is what I get: NIOTest ---------- Native ByteOrder: LITTLE_ENDIAN buffer byte order: LITTLE_ENDIAN buffer2 byte order: LITTLE_ENDIAN bufferWrite2 byte order: LITTLE_ENDIAN buffer.get(): 65536 buffer2.get(): 65536 On the G-Slate / Honeycomb: NIOTest ---------- Native ByteOrder: LITTLE_ENDIAN buffer byte order: LITTLE_ENDIAN buffer2 byte order: LITTLE_ENDIAN bufferWrite2 byte order: BIG_ENDIAN buffer.get(): 65536 buffer2.get(): 256 So my understanding is that Honeycomb has a defect for duplicate(), slice(), etc. I was able to update the buffer creation in my extended NIO buffer API to create them like this: ByteBuffer tempBuffer = direct ? ByteBuffer.allocateDirect(capacity * s_SIZE_OF_FLOAT) : ByteBuffer.allocate(capacity * s_SIZE_OF_FLOAT);; buffer1 = nativeOrder ? tempBuffer.order(ByteOrder.nativeOrder()).asFloatBuffer() : tempBuffer.asFloatBuffer(); read = nativeOrder ? tempBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder()).asFloatBuffer() : tempBuffer.asReadOnlyBuffer().asFloatBuffer(); write = nativeOrder ? tempBuffer.duplicate().order(ByteOrder.nativeOrder()).asFloatBuffer() : tempBuffer.duplicate().asFloatBuffer(); -------------- It does suck that one needs to have a ByteBuffer to change the order. There are copy constructors in my NIO API (that don't appear to be used or don't cause any problems presently on Honeycomb) that only have access to the specific buffer (FloatBuffer, etc.) and order(<byte order>) can't be called on them. Only ByteBuffer. However with the above change now things work well on Honeycomb and Auriga3D is fully back working.. phew.. Thanks for mentioning that this will be fixed in ICS and providing the last little missing link I needed to get things working again regardless of the regression and maintain the contract of my extended API. Regards, --Mike On Apr 28, 3:13 pm, Elliott Hughes <e...@google.com> wrote: > from the unit tests: > > // duplicate always returns a big-endian buffer. > b.order(ByteOrder.BIG_ENDIAN); > assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order()); > b.order(ByteOrder.LITTLE_ENDIAN); > assertEquals(ByteOrder.BIG_ENDIAN, b.duplicate().order()); > > allocate/allocateDirect/map/wrap/duplicate/slice always return a big- > endian buffer. > asXBuffer (asCharBuffer et cetera) always returns a buffer with the > same endian as the source. > ...except for asReadOnlyBuffer, which always returns a big-endian > buffer. (note that this is broken in Honeycomb; ICS gets it right.) > > the API's sufficiently unfriendly that any time you make a new Buffer > you should probably call order(ByteOrder), just to preserve your own > sanity. > > (or only ever run your code on a big-endian device, which is > presumably how the API ended up this way... SPARC lives!) > > --elliott > > On Apr 28, 2:59 pm, MichaelEGR <foun...@egrsoftware.com> wrote: > > > > > > > > > CRITICAL NIO FLAW FOUND > > > And I did the leg work again here and put in ~4 hours to reduce the > > bug to a most fundamental example that should be a unit test in > > Android. That it is not and this bug made it to production / shipping > > is amazing. > > > On all Java platforms 1.4, 5.0, 6.0 and Android OS version 1.0 - 2.3 > > the value of index 1 of buffer & buffer2 is 0x10000 (65535). On > > Android 3.0 / Honeycomb index 1 of buffer is 65535 and buffer 2 is > > 256.. Clearly a major if not critical flaw in Honeycomb for usage of > > the NIO API and calling duplicate() on a Buffer. Any code using NIO > > and duplicate() will likely break on Honeycomb. > > > Being that this is a critical flaw.. Do you guys offer rewards or is > > that only security flaws? I'll take my $1,337 check or a Google I/O > > ticket. > > > You guys do understand that the 4 hours I did to reduce this critical > > bug to an easily demonstrable level I'd charge more than a Google I/O > > ticket on an invoice. > > > To run on Android simply call com.egrsoftware.niotest.NIOTest.test() > > from onCreate() of any Activity and check system output via adb logcat > > or ddms. > > > --------------------------------------------------------------------------- > > ----------- > > > package com.egrsoftware.niotest; > > > import java.nio.ByteBuffer; > > import java.nio.ByteOrder; > > import java.nio.IntBuffer; > > > /** > > * NIOTest - Extremely simple unit test that Google should include in > > Android because it catches a bug in NIO that is > > * found in Android 3.0 / Honeycomb. This is a really nefarious bug as > > the affected code could be networking code, any > > * native JNI code, or in my case 3D rendering via the Android OpenGL > > ES API. Any code using NIO and "duplicate()" is > > * broken. > > * > > * On all Java platforms with NIO and Android versions 1.0 to 2.3 both > > buffers should print out 65535. On Android / > > * Honeycomb the 1st value in buffer 1 is 65535 and buffer 2 is > > 256!!!! Clearly a bug that any simple unit testing > > * should have found. This bug affects _ALL_ code that uses the NIO > > duplicate() method on a Buffer. The fall out of > > * this is immense! This is a critical bug! > > */ > > public class NIOTest > > { > > private static int s_SIZE_OF_INT = 4; > > > public static void test() > > { > > IntBuffer buffer = ByteBuffer.allocateDirect(1 * > > s_SIZE_OF_INT).order( > > ByteOrder.nativeOrder()).asIntBuffer(); > > > IntBuffer buffer2 = ByteBuffer.allocateDirect(1 * > > s_SIZE_OF_INT).order( > > ByteOrder.nativeOrder()).asIntBuffer(); > > > IntBuffer bufferWrite2 = buffer2.duplicate(); > > > buffer.put(0, 0x10000); //put 65535 > > bufferWrite2.put(0, 0x10000); > > > System.err.println("NIOTest ----------"); > > System.err.println("buffer.get(): " +buffer.get()); > > System.err.println("buffer2.get(): " +buffer2.get()); > > } > > > public static void main(String args[]) > > { > > test(); > > } > > > } -- 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