Save Eve display by TGLViewer::SavePictureUsingFBO (TGLFBO::Init error)

Hello.
I’m saving my TEveViewer instance (3D Eve display) as a png picture in the task of our software but it causes the following errors and hangs a little bit later:

Warning in <TGLLogicalShape::Draw>: display-list registration failed. Warning in <TGLLogicalShape::Draw>: display-list registration failed. Warning in <TGLLogicalShape::Draw>: display-list registration failed. Warning in <TGLLogicalShape::Draw>: display-list registration failed. Warning in <TGLLogicalShape::Draw>: display-list registration failed. Warning in <TGLLogicalShape::Draw>: display-list registration failed. Error in <TGLSAViewer::TGLViewer::SavePictureUsingFBO>: TGLFBO::Init Constructed TGLFBO is not complete, unexpected error. Info in <TGLSAViewer::TGLViewer::SavePictureUsingFBO>: Falling back to saving image via back-buffer. Window must be fully visible. Error in <TGLLockable::TakeLock>: 'TGLViewerBase' unable to take DrawLock, already DrawLock Error in <TGLSAViewer::TGLViewer::SavePictureUsingBB>: viewer locked - try later

The part of my code (ROOT 5.34/34, nvidia driver 340.96):

gEve->Redraw3D(); gSystem->ProcessEvents(); gEve->GetDefaultGLViewer()-> SavePicture(fileName.Data());

I can’t understand what is the reason. I have tried SL 6.7 and Ubuntu 15, but there are similar errors. Please, help.
Thanks you.
With best wishes, Konstantin.

One of the error messages says :

Window must be fully visible.

Is it the case ?

[quote=“couet”]
Is it the case ?[/quote]
Thank you for suggestion but it’s fully visible. It’s inside my desktop and e.g. it’s about 2 time less than my desktop.

By the way there were the similar but not exactly the same errors in SL 6.7. Unfortunately, I don’t have an access to the computer with SL now. It seems that it didn’t include the message about window visibility and it also included the message concerned with incorrect GL_MAX_RENDERBUFFER_SIZE_EXT value.

I asked the TEve author to look at this.

Thank you, i will wait. I’m not sure but it exactly occurs witn nvidia drivers and not always with nouveau drivers.

Hi,

At what scale are you saving the image? Maximum supported by most GL implementations is 8192x8192.

Cheers,
Matevz

[quote=“matevz”]Hi,
At what scale are you saving the image? Maximum supported by most GL implementations is 8192x8192.
Cheers,
Matevz[/quote]
Good morning.
I don’t change the scale (only SavePicture function), i think it’s equal to 1.0 by default.
The result images have sizes of about 790*560 pixels.

May be these errors are due to the fact that i call the functions in a separate (new) thread? It looks like some opengl functions are called outside the opengl context or there are some thread-unsafe operations…

Hi,

It’s good night here :wink:

Yes, you shouldn’t call them from another thread … call the function via gROOT->ProcessLine(), as in:
github.com/root-mirror/root/blo … r.cxx#L458
just replace the DoDraw with whatever function you call to dump the image.

The thing is that a lot of GL context information is stored in thread local storage within the driver code so the thread that creates the GL context should be the only thread doing actual GL calls.

Cheers,
Matevz

Oh, thank you much for explanation.

Please, advice me how to find a compromise.
I need not to block GUI during a demonstration of a number of events, e.g. in order to allow stopping demonstration (clicking on the button “Stop demonstration”) and some other things. Should I call all graphic (opengl) functions via gROOT->ProcessLine() in a separate thread? or can i do it somehow in the main thread without blocking GUI?

P.S. It’s strange that it works well with nouveau drivers but errors always occur in case of nvidia drivers.

Well, there is no easy way out … the right solution would be to make TGLViewer/Context be able to run in a different thread but this would be super hard as TGLViewer is polluted with the calls as the one I sent you earlier. The reason for those guys is that on windows GUI always ran in a separate thread and this was the way to get it to work. I don’t know all the details, but Timur and Bertrand probably do :slight_smile:

Could you get by with just calling gSystem->ProcessEvents() between each redraw? You could still do any calculations in another thread.

And yes, nvidia drivers are the guys using thread-local storage for gl context state, I think catalyst does that, too.