Multithreading screenshots

Hi all,

in my project I need to render a set of models and obtain their separated screenshots.
The simple way is to load model to the world, set the positions of the model, camera and source of light, render frame, save screenshot and clear the world.
Going through this process in one thread can take approx. 1 second and more models will take more time.

Is there any way to run these tasks in parallel mode?
May the method with loading all models at once and then showing one model and hiding all other models be faster?

I would suggest doing some testing (perhaps via PStats) to determine which elements of the process are taking the most time, and then looking at a way to parallelise those first.

Thank you for your reply!

I’ve done some time measures:
render_time: 0:00:00.005116
get_screenshot_time: 0:00:00.032409

So in case of 1000 models the process will take noticeable amount of time…

After getting screenshot I need to obtain intensity of all image pixels and this step appears to be the most time-consuming: for 2000*2000 pixels it takes 0:00:00.652523 s on my laptop.

I have been trying to create a number of display regions and get screenshots in different threads but in this case

dr.getScreenshot(pnmimage)

resulted in the error “EGL_BAD_ACCESS” and an empty image.

Just to check: have you looked into the time taken in saving out your screenshots? That, too, could be taking up some time.

Oof, yeah–that could very much add up indeed. Is there perhaps a C++ module that you could use to do this more quickly?

Otherwise, this step looks like the first thing to parallelise: store your images until you’re done with them and have a thread run through the pixels while your program does other things.

I’m not sure about the rest (such as the “bad access” error) offhand myself, I’m afraid–perhaps someone else will have an answer for you!

I’m not sure what exactly you are doing on the pixels, but perhaps one of the operations already implemented in PNMImage, such as getAverageGray, can help?

As for reducing your frame time, I am not sure how the frame render can be parallelized effectively (it may be possible with separate contexts, but the GPU is ultimately processing render commands one at a time). Perhaps it would help to create many separate GraphicsBuffers that are set up with a RTMCopyRam texture each and then use a single renderFrame() to fire them all off in one go.

It might actually be even faster to just use a single GraphicsBuffer with an array texture bound to it, and create one DisplayRegion per model, and set the texture page to render to. Again, not multithreaded, but may help to reduce overhead.

I call getBright(x, y) for every pixel to get image brightness.

Regarding getAverageGray, am I correct for color image it will return brightness only for blue channel?

About setting the texture page I will be thinking, thank you!

Sorry for the late reply. Yes, getAverageGray will only return the blue channel, whereas getAverageXel returns all three (and getAverageXelA also includes alpha).

Thank you for reply! I’ll try using getAverageXel later.

For now I’ve ended up with saving rendered frames into files consecutively and then processing them in parallel.

FWIW, I was doing something similar and used getRamImageAs() to speed things up.