qt5base-lts/tests/manual/rhi/multiwindow_threaded/window.cpp

88 lines
2.2 KiB
C++
Raw Normal View History

// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "window.h"
#include <QPlatformSurfaceEvent>
#if QT_CONFIG(vulkan)
extern QVulkanInstance *instance;
#endif
Window::Window(const QString &title, GraphicsApi api)
{
switch (api) {
case OpenGL:
setSurfaceType(OpenGLSurface);
break;
case Vulkan:
setSurfaceType(VulkanSurface);
rhi: gl: Avoid magic adjustments to the context/window format ...by removing the entire adjustedFormat() helper. Qt Quick has never used this, which indicates it is not that useful. Same goes for Qt Multimedia or Qt 3D. Ensuring depth and stencil is requested is already solved by using QSurfaceFormat::setDefaultFormat() or by adjusting the formats everywhere as appropriate. The helper function's usages are in the manual tests that use it as a shortcut, and in the GL backend itself. Remove it and leave it up the client to set the depth or stencil buffer size, typically in the global default surface format. (which in fact many of the mentioned manual tests already did, so some of calls to window->setFormat(adjustedFormat()) were completely unnecessary) By not having the built-in magic that tries to always force depth and stencil, we avoid problems that arise then the helper cannot be easily invoked (thinking of widgets and backingstores), and so one ends up with unexpected stencil (or depth) in the context (where the GL backend auto-adjusts), but not in the window (which is not under QRhi's control). It was in practice possible to trigger EGL_BAD_MATCH failures with the new rhi-based widget composition on EGL-based systems. For example, if an application with a QOpenGLWidget did not set both depth and stencil (but only one, or none), it ended up failing due to the context - surface EGLConfig mismatches. On other platforms this matters less due to less strict config/pixelformat management. Pick-to: 6.4 Change-Id: I28ae2de163de63ee91bee3ceae08b58e106e1380 Fixes: QTBUG-104951 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
2022-07-15 12:16:23 +00:00
#if QT_CONFIG(vulkan)
setVulkanInstance(instance);
#endif
break;
case D3D11:
rhi: Make it a QPA-style private but semi-public API 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>
2023-04-27 11:16:29 +00:00
case D3D12:
setSurfaceType(Direct3DSurface);
break;
case Metal:
setSurfaceType(MetalSurface);
break;
default:
break;
}
resize(800, 600);
setTitle(title);
}
Window::~Window()
{
}
void Window::exposeEvent(QExposeEvent *)
{
if (isExposed()) {
if (!m_running) {
// initialize and start rendering when the window becomes usable for graphics purposes
m_running = true;
m_notExposed = false;
emit initRequested();
emit renderRequested(true);
} else {
// continue when exposed again
if (m_notExposed) {
m_notExposed = false;
emit renderRequested(true);
} else {
// resize generates exposes - this is very important here (unlike in a single-threaded renderer)
emit syncSurfaceSizeRequested();
}
}
} else {
// stop pushing frames when not exposed (on some platforms this is essential, optional on others)
if (m_running)
m_notExposed = true;
}
}
bool Window::event(QEvent *e)
{
switch (e->type()) {
case QEvent::UpdateRequest:
if (!m_notExposed)
emit renderRequested(false);
break;
case QEvent::PlatformSurface:
// this is the proper time to tear down the swapchain (while the native window and surface are still around)
if (static_cast<QPlatformSurfaceEvent *>(e)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed)
emit surfaceGoingAway();
break;
default:
break;
}
return QWindow::event(e);
}