Problem in VTK 8.2 with defaultFormat() and QVTKOpenGLWidget on Windows 10/Intel

Thanks for the update. That said, do you know if the particular problem discussed here has been reported to Qt.

It sounds like you have a good handle on what happens in Qt WRT to this.

Only insofar as trying to get Mesa working on Windows guided me.

That said, do you know if the particular problem discussed here has been reported to Qt.

I haven’t reported it. If someone can give me a description, I already have a Qt account to file it with. I also haven’t searched for it either.

Has it been ruled out that this is a bug in VTK yet though? It works on Linux and Mac, and it works with the old VTK widget (QVTKOpenGLNativeWidget aka QVTKOpenGLWidget in older VTKs). Could it not be some missing event handling or something in the new widget?

The smallest reproducer I have is the VTK program in my post above. I’m not sure how I would go about reproducing it without VTK (just plain QOpenGLWidget).

Probably VTK probably does something “special”. It may be a valid operation but it is something uncommon, that most other applications don’t do.

I’ve found that in Slicer if I start up the application without having any QVTK widget and then later add a QVTK widget to the layout then the problem does not occur.

I think you’re right @lassoan , just remains to find what that “special” thing is, and if it’s a valid assumption by VTK or not.

That it works by later adding a QVTK widget I guess could be simply that circumstances causes two renders (so the bug won’t manifest itself). I think I noticed something similar in our app while I was playing around: We have a QVTKOpenGLNativeWidget in another place, and if that widget is initially visible (it’s normally not, but I hacked it to be so), then the QVTKOpenGLWidget did not seem to exhibit the bug.

We have done some more research and testing in 3D Slicer and the conclusion is the following:

Why the problem occurs? If an application does not work correctly with a core profile then it indicates that still some old API or methods are used somewhere. Of course it may also mean that there are some other OpenGL handling mistakes that happen to not cause any problems when a compatibility profile is used. Qt is supposed to fully support core profiles since Qt-5.10, but it is a large project, so maybe there are still some issues. Overall, it is somewhat more likely that VTK has some OpenGL usage related bug, most probably related to initialization (as the application works well even with core profile, depending on what the main application window contains on application startup). We will not spend more time trying to pinpoint the issue, hopefully it will come up and fixed in another scenario (either in VTK or Qt).

What is the solution? We have decided to use compatibility profile for Windows, and core profile on Mac & Linux. Compatibility profiles are not fully supported on Mac, so core profile must be used there. We added an application setting option (not exposed on the application user interface) that allows forcing compatibility/core profile so that we can experiment with it and users can override it as needed.

Any regressions or risks of regressions? Using a compatibility profile on Windows does not seem to have any disadvantages. Performance may be even better than with a core profile.

Thanks @lassoan , we have done the same thing (sans the runtime toggle). Would of course really like to track this down, if it’s in VTK or Qt (like you, I suspect the former).

@lassoan Just thought I should ask: Have you guys ran into any trouble on macOS after porting to the new widget?

After some more testing here, I realised that we have a serious issue on macOS as well - one of our VTK windows will not update/re-render until you resize the window a little, or if you Command+Tab to another application and back again. That particular widget is in a tab in a QTabWidget (though I’m not sure that has any relevance, just that we have another VTK widget that also uses the same new QVTKOpenGLWidget, and it seems to work alright, and it’s not in a QTabWidget).

Just thought I should ask, since the problem seems slightly similar to this one.

(We are currently running with the same workaround as you guys, compete profile on Windows, core profile (the default) on Linux and macOS)

@utkarshayachit may confirm, but we are always using QVTKOpenGLNativeWidget on MacOS in ParaView as they are way too many bugs in Qt in this case.

Alright, thanks for that info @mwestphal. I may try upgrading our Qt to 5.12.3 (using Qt 5.12.0 on macOS at the moment), though I doubt that changes anything. If it doesn’t, I guess we’ll revert to using QVTKOpenGLNativeWidget instead.

We, too, use QVTKOpenGLNativeWidget in most cases. You must use this native variant if the widget is embedded in certain Qt widgets, such as those that can do scrolling, but probably the same is true for tab widget. We only use the non-native for small popup windows.

Right, I’m aware of the restrictions on the QVTKOpenGLWidget, but did not think QTabWidget was one of those circumstances. AFAIK it has no nested QScrollArea or similar inside it.

