summaryrefslogtreecommitdiffstats
path: root/src/opengl/qopenglcompositorbackingstore.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Deprecate and remove traces of RasterGLSurfaceTor Arne Vestbø2025-09-031-1/+1
| | | | | | | | | | We no longer use this hybrid surface type approach for Qt Widget's composition mode. Nowadays we use RHI to compose the widget texture and the native textures, and the window surface type depends on the RHI API in use, e.g. QSurface::MetalSurface, or QSurface::OpenGLSurface. Change-Id: I85001100f681a1cf524b8b7dc50f680a9579b447 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* Account for already transformed coordinates in QRhiBackingStore::flushTor Arne Vestbø2025-07-081-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The implementation of QRhiBackingStore::flush uses rhiFlush, which assumed that the incoming region and offset were in logical coordinates, and then applied the sourceDevicePixelRatio to map them to device coordinates. This works for QWidgetRepaintManager::flush, which passes on the region and offset in logical coordinates, but QRhiBackingStore::flush has logic to pre-transform the coordinates from device independent to native for the case where QtGui is doing the high-DPI scaling (Windows, Wayland, Android, etc, as opposed to macOS/iOS where the OS does the scaling). As a result QRhiBackingStore::flush would get pre-transformed coordinates that it then passed on to rhiFlush, mapping it as if it was in logical coordinates. Fixing this by inverting the transform in QRhiBackingStore::flush is not trivial due to fractional DPR accumulation, which QBackingStore::flush already takes care of. Instead we pass on the DPR coming from the platform window, which will typically be 1 on platforms like Windows and Android, but may be non-1 when testing with QT_SCALE_FACTOR on e.g. macOS. This results in the right transformation applied in QBackingStoreDefaultCompositor::flush. We still need to pass the source DPR, as QBackingStoreDefaultCompositor relies on the source DPR to compute the window-relative source rect, which needs to reflect the DPR of the raw source pixels. Tested with every combination of QT_WIDGETS_RHI, QT_SCALE_FACTOR, QT_WIDGETS_HIGHDPI_DOWNSCALE, on 1x and 2x screens, with both integer and fractional scale factors. Note, in testing this it was revealed that we have an issue with rounding errors when using both QtGui level high-DPI scaling, e.g. via QT_SCALE_FACTOR=1.25 and OS-level scaling (e.g. 2x retina on macOS). In this case QBackingStore applies the QtGui scale, but rounds before passing things on to the platform, where we then multiply the rounding error. The reason we don't see any visual artifacts for this right now with QT_WIDGETS_RHI is that even though we clear too much in beginPaint, the rhiFlush code path used by QWidgetRepaintManager directly does not do any QHighDpiScaling, so we end up not flushing the wrongly cleared pixels. Solving this is not straight forward, as the QPlatformBackingStore API surface uses QRegion extensively, and we surprisingly don't have a QRegionF. Fixes: QTBUG-128794 Fixes: QTBUG-133549 Fixes: QTBUG-128457 Fixes: QTBUG-128422 Fixes: QTBUG-121757 Task-number: QTBUG-138261 Pick-to: 6.10 6.9 6.8 Change-Id: I47884c28ef0ba8223ee16229d21e9c38801ae11f Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
* eglfs: Restore raster window support code that went missingLaszlo Agocs2024-11-051-0/+4
| | | | | | | | | | | Restore the snippet added in 4bc8f548222a0dd2967063a23e76c37d302253cb Amends 0a10d23c4a49dd14a1ded41b7cc6921909b0ee7a Change-Id: Id83ff523e6343003c198600fe0ee91a71fb6e3e0 Pick-to: 6.8 Fixes: QTBUG-129512 Reviewed-by: Inho Lee <inho.lee@qt.io>
* eglfs: Revive QWidget renderingLaszlo Agocs2024-06-131-23/+11
| | | | | | | | | | | | | | | After recent changes to widgets and backingstores, attempting to run any widget-based application with eglfs resulted in a crash. The backingstore implementation used here was not fully migrated. Update flush() to create the rendering infrastructure if needed, and make it call into rhiFlush(). Amends eb4cb719257d3b57cd801273d4011579d8c81714 Change-Id: I253c37200f5a902a0e61b62581ac456549f3aeba Pick-to: 6.8 Fixes: QTBUG-126221 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* widgets: Use per-surface-format RHI support and compositorTor Arne Vestbø2024-06-011-10/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The RHI support and compositor in QPlatformBackingStore were tied to the surface format of the top level window owning the backing store. This meant that inserting an RHI-enabled widget (QRhiWidget, QOpenGLWidget, QQuickWidget, QWebEngineView) into the widget hierarchy required recreating the top level window with a matching surface format that could support the RHI composition. It also meant that we could not have two RHI enabled widgets with different surface format requirements (Metal and OpenGL for example) in the same top level widget hierarchy. The recreation of the window had various visual side effects, such as temporarily switching out of full screen state, or the widget rendering a frame of black, as well as more serious problems such as not correctly restoring the window geometry. In addition, if client code had pulled out the winId() of the window, and did not invalidate these references on window destruction via QEvent::WinIdChange or QEvent::PlatformSurface, the client would reference stale window handles. Although this is a programming error (QWidget::winId() specifically mentions this requirement), we should avoid recreation if we can. We were already supporting flushing the backingstore to individual native child widgets, but always did so via a single RHI managed by the platform backingstore. By expanding QPlatformBackingStore to keep one set of RHI support and compositor per surface format, we can refine the logic in QWidget and QWidgetRepaintManager to not require recreating the top level. Native child widgets are then flushed independently, including any RHI textures and raster content that overlaps with the widget. We still assume that a single RHI support and compositor can be be used for multiple windows, as long as those windows have the same surface format. In the future, if needed, we can refine this to use one set per surface format e.g. Fixes: QTBUG-119221 Fixes: QTBUG-121181 Fixes: QTBUG-120096 Task-number: QTBUG-115652 Task-number: QTBUG-108344 Task-number: QTBUG-113557 Task-number: QTBUG-119309 Change-Id: I2635ed3d20c2fb76eab3b8130007dd656a0b93e5 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* Make sure OpenGLContext is not nullptrJacek Poplawski2024-01-101-0/+2
| | | | | | | | | In QOpenGLCompositorBackingStore::resize it is already checked whether dstWin is valid, but dstCtx may also be nullptr at this point. Pick-to: 6.7 Task-number: QTBUG-120078 Change-Id: I4a6ad71dd8225b94baff05984275ad1860298dfc Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* QOpenGLCompositorBackingStore: ensure backing store on flushed windowsAxel Spoerl2023-09-131-0/+3
| | | | | | | | | | | | | | | | | | | | | | | When the first QEglFSWindow got created for a QWindow, a backing store was created with it and associated to the new QEglFSWindow. When the window was hidden on the platform screen, the QEglFSWindow got deleted and re-created when it was supposed to be shown. The re-created QEglFSWindow was no longer associated to the backing store. It was therefore not rendered on the screen. => ensure that the backing store is re-associated to the QEglFSWindow, corrsponding to the QWindow argument passed to flush(). No autotest is added, because the fix is purely visual. The widgets/menus example can be used to test the functionality manually (see bug reports). Fixes: QTBUG-115196 Fixes: QTBUG-116769 Pick-to: 6.6 6.5 6.2 Change-Id: I92ce2e8f7e76bd2d26e713a4d20612d079fb4717 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* rhi: Make it a QPA-style private but semi-public APILaszlo Agocs2023-05-211-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | qrhi.h, qshader.h, qshaderdescription.h (and qshaderbaker.h from shadertools; done separately) become "RHI APIs", following the concept of QPA APIs. Mirror completely what is done for QPA headers, but using the "rhi" prefix for the headers. This involves updating syncqt to handle the new category of headers. (a note on the regex: matching everything starting with "qrhi" is not acceptable due to incorrectly matching existing and future headers, hence specifying the four header names explicitly) There is going to be one difference to QPA: the documentation for everything RHI is going to be public and part of the regular docs, not hidden with \internal. In addition to the header renaming and adding the comments and documentation notes and warnings, there is one significant change here: there is no longer a need to do API-specific includes, such as qrhid3d11[_p].h, qrhivulkan[_p].h, etc. These are simply merged into a single header that is then included from qrhi.h. This means that users within Qt, and any future applications can just do #include <rhi/qrhi.h> (or rhi/qshader.h if the QRhi stuff is not relevant), no other headers are needed. There are no changes to functionality in this patch. Only the documentation is expanded, quite a lot, to eliminate all qdoc warnings and make the generated API docs complete. An example, with a quite extensive doc page is added as well. Task-number: QTBUG-113331 Change-Id: I91c749826348f14320cb335b1c83e9d1ea2b1d8b Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Make rhiFlush() support custom source DPRMorten Sørvig2022-06-141-0/+2
| | | | | | | | | | | | | | | | | | | | | | | The rhiFlush() implementation currently assumes that QWindow->devicePixelRatio() is the correct scale factor for transforming device independent window geometry to source geometry. However, this assumption does not hold if/when we add support for drawing to a rounded-up DPR, with a downscale later in the rhiFlush implementation. Fix this by adding a sourceDevicePixelRatio argument to rhiFlush(), which is set to either QWindow::devicePixelRatio() or QWidget::devicePixelRatio(), depending on from where it is used. Change deviceRect() and friends in qbackingstoredefualtcompositor.cpp to be scale*() functions instead which take a scale factor instead of a QWindow. Update call sites to use srouceDevicePixelRatio where that makes sense. Pick-to: 6.4 Change-Id: Idb7b1e2f36816a201e00f0defe100d2dc079cb17 Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-161-38/+2
| | | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* Revive eglfs' raster window supportLaszlo Agocs2022-04-271-32/+32
| | | | | | | | | | | | | | | | | | | A number of consequences of the new rhi-based backingstore composition were not handled. Most importantly, the fact that RasterGLSurface is not a thing anymore in practice causes challenges because we can no longer decide just based on the surfaceType what a QWindow with OpenGLSurface would be. (a plain GL window or a GL window with a backing store?) Also, the backingstore needs to be able to initialize its backing QRhi by itself, because with eglfs going through OpenGL is the only way. Amends 68a4c5da9a080101cccd8a3b2edb1c908da0ca8e Fixes: QTBUG-102750 Change-Id: Ia1ca59d01e3012264a76b50e591612fdcc2a0bd6 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andy Nichols <andy.nichols@qt.io>
* Compose render-to-texture widgets through QRhiLaszlo Agocs2022-03-111-15/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QPlatformTextureList holds a QRhiTexture instead of GLuint. A QPlatformBackingStore now optionally can own a QRhi and a QRhiSwapChain for the associated window. Non-GL rendering must use this QRhi everywhere, whereas GL (QOpenGLWidget) can choose to still rely on resource sharing between contexts. A widget tells that it wants QRhi and the desired configuration in a new virtual function in QWidgetPrivate returning a QPlatformBackingStoreRhiConfig. This is evaluated (among a top-level's all children) upon create() before creating the repaint manager and the QWidgetWindow. In QOpenGLWidget what do request is obvious: it will request an OpenGL-based QRhi. QQuickWidget (or a potential future QRhiWidget) will be more interesting: it needs to honor the standard Qt Quick env.vars. and QQuickWindow APIs (or, in whatever way the user configured the QRhiWidget), and so will set up the config struct accordingly. In addition, the rhiconfig and surface type is (re)evaluated when (re)parenting a widget to a new tlw. If needed, this will now trigger a destroy - create on the tlw. This should be be safe to do in setParent. When multiple child widgets report an enabled rhiconfig, the first one (the first child encountered) wins. So e.g. attempting to have a QOpenGLWidget and a Vulkan-based QQuickWidget in the same top-level window will fail one of the widgets (it likely won't render). RasterGLSurface is no longer used by widgets. Rather, the appropriate surface type is chosen. The rhi support in the backingstore is usable without widgets as well. To make rhiFlush() functional, one needs to call setRhiConfig() after creating the QBackingStore. (like QWidget does to top-level windows) Most of the QT_NO_OPENGL ifdefs are eliminated all over the place. Everything with QRhi is unconditional code at compile time, except the actual initialization. Having to plumb the widget tlw's shareContext (or, now, the QRhi) through QWindowPrivate is no longer needed. The old approach does not scale: to implement composeAndFlush (now rhiFlush) we need more than just a QRhi object, and this way we no longer pollute everything starting from the widget level (QWidget's topextra -> QWidgetWindow -> QWindowPrivate) just to send data around. The BackingStoreOpenGLSupport interface and the QtGui - QtOpenGL split is all gone. Instead, there is a QBackingStoreDefaultCompositor in QtGui which is what the default implementations of composeAndFlush and toTexture call. (overriding composeAndFlush and co. f.ex. in eglfs should continue working mostly as-is, apart from adapting to the texture list changes and getting the native OpenGL texture id out of the QRhiTexture) As QQuickWidget is way too complicated to just port as-is, an rhi manual test (rhiwidget) is introduced as a first step, in ordewr to exercise a simple, custom render-to-texture widget that does something using a (not necessarily OpenGL-backed) QRhi and acts as fully functional QWidget (modeled after QOpenGLWidget). This can also form the foundation of a potential future QRhiWidget. It is also possible to force the QRhi-based flushing always, regardless of the presence of render-to-texture widgets. To exercise this, set the env.var. QT_WIDGETS_RHI=1. This picks a platform-specific default, and can be overridden with QT_WIDGETS_RHI_BACKEND. (in sync with Qt Quick) This can eventually be extended to query the platform plugin as well to check if the platform plugin prefers to always do flushes with a 3D API. QOpenGLWidget should work like before from the user's perspective, while internally it has to do some things differently to play nice and prevent regressions with the new rendering architecture. To exercise this better, the qopenglwidget example gets a new tab-based view (that could perhaps replace the example's main window later on?). The openglwidget manual test is made compatible with Qt 6, and gets a counterpart in form of the dockedopenglwidget manual test, which is a modified version of the cube example that features dock widgets. This is relevant in particular because render-to-texture widgets within a QDockWidget has its own specific quirks, with logic taking this into account, hence testing is essential. For existing applications there are two important consequences with this patch in place: - Once the rhi-based composition is enabled, it stays active for the lifetime of the top-level window. - Dynamically creating and parenting the first render-to-texture widget to an already created tlw will destroy and recreate the tlw (and the underlying window). The visible effects of this depend on the platform. (e.g. the window may disappear and reappear on some, whereas with other windowing systems it is not noticeable at all - this is not really different from similar situtions with reparenting or when moving windows between screens, so should be acceptable in practice) - On iOS raster windows are flushed with Metal (and rhi) from now on (previously this was through OpenGL by making flush() call composeAndFlush(). Change-Id: Id05bd0f7a26fa845f8b7ad8eedda3b0e78ab7a4e Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Fix run time failure for UI autotests (INTEGRITY)Tatiana Borisova2022-01-251-6/+8
| | | | | | | | | | | | | | | | - Add WFD resources release: It provides possibility to re-create native window on run time. It allows to run several Qt UI applications (one by one) without device reboot. - Fix crash that found during window re-creation: ~QOpenGLCompositorBacking() calls QOpenGLCompositor::instance(). But compositor is deleted for that moment. Task-number: QTBUG-99123 Pick-to: 6.2 6.3 Change-Id: I1e6dc9a012a166d1fd6cd1c24f9d2e9a8995fc00 Reviewed-by: Kimmo Ollila <kimmo.ollila@qt.io> Reviewed-by: Janne Koskinen <janne.p.koskinen@qt.io> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
* Move QtPlatformCompositorSupport into QtOpenGLTor Arne Vestbø2020-05-281-0/+292
Task-number: QTBUG-83255 Change-Id: Id9ea654db8efb00b487d53aea03d7f23a7ab1a54 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>