diff --git a/src/qt/CMakeLists.txt b/src/qt/CMakeLists.txt index bed9d27c0..076d5cc42 100644 --- a/src/qt/CMakeLists.txt +++ b/src/qt/CMakeLists.txt @@ -85,8 +85,6 @@ add_library(ui STATIC qt_renderercommon.hpp qt_softwarerenderer.cpp qt_softwarerenderer.hpp - qt_hardwarerenderer.cpp - qt_hardwarerenderer.hpp qt_openglrenderer.cpp qt_openglrenderer.hpp qt_glsl_parser.cpp diff --git a/src/qt/qt.c b/src/qt/qt.c index 9ec907f33..f9c617e9d 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -38,21 +38,16 @@ qt_nvr_save(void) int plat_vidapi(const char *api) { - if (!strcasecmp(api, "default") || !strcasecmp(api, "system")) { + if (!strcasecmp(api, "default") || !strcasecmp(api, "system")) return 0; - } else if (!strcasecmp(api, "qt_software")) { + else if (!strcasecmp(api, "qt_software")) return 0; - } else if (!strcasecmp(api, "qt_opengl")) { + else if (!strcasecmp(api, "qt_opengl") || !strcasecmp(api, "qt_opengles") || !strcasecmp(api, "qt_opengl3")) return 1; - } else if (!strcasecmp(api, "qt_opengles")) { + else if (!strcasecmp(api, "qt_vulkan")) return 2; - } else if (!strcasecmp(api, "qt_opengl3")) { + else if (!strcasecmp(api, "vnc")) return 3; - } else if (!strcasecmp(api, "qt_vulkan")) { - return 4; - } else if (!strcasecmp(api, "vnc")) { - return 5; - } return 0; } @@ -67,18 +62,12 @@ plat_vidapi_name(int api) name = "qt_software"; break; case 1: - name = "qt_opengl"; - break; - case 2: - name = "qt_opengles"; - break; - case 3: name = "qt_opengl3"; break; - case 4: + case 2: name = "qt_vulkan"; break; - case 5: + case 3: name = "vnc"; break; default: @@ -87,4 +76,4 @@ plat_vidapi_name(int api) } return name; -} \ No newline at end of file +} diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp deleted file mode 100644 index fb84606b0..000000000 --- a/src/qt/qt_hardwarerenderer.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Hardware renderer module. - * - * - * - * Authors: Joakim L. Gilje - * Cacodemon345 - * Teemu Korhonen - * - * Copyright 2021 Joakim L. Gilje - * Copyright 2021-2022 Cacodemon345 - * Copyright 2021-2022 Teemu Korhonen - */ -#include "qt_hardwarerenderer.hpp" -#include -#include -#include - -#include -#include -#include - -extern "C" { -#include <86box/86box.h> -#include <86box/plat.h> -#include <86box/video.h> -} - -void -HardwareRenderer::resizeGL(int w, int h) -{ - m_context->makeCurrent(this); - glViewport(0, 0, qRound(w * devicePixelRatioF()), qRound(h * devicePixelRatioF())); -} - -#define PROGRAM_VERTEX_ATTRIBUTE 0 -#define PROGRAM_TEXCOORD_ATTRIBUTE 1 - -void -HardwareRenderer::initializeGL() -{ - m_context->makeCurrent(this); - initializeOpenGLFunctions(); - auto image = QImage(2048, 2048, QImage::Format_RGB32); - image.fill(0xff000000); - m_texture = new QOpenGLTexture(image); - m_blt = new QOpenGLTextureBlitter; - m_blt->setRedBlueSwizzle(true); - m_blt->create(); - QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); - const char *vsrc = "attribute highp vec4 VertexCoord;\n" - "attribute mediump vec4 TexCoord;\n" - "varying mediump vec4 texc;\n" - "uniform mediump mat4 MVPMatrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = MVPMatrix * VertexCoord;\n" - " texc = TexCoord;\n" - "}\n"; - QString vsrccore = "in highp vec4 VertexCoord;\n" - "in mediump vec4 TexCoord;\n" - "out mediump vec4 texc;\n" - "uniform mediump mat4 MVPMatrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = MVPMatrix * VertexCoord;\n" - " texc = TexCoord;\n" - "}\n"; - if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { - vsrccore.prepend("#version 300 es\n"); - vshader->compileSourceCode(vsrccore); - } else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) { - vsrccore.prepend("#version 130\n"); - vshader->compileSourceCode(vsrccore); - } else - vshader->compileSourceCode(vsrc); - - QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); - const char *fsrc = "uniform sampler2D texture;\n" - "varying mediump vec4 texc;\n" - "void main(void)\n" - "{\n" - " gl_FragColor = texture2D(texture, texc.st).bgra;\n" - "}\n"; - QString fsrccore = "uniform sampler2D texture;\n" - "in mediump vec4 texc;\n" - "out highp vec4 FragColor;\n" - "void main(void)\n" - "{\n" - " FragColor = texture2D(texture, texc.st).bgra;\n" - "}\n"; - if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { - fsrccore.prepend("#version 300 es\n"); - fshader->compileSourceCode(fsrccore); - } else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) { - fsrccore.prepend("#version 130\n"); - fshader->compileSourceCode(fsrccore); - } else - fshader->compileSourceCode(fsrc); - - m_prog = new QOpenGLShaderProgram; - m_prog->addShader(vshader); - m_prog->addShader(fshader); - m_prog->bindAttributeLocation("VertexCoord", PROGRAM_VERTEX_ATTRIBUTE); - m_prog->bindAttributeLocation("TexCoord", PROGRAM_TEXCOORD_ATTRIBUTE); - m_prog->link(); - - m_prog->bind(); - m_prog->setUniformValue("texture", 0); - - if (m_context->format().version() >= qMakePair(3, 0) && m_vao.create()) { - m_vao.bind(); - } - - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].create(); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].allocate(sizeof(QVector2D) * 4); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].create(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].allocate(sizeof(QVector2D) * 4); - - pclog("OpenGL vendor: %s\n", glGetString(GL_VENDOR)); - pclog("OpenGL renderer: %s\n", glGetString(GL_RENDERER)); - pclog("OpenGL version: %s\n", glGetString(GL_VERSION)); - pclog("OpenGL shader language version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - glClearColor(0, 0, 0, 1); - m_texture->setWrapMode(QOpenGLTexture::ClampToEdge); - glClear(GL_COLOR_BUFFER_BIT); - m_context->swapBuffers(this); -} - -void -HardwareRenderer::paintGL() -{ - m_context->makeCurrent(this); - glClear(GL_COLOR_BUFFER_BIT); - QVector verts; - QVector texcoords; - QMatrix4x4 mat; - mat.setToIdentity(); - mat.ortho(QRectF(0, 0, (qreal) width() * (qreal) devicePixelRatioF(), (qreal) height() * (qreal) devicePixelRatioF())); - verts.push_back(QVector2D((float) destination.x(), (float) destination.y())); - verts.push_back(QVector2D((float) destination.x(), (float) destination.y() + (float) destination.height())); - verts.push_back(QVector2D((float) destination.x() + (float) destination.width(), (float) destination.y() + (float) destination.height())); - verts.push_back(QVector2D((float) destination.x() + (float) destination.width(), (float) destination.y())); - texcoords.push_back(QVector2D((float) source.x() / 2048.f, (float) (source.y()) / 2048.f)); - texcoords.push_back(QVector2D((float) source.x() / 2048.f, (float) (source.y() + source.height()) / 2048.f)); - texcoords.push_back(QVector2D((float) (source.x() + source.width()) / 2048.f, (float) (source.y() + source.height()) / 2048.f)); - texcoords.push_back(QVector2D((float) (source.x() + source.width()) / 2048.f, (float) (source.y()) / 2048.f)); - - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].write(0, verts.data(), sizeof(QVector2D) * 4); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].write(0, texcoords.data(), sizeof(QVector2D) * 4); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); - - m_prog->setUniformValue("MVPMatrix", mat); - m_prog->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE); - m_prog->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE); - - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); - m_prog->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2, 0); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); - m_prog->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2, 0); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); - m_texture->bind(); - m_texture->setMinMagFilters(video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest, video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -} - -void -HardwareRenderer::setRenderType(RenderType type) -{ - QSurfaceFormat format; - switch (type) { - case RenderType::OpenGL3: - format.setVersion(3, 0); - format.setProfile(QSurfaceFormat::CoreProfile); - case RenderType::OpenGL: - format.setRenderableType(QSurfaceFormat::OpenGL); - break; - case RenderType::OpenGLES: - format.setRenderableType(QSurfaceFormat::OpenGLES); - break; - } - format.setSwapInterval(0); - setFormat(format); -} - -void -HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) -{ - auto tval = this; - void *nuldata = 0; - if (memcmp(&tval, &nuldata, sizeof(void *)) == 0) - return; - auto origSource = source; - if (!m_texture || !m_texture->isCreated()) { - buf_usage[buf_idx].clear(); - source.setRect(x, y, w, h); - return; - } - m_context->makeCurrent(this); -#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - m_texture->setData(x, y, 0, w, h, 0, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void *) ((uintptr_t) imagebufs[buf_idx].get() + (uintptr_t) (2048 * 4 * y + x * 4)), &m_transferOptions); -#else - m_texture->bind(); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 2048); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void *) ((uintptr_t) imagebufs[buf_idx].get() + (uintptr_t) (2048 * 4 * y + x * 4))); - m_texture->release(); -#endif - buf_usage[buf_idx].clear(); - source.setRect(x, y, w, h); - if (origSource != source) { - this->pixelRatio = devicePixelRatioF(); - onResize(this->width(), this->height()); - } - update(); -} - -void -HardwareRenderer::resizeEvent(QResizeEvent *event) -{ - this->pixelRatio = devicePixelRatioF(); - onResize(width(), height()); - - QOpenGLWindow::resizeEvent(event); -} - -bool -HardwareRenderer::event(QEvent *event) -{ - bool res = false; - if (!eventDelegate(event, res)) - return QOpenGLWindow::event(event); - return res; -} - -std::vector> -HardwareRenderer::getBuffers() -{ - std::vector> buffers; - - buffers.push_back(std::make_tuple(imagebufs[0].get(), &buf_usage[0])); - buffers.push_back(std::make_tuple(imagebufs[1].get(), &buf_usage[1])); - - return buffers; -} diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp deleted file mode 100644 index f7861d2bd..000000000 --- a/src/qt/qt_hardwarerenderer.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "qt_renderercommon.hpp" - -#ifdef WAYLAND -# include "wl_mouse.hpp" -#endif - -class HardwareRenderer : public QOpenGLWindow, protected QOpenGLFunctions, public RendererCommon { - Q_OBJECT - -private: - bool wayland = false; - QOpenGLContext *m_context; - QOpenGLTexture *m_texture { nullptr }; - QOpenGLShaderProgram *m_prog { nullptr }; - QOpenGLTextureBlitter *m_blt { nullptr }; - QOpenGLBuffer m_vbo[2]; - QOpenGLVertexArrayObject m_vao; - QOpenGLPixelTransferOptions m_transferOptions; - -public: - enum class RenderType { - OpenGL, - OpenGLES, - OpenGL3, - }; - void resizeGL(int w, int h) override; - void initializeGL() override; - void paintGL() override; - void exposeEvent(QExposeEvent *event) override - { - onResize(size().width(), size().height()); - } - - std::vector> getBuffers() override; - HardwareRenderer(QWidget *parent = nullptr, RenderType rtype = RenderType::OpenGL) - : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()) - , QOpenGLFunctions() - { - imagebufs[0] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); - imagebufs[1] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); - - buf_usage = std::vector(2); - buf_usage[0].clear(); - buf_usage[1].clear(); - - setMinimumSize(QSize(16, 16)); - setFlags(Qt::FramelessWindowHint); - parentWidget = parent; - setRenderType(rtype); - - m_transferOptions.setRowLength(2048); - - m_context = new QOpenGLContext(); - m_context->setFormat(format()); - m_context->create(); - update(); - } - ~HardwareRenderer() - { - m_context->makeCurrent(this); - if (m_blt) - m_blt->destroy(); - m_prog->release(); - delete m_prog; - m_prog = nullptr; - m_context->doneCurrent(); - delete m_context; - } - - void setRenderType(RenderType type); - -public slots: - void onBlit(int buf_idx, int x, int y, int w, int h); - -protected: - std::array, 2> imagebufs; - - void resizeEvent(QResizeEvent *event) override; - bool event(QEvent *event) override; -}; diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 5c9e10a85..e7835b5a4 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -420,22 +420,10 @@ MainWindow::MainWindow(QWidget *parent) ui->actionEnable_Discord_integration->setEnabled(discord_loaded); #endif -#if defined Q_OS_WINDOWS || defined Q_OS_MACOS - /* Make the option visible only if ANGLE is loaded. */ - ui->actionHardware_Renderer_OpenGL_ES->setVisible(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES); - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) - vid_api = 1; -#endif - ui->actionHardware_Renderer_OpenGL->setVisible(QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES); - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && vid_api == 1) - vid_api = 0; - if ((QApplication::platformName().contains("eglfs") || QApplication::platformName() == "haiku")) { if (vid_api >= 1) fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data()); vid_api = 0; - ui->actionHardware_Renderer_OpenGL->setVisible(false); - ui->actionHardware_Renderer_OpenGL_ES->setVisible(false); ui->actionVulkan->setVisible(false); ui->actionOpenGL_3_0_Core->setVisible(false); } @@ -469,8 +457,6 @@ MainWindow::MainWindow(QWidget *parent) auto actGroup = new QActionGroup(this); actGroup->addAction(ui->actionSoftware_Renderer); - actGroup->addAction(ui->actionHardware_Renderer_OpenGL); - actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES); actGroup->addAction(ui->actionOpenGL_3_0_Core); actGroup->addAction(ui->actionVulkan); actGroup->addAction(ui->actionVNC); @@ -495,19 +481,13 @@ MainWindow::MainWindow(QWidget *parent) newVidApi = RendererStack::Renderer::Software; break; case 1: - newVidApi = RendererStack::Renderer::OpenGL; - break; - case 2: - newVidApi = RendererStack::Renderer::OpenGLES; - break; - case 3: newVidApi = RendererStack::Renderer::OpenGL3; break; - case 4: + case 2: newVidApi = RendererStack::Renderer::Vulkan; break; #ifdef USE_VNC - case 5: + case 3: { newVidApi = RendererStack::Renderer::Software; startblit(); diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 83a80342b..7f443495c 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -121,8 +121,6 @@ Re&nderer - - diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 31cc495b0..b47ea3f7a 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -21,7 +21,6 @@ #include "qt_rendererstack.hpp" #include "ui_qt_rendererstack.h" -#include "qt_hardwarerenderer.hpp" #include "qt_openglrenderer.hpp" #include "qt_softwarerenderer.hpp" #include "qt_vulkanwindowrenderer.hpp" @@ -336,24 +335,6 @@ RendererStack::createRenderer(Renderer renderer) #endif } break; - case Renderer::OpenGL: - { - this->createWinId(); - auto hw = new HardwareRenderer(this); - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); - current.reset(this->createWindowContainer(hw, this)); - break; - } - case Renderer::OpenGLES: - { - this->createWinId(); - auto hw = new HardwareRenderer(this, HardwareRenderer::RenderType::OpenGLES); - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &HardwareRenderer::onBlit, Qt::QueuedConnection); - current.reset(this->createWindowContainer(hw, this)); - break; - } case Renderer::OpenGL3: { this->createWinId(); diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 3a76f3ada..99de85c99 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -80,8 +80,6 @@ public: enum class Renderer { Software, - OpenGL, - OpenGLES, OpenGL3, Vulkan, None = -1