Remove the OpenGL (non-Core) and OpenGL ES renderers.

This commit is contained in:
OBattler
2025-06-28 20:41:04 +02:00
parent 2199722744
commit d15e062c83
8 changed files with 10 additions and 426 deletions

View File

@@ -85,8 +85,6 @@ add_library(ui STATIC
qt_renderercommon.hpp qt_renderercommon.hpp
qt_softwarerenderer.cpp qt_softwarerenderer.cpp
qt_softwarerenderer.hpp qt_softwarerenderer.hpp
qt_hardwarerenderer.cpp
qt_hardwarerenderer.hpp
qt_openglrenderer.cpp qt_openglrenderer.cpp
qt_openglrenderer.hpp qt_openglrenderer.hpp
qt_glsl_parser.cpp qt_glsl_parser.cpp

View File

@@ -38,21 +38,16 @@ qt_nvr_save(void)
int int
plat_vidapi(const char *api) plat_vidapi(const char *api)
{ {
if (!strcasecmp(api, "default") || !strcasecmp(api, "system")) { if (!strcasecmp(api, "default") || !strcasecmp(api, "system"))
return 0; return 0;
} else if (!strcasecmp(api, "qt_software")) { else if (!strcasecmp(api, "qt_software"))
return 0; return 0;
} else if (!strcasecmp(api, "qt_opengl")) { else if (!strcasecmp(api, "qt_opengl") || !strcasecmp(api, "qt_opengles") || !strcasecmp(api, "qt_opengl3"))
return 1; return 1;
} else if (!strcasecmp(api, "qt_opengles")) { else if (!strcasecmp(api, "qt_vulkan"))
return 2; return 2;
} else if (!strcasecmp(api, "qt_opengl3")) { else if (!strcasecmp(api, "vnc"))
return 3; return 3;
} else if (!strcasecmp(api, "qt_vulkan")) {
return 4;
} else if (!strcasecmp(api, "vnc")) {
return 5;
}
return 0; return 0;
} }
@@ -67,18 +62,12 @@ plat_vidapi_name(int api)
name = "qt_software"; name = "qt_software";
break; break;
case 1: case 1:
name = "qt_opengl";
break;
case 2:
name = "qt_opengles";
break;
case 3:
name = "qt_opengl3"; name = "qt_opengl3";
break; break;
case 4: case 2:
name = "qt_vulkan"; name = "qt_vulkan";
break; break;
case 5: case 3:
name = "vnc"; name = "vnc";
break; break;
default: default:
@@ -87,4 +76,4 @@ plat_vidapi_name(int api)
} }
return name; return name;
} }

View File

@@ -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 <jgilje@jgilje.net>
* Cacodemon345
* Teemu Korhonen
*
* Copyright 2021 Joakim L. Gilje
* Copyright 2021-2022 Cacodemon345
* Copyright 2021-2022 Teemu Korhonen
*/
#include "qt_hardwarerenderer.hpp"
#include <QApplication>
#include <QVector2D>
#include <QOpenGLPixelTransferOptions>
#include <atomic>
#include <cstdint>
#include <vector>
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<QVector2D> verts;
QVector<QVector2D> 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<std::tuple<uint8_t *, std::atomic_flag *>>
HardwareRenderer::getBuffers()
{
std::vector<std::tuple<uint8_t *, std::atomic_flag *>> 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;
}

View File

