From 07af487acb04ff1de5426b93e04620d10280a76d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 25 Dec 2021 15:34:00 +0600 Subject: [PATCH] * Fix rare crash when switching renderers * Abandon QPainter in hardware renderers in favour of OpenGL * Disable VSync in the application globally --- src/qt/qt_hardwarerenderer.cpp | 16 ++++++++++++++-- src/qt/qt_hardwarerenderer.hpp | 10 +++++++++- src/qt/qt_main.cpp | 4 ++++ src/qt/qt_rendererstack.cpp | 1 + src/qt/qt_softwarerenderer.cpp | 3 +++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index ec0f71f3a..9c3df9c48 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -16,10 +16,18 @@ void HardwareRenderer::initializeGL() { m_context->makeCurrent(this); initializeOpenGLFunctions(); + m_texture = new QOpenGLTexture(image); + m_blt = new QOpenGLTextureBlitter; + m_blt->setRedBlueSwizzle(true); + m_blt->create(); } void HardwareRenderer::paintGL() { - onPaint(this); + m_context->makeCurrent(this); + m_blt->bind(); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(0, 0, 2048, 2048), source); + m_blt->blit(m_texture->textureId(), target, QOpenGLTextureBlitter::Origin::OriginTopLeft); + m_blt->release(); } void HardwareRenderer::setRenderType(RenderType type) { @@ -37,7 +45,11 @@ void HardwareRenderer::setRenderType(RenderType type) { } void HardwareRenderer::onBlit(const std::unique_ptr* img, int x, int y, int w, int h, std::atomic_flag* in_use) { - memcpy(image.bits(), img->get(), 2048 * 2048 * 4); + auto tval = this; + void* nuldata = 0; + if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + m_context->makeCurrent(this); + m_texture->setData(QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)img->get()); in_use->clear(); source.setRect(x, y, w, h); update(); diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index d2152def5..f64fa121f 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -3,6 +3,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -25,6 +29,9 @@ private: bool wayland = false; QWidget* parentWidget{nullptr}; QOpenGLContext* m_context; + QOpenGLTexture* m_texture; + QOpenGLShaderProgram* m_prog; + QOpenGLTextureBlitter* m_blt; public: void resizeGL(int w, int h) override; void initializeGL() override; @@ -41,7 +48,8 @@ public: } ~HardwareRenderer() { - makeCurrent(); + m_context->makeCurrent(this); + if (m_blt) m_blt->destroy(); } enum class RenderType { diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 562944385..91fee7408 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -94,6 +95,9 @@ main_thread_fn() int main(int argc, char* argv[]) { QApplication app(argc, argv); + QSurfaceFormat fmt = QSurfaceFormat::defaultFormat(); + fmt.setSwapInterval(0); + QSurfaceFormat::setDefaultFormat(fmt); app.setStyle(new StyleOverride()); #ifdef __APPLE__ CocoaEventFilter cocoafilter; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 15ab840d1..ed5d01e1d 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -203,6 +203,7 @@ void RendererStack::switchRenderer(Renderer renderer) { current->setFocusProxy(this); addWidget(current.get()); + this->setStyleSheet("background-color: black"); for (auto& in_use : buffers_in_use) in_use.clear(); diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 9a64fe043..d9195d7b6 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -8,6 +8,9 @@ void SoftwareRenderer::paintEvent(QPaintEvent *event) { } void SoftwareRenderer::onBlit(const std::unique_ptr* img, int x, int y, int w, int h, std::atomic_flag* in_use) { + auto tval = this; + void* nuldata = 0; + if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; memcpy(image.bits(), img->get(), 2048 * 2048 * 4); in_use->clear(); source.setRect(x, y, w, h);