qt: Remove the Direct3D 9 renderer
This commit is contained in:
@@ -197,8 +197,7 @@ if(WIN32)
|
|||||||
else()
|
else()
|
||||||
target_sources(plat PRIVATE win_joystick_rawinput.c)
|
target_sources(plat PRIVATE win_joystick_rawinput.c)
|
||||||
endif()
|
endif()
|
||||||
target_sources(ui PRIVATE qt_d3d9renderer.hpp qt_d3d9renderer.cpp)
|
target_link_libraries(86Box hid)
|
||||||
target_link_libraries(86Box hid d3d9)
|
|
||||||
|
|
||||||
# CMake 3.22 messed this up for clang/clang++
|
# CMake 3.22 messed this up for clang/clang++
|
||||||
# See https://gitlab.kitware.com/cmake/cmake/-/issues/22611
|
# See https://gitlab.kitware.com/cmake/cmake/-/issues/22611
|
||||||
|
@@ -52,10 +52,8 @@ plat_vidapi(char *api)
|
|||||||
return 3;
|
return 3;
|
||||||
} else if (!strcasecmp(api, "qt_vulkan")) {
|
} else if (!strcasecmp(api, "qt_vulkan")) {
|
||||||
return 4;
|
return 4;
|
||||||
} else if (!strcasecmp(api, "qt_d3d9")) {
|
|
||||||
return 5;
|
|
||||||
} else if (!strcasecmp(api, "vnc")) {
|
} else if (!strcasecmp(api, "vnc")) {
|
||||||
return 6;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -83,9 +81,6 @@ plat_vidapi_name(int api)
|
|||||||
name = "qt_vulkan";
|
name = "qt_vulkan";
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
name = "qt_d3d9";
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
name = "vnc";
|
name = "vnc";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -1,200 +0,0 @@
|
|||||||
#include "qt_mainwindow.hpp"
|
|
||||||
#include "qt_d3d9renderer.hpp"
|
|
||||||
#include <QResizeEvent>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <86box/86box.h>
|
|
||||||
#include <86box/video.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index)
|
|
||||||
: QWidget { parent }
|
|
||||||
, RendererCommon()
|
|
||||||
{
|
|
||||||
QPalette pal = palette();
|
|
||||||
pal.setColor(QPalette::Window, Qt::black);
|
|
||||||
setAutoFillBackground(true);
|
|
||||||
setPalette(pal);
|
|
||||||
|
|
||||||
setAttribute(Qt::WA_NativeWindow);
|
|
||||||
setAttribute(Qt::WA_PaintOnScreen);
|
|
||||||
setAttribute(Qt::WA_NoSystemBackground);
|
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
|
||||||
|
|
||||||
windowHandle = (HWND) winId();
|
|
||||||
surfaceInUse = true;
|
|
||||||
finalized = true;
|
|
||||||
|
|
||||||
RendererCommon::parentWidget = parent;
|
|
||||||
|
|
||||||
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
this->m_monitor_index = monitor_index;
|
|
||||||
|
|
||||||
d3d9surface = nullptr;
|
|
||||||
d3d9dev = nullptr;
|
|
||||||
d3d9 = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D9Renderer::~D3D9Renderer()
|
|
||||||
{
|
|
||||||
finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
D3D9Renderer::finalize()
|
|
||||||
{
|
|
||||||
if (!finalized) {
|
|
||||||
while (surfaceInUse) { }
|
|
||||||
finalized = true;
|
|
||||||
}
|
|
||||||
surfaceInUse = true;
|
|
||||||
if (d3d9surface) {
|
|
||||||
d3d9surface->Release();
|
|
||||||
d3d9surface = nullptr;
|
|
||||||
}
|
|
||||||
if (d3d9dev) {
|
|
||||||
d3d9dev->Release();
|
|
||||||
d3d9dev = nullptr;
|
|
||||||
}
|
|
||||||
if (d3d9) {
|
|
||||||
d3d9->Release();
|
|
||||||
d3d9 = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
D3D9Renderer::hideEvent(QHideEvent *event)
|
|
||||||
{
|
|
||||||
finalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
D3D9Renderer::showEvent(QShowEvent *event)
|
|
||||||
{
|
|
||||||
if (d3d9) finalize();
|
|
||||||
params = {};
|
|
||||||
|
|
||||||
if (FAILED(Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d9))) {
|
|
||||||
return error("Failed to create Direct3D 9 context");
|
|
||||||
}
|
|
||||||
|
|
||||||
params.Windowed = true;
|
|
||||||
params.SwapEffect = D3DSWAPEFFECT_FLIPEX;
|
|
||||||
params.BackBufferWidth = width() * devicePixelRatioF();
|
|
||||||
params.BackBufferHeight = height() * devicePixelRatioF();
|
|
||||||
params.BackBufferCount = 1;
|
|
||||||
params.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
|
||||||
params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
||||||
params.hDeviceWindow = (HWND) winId();
|
|
||||||
|
|
||||||
HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev);
|
|
||||||
if (FAILED(result))
|
|
||||||
result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev);
|
|
||||||
if (FAILED(result)) {
|
|
||||||
return error("Failed to create Direct3D 9 device");
|
|
||||||
}
|
|
||||||
|
|
||||||
result = d3d9dev->CreateOffscreenPlainSurface(2048, 2048, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr);
|
|
||||||
if (FAILED(result))
|
|
||||||
result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr);
|
|
||||||
if (FAILED(result)) {
|
|
||||||
return error("Failed to create Direct3D 9 surface");
|
|
||||||
}
|
|
||||||
if (!alreadyInitialized) {
|
|
||||||
emit initialized();
|
|
||||||
alreadyInitialized = true;
|
|
||||||
}
|
|
||||||
surfaceInUse = false;
|
|
||||||
finalized = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
D3D9Renderer::paintEvent(QPaintEvent *event)
|
|
||||||
{
|
|
||||||
IDirect3DSurface9 *backbuffer = nullptr;
|
|
||||||
RECT srcRect;
|
|
||||||
RECT dstRect;
|
|
||||||
HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
|
|
||||||
|
|
||||||
if (FAILED(result)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
srcRect.top = source.top();
|
|
||||||
srcRect.bottom = source.bottom();
|
|
||||||
srcRect.left = source.left();
|
|
||||||
srcRect.right = source.right();
|
|
||||||
dstRect.top = destination.top() * devicePixelRatioF();
|
|
||||||
dstRect.bottom = destination.bottom() * devicePixelRatioF();
|
|
||||||
dstRect.left = destination.left() * devicePixelRatioF();
|
|
||||||
dstRect.right = destination.right() * devicePixelRatioF();
|
|
||||||
d3d9dev->BeginScene();
|
|
||||||
d3d9dev->Clear(0, nullptr, D3DCLEAR_TARGET, 0xFF000000, 0, 0);
|
|
||||||
while (surfaceInUse) { }
|
|
||||||
surfaceInUse = true;
|
|
||||||
d3d9dev->StretchRect(d3d9surface, &srcRect, backbuffer, &dstRect, video_filter_method == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR);
|
|
||||||
result = d3d9dev->EndScene();
|
|
||||||
surfaceInUse = false;
|
|
||||||
if (SUCCEEDED(result)) {
|
|
||||||
if (FAILED(d3d9dev->PresentEx(nullptr, nullptr, 0, nullptr, 0))) {
|
|
||||||
finalize();
|
|
||||||
showEvent(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
D3D9Renderer::event(QEvent *event)
|
|
||||||
{
|
|
||||||
bool res = false;
|
|
||||||
if (!eventDelegate(event, res))
|
|
||||||
return QWidget::event(event);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
D3D9Renderer::resizeEvent(QResizeEvent *event)
|
|
||||||
{
|
|
||||||
onResize(event->size().width() * devicePixelRatioF(), event->size().height() * devicePixelRatioF());
|
|
||||||
|
|
||||||
params.BackBufferWidth = event->size().width() * devicePixelRatioF();
|
|
||||||
params.BackBufferHeight = event->size().height() * devicePixelRatioF();
|
|
||||||
if (d3d9dev)
|
|
||||||
d3d9dev->Reset(¶ms);
|
|
||||||
QWidget::resizeEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
D3D9Renderer::blit(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) {
|
|
||||||
video_blit_complete_monitor(m_monitor_index);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
surfaceInUse = true;
|
|
||||||
auto origSource = source;
|
|
||||||
source.setRect(x, y, w, h);
|
|
||||||
RECT srcRect;
|
|
||||||
D3DLOCKED_RECT lockRect;
|
|
||||||
srcRect.top = source.top();
|
|
||||||
srcRect.bottom = source.bottom();
|
|
||||||
srcRect.left = source.left();
|
|
||||||
srcRect.right = source.right();
|
|
||||||
|
|
||||||
if (monitors[m_monitor_index].mon_screenshots) {
|
|
||||||
video_screenshot_monitor((uint32_t *) &(monitors[m_monitor_index].target_buffer->line[y][x]), 0, 0, 2048, m_monitor_index);
|
|
||||||
}
|
|
||||||
if (SUCCEEDED(d3d9surface->LockRect(&lockRect, &srcRect, 0))) {
|
|
||||||
for (int y1 = 0; y1 < h; y1++) {
|
|
||||||
video_copy(((uint8_t *) lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4);
|
|
||||||
}
|
|
||||||
video_blit_complete_monitor(m_monitor_index);
|
|
||||||
d3d9surface->UnlockRect();
|
|
||||||
} else
|
|
||||||
video_blit_complete_monitor(m_monitor_index);
|
|
||||||
if (origSource != source)
|
|
||||||
onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF());
|
|
||||||
surfaceInUse = false;
|
|
||||||
QTimer::singleShot(0, this, [this] { this->update(); });
|
|
||||||
}
|
|
@@ -1,45 +0,0 @@
|
|||||||
#ifndef D3D9RENDERER_HPP
|
|
||||||
#define D3D9RENDERER_HPP
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include "qt_renderercommon.hpp"
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <d3d9.h>
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
class D3D9Renderer : public QWidget, public RendererCommon {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit D3D9Renderer(QWidget *parent = nullptr, int monitor_index = 0);
|
|
||||||
~D3D9Renderer();
|
|
||||||
bool hasBlitFunc() override { return true; }
|
|
||||||
void blit(int x, int y, int w, int h) override;
|
|
||||||
void finalize() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void showEvent(QShowEvent *event) override;
|
|
||||||
void hideEvent(QHideEvent *event) override;
|
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
|
||||||
void paintEvent(QPaintEvent *event) override;
|
|
||||||
bool event(QEvent *event) override;
|
|
||||||
QPaintEngine *paintEngine() const override { return nullptr; }
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void initialized();
|
|
||||||
void error(QString);
|
|
||||||
|
|
||||||
private:
|
|
||||||
HWND windowHandle = 0;
|
|
||||||
D3DPRESENT_PARAMETERS params {};
|
|
||||||
IDirect3D9Ex *d3d9 = nullptr;
|
|
||||||
IDirect3DDevice9Ex *d3d9dev = nullptr;
|
|
||||||
IDirect3DSurface9 *d3d9surface = nullptr;
|
|
||||||
|
|
||||||
std::atomic<bool> surfaceInUse { false };
|
|
||||||
std::atomic<bool> finalized { false };
|
|
||||||
bool alreadyInitialized = false;
|
|
||||||
int m_monitor_index = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // D3D9RENDERER_HPP
|
|
@@ -342,7 +342,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* Set the PAUSE mode depending on the renderer. */
|
/* Set the PAUSE mode depending on the renderer. */
|
||||||
#ifdef USE_VNC
|
#ifdef USE_VNC
|
||||||
if (vnc_enabled && vid_api != 6)
|
if (vnc_enabled && vid_api != 5)
|
||||||
plat_pause(1);
|
plat_pause(1);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@@ -157,8 +157,6 @@ keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter)
|
|||||||
static BMessageFilter *filter;
|
static BMessageFilter *filter;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::atomic<bool> blitDummied { false };
|
|
||||||
|
|
||||||
extern void qt_mouse_capture(int);
|
extern void qt_mouse_capture(int);
|
||||||
extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index);
|
extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index);
|
||||||
|
|
||||||
@@ -369,14 +367,9 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
ui->actionVulkan->setVisible(false);
|
ui->actionVulkan->setVisible(false);
|
||||||
ui->actionOpenGL_3_0_Core->setVisible(false);
|
ui->actionOpenGL_3_0_Core->setVisible(false);
|
||||||
}
|
}
|
||||||
#if !defined Q_OS_WINDOWS
|
|
||||||
ui->actionDirect3D_9->setVisible(false);
|
|
||||||
if (vid_api == 5)
|
|
||||||
vid_api = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USE_VNC
|
#ifndef USE_VNC
|
||||||
if (vid_api == 6)
|
if (vid_api == 5)
|
||||||
vid_api = 0;
|
vid_api = 0;
|
||||||
ui->actionVNC->setVisible(false);
|
ui->actionVNC->setVisible(false);
|
||||||
#endif
|
#endif
|
||||||
@@ -410,14 +403,13 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
actGroup->addAction(ui->actionHardware_Renderer_OpenGL_ES);
|
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->actionDirect3D_9);
|
|
||||||
actGroup->addAction(ui->actionVNC);
|
actGroup->addAction(ui->actionVNC);
|
||||||
actGroup->setExclusive(true);
|
actGroup->setExclusive(true);
|
||||||
|
|
||||||
connect(actGroup, &QActionGroup::triggered, [this](QAction *action) {
|
connect(actGroup, &QActionGroup::triggered, [this](QAction *action) {
|
||||||
vid_api = action->property("vid_api").toInt();
|
vid_api = action->property("vid_api").toInt();
|
||||||
#ifdef USE_VNC
|
#ifdef USE_VNC
|
||||||
if (vnc_enabled && vid_api != 6) {
|
if (vnc_enabled && vid_api != 5) {
|
||||||
startblit();
|
startblit();
|
||||||
vnc_enabled = 0;
|
vnc_enabled = 0;
|
||||||
vnc_close();
|
vnc_close();
|
||||||
@@ -442,11 +434,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
case 4:
|
case 4:
|
||||||
newVidApi = RendererStack::Renderer::Vulkan;
|
newVidApi = RendererStack::Renderer::Vulkan;
|
||||||
break;
|
break;
|
||||||
case 5:
|
|
||||||
newVidApi = RendererStack::Renderer::Direct3D9;
|
|
||||||
break;
|
|
||||||
#ifdef USE_VNC
|
#ifdef USE_VNC
|
||||||
case 6:
|
case 5:
|
||||||
{
|
{
|
||||||
newVidApi = RendererStack::Renderer::Software;
|
newVidApi = RendererStack::Renderer::Software;
|
||||||
startblit();
|
startblit();
|
||||||
@@ -612,7 +601,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||||||
video_setblit(qt_blit);
|
video_setblit(qt_blit);
|
||||||
|
|
||||||
if (start_in_fullscreen) {
|
if (start_in_fullscreen) {
|
||||||
connect(ui->stackedWidget, &RendererStack::blit, this, [this] () {
|
connect(ui->stackedWidget, &RendererStack::blitToRenderer, this, [this] () {
|
||||||
if (start_in_fullscreen) {
|
if (start_in_fullscreen) {
|
||||||
QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger);
|
QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger);
|
||||||
start_in_fullscreen = 0;
|
start_in_fullscreen = 0;
|
||||||
@@ -1156,8 +1145,6 @@ MainWindow::on_actionFullscreen_triggered()
|
|||||||
{
|
{
|
||||||
if (video_fullscreen > 0) {
|
if (video_fullscreen > 0) {
|
||||||
showNormal();
|
showNormal();
|
||||||
if (vid_api == 5)
|
|
||||||
QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); });
|
|
||||||
ui->menubar->show();
|
ui->menubar->show();
|
||||||
if (!hide_status_bar)
|
if (!hide_status_bar)
|
||||||
ui->statusbar->show();
|
ui->statusbar->show();
|
||||||
@@ -1193,8 +1180,6 @@ MainWindow::on_actionFullscreen_triggered()
|
|||||||
ui->toolBar->hide();
|
ui->toolBar->hide();
|
||||||
ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
|
||||||
showFullScreen();
|
showFullScreen();
|
||||||
if (vid_api == 5)
|
|
||||||
QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); });
|
|
||||||
}
|
}
|
||||||
ui->stackedWidget->onResize(width(), height());
|
ui->stackedWidget->onResize(width(), height());
|
||||||
}
|
}
|
||||||
@@ -1316,7 +1301,7 @@ void
|
|||||||
MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index)
|
MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index)
|
||||||
{
|
{
|
||||||
if (monitor_index >= 1) {
|
if (monitor_index >= 1) {
|
||||||
if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible())
|
if (renderers[monitor_index] && renderers[monitor_index]->isVisible())
|
||||||
renderers[monitor_index]->blit(x, y, w, h);
|
renderers[monitor_index]->blit(x, y, w, h);
|
||||||
else
|
else
|
||||||
video_blit_complete_monitor(monitor_index);
|
video_blit_complete_monitor(monitor_index);
|
||||||
@@ -1976,8 +1961,6 @@ MainWindow::on_actionShow_non_primary_monitors_triggered()
|
|||||||
{
|
{
|
||||||
show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked();
|
show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked();
|
||||||
|
|
||||||
blitDummied = true;
|
|
||||||
|
|
||||||
if (show_second_monitors) {
|
if (show_second_monitors) {
|
||||||
for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
|
for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) {
|
||||||
auto &secondaryRenderer = renderers[monitor_index];
|
auto &secondaryRenderer = renderers[monitor_index];
|
||||||
@@ -2007,8 +1990,6 @@ MainWindow::on_actionShow_non_primary_monitors_triggered()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blitDummied = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -12,8 +12,6 @@
|
|||||||
class MediaMenu;
|
class MediaMenu;
|
||||||
class RendererStack;
|
class RendererStack;
|
||||||
|
|
||||||
extern std::atomic<bool> blitDummied;
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
}
|
}
|
||||||
|
@@ -117,7 +117,6 @@
|
|||||||
<addaction name="actionHardware_Renderer_OpenGL_ES"/>
|
<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="actionDirect3D_9"/>
|
|
||||||
<addaction name="actionVNC"/>
|
<addaction name="actionVNC"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuWindow_scale_factor">
|
<widget class="QMenu" name="menuWindow_scale_factor">
|
||||||
@@ -831,17 +830,6 @@
|
|||||||
<string>MCA devices...</string>
|
<string>MCA devices...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionDirect3D_9">
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Direct3D 9</string>
|
|
||||||
</property>
|
|
||||||
<property name="vid_api" stdset="0">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionShow_non_primary_monitors">
|
<action name="actionShow_non_primary_monitors">
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@@ -35,9 +35,6 @@ public:
|
|||||||
/* Reloads options of renderer */
|
/* Reloads options of renderer */
|
||||||
virtual void reloadOptions() { }
|
virtual void reloadOptions() { }
|
||||||
|
|
||||||
virtual bool hasBlitFunc() { return false; }
|
|
||||||
virtual void blit(int x, int y, int w, int h) { }
|
|
||||||
|
|
||||||
int r_monitor_index = 0;
|
int r_monitor_index = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -25,9 +25,6 @@
|
|||||||
#include "qt_openglrenderer.hpp"
|
#include "qt_openglrenderer.hpp"
|
||||||
#include "qt_softwarerenderer.hpp"
|
#include "qt_softwarerenderer.hpp"
|
||||||
#include "qt_vulkanwindowrenderer.hpp"
|
#include "qt_vulkanwindowrenderer.hpp"
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
# include "qt_d3d9renderer.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "qt_mainwindow.hpp"
|
#include "qt_mainwindow.hpp"
|
||||||
#include "qt_util.hpp"
|
#include "qt_util.hpp"
|
||||||
@@ -279,31 +276,6 @@ RendererStack::switchRenderer(Renderer renderer)
|
|||||||
{
|
{
|
||||||
startblit();
|
startblit();
|
||||||
if (current) {
|
if (current) {
|
||||||
if ((current_vid_api == Renderer::Direct3D9 && renderer != Renderer::Direct3D9)
|
|
||||||
|| (current_vid_api != Renderer::Direct3D9 && renderer == Renderer::Direct3D9)) {
|
|
||||||
rendererWindow->finalize();
|
|
||||||
if (rendererWindow->hasBlitFunc()) {
|
|
||||||
while (directBlitting) { }
|
|
||||||
connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection);
|
|
||||||
disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer);
|
|
||||||
} else {
|
|
||||||
connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection);
|
|
||||||
disconnect(this, &RendererStack::blit, this, &RendererStack::blitCommon);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeWidget(current.get());
|
|
||||||
disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr);
|
|
||||||
|
|
||||||
/* Create new renderer only after previous is destroyed! */
|
|
||||||
connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) {
|
|
||||||
createRenderer(renderer);
|
|
||||||
disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy);
|
|
||||||
blitDummied = false;
|
|
||||||
QTimer::singleShot(1000, this, []() { blitDummied = false; });
|
|
||||||
});
|
|
||||||
|
|
||||||
rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater();
|
|
||||||
} else {
|
|
||||||
rendererWindow->finalize();
|
rendererWindow->finalize();
|
||||||
removeWidget(current.get());
|
removeWidget(current.get());
|
||||||
disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr);
|
disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr);
|
||||||
@@ -312,7 +284,6 @@ RendererStack::switchRenderer(Renderer renderer)
|
|||||||
connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); });
|
connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); });
|
||||||
|
|
||||||
current.release()->deleteLater();
|
current.release()->deleteLater();
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
createRenderer(renderer);
|
createRenderer(renderer);
|
||||||
}
|
}
|
||||||
@@ -321,7 +292,6 @@ RendererStack::switchRenderer(Renderer renderer)
|
|||||||
void
|
void
|
||||||
RendererStack::createRenderer(Renderer renderer)
|
RendererStack::createRenderer(Renderer renderer)
|
||||||
{
|
{
|
||||||
current_vid_api = renderer;
|
|
||||||
switch (renderer) {
|
switch (renderer) {
|
||||||
default:
|
default:
|
||||||
case Renderer::Software:
|
case Renderer::Software:
|
||||||
@@ -374,27 +344,6 @@ RendererStack::createRenderer(Renderer renderer)
|
|||||||
current.reset(this->createWindowContainer(hw, this));
|
current.reset(this->createWindowContainer(hw, this));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
case Renderer::Direct3D9:
|
|
||||||
{
|
|
||||||
this->createWinId();
|
|
||||||
auto hw = new D3D9Renderer(this, m_monitor_index);
|
|
||||||
rendererWindow = hw;
|
|
||||||
connect(hw, &D3D9Renderer::error, this, [this](QString str) {
|
|
||||||
auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok);
|
|
||||||
msgBox->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
msgBox->show();
|
|
||||||
imagebufs = {};
|
|
||||||
QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); });
|
|
||||||
});
|
|
||||||
connect(hw, &D3D9Renderer::initialized, this, [this]() {
|
|
||||||
endblit();
|
|
||||||
emit rendererChanged();
|
|
||||||
});
|
|
||||||
current.reset(hw);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if QT_CONFIG(vulkan)
|
#if QT_CONFIG(vulkan)
|
||||||
case Renderer::Vulkan:
|
case Renderer::Vulkan:
|
||||||
{
|
{
|
||||||
@@ -444,44 +393,18 @@ RendererStack::createRenderer(Renderer renderer)
|
|||||||
|
|
||||||
currentBuf = 0;
|
currentBuf = 0;
|
||||||
|
|
||||||
if (rendererWindow->hasBlitFunc()) {
|
if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan) {
|
||||||
connect(this, &RendererStack::blit, this, &RendererStack::blitRenderer, Qt::DirectConnection);
|
|
||||||
} else {
|
|
||||||
connect(this, &RendererStack::blit, this, &RendererStack::blitCommon, Qt::DirectConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan && renderer != Renderer::Direct3D9) {
|
|
||||||
imagebufs = rendererWindow->getBuffers();
|
imagebufs = rendererWindow->getBuffers();
|
||||||
endblit();
|
endblit();
|
||||||
emit rendererChanged();
|
emit rendererChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
RendererStack::blitDummy(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
video_blit_complete_monitor(m_monitor_index);
|
|
||||||
blitDummied = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RendererStack::blitRenderer(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
if (blitDummied) {
|
|
||||||
blitDummied = false;
|
|
||||||
video_blit_complete_monitor(m_monitor_index);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
directBlitting = true;
|
|
||||||
rendererWindow->blit(x, y, w, h);
|
|
||||||
directBlitting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// called from blitter thread
|
// called from blitter thread
|
||||||
void
|
void
|
||||||
RendererStack::blitCommon(int x, int y, int w, int h)
|
RendererStack::blit(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set()) {
|
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set()) {
|
||||||
video_blit_complete_monitor(m_monitor_index);
|
video_blit_complete_monitor(m_monitor_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -59,7 +59,6 @@ public:
|
|||||||
OpenGLES,
|
OpenGLES,
|
||||||
OpenGL3,
|
OpenGL3,
|
||||||
Vulkan,
|
Vulkan,
|
||||||
Direct3D9,
|
|
||||||
None = -1
|
None = -1
|
||||||
};
|
};
|
||||||
void switchRenderer(Renderer renderer);
|
void switchRenderer(Renderer renderer);
|
||||||
@@ -81,13 +80,10 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void blitToRenderer(int buf_idx, int x, int y, int w, int h);
|
void blitToRenderer(int buf_idx, int x, int y, int w, int h);
|
||||||
void blit(int x, int y, int w, int h);
|
|
||||||
void rendererChanged();
|
void rendererChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void blitCommon(int x, int y, int w, int h);
|
void blit(int x, int y, int w, int h);
|
||||||
void blitRenderer(int x, int y, int w, int h);
|
|
||||||
void blitDummy(int x, int y, int w, int h);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createRenderer(Renderer renderer);
|
void createRenderer(Renderer renderer);
|
||||||
@@ -107,13 +103,10 @@ private:
|
|||||||
int isMouseDown = 0;
|
int isMouseDown = 0;
|
||||||
int m_monitor_index = 0;
|
int m_monitor_index = 0;
|
||||||
|
|
||||||
Renderer current_vid_api = Renderer::None;
|
|
||||||
|
|
||||||
std::vector<std::tuple<uint8_t *, std::atomic_flag *>> imagebufs;
|
std::vector<std::tuple<uint8_t *, std::atomic_flag *>> imagebufs;
|
||||||
|
|
||||||
RendererCommon *rendererWindow { nullptr };
|
RendererCommon *rendererWindow { nullptr };
|
||||||
std::unique_ptr<QWidget> current;
|
std::unique_ptr<QWidget> current;
|
||||||
std::atomic<bool> directBlitting { false };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QT_RENDERERCONTAINER_HPP
|
#endif // QT_RENDERERCONTAINER_HPP
|
||||||
|
Reference in New Issue
Block a user