We have a couple of VTK widgets where we have to use the native widget (e.g. color/opacity settings, similar to Paraview’s situation).

…but, I’m actually pleasantly shocked, because upgrading to Qt 5.12.3 seems to have solved that particular problem I described above.

Still having some problem with another one of our VTK widgets on macOS though, the problem there being that the very first render seems to be a hit and miss (sometimes it works, sometimes it doesn’t, and a resize is necessary to get it back into shape).

QTabWidget does not have these restrictions afaik. They are macOS specific issues though.

Glad an update fixed parts of your issues.

The remaining issue we have on macOS (occurring in just one of our VTK widgets, this time not in a QTabWidget, but just in a QSplitter in our central application area) seems very similar to the issue we had on Windows actually (start of this thread). The initial render is ineffective (sometimes, seems timing dependent/racy), and a resize is required to get it back into shape (after that, it seems to work alright).

I made a separate post with some questions about choosing the native or non-native widget: How to decide between QVTKOpenGL{Native}Widget?

I started digging around, and it seems the problem can also be “fixed” by using a OpenGL compatibility profile instead of core profile (which is what QVTKOpenGLWidget::defaultFormat() returns).

The problem is not appearing on our Linux or macOS test machines, only on the Windows 10 machine (Intel graphics, though not sure that matters).

I believe it does matter. IIRC, compatibility profile is legacy OpenGL (version <= 2) where you only have fixed functions (no shaders; software rendering only), while core profile is modern OpenGL (includes shaders; render on gpu).

Windows ships with legacy OpenGL (in case you don’t have hardware to support modern OpenGL). Even though switching to compatibility profile will make it work, you’re likely not getting minimal (if any) hardware acceleration.

When we add some actors to the renderer during runtime and then call Render() , the rendering seems ineffective (nothing shows up) until the user resizes the widget a little (causing a second render).

Has anyone seen this problem before?

Yes, I see this as well. You can refer to my issue QPainter::begin: Paint device returned engine == 0, type: 1. I added gif’s showing this exact problem.

This is independent of QVTKOpenGLWidget. In my example, I inherit from QWidget. I’m able to recreate the problem without using QVTKOpenGLWidget at all.

Since Qt4, all QWidget’s are double-buffered, and WA_PaintOnScreen was added for backwards-compatibility to allow setting a widget to use single buffering.

I believe the issue stems from how VTK interprets how Qt version >=4 renders. I think it is still interpreting that Qt is single-buffered by default.

I’m not sure what is the impact of enabling QSurfaceFormat::CompatibilityProfile. Could we just enable it on all configurations?

Compatibility Profile is legacy OpenGL (version <= 2) where you only have fixed functions (no shaders; software rendering only), while core profile is modern OpenGL (includes shaders; render on gpu). Most OS’s ship with legacy OpenGL to handle the case where you don’t have dedicated rendering hardware.

I don’t recommend enabling it on all configurations because then you’re turning off hardware rendering.

Hm I don’t think this is the case. Even if the compatibility profile includes fixed-function APIs that were deprecated in OpenGL 3.0, while the core profile does not, surely those fixed-function APIs are hardware accelerated by the common OpenGL implementations (Intel, NVIDIA, AMD, …)?

And in any case, the question is more how VTK will react to running under compatibility profile vs core profile, which I think is up to VTK. Everything in core profile is also available in compatibility profile, so in theory it could run the exact same code. But I did find back when struggling with this issue that it seemingly “fixed” itself when using a compatibility profile.

I haven’t looked back at this issue in a long time, but as far as I know we are still using QVTKOpenGLNativeWidget everywhere (note QVTKOpenGLWidget), partly because of this.

I don’t believe so because you’re telling Qt: “I don’t have hardware to accelerate my graphics, so please use software rendering.” The “compatible” in “compatibility profile” means “use old opengl so we work.”

I don’t think that’s correct: Otherwise, there would be no need for 2 profiles. Core should have more functions that compatibility.

1 Like

@estan From the Qt Wiki:

When using the Core profile, all access to the legacy fixed-functionality pipeline is removed. This means that to get anything drawn on screen we have to make use of glsl shaders and vertex arrays or buffers.

and interestingly, they also note:

This is known to work under Linux but Windows and macOS have some issues inside of Qt for creating Core Profile contexts.