@@ -1,103 +0,0 @@
#pragma once
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLWindow>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLTexture>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLTextureBlitter>
#include <QOpenGLPixelTransferOptions>
#include <QPainter>
#include <QEvent>
#include <QKeyEvent>
#include <QWidget>
#include <atomic>
#include <mutex>
#include <array>
#include <vector>
#include <memory>
#include <QApplication>
#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<std::tuple<uint8_t *, std::atomic_flag *>> getBuffers() override;
HardwareRenderer(QWidget *parent = nullptr, RenderType rtype = RenderType::OpenGL)
: QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle())
, QOpenGLFunctions()
{
imagebufs[0] = std::unique_ptr<uint8_t>(new uint8_t[2048 * 2048 * 4]);
imagebufs[1] = std::unique_ptr<uint8_t>(new uint8_t[2048 * 2048 * 4]);
buf_usage = std::vector<std::atomic_flag>(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<std::unique_ptr<uint8_t>, 2> imagebufs;
void resizeEvent(QResizeEvent *event) override;
bool event(QEvent *event) override;
};

View File

@@ -420,22 +420,10 @@ MainWindow::MainWindow(QWidget *parent)
ui->actionEnable_Discord_integration->setEnabled(discord_loaded); ui->actionEnable_Discord_integration->setEnabled(discord_loaded);
#endif #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 ((QApplication::platformName().contains("eglfs") || QApplication::platformName() == "haiku")) {
if (vid_api >= 1) if (vid_api >= 1)
fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data()); fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data());
vid_api = 0; vid_api = 0;
ui->actionHardware_Renderer_OpenGL->setVisible(false);
ui->actionHardware_Renderer_OpenGL_ES->setVisible(false);
ui->actionVulkan->setVisible(false); ui->actionVulkan->setVisible(false);
ui->actionOpenGL_3_0_Core->setVisible(false); ui->actionOpenGL_3_0_Core->setVisible(false);
} }
@@ -469,8 +457,6 @@ MainWindow::MainWindow(QWidget *parent)
auto actGroup = new QActionGroup(this); auto actGroup = new QActionGroup(this);
actGroup->addAction(ui->actionSoftware_Renderer); 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->actionOpenGL_3_0_Core);
actGroup->addAction(ui->actionVulkan); actGroup->addAction(ui->actionVulkan);
actGroup->addAction(ui->actionVNC); actGroup->addAction(ui->actionVNC);
@@ -495,19 +481,13 @@ MainWindow::MainWindow(QWidget *parent)
newVidApi = RendererStack::Renderer::Software; newVidApi = RendererStack::Renderer::Software;
break; break;
case 1: case 1:
newVidApi = RendererStack::Renderer::OpenGL;
break;
case 2:
newVidApi = RendererStack::Renderer::OpenGLES;
break;
case 3:
newVidApi = RendererStack::Renderer::OpenGL3; newVidApi = RendererStack::Renderer::OpenGL3;
break; break;
case 4: case 2:
newVidApi = RendererStack::Renderer::Vulkan; newVidApi = RendererStack::Renderer::Vulkan;
break; break;
#ifdef USE_VNC #ifdef USE_VNC
case 5: case 3:
{ {
newVidApi = RendererStack::Renderer::Software; newVidApi = RendererStack::Renderer::Software;
startblit(); startblit();

View File

@@ -121,8 +121,6 @@
<string>Re&amp;nderer</string> <string>Re&amp;nderer</string>
</property> </property>
<addaction name="actionSoftware_Renderer"/> <addaction name="actionSoftware_Renderer"/>
<addaction name="actionHardware_Renderer_OpenGL"/>
<addaction name="actionHardware_Renderer_OpenGL_ES"/>
<addaction name="actionOpenGL_3_0_Core"/> <addaction name="actionOpenGL_3_0_Core"/>
<addaction name="actionVulkan"/> <addaction name="actionVulkan"/>
<addaction name="actionVNC"/> <addaction name="actionVNC"/>

View File

@@ -21,7 +21,6 @@
#include "qt_rendererstack.hpp" #include "qt_rendererstack.hpp"
#include "ui_qt_rendererstack.h" #include "ui_qt_rendererstack.h"
#include "qt_hardwarerenderer.hpp"
#include "qt_openglrenderer.hpp" #include "qt_openglrenderer.hpp"
#include "qt_softwarerenderer.hpp" #include "qt_softwarerenderer.hpp"
#include "qt_vulkanwindowrenderer.hpp" #include "qt_vulkanwindowrenderer.hpp"
@@ -336,24 +335,6 @@ RendererStack::createRenderer(Renderer renderer)
#endif #endif
} }
break; 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: case Renderer::OpenGL3:
{ {
this->createWinId(); this->createWinId();

View File

@@ -80,8 +80,6 @@ public:
enum class Renderer { enum class Renderer {
Software, Software,
OpenGL,
OpenGLES,
OpenGL3, OpenGL3,
Vulkan, Vulkan,
None = -1 None = -1