How to get notified when glTexImage2D finished upload? - ios

I want to render after a texture is uploaded to OpenGL, but I cannot get notified about the completition.
I do want to avoid using animation, or any kind of repetitive rendering.
Is glTexImage2D asynchronous at all? As far as I know, almost every OpenGL call is async.
It would be great anyway, if I could be informed about a glDrawArrays completition as well.

The answer is, just continue after the call to glTexImage2D returns. From your point of view it is a synchronous call in the sense that everything is properly set up after it returns. You can make texture uploads asynchronous by using PBOs as intermediate storage, but even then everything is managed by the driver for you and all you need to know is that when glTexImage2D returns you can assume the texture data to be properly uploaded and start rendering. If the texture data is not yet uploaded internally your things won't get rendered anyway and will wait for the texture to be set up.
You are correct that most OpenGL calls can be seen as asynchronous in the sense that they only schedule commands to be sent to the graphics card and the driver decides when to finally send them to the hardware and the hardware is free to decide when to process them, not to speak of the fact that nobody knows when they're actually finished. But you know what, you usually just don't care. If anything needs to block in order to wait for some previous operation to complete (like an asynchronous texture upload), then it will be managed for you automagically and once an OpenGL function returned you can be sure it has done its work from your point of view.
disclaimer: There are indeed situations when you really need to know when an actual operation has finally finished its work on the device. Though your scenario isn't one of those. One of the few situations when you might really want to synchronize operations is, when you are timing something for debugging or profiling reasons. And since OpenGL ES probably lacks ARB_timer_query, issuing a glFinish (like suggested in BlueVoodoo's answer) might be an option in this case.
EDIT: In the same way you don't get notified when your things drawn with glDrawArrays are finally rendered to screen, but you just don't care about it.

I guess you meant it's an asynchronous call? Otherwise, why do you need to get notified? If you need it to be synchronous, have a look at glFinish(). I don't know of any notifications for openGL methods.

Related

performSelectorInBackground called method slowing down main thread - can that be fixed?

The client wrote a REST API for their website before ever starting on an app. it's a nice API, but it was designed to interact with a service that's running on the same network. The client didn't account for the fact that interaction over cellular data would take an exponentially longer amount of time than interaction on the same network, or even the same physical computer. Due to the fact that the client didn't account for this during server design, I am now left with an API that requires I transfer an entire object back and forth every single time the user changes 1 option. At first, it was slowing my main thread down by a ridiculous amount. So, I attempted to fix the problem by putting the API interaction on a background thread with a call to
[self performSelectorInBackground:]
This helped a great deal. However, the graphics are still a little bit choppy. The speed at which the data is transferred and returned isn't overly important, as long as it happens. I was wondering if there's a method of lowering the background thread's priority so that the graphics on the main thread aren't affected at all, or at least, very little. Is that possible?
By default, running a method on the background thread is lowering the priority below the main thread, so it should not be slowing the main (UI) thread. I would guess there is something else going on. I would venture that you are doing something else on the main thread that you are not aware of that is slowing down your "graphics". To check, try stubbing out your server calls, because there is almost no way that a download / parsing of data on the background thread would slow things to the point where the main thread would get hung and cause animations to stutter. The other possibility is that your animations are not done efficiently and are just choppy themselves.
You will need to be more specific with what you mean by the graphics being choppy to get a better answer, though.

WebGL is it possible to emulate an asynchronous call to gl.finish()

