On Jul 13, 2012, at 6:03 AM, l0nestar wrote:
> I'm trying to optimise my test game. I'm using Android.Opengl.GLES11 to do
> all of my interaction with GL. However it seems to me that the cost for
> calling the API is quite high. I assume that each call i make to GLES11 maps
> to an equivalent java call, is there a cost associated with this transition?
Yes. It's...not cheap.
Short version: if at all possible, use OpenTK or MonoGame. (This will also
result in code that is more portable to other platforms - Win!)
Long version: All bindings of Java types involve lots of JNI glue code, via the
JNIEnv type:
http://docs.xamarin.com/android/advanced_topics/Binding_Android_Types
http://androidapi.xamarin.com/?link=T:Android.Runtime.JNIEnv
http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html
JNIEnv itself is fairly trivial: JNI provides a JNINativeInterface structure
pointer, which contains pointers to functions for all the JNI methods, e.g.:
/* excerpted from <jni.h> */
struct JNINativeInterface {
/* ... */
jint (*GetVersion)(JNIEnv*);
jclass (*FindClass)(JNIEnv*, const char*, jobject, const
jbyte*, jsize);
/* ... */
};
Invoking these is fairly straightforward: declare a C# "mirror" struct
declaration, wrap the function pointers into a delegate via
Marshal.GetDelegateForFunctionPointer(), then invoke the delegate (along with
parameter marshaling, etc.). A JNI method invoke thus consists of invoking a
delegate, which invokes a native function pointer, which calls into Dalvik.
Invocation thus has two sources of overhead:
1. Mono's P/Invoke delegate invocation mechanism
2. Dalvik's JNI mechanism.
Mono's P/Invoke mechanism isn't that bad; if you have a C function which does
nothing, and a C# method which does nothing, and call each in a loop, P/Invoke
method invoke takes ~10x the time of a non-inlined C# method invoke. Probably
not noticeable, since normally your native method would actually be doing
something, not nothing...
Dalvik's JNI overhead, on the other hand... Worst case, using JNI to invoke an
empty Java method, is 160x-280x the time of an equivalent non-inlined C#
method. For event-driven use this is acceptable -- you're usually invoking Java
methods which will actually Do Something, while waiting for user input -- but
OpenGL is another case entirely.
This is why you should stick with OpenTK, as it's just direct P/Invokes into
libopengles.so/etc. This is the P/Invoke overhead case (10x), not the JNI
overhead case (160x).
- Jon
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid