Problem
Qt6 is going to drop ANGLE which will require us to use OpenGL on Windows which is known to be buggy.
Options
There are three main things which we can do to port our canvas to OpenGL.
Window Container based approach
Krita being a QWidget based app we can use QWidget::createWindowContainer to embed a QWindow (our canvas) in our Main window. The way this would work is we set the desired Surface type (e.g OpenGLSurface, Direct3DSurface ...) for our QWindow and create our QRhi instance, which will create an instance that is platform specific. We can then use the abstraction to carry out our canvas rendering.
Demo Link: https://github.com/sh-zam/qt6-demo-app/tree/rhi (NOTE: This is on a different branch)
QRhi docs: https://alpqr.github.io/qtrhi/qrhi.html
Issues
- QWindow is a heavy class, having bunch of them can be expensive.
- There are several known limitations for using window containers (as per the docs), the one applicable to us could be:
- Using window container in QMdiArea will make everything that is its child a native window. Which as per the docs can cause performance issues.
- QRhi is still a private API, so using it this way is probably something which Qt devs won't recommend. That being said, there is an app which already uses the API, in the way described here.
Porting to QML
QML is already capable of rendering via different graphics APIs (OpenGL, Metal..) on a QQuickWindow. Porting to QML would open two ways to render to the window.
- Using custom implementation for each platform (Metal, Direct3D, OpenGL).
- Using QRhi based implementation.
Demo: This is a well established approach, there are several examples in the Qt's tree.
Issues
Porting to QML is a huge project. QRhi is still a private API, this is something to keep in mind. There is already a task for what it would take for QML port: https://phabricator.kde.org/T13339
Custom backend for QWidget
In theory it should be possible to render using native APIs if the Qt's paintEngine is turned off (QT::WA_PaintOnScreen). However, this seems to be only supported on X11 (as per the docs) and we would have to render on the screen directly.
Issues
I looked at this very briefly. Mostly because this would be too hacky and I am not sure what or how the other widgets (other than canvas, like dockers) would be rendered.
I came across this approach through this: https://github.com/giladreich/QtDirect3D