[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] Typed arrays and network data



On Fri, Feb 5, 2010 at 6:17 AM, Chris Marrin <cmarrin@apple.com> wrote:
>
> On Feb 3, 2010, at 3:28 PM, Kenneth Russell wrote:
>
>> I've seen a few comments about the typed array proposal and some
>> missing features for parsing data from the network. If we add one more
>> type of view, I think we can cover a large number of additional use
>> cases and improve the chances of widespread acceptance of the
>> proposal.
>>
>> Consider adding a type called DataStream, which has a cursor and gets
>> or sets data at that point.
>
> I really think this is way too much for the ArrayBuffer spec. I think it would be sufficient to have simple methods to swizzle and unswizzle values in the typed array classes themselves. A while back I proposed these be new ctors. But it might be better if they were simple set/get methods. For instance we could have 3 enum values: BigEndian, LittleEndian, and NetworkEndian. Then each of the typed arrays with element size > 1 (Int16, UInt16, Int32, UInt32, Float and Double) would have:
>
>        void set(in UInt8Array array, in EndianType endian, in optional unsigned long offset);
>        UInt8Array get(in EndianType endian, in optional unsigned long offset, in optional unsigned long length);
>
> I think this would be the simplest addition to the API and would allow your DataStream class to be build on top of it.

These API suggestions improve neither programmer convenience nor performance.

My DataStream proposal can already be implemented on top of the other
TypedArrays, but doing so is inefficient. To read a big-endian float
from the network, you need to read four bytes from a UInt8Array, store
them in the appropriate order into a temporary UInt8Array that also
has a FloatArray pointing at the same buffer, and then read from the
FloatArray. To write a float in big-endian format, you need to store
it to a temporary FloatArray that also has a UInt8Array pointing at
the same buffer, read the first four bytes from the UInt8Array in the
appropriate order, and store them to the destination buffer.

Primitives which handle unaligned and possibly byte-swapped loads and
stores can be optimized to run many times faster than this sort of
code. The primitives you suggest above do not achieve the desired
efficiency. Returning a newly allocated UInt8Array from get() is
unusably expensive, and set() does not add any significant value.

Handling heterogeneous data from the network is a basic use case that
people have been criticizing the TypedArray proposal for not
supporting. The proposal should at least have some mention to make
reviewers aware that it is extensible to handle this use case, and
without perturbing the existing TypedArray classes at all.

I'm going to send email to es-discuss about this to expand the audience.

-Ken

>
>>
>> [
>>  Constructor(in ArrayBuffer buffer,
>>      optional in unsigned long byteOffset,
>>      optional in unsigned long length)
>> ]
>> interface DataStream : TypedArray {
>>  const object BIG_ENDIAN;
>>  const object LITTLE_ENDIAN;
>>  // Takes either BIG_ENDIAN or LITTLE_ENDIAN as argument
>>  void setEndianness(object endianness);
>>  // Fetches the given type at the cursor with the current endianness.
>>  // Increments the cursor by the size in bytes of the type.
>>  // Throws an exception if the operation would read past the end of the view.
>>  unsigned byte getUint8();
>>  byte getInt8();
>>  unsigned short getUint16();
>>  short getInt16();
>>  unsigned long getUint32();
>>  long getInt32();
>>  unsigned long long getUint64();
>>  long long getInt64();
>>  float getFloat();
>>  double getDouble();
>>  // Sets the given type at the cursor with the current endianness.
>>  // Increments the cursor by the size in bytes of the type.
>>  // Throws an exception if the operation would read past the end of the view.
>>  void setUint8(in unsigned byte value);
>>  void setInt8(in byte value);
>>  void setUint16(in unsigned short value);
>>  void setInt16(in short value);
>>  void setUint32(in unsigned long value);
>>  void setInt32(in long value);
>>  void setUint64(in unsigned long long value);
>>  void setInt64(in long long value);
>>  void setFloat(in float value);
>>  void setDouble(in double value);
>>  // Gets the current position of the cursor, in bytes, from the
>> beginning of the view.
>>  unsigned long getCursorPosition();
>>  // Sets the current position of the cursor, in bytes, from the
>> beginning of the view.
>>  void setCursorPosition(in unsigned long byteOffset);
>> };
>>
>> Note that this wouldn't perturb any of the other interfaces in the spec.
>>
>> What do you think?
>>
>> -Ken
>> -----------------------------------------------------------
>> You are currently subscribe to public_webgl@khronos.org.
>> To unsubscribe, send an email to majordomo@khronos.org with
>> the following command in the body of your email:
>>
>
> -----
> ~Chris
> cmarrin@apple.com
>
>
>
>
> -----------------------------------------------------------
> You are currently subscribe to public_webgl@khronos.org.
> To unsubscribe, send an email to majordomo@khronos.org with
> the following command in the body of your email:
>
>

-----------------------------------------------------------
You are currently subscribe to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email: