More qt5 port notes

Arjen Hiemstra ahiemstra at heimr.nl
Tue Jun 9 00:04:46 BST 2015


On Monday 08 June 2015 17:43:24 Boudewijn Rempt wrote:
> I also talked about the opengl canvas problems with kwin maintainer Martin
> Graesslin. He was pretty clear that Qt's undocumented qglfunctions thing
> is rather badly designed, and he said to use libepoxy instead of either
> that or our glew + qlibrary thing, but that doesn't work on osx, and is
> another dependency.
> 
> I guess we could try to drop qlibrary and use dlopen directly, or figure
> out how to fix our code to use QFunctionPointer. I have no idea about that
> atm, I need more leisure than I have to look into it.
> 

While Martin is for the most part right in it being badly designed, I 
personally do think it is a better solution than using a dependency you cannot 
use on OSX or trying to do something manually - unless there is no other 
choice. We actually use QOpenGLFunctions at work and with some side notes and 
caveats it can be used. To be fair, work code is python[1] so this might be a 
little different from C++ as the python code has some additional contraints.

To get a QOpenGLFunctions object you can use 
QOpenGLContext::versionFunctions(). This will return a functions object based 
on the version of the current context. Since PyQt is a bit limited, in our 
case this is a QOpenGLFunctions_GL_2_0 or similar object, at least the object 
corresponding to OpenGL 2.0 . This also introduces another limitation: When 
using this object, you will be able to access OpenGL 2.0 functions and *only* 
OpenGL 2.0 functions. No extensions, no functions from higher versions, 
nothing. So you will need to be fairly explicit with your function usage, 
since for example glFenceSync is only available in the OpenGL 3.2 function 
objects[2], though I cannot recall whether or not it is even available as 
extension.

On the other hand, it does introduce a more reliable form of feature 
detection: If you cannot get a proper version object for a certain version, 
you can fall back to a rendering path that does not rely on features in that 
version. QOpenGLFunctions::versionFunctions() will return a null pointer if it 
cannot provide the right version of the functions, so you can fairly easily 
check that and fall back if it fails. One thing it fails at though is falling 
back to extensions if a certain mainline item is not available, which also 
happens to be one of the reasons many people would discourage using 
QOpenGLFunctions iirc. For example the buffer functions like glGenBuffers() will 
not properly fallback to the ARB version glGenBuffersARB() but instead fail to 
create a proper functions object.

All that said, for us it was a fairly easy choice as we do not require more 
than OpenGL 2.0 with Framebuffers and we also wanted to keep support for the 
ANGLE fallback on Windows. In the case of Krita, you probably need to add some 
more proper version detection and fallback paths, but I think for most things 
it covers the use cases.

- Arjen

[1]: See 
https://github.com/Ultimaker/Uranium/blob/master/UM/Qt/QtGL2Renderer.py#L317
for the code that uses it.
[2]: See http://doc.qt.io/qt-5/qopenglfunctions-3-1.html vs. 
http://doc.qt.io/qt-5/qopenglfunctions-3-2-compatibility.html for example.



More information about the calligra-devel mailing list