Hi,
I am developing an OpenGL module for Appcelerator. Here is a sample code snippet of how its going to be used in JS:
var glView = tiuoozo.createGlView({ left: 10, top: 10, width: 200, height: 200, // backgroundColor: "#00FFFF" }); window.add(glView); var gl = glView; var texture = gl.createTexture(); Ti.API.info("Texture Is: " + texture); gl.bindTexture(gl.TEXTURE_2D, texture);Now the problem is that createGlView actually doesn't create the view and the GL context isn't ready when the
gl.createTexture(); call is made. This is completely screwing up my code flow.
How can I block javascript while my view is being initialized (i.e. initWithFrame). I would also like to block when frameSizeChanged is called because certain GL elements will need to be reinitialized.
This is iOS btw. I will have an equivalent Android module as well. I would appreciate if someone can tell me the relevant API for that platform as well.
Thanks.
2 Answers
Hi, view creation is always asynchronous and you cannot change this behavior. What gets created in a synchronous way is the ViewProxy object, which is responsible of the creation of the View object.
Now, what do you mean with "while my view is being initialized. I would also like to block when frameSizeChanged is called because certain GL elements will need to be reinitialized"?
When the proxy instantiates the view you have the chance to initialize it by overriding the initializeState method of TiUIView. Overriding initWithFrame doesn't usually do what you'd expect, since the view is initially created with a fictitious frame that doesn't reflect the values of the layout properties set in JS-land. So, getting to the point, bindTexture() should set the texture on the view with the current information (i.e. a possibly screwed frame), then you have the chance to fix things in frameSizeChanged() (which is called several times during the view lifeCycle). There you should probably do something similar to what you did in bindTexture() reapplying the texture considering the changed frame size.
I hope this clarifies things a bit. For better understanding what's going on under the hood I suggest you to have a look at how the various views under the Ti.UI namespace are implemented in the Ti SDK source code.
Cheers
Hi,
I've been working on an Appcelerator OpenGL module for a week or so and the concurrency model for modules just baffles my mind. Consider the following source:
var textureId = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, textureId);Straight forward eh?! The
gl object is a proxy which encapsulates a view wrapping the native OpenGL ES API. My problem is that, generally speaking, you either want the whole thing to be concurrent or not. Since OpenGL in iOS does not support multithreading I queue up the operation on the main thread and get a nonsense value in textureId which is unusable in the bindTexture call later on. I can get around this whole problem by using double indirection i.e. returning a textureId which maps to an array of (un)initialized GL textures which I can then lazy initialize whenever someone tries to do an operation on that texture. This is a pain, to say the least and completely counter-intuitive.
I should have the power to make entire proxy calls run on a single thread. Its generally pointless queuing one function call on one thread and the next one another one.
So essentially my questions are:
- Can I make everything belonging to a particular proxy run on a single thread? Remember that I also have to return values and I would like to avoid double lookups as much as possible.
- If the above is not possible then what is the best way of returning 'something' which I can then lazy initialize later on?
Your Answer
Think you can help? Login to answer this question!