WebGL is nice and asynchronous in that you can send off a long list of rendering commands without waiting for them to complete. However, if for some reason you do need to wait for the rendering to complete, you have to do it synchronously with gl.finish(). Surely it would be better if gl.finish accepted a callback and returned immediately?
Question: Is there any way to emulate this reliably?
Usage case: I am rendering a large number of vertices to a large off-screen canvas and then using drawImage to copy sections of this large canvas to small canvases on the page. I don't actually use gl.finish() but drawImage() seems to have the same effect. In my application, re-rendering is only triggered when the user performs an action (e.g. clicking a button), and it may take several hundred milliseconds. It would be nice if during rendering the browser was still responsive allowing scrolling etc. I am looking in particular for a Chrome solution, though something that also works in Firefox and Safari would be good.
Possible (bad) answer: You could try and estimate how long rendering is going to take and then set a timeout that begins with the call to gl.finish(). However, reliably doing this estimation for all sizes of vertex buffer and all users is going to be pretty tricky and inaccurate.
Possible (non-)answer: requestAnimationFrame does what I'm looking for...it doesn't though, does it?
Possible answer in 2018: Perhaps the ImageBitmap API solves this problem - see MDN docs.
You've already partially hit on your answer: drawImage() does indeed have finish-like behavior in that it forces all outstanding drawing commands to complete before it reads back the image data. The problem is that even if gl.finish() did what you wanted it to, wait for rendering to complete, you would still have the same behavior using it as you do now. The main thread would be blocked while the rendering finishes, interrupting the user's ability to interact with the page.
Ideally what you would want in this scenario is some sort of callback that indicates when a set of draw commands have been completed without actually blocking to wait for them. Unfortunately no such callback exists (and it would be surprisingly difficult to provide one, given the way the browser's internals work!)
A decent middle-ground in your case may be to do some intelligent estimations of when you feel the image may be ready. For example, once you have dispatched your draw call spin through 3 or 4 requestAnimationFrames before you call drawImage. If you consistently observe it taking longer (10 frames?) then spin for longer. This would allow users to continue interacting with the page normally and either produce no delay when doing the draw image, because the contents have finished rendering, or much less delay because you do the synchronous step mid-way through the render. Depending on the intended usage of your site non-realtime rendering could probably even stand to spin for a full second or so before presenting.
This certainly isn't a perfect solution, and I wish I had a better answer for you. Perhaps WebGL will gain the ability to query this type of status in the future, because it would be valuable in cases like yours, but for now this is likely the best you can do.

Do I need to elimate extra calls to `glUseProgram()`?

Say I have a bit of code that calls glUseProgram(programId) at different points, but sometimes ends up calling glUseProgram(1) twice, with the same argument (ie program1 is asked for twice).
Should I eliminate the spurious calls to glUseProgram or does glUseProgram already perform that check internally?
As suggested in OpenGL ES Programming Guide for iOS you should prevent redundant calls for glEnable state changes. So an assumption could be made that the same applies to the glUseProgram. Even if this assumption is incorrect, it is still a good idea to order your drawing calls by program and uniform setting if possible.
On my computer, if I use gluseprogram(PROGRAMID) with the same ID twice, without setting to something else in between, the display driver crashes. So I wouldn't.
(edit) Sorry, that was not true. It was actually something to do with the SFML windowing environment. Had wrong settings so was closing the window (and thus the OpenGL environment) before the OpenGL functions were able to 'clean house'.

Why not compile shaders on a background thread?

I've been learning OpenGL ES 2.0/GLSL and related iOS quirks by looking at code and developer videos and I've noticed that there's never any mention of asynchronous shader compilation. Aside from instructors, writers, or salesmen (er, engineers) worrying about adding complexity to their examples, is there a reason for that?
For example, most web data retrieval tutorials hammer home the need for doing some sort of gymnastics (pthreads, NSOperation, GCD, baked in asynch instance methods, etc) to keep from blocking the main thread- why would blocking an app launch be considered acceptable?
It can be a little bit tricky to synchronize two EAGLContext's, beside that, there is nothing against loading this kind of stuff in the background (generally, loading every kind of asset, textures, shaders etc).
Probably the real reasons are that most people think of OpenGL (ES) as something monolithic that only works on one single thread or they never had an issue with loading times that made it worth to load stuff in a background thread or they just don't care (for some people its probably everything together).
For your last question: Networking can add a HUGE latence and with "can" I mean "will". Resource loading isn't that problematic, compared to a network access, loading a shader or texture takes way less time and its already known ahead how much time it will take in the normal case. Plus, people are used to loading screens in game while they don't want to see loading screens when they scroll a table view just so that your application can fetch a picture from a server that doesn't respond.

Delaying event handling in Flash

I'd like to delay the handling for some captured events in ActionScript until a certain time. Right now, I stick them in an Array when captured and go through it when needed, but this seems inefficient. Is there a better way to do this?
Well, to me this seems a clean and efficient way of doing that.
What do you mean by delaying? you mean simply processing them later, or processing them after a given time?
You can always set a timout to the actual processing function in your event handler (using flash.utils.setTimeout), to process the event at a precise moment in time. But that can become inefficient, since you may have many timeouts dangeling about, that need to be handled by the runtime.
Maybe you could specify your needs a little more.
edit:
Ok, basically, flash player is single threaded - that is bytecode execution is single threaded. And any event, that is dispatched, is processed immediatly, i.e. dispatchEvent(someEvent) will directly call all registered handlers (thus AS bytecode).
Now there are events, which actually are generated in the background. These come either from I/O (network, userinput) or timers (TimerEvents). It may happen, that some of these events actually occur, while bytecode is executed. This usually happens in a background thread, which passes the event (in the abstract sense of the term) to the main thread through a (de)queue.
If the main thread is busy executing bytecode, then it will ignore these messages until it is done (notice: nearly any bytecode execution is always the implicit consequence of an event (be it enter frame, or input, or timer or load operation or whatever)). When it is idle, it will look in all queues, until it finds an available message, wraps the information into an ActionScript Event object, and dispatches it as previously described.
Thus this queueing is a very low level mechanism, that comes from thread-to-thread communication (and appears in many multi-threading scenarios), and is inaccessible to you.
But as I said before, your approach both is valid and makes sense.
Store them into Vector instead of Array :p
I think it's all about how you structure your program, maybe you can assign the captured event under the related instance? So that it's all natural to process the captured event with it instead of querying from a global vector

Resources