summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/osd/modules.lua92
-rw-r--r--scripts/src/osd/sdl.lua5
-rw-r--r--scripts/src/osd/windows.lua4
-rw-r--r--src/osd/mac/video.cpp100
-rw-r--r--src/osd/mac/window.cpp47
-rw-r--r--src/osd/mac/window.h29
-rw-r--r--src/osd/modules/debugger/debugwin.cpp6
-rw-r--r--src/osd/modules/debugger/win/debugwininfo.cpp2
-rw-r--r--src/osd/modules/font/font_module.h2
-rw-r--r--src/osd/modules/input/input_dinput.cpp15
-rw-r--r--src/osd/modules/input/input_rawinput.cpp2
-rw-r--r--src/osd/modules/input/input_win32.cpp10
-rw-r--r--src/osd/modules/lib/osdobj_common.cpp105
-rw-r--r--src/osd/modules/lib/osdobj_common.h35
-rw-r--r--src/osd/modules/osdmodule.cpp64
-rw-r--r--src/osd/modules/osdmodule.h8
-rw-r--r--src/osd/modules/osdwindow.cpp95
-rw-r--r--src/osd/modules/osdwindow.h138
-rw-r--r--src/osd/modules/output/network.cpp22
-rw-r--r--src/osd/modules/output/output_module.h8
-rw-r--r--src/osd/modules/output/win32_output.cpp20
-rw-r--r--src/osd/modules/render/aviwrite.h13
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.cpp28
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.h9
-rw-r--r--src/osd/modules/render/bgfx/effect.cpp34
-rw-r--r--src/osd/modules/render/bgfx/effect.h20
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.cpp69
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.h29
-rw-r--r--src/osd/modules/render/bgfx/effectreader.cpp85
-rw-r--r--src/osd/modules/render/bgfx/effectreader.h12
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.cpp11
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.h14
-rw-r--r--src/osd/modules/render/bgfx/uniformreader.cpp18
-rw-r--r--src/osd/modules/render/bgfx/uniformreader.h6
-rw-r--r--src/osd/modules/render/bgfx/view.cpp4
-rw-r--r--src/osd/modules/render/bgfx/view.h4
-rw-r--r--src/osd/modules/render/blit13.ipp (renamed from src/osd/modules/render/blit13.h)0
-rw-r--r--src/osd/modules/render/d3d/d3dcomm.h96
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp492
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.h69
-rw-r--r--src/osd/modules/render/draw13.cpp688
-rw-r--r--src/osd/modules/render/draw13.h215
-rw-r--r--src/osd/modules/render/drawbgfx.cpp710
-rw-r--r--src/osd/modules/render/drawbgfx.h45
-rw-r--r--src/osd/modules/render/drawd3d.cpp673
-rw-r--r--src/osd/modules/render/drawd3d.h57
-rw-r--r--src/osd/modules/render/drawgdi.cpp119
-rw-r--r--src/osd/modules/render/drawgdi.h55
-rw-r--r--src/osd/modules/render/drawnone.cpp80
-rw-r--r--src/osd/modules/render/drawnone.h33
-rw-r--r--src/osd/modules/render/drawogl.cpp876
-rw-r--r--src/osd/modules/render/drawogl.h244
-rw-r--r--src/osd/modules/render/drawsdl.cpp314
-rw-r--r--src/osd/modules/render/drawsdl.h94
-rw-r--r--src/osd/modules/render/render_module.h38
-rw-r--r--src/osd/modules/sound/coreaudio_sound.cpp35
-rw-r--r--src/osd/modules/sound/direct_sound.cpp31
-rw-r--r--src/osd/modules/sound/js_sound.cpp32
-rw-r--r--src/osd/modules/sound/pa_sound.cpp17
-rw-r--r--src/osd/modules/sound/pulse_sound.cpp10
-rw-r--r--src/osd/modules/sound/sdl_sound.cpp26
-rw-r--r--src/osd/modules/sound/sound_module.h8
-rw-r--r--src/osd/modules/sound/xaudio2_sound.cpp90
-rw-r--r--src/osd/sdl/osdsdl.cpp53
-rw-r--r--src/osd/sdl/osdsdl.h4
-rw-r--r--src/osd/sdl/video.cpp126
-rw-r--r--src/osd/sdl/window.cpp142
-rw-r--r--src/osd/sdl/window.h39
-rw-r--r--src/osd/windows/video.cpp101
-rw-r--r--src/osd/windows/window.cpp226
-rw-r--r--src/osd/windows/window.h21
-rw-r--r--src/osd/windows/winmain.cpp21
-rw-r--r--src/osd/windows/winmain.h2
73 files changed, 3279 insertions, 3768 deletions
diff --git a/scripts/src/osd/modules.lua b/scripts/src/osd/modules.lua
index a6f8a7db820..6db305a9ff8 100644
--- a/scripts/src/osd/modules.lua
+++ b/scripts/src/osd/modules.lua
@@ -59,69 +59,76 @@ function osdmodulesbuild()
MAME_DIR .. "src/osd/interface/inputseq.cpp",
MAME_DIR .. "src/osd/interface/inputseq.h",
MAME_DIR .. "src/osd/modules/debugger/debug_module.h",
- MAME_DIR .. "src/osd/modules/font/font_module.h",
- MAME_DIR .. "src/osd/modules/midi/midi_module.h",
- MAME_DIR .. "src/osd/modules/netdev/netdev_module.h",
- MAME_DIR .. "src/osd/modules/sound/sound_module.h",
- MAME_DIR .. "src/osd/modules/diagnostics/diagnostics_module.h",
- MAME_DIR .. "src/osd/modules/monitor/monitor_module.h",
- MAME_DIR .. "src/osd/modules/lib/osdobj_common.cpp",
- MAME_DIR .. "src/osd/modules/lib/osdobj_common.h",
- MAME_DIR .. "src/osd/modules/diagnostics/none.cpp",
- MAME_DIR .. "src/osd/modules/diagnostics/diagnostics_win32.cpp",
- MAME_DIR .. "src/osd/modules/debugger/none.cpp",
- MAME_DIR .. "src/osd/modules/debugger/debugwin.cpp",
- MAME_DIR .. "src/osd/modules/debugger/debugimgui.cpp",
MAME_DIR .. "src/osd/modules/debugger/debuggdbstub.cpp",
+ MAME_DIR .. "src/osd/modules/debugger/debugimgui.cpp",
+ MAME_DIR .. "src/osd/modules/debugger/debugwin.cpp",
+ MAME_DIR .. "src/osd/modules/debugger/none.cpp",
MAME_DIR .. "src/osd/modules/debugger/xmlconfig.cpp",
MAME_DIR .. "src/osd/modules/debugger/xmlconfig.h",
- MAME_DIR .. "src/osd/modules/font/font_sdl.cpp",
- MAME_DIR .. "src/osd/modules/font/font_windows.cpp",
+ MAME_DIR .. "src/osd/modules/diagnostics/diagnostics_module.h",
+ MAME_DIR .. "src/osd/modules/diagnostics/diagnostics_win32.cpp",
+ MAME_DIR .. "src/osd/modules/diagnostics/none.cpp",
MAME_DIR .. "src/osd/modules/font/font_dwrite.cpp",
- MAME_DIR .. "src/osd/modules/font/font_osx.cpp",
+ MAME_DIR .. "src/osd/modules/font/font_module.h",
MAME_DIR .. "src/osd/modules/font/font_none.cpp",
- MAME_DIR .. "src/osd/modules/netdev/taptun.cpp",
- MAME_DIR .. "src/osd/modules/netdev/pcap.cpp",
- MAME_DIR .. "src/osd/modules/netdev/none.cpp",
- MAME_DIR .. "src/osd/modules/midi/portmidi.cpp",
- MAME_DIR .. "src/osd/modules/midi/none.cpp",
- MAME_DIR .. "src/osd/modules/sound/js_sound.cpp",
- MAME_DIR .. "src/osd/modules/sound/direct_sound.cpp",
- MAME_DIR .. "src/osd/modules/sound/pa_sound.cpp",
- MAME_DIR .. "src/osd/modules/sound/pulse_sound.cpp",
- MAME_DIR .. "src/osd/modules/sound/coreaudio_sound.cpp",
- MAME_DIR .. "src/osd/modules/sound/sdl_sound.cpp",
- MAME_DIR .. "src/osd/modules/sound/xaudio2_sound.cpp",
- MAME_DIR .. "src/osd/modules/sound/none.cpp",
- MAME_DIR .. "src/osd/modules/input/input_module.h",
+ MAME_DIR .. "src/osd/modules/font/font_osx.cpp",
+ MAME_DIR .. "src/osd/modules/font/font_sdl.cpp",
+ MAME_DIR .. "src/osd/modules/font/font_windows.cpp",
MAME_DIR .. "src/osd/modules/input/input_common.cpp",
MAME_DIR .. "src/osd/modules/input/input_common.h",
MAME_DIR .. "src/osd/modules/input/input_dinput.cpp",
MAME_DIR .. "src/osd/modules/input/input_dinput.h",
+ MAME_DIR .. "src/osd/modules/input/input_mac.cpp",
+ MAME_DIR .. "src/osd/modules/input/input_module.h",
MAME_DIR .. "src/osd/modules/input/input_none.cpp",
MAME_DIR .. "src/osd/modules/input/input_rawinput.cpp",
- MAME_DIR .. "src/osd/modules/input/input_win32.cpp",
MAME_DIR .. "src/osd/modules/input/input_sdl.cpp",
- MAME_DIR .. "src/osd/modules/input/input_x11.cpp",
+ MAME_DIR .. "src/osd/modules/input/input_win32.cpp",
MAME_DIR .. "src/osd/modules/input/input_wincommon.h",
MAME_DIR .. "src/osd/modules/input/input_windows.cpp",
MAME_DIR .. "src/osd/modules/input/input_windows.h",
+ MAME_DIR .. "src/osd/modules/input/input_winhybrid.cpp",
+ MAME_DIR .. "src/osd/modules/input/input_x11.cpp",
MAME_DIR .. "src/osd/modules/input/input_xinput.cpp",
MAME_DIR .. "src/osd/modules/input/input_xinput.h",
- MAME_DIR .. "src/osd/modules/input/input_winhybrid.cpp",
- MAME_DIR .. "src/osd/modules/input/input_mac.cpp",
- MAME_DIR .. "src/osd/modules/output/output_module.h",
- MAME_DIR .. "src/osd/modules/output/none.cpp",
+ MAME_DIR .. "src/osd/modules/lib/osdobj_common.cpp",
+ MAME_DIR .. "src/osd/modules/lib/osdobj_common.h",
+ MAME_DIR .. "src/osd/modules/midi/midi_module.h",
+ MAME_DIR .. "src/osd/modules/midi/none.cpp",
+ MAME_DIR .. "src/osd/modules/midi/portmidi.cpp",
+ MAME_DIR .. "src/osd/modules/monitor/monitor_common.cpp",
+ MAME_DIR .. "src/osd/modules/monitor/monitor_common.h",
+ MAME_DIR .. "src/osd/modules/monitor/monitor_dxgi.cpp",
+ MAME_DIR .. "src/osd/modules/monitor/monitor_mac.cpp",
+ MAME_DIR .. "src/osd/modules/monitor/monitor_module.h",
+ MAME_DIR .. "src/osd/modules/monitor/monitor_sdl.cpp",
+ MAME_DIR .. "src/osd/modules/monitor/monitor_win32.cpp",
+ MAME_DIR .. "src/osd/modules/netdev/netdev_module.h",
+ MAME_DIR .. "src/osd/modules/netdev/none.cpp",
+ MAME_DIR .. "src/osd/modules/netdev/pcap.cpp",
+ MAME_DIR .. "src/osd/modules/netdev/taptun.cpp",
MAME_DIR .. "src/osd/modules/output/console.cpp",
MAME_DIR .. "src/osd/modules/output/network.cpp",
+ MAME_DIR .. "src/osd/modules/output/none.cpp",
+ MAME_DIR .. "src/osd/modules/output/output_module.h",
MAME_DIR .. "src/osd/modules/output/win32_output.cpp",
MAME_DIR .. "src/osd/modules/output/win32_output.h",
- MAME_DIR .. "src/osd/modules/monitor/monitor_common.h",
- MAME_DIR .. "src/osd/modules/monitor/monitor_common.cpp",
- MAME_DIR .. "src/osd/modules/monitor/monitor_win32.cpp",
- MAME_DIR .. "src/osd/modules/monitor/monitor_dxgi.cpp",
- MAME_DIR .. "src/osd/modules/monitor/monitor_sdl.cpp",
- MAME_DIR .. "src/osd/modules/monitor/monitor_mac.cpp",
+ MAME_DIR .. "src/osd/modules/render/blit13.ipp",
+ MAME_DIR .. "src/osd/modules/render/draw13.cpp",
+ MAME_DIR .. "src/osd/modules/render/drawgdi.cpp",
+ MAME_DIR .. "src/osd/modules/render/drawnone.cpp",
+ MAME_DIR .. "src/osd/modules/render/drawogl.cpp",
+ MAME_DIR .. "src/osd/modules/render/drawsdl.cpp",
+ MAME_DIR .. "src/osd/modules/render/render_module.h",
+ MAME_DIR .. "src/osd/modules/sound/coreaudio_sound.cpp",
+ MAME_DIR .. "src/osd/modules/sound/direct_sound.cpp",
+ MAME_DIR .. "src/osd/modules/sound/js_sound.cpp",
+ MAME_DIR .. "src/osd/modules/sound/none.cpp",
+ MAME_DIR .. "src/osd/modules/sound/pa_sound.cpp",
+ MAME_DIR .. "src/osd/modules/sound/pulse_sound.cpp",
+ MAME_DIR .. "src/osd/modules/sound/sdl_sound.cpp",
+ MAME_DIR .. "src/osd/modules/sound/sound_module.h",
+ MAME_DIR .. "src/osd/modules/sound/xaudio2_sound.cpp",
}
includedirs {
MAME_DIR .. "src/osd",
@@ -152,7 +159,6 @@ function osdmodulesbuild()
}
else
files {
- MAME_DIR .. "src/osd/modules/render/drawogl.cpp",
MAME_DIR .. "src/osd/modules/opengl/gl_shader_tool.cpp",
MAME_DIR .. "src/osd/modules/opengl/gl_shader_mgr.cpp",
MAME_DIR .. "src/osd/modules/opengl/gl_shader_mgr.h",
diff --git a/scripts/src/osd/sdl.lua b/scripts/src/osd/sdl.lua
index 4c6a979f952..3aa046b8ab1 100644
--- a/scripts/src/osd/sdl.lua
+++ b/scripts/src/osd/sdl.lua
@@ -430,7 +430,6 @@ project ("osd_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/osdepend.h",
MAME_DIR .. "src/osd/modules/osdwindow.cpp",
MAME_DIR .. "src/osd/modules/osdwindow.h",
- MAME_DIR .. "src/osd/modules/render/drawsdl.cpp",
MAME_DIR .. "src/osd/sdl/osdsdl.cpp",
MAME_DIR .. "src/osd/sdl/osdsdl.h",
MAME_DIR .. "src/osd/sdl/sdlmain.cpp",
@@ -441,10 +440,6 @@ project ("osd_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/sdl/window.cpp",
MAME_DIR .. "src/osd/sdl/window.h",
}
- files {
- MAME_DIR .. "src/osd/modules/render/draw13.cpp",
- MAME_DIR .. "src/osd/modules/render/blit13.h",
- }
project ("ocore_" .. _OPTIONS["osd"])
diff --git a/scripts/src/osd/windows.lua b/scripts/src/osd/windows.lua
index be91ec26237..ac300261ce8 100644
--- a/scripts/src/osd/windows.lua
+++ b/scripts/src/osd/windows.lua
@@ -132,10 +132,6 @@ project ("osd_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/modules/render/d3d/d3dhlsl.h",
MAME_DIR .. "src/osd/modules/render/drawd3d.cpp",
MAME_DIR .. "src/osd/modules/render/drawd3d.h",
- MAME_DIR .. "src/osd/modules/render/drawgdi.cpp",
- MAME_DIR .. "src/osd/modules/render/drawgdi.h",
- MAME_DIR .. "src/osd/modules/render/drawnone.cpp",
- MAME_DIR .. "src/osd/modules/render/drawnone.h",
MAME_DIR .. "src/osd/windows/video.cpp",
MAME_DIR .. "src/osd/windows/video.h",
MAME_DIR .. "src/osd/windows/window.cpp",
diff --git a/src/osd/mac/video.cpp b/src/osd/mac/video.cpp
index e534fbc7fb9..4ae04c4e132 100644
--- a/src/osd/mac/video.cpp
+++ b/src/osd/mac/video.cpp
@@ -74,10 +74,12 @@ bool mac_osd_interface::video_init()
get_resolution(options().resolution(), options().resolution(index), &conf, true);
// create window ...
- std::shared_ptr<mac_window_info> win = std::make_shared<mac_window_info>(machine(), index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf);
+ auto win = std::make_unique<mac_window_info>(machine(), *m_render, index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf);
if (win->window_init())
return false;
+
+ s_window_list.emplace_back(std::move(win));
}
return true;
@@ -104,7 +106,7 @@ void mac_osd_interface::update(bool skip_redraw)
if (!skip_redraw)
{
// profiler_mark(PROFILER_BLIT);
- for (auto window : osd_common_t::s_window_list)
+ for (auto const &window : osd_common_t::window_list())
window->update();
// profiler_mark(PROFILER_END);
}
@@ -135,11 +137,11 @@ static void check_osd_inputs(running_machine &machine)
// check for toggling fullscreen mode
if (machine.ui_input().pressed(IPT_OSD_1))
{
- for (auto curwin : osd_common_t::s_window_list)
- std::static_pointer_cast<mac_window_info>(curwin)->toggle_full_screen();
+ for (auto const &curwin : osd_common_t::window_list())
+ dynamic_cast<mac_window_info &>(*curwin).toggle_full_screen();
}
- auto window = osd_common_t::s_window_list.front();
+ auto const &window = osd_common_t::window_list().front();
//FIXME: on a per window basis
if (machine.ui_input().pressed(IPT_OSD_5))
@@ -149,10 +151,10 @@ static void check_osd_inputs(running_machine &machine)
}
if (machine.ui_input().pressed(IPT_OSD_6))
- std::static_pointer_cast<mac_window_info>(window)->modify_prescale(-1);
+ dynamic_cast<mac_window_info &>(*window).modify_prescale(-1);
if (machine.ui_input().pressed(IPT_OSD_7))
- std::static_pointer_cast<mac_window_info>(window)->modify_prescale(1);
+ dynamic_cast<mac_window_info &>(*window).modify_prescale(1);
if (machine.ui_input().pressed(IPT_OSD_8))
window->renderer().record();
@@ -164,8 +166,6 @@ static void check_osd_inputs(running_machine &machine)
void mac_osd_interface::extract_video_config()
{
- const char *stemp;
-
// global options: extract the data
video_config.windowed = options().window();
video_config.prescale = options().prescale();
@@ -176,37 +176,6 @@ void mac_osd_interface::extract_video_config()
if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)
video_config.windowed = true;
- // default to working video please
- video_config.novideo = 0;
-
- // d3d options: extract the data
- stemp = options().video();
- if (strcmp(stemp, "auto") == 0)
- {
- stemp = "opengl";
- }
-
- if (strcmp(stemp, OSDOPTVAL_NONE) == 0)
- {
- video_config.mode = VIDEO_MODE_SOFT;
- video_config.novideo = 1;
-
- if (!emulator_info::standalone() && options().seconds_to_run() == 0)
- osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
- }
-
- else if (strcmp(stemp, MACOPTVAL_OPENGL) == 0)
- video_config.mode = VIDEO_MODE_OPENGL;
- else if (strcmp(stemp, MACOPTVAL_BGFX) == 0)
- {
- video_config.mode = VIDEO_MODE_BGFX;
- }
- else
- {
- osd_printf_warning("Invalid video value %s; reverting to OpenGL\n", stemp);
- video_config.mode = VIDEO_MODE_OPENGL;
- }
-
video_config.switchres = options().switch_res();
video_config.waitvsync = options().wait_vsync();
video_config.syncrefresh = options().sync_refresh();
@@ -222,57 +191,6 @@ void mac_osd_interface::extract_video_config()
video_config.prescale = 1;
}
- // default to working video please
- video_config.forcepow2texture = options().gl_force_pow2_texture();
- video_config.allowtexturerect = !(options().gl_no_texture_rect());
- video_config.vbo = options().gl_vbo();
- video_config.pbo = options().gl_pbo();
- video_config.glsl = options().gl_glsl();
- if ( video_config.glsl )
- {
- int i;
- video_config.glsl_filter = options().glsl_filter();
- video_config.glsl_shader_mamebm_num=0;
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- stemp = options().shader_mame(i);
- if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
- {
- video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1);
- strcpy(video_config.glsl_shader_mamebm[i], stemp);
- video_config.glsl_shader_mamebm_num++;
- } else {
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- }
- video_config.glsl_shader_scrn_num=0;
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- stemp = options().shader_screen(i);
- if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
- {
- video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1);
- strcpy(video_config.glsl_shader_scrn[i], stemp);
- video_config.glsl_shader_scrn_num++;
- } else {
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
- } else {
- int i;
- video_config.glsl_filter = 0;
- video_config.glsl_shader_mamebm_num=0;
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- video_config.glsl_shader_scrn_num=0;
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
-
// misc options: sanity check values
// global options: sanity check values
diff --git a/src/osd/mac/window.cpp b/src/osd/mac/window.cpp
index ea2adbb631f..f8d95a40205 100644
--- a/src/osd/mac/window.cpp
+++ b/src/osd/mac/window.cpp
@@ -27,8 +27,6 @@
#include "window.h"
#include "osdmac.h"
-#include "modules/render/drawbgfx.h"
-#include "modules/render/drawogl.h"
#include "modules/monitor/monitor_common.h"
//============================================================
@@ -115,7 +113,7 @@ bool mac_osd_interface::window_init()
void mac_osd_interface::update_slider_list()
{
- for (auto window : osd_common_t::s_window_list)
+ for (auto const &window : osd_common_t::window_list())
{
// check if any window has dirty sliders
if (window->renderer().sliders_dirty())
@@ -130,7 +128,7 @@ void mac_osd_interface::build_slider_list()
{
m_sliders.clear();
- for (auto window : osd_common_t::s_window_list)
+ for (auto const &window : osd_common_t::window_list())
{
std::vector<ui::menu_item> window_sliders = window->renderer().get_slider_list();
m_sliders.insert(m_sliders.end(), window_sliders.begin(), window_sliders.end());
@@ -149,23 +147,11 @@ void mac_osd_interface::window_exit()
// free all the windows
while (!osd_common_t::s_window_list.empty())
{
- auto window = osd_common_t::s_window_list.front();
-
- // Part of destroy removes the window from the list
+ auto window = std::move(osd_common_t::s_window_list.back());
+ s_window_list.pop_back();
window->destroy();
}
- switch(video_config.mode)
- {
- case VIDEO_MODE_BGFX:
- renderer_bgfx::exit();
- break;
- case VIDEO_MODE_OPENGL:
- renderer_ogl::exit();
- break;
- default:
- break;
- }
osd_printf_verbose("Leave macwindow_exit\n");
}
@@ -256,7 +242,7 @@ void mac_window_info::toggle_full_screen()
downcast<mac_osd_interface &>(machine().osd()).release_keys();
- set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
+ renderer_create();
// toggle the window mode
set_fullscreen(!fullscreen());
@@ -338,7 +324,7 @@ int mac_window_info::window_init()
create_target();
- set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast<osd_window*>(this)->shared_from_this()));
+ renderer_create();
result = complete_create();
@@ -586,24 +572,6 @@ int mac_window_info::complete_create()
set_platform_window(window);
- // set main window
- if (index() > 0)
- {
- for (auto w : osd_common_t::s_window_list)
- {
- if (w->index() == 0)
- {
- set_main_window(std::dynamic_pointer_cast<osd_window>(w));
- break;
- }
- }
- }
- else
- {
- // We must be the main window
- set_main_window(shared_from_this());
- }
-
// update monitor resolution after mode change to ensure proper pixel aspect
monitor()->refresh();
if (fullscreen() && video_config.switchres)
@@ -909,10 +877,11 @@ osd_dim mac_window_info::get_max_bounds(int constrain)
mac_window_info::mac_window_info(
running_machine &a_machine,
+ render_module &renderprovider,
int index,
std::shared_ptr<osd_monitor_info> a_monitor,
const osd_window_config *config)
- : osd_window_t(a_machine, index, a_monitor, *config)
+ : osd_window_t(a_machine, renderprovider, index, a_monitor, *config)
, m_startmaximized(0)
// Following three are used by input code to defer resizes
, m_minimum_dim(0, 0)
diff --git a/src/osd/mac/window.h b/src/osd/mac/window.h
index e93257aa132..0c08784667d 100644
--- a/src/osd/mac/window.h
+++ b/src/osd/mac/window.h
@@ -8,8 +8,10 @@
//
//============================================================
-#ifndef __MACWINDOW__
-#define __MACWINDOW__
+#ifndef MAME_OSD_MAC_WINDOW_H
+#define MAME_OSD_MAC_WINDOW_H
+
+#pragma once
#include "osdmac.h"
#include "osdsync.h"
@@ -90,25 +92,4 @@ private:
void measure_fps(int update);
};
-struct osd_draw_callbacks
-{
- osd_renderer *(*create)(osd_window *window);
-};
-
-//============================================================
-// PROTOTYPES
-//============================================================
-
-//============================================================
-// PROTOTYPES - drawogl.c
-//============================================================
-
-int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks);
-
-//============================================================
-// PROTOTYPES - drawbgfx.c
-//============================================================
-
-int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks);
-
-#endif /* __MACWINDOW__ */
+#endif // MAME_OSD_MAC_WINDOW_H
diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp
index 756aa7a5dd8..2793452dbe6 100644
--- a/src/osd/modules/debugger/debugwin.cpp
+++ b/src/osd/modules/debugger/debugwin.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// debugwin.c - Win32 debug window handling
+// debugwin.cpp - Win32 debug window handling
//
//============================================================
@@ -156,7 +156,7 @@ void debugger_windows::wait_for_debugger(device_t &device, bool firststop)
// set the starting position for new auxiliary windows
HMONITOR const nearest_monitor = MonitorFromWindow(
- std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(),
+ dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window(),
MONITOR_DEFAULTTONEAREST);
if (nearest_monitor)
{
@@ -321,7 +321,7 @@ void debugger_windows::show_all()
void debugger_windows::hide_all()
{
- SetForegroundWindow(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window());
+ SetForegroundWindow(dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window());
for (auto &info : m_window_list)
info->hide();
}
diff --git a/src/osd/modules/debugger/win/debugwininfo.cpp b/src/osd/modules/debugger/win/debugwininfo.cpp
index 473236fcd8d..8c3275a7549 100644
--- a/src/osd/modules/debugger/win/debugwininfo.cpp
+++ b/src/osd/modules/debugger/win/debugwininfo.cpp
@@ -47,7 +47,7 @@ debugwin_info::debugwin_info(debugger_windows_interface &debugger, bool is_main_
m_wnd = win_create_window_ex_utf8(
DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
0, 0, 100, 100,
- std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(),
+ dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window(),
create_standard_menubar(),
GetModuleHandleUni(),
this);
diff --git a/src/osd/modules/font/font_module.h b/src/osd/modules/font/font_module.h
index 81ffaca74e5..7fe04e32628 100644
--- a/src/osd/modules/font/font_module.h
+++ b/src/osd/modules/font/font_module.h
@@ -24,7 +24,7 @@
class font_module
{
public:
- virtual ~font_module() { }
+ virtual ~font_module() = default;
/** attempt to allocate a font instance */
virtual osd_font::ptr font_alloc() = 0;
diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp
index 93b1f233000..31a36fc841a 100644
--- a/src/osd/modules/input/input_dinput.cpp
+++ b/src/osd/modules/input/input_dinput.cpp
@@ -625,11 +625,11 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a
HWND window_handle;
DWORD di_cooperative_level;
#if defined(OSD_WINDOWS)
- auto const window = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front());
- bool const standalone_window = window && !window->attached_mode();
+ auto const &window = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front());
+ bool const standalone_window = !window.attached_mode();
#elif defined(SDLMAME_WIN32)
- auto const window = std::static_pointer_cast<sdl_window_info>(osd_common_t::s_window_list.front());
- bool const standalone_window = bool(window);
+ auto const &window = dynamic_cast<sdl_window_info &>(*osd_common_t::window_list().front());
+ bool const standalone_window = true;
#endif
if (!standalone_window)
{
@@ -640,12 +640,13 @@ std::pair<Microsoft::WRL::ComPtr<IDirectInputDevice8>, LPCDIDATAFORMAT> dinput_a
else
{
#if defined(OSD_WINDOWS)
- window_handle = window->platform_window();
+ window_handle = window.platform_window();
#elif defined(SDLMAME_WIN32)
- auto const sdlwindow = window->platform_window();
+ auto const sdlwindow = window.platform_window();
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
- SDL_GetWindowWMInfo(sdlwindow, &info);
+ if (!SDL_GetWindowWMInfo(sdlwindow, &info))
+ return std::make_pair(nullptr, nullptr);
window_handle = info.info.win.window;
#endif
switch (cooperative_level)
diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp
index 804f4ae53cd..910e1873a76 100644
--- a/src/osd/modules/input/input_rawinput.cpp
+++ b/src/osd/modules/input/input_rawinput.cpp
@@ -595,7 +595,7 @@ public:
registration.dwFlags = RIDEV_DEVNOTIFY;
if (background_input())
registration.dwFlags |= RIDEV_INPUTSINK;
- registration.hwndTarget = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
+ registration.hwndTarget = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
// register the device
RegisterRawInputDevices(&registration, 1, sizeof(registration));
diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp
index 92281f1cf49..a98d928ba5a 100644
--- a/src/osd/modules/input/input_win32.cpp
+++ b/src/osd/modules/input/input_win32.cpp
@@ -154,7 +154,9 @@ public:
m_mouse.lY = (cursor_info.ptScreenPos.y - m_win32_mouse.last_point.y) * INPUT_RELATIVE_PER_PIXEL;
RECT window_pos = {0};
- GetWindowRect(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(), &window_pos);
+ GetWindowRect(
+ dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window(),
+ &window_pos);
// We reset the cursor position to the middle of the window each frame
m_win32_mouse.last_point.x = window_pos.left + (window_pos.right - window_pos.left) / 2;
@@ -326,10 +328,10 @@ public:
// get the cursor position and transform into final results
POINT mousepos;
GetCursorPos(&mousepos);
- if (!osd_common_t::s_window_list.empty())
+ if (!osd_common_t::window_list().empty())
{
// get the position relative to the window
- HWND const hwnd = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
+ HWND const hwnd = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
RECT client_rect;
GetClientRect(hwnd, &client_rect);
ScreenToClient(hwnd, &mousepos);
@@ -390,7 +392,7 @@ protected:
if (args.keydown)
{
// get the position relative to the window
- HWND const hwnd = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
+ HWND const hwnd = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
RECT client_rect;
GetClientRect(hwnd, &client_rect);
diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp
index de6c0a4f2fd..92eacddc739 100644
--- a/src/osd/modules/lib/osdobj_common.cpp
+++ b/src/osd/modules/lib/osdobj_common.cpp
@@ -10,12 +10,14 @@
#include "osdobj_common.h"
+#include "modules/osdwindow.h"
#include "modules/debugger/debug_module.h"
#include "modules/font/font_module.h"
#include "modules/input/input_module.h"
#include "modules/midi/midi_module.h"
#include "modules/monitor/monitor_module.h"
#include "modules/netdev/netdev_module.h"
+#include "modules/render/render_module.h"
#include "modules/sound/sound_module.h"
#include "osdnet.h"
@@ -66,7 +68,6 @@ const options_entry osd_options::s_option_entries[] =
{ OSDOPTION_BENCH, "0", core_options::option_type::INTEGER, "benchmark for the given number of emulated seconds; implies -video none -sound none -nothrottle" },
{ nullptr, nullptr, core_options::option_type::HEADER, "OSD VIDEO OPTIONS" },
-// OS X can be trusted to have working hardware OpenGL, so default to it on for the best user experience
{ OSDOPTION_VIDEO, OSDOPTVAL_AUTO, core_options::option_type::STRING, "video output method: " },
{ OSDOPTION_NUMSCREENS "(1-4)", "1", core_options::option_type::INTEGER, "number of output screens/windows to create; usually, you want just one" },
{ OSDOPTION_WINDOW ";w", "0", core_options::option_type::BOOLEAN, "enable window mode; otherwise, full screen mode is assumed" },
@@ -181,7 +182,7 @@ const options_entry osd_options::s_option_entries[] =
{ OSDOPTION_BGFX_LUT, "lut-default.png", core_options::option_type::STRING, "LUT texture name" },
{ OSDOPTION_BGFX_AVI_NAME, OSDOPTVAL_AUTO, core_options::option_type::PATH, "filename for BGFX output logging" },
- // End of list
+ // End of list
{ nullptr }
};
@@ -192,7 +193,7 @@ osd_options::osd_options()
}
// Window list
-std::list<std::shared_ptr<osd_window>> osd_common_t::s_window_list;
+std::list<std::unique_ptr<osd_window> > osd_common_t::s_window_list;
//-------------------------------------------------
// osd_interface - constructor
@@ -237,6 +238,26 @@ void osd_common_t::register_options()
REGISTER_MODULE(m_mod_man, FONT_SDL);
REGISTER_MODULE(m_mod_man, FONT_NONE);
+#if defined(SDLMAME_EMSCRIPTEN)
+ REGISTER_MODULE(m_mod_man, RENDERER_SDL1); // don't bother trying to use video acceleration in browsers
+#endif
+#if defined(OSD_WINDOWS)
+ REGISTER_MODULE(m_mod_man, RENDERER_D3D); // this is only built for OSD=windows, there's no dummy stub
+#endif
+#if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
+ REGISTER_MODULE(m_mod_man, RENDERER_BGFX); // try BGFX before GDI on windows to get DirectX 10/11 acceleration
+#endif
+ REGISTER_MODULE(m_mod_man, RENDERER_GDI); // GDI ahead of OpenGL as there's a chance Windows has no OpenGL
+ REGISTER_MODULE(m_mod_man, RENDERER_OPENGL);
+#if !defined(OSD_WINDOWS) && !defined(SDLMAME_WIN32)
+ REGISTER_MODULE(m_mod_man, RENDERER_BGFX); // try BGFX after OpenGL on other operating systems for now
+#endif
+ REGISTER_MODULE(m_mod_man, RENDERER_SDL2);
+#if !defined(SDLMAME_EMSCRIPTEN)
+ REGISTER_MODULE(m_mod_man, RENDERER_SDL1);
+#endif
+ REGISTER_MODULE(m_mod_man, RENDERER_NONE);
+
REGISTER_MODULE(m_mod_man, SOUND_DSOUND);
REGISTER_MODULE(m_mod_man, SOUND_XAUDIO2);
REGISTER_MODULE(m_mod_man, SOUND_COREAUDIO);
@@ -306,23 +327,18 @@ void osd_common_t::register_options()
// after initialization we know which modules are supported
-
- update_option(OSD_MONITOR_PROVIDER, m_mod_man.get_module_names(OSD_MONITOR_PROVIDER));
update_option(OSD_FONT_PROVIDER, m_mod_man.get_module_names(OSD_FONT_PROVIDER));
+ update_option(OSD_RENDERER_PROVIDER, m_mod_man.get_module_names(OSD_RENDERER_PROVIDER));
+ update_option(OSD_SOUND_PROVIDER, m_mod_man.get_module_names(OSD_SOUND_PROVIDER));
+ update_option(OSD_MONITOR_PROVIDER, m_mod_man.get_module_names(OSD_MONITOR_PROVIDER));
update_option(OSD_KEYBOARDINPUT_PROVIDER, m_mod_man.get_module_names(OSD_KEYBOARDINPUT_PROVIDER));
update_option(OSD_MOUSEINPUT_PROVIDER, m_mod_man.get_module_names(OSD_MOUSEINPUT_PROVIDER));
update_option(OSD_LIGHTGUNINPUT_PROVIDER, m_mod_man.get_module_names(OSD_LIGHTGUNINPUT_PROVIDER));
update_option(OSD_JOYSTICKINPUT_PROVIDER, m_mod_man.get_module_names(OSD_JOYSTICKINPUT_PROVIDER));
- update_option(OSD_SOUND_PROVIDER, m_mod_man.get_module_names(OSD_SOUND_PROVIDER));
update_option(OSD_MIDI_PROVIDER, m_mod_man.get_module_names(OSD_MIDI_PROVIDER));
update_option(OSD_NETDEV_PROVIDER, m_mod_man.get_module_names(OSD_NETDEV_PROVIDER));
update_option(OSD_DEBUG_PROVIDER, m_mod_man.get_module_names(OSD_DEBUG_PROVIDER));
update_option(OSD_OUTPUT_PROVIDER, m_mod_man.get_module_names(OSD_OUTPUT_PROVIDER));
-
- // Register video options and update options
- video_options_add("none", nullptr);
- video_register();
- update_option(OSDOPTION_VIDEO, m_video_names);
}
void osd_common_t::update_option(const std::string &key, std::vector<std::string_view> const &values)
@@ -575,28 +591,18 @@ bool osd_common_t::execute_command(const char *command)
{
if (strcmp(command, OSDCOMMAND_LIST_NETWORK_ADAPTERS) == 0)
{
- osd_module *om = select_module_options(options(), OSD_NETDEV_PROVIDER);
-
- if (om->probe())
- {
- om->init(*this, options());
- osd_list_network_adapters();
- om->exit();
- }
+ osd_module &om = select_module_options<osd_module>(OSD_NETDEV_PROVIDER);
+ osd_list_network_adapters();
+ om.exit();
return true;
}
else if (strcmp(command, OSDCOMMAND_LIST_MIDI_DEVICES) == 0)
{
- osd_module *om = select_module_options(options(), OSD_MIDI_PROVIDER);
- auto *pm = select_module_options<midi_module *>(options(), OSD_MIDI_PROVIDER);
+ osd_module &om = select_module_options<osd_module>(OSD_MIDI_PROVIDER);
+ dynamic_cast<midi_module &>(om).list_midi_devices();
+ om.exit();
- if (om->probe())
- {
- om->init(*this, options());
- pm->list_midi_devices();
- om->exit();
- }
return true;
}
@@ -612,10 +618,10 @@ static void output_notifier_callback(const char *outname, int32_t value, void *p
void osd_common_t::init_subsystems()
{
// monitors have to be initialized before video init
- m_monitor_module = select_module_options<monitor_module *>(options(), OSD_MONITOR_PROVIDER);
- assert(m_monitor_module != nullptr);
- m_monitor_module->init(*this, options());
+ m_monitor_module = &select_module_options<monitor_module>(OSD_MONITOR_PROVIDER);
+ // various modules depend on having a window handle
+ m_render = &select_module_options<render_module>(OSD_RENDERER_PROVIDER);
if (!video_init())
{
video_exit();
@@ -625,28 +631,23 @@ void osd_common_t::init_subsystems()
exit(-1);
}
- m_keyboard_input = select_module_options<input_module *>(options(), OSD_KEYBOARDINPUT_PROVIDER);
- m_mouse_input = select_module_options<input_module *>(options(), OSD_MOUSEINPUT_PROVIDER);
- m_lightgun_input = select_module_options<input_module *>(options(), OSD_LIGHTGUNINPUT_PROVIDER);
- m_joystick_input = select_module_options<input_module *>(options(), OSD_JOYSTICKINPUT_PROVIDER);
+ m_keyboard_input = &select_module_options<input_module>(OSD_KEYBOARDINPUT_PROVIDER);
+ m_mouse_input = &select_module_options<input_module>(OSD_MOUSEINPUT_PROVIDER);
+ m_lightgun_input = &select_module_options<input_module>(OSD_LIGHTGUNINPUT_PROVIDER);
+ m_joystick_input = &select_module_options<input_module>(OSD_JOYSTICKINPUT_PROVIDER);
- m_font_module = select_module_options<font_module *>(options(), OSD_FONT_PROVIDER);
- m_sound = select_module_options<sound_module *>(options(), OSD_SOUND_PROVIDER);
- m_sound->m_sample_rate = options().sample_rate();
- m_sound->m_audio_latency = options().audio_latency();
+ m_font_module = &select_module_options<font_module>(OSD_FONT_PROVIDER);
+ m_sound = &select_module_options<sound_module>(OSD_SOUND_PROVIDER);
- m_debugger = select_module_options<debug_module *>(options(), OSD_DEBUG_PROVIDER);
+ m_debugger = &select_module_options<debug_module>(OSD_DEBUG_PROVIDER);
- select_module_options<netdev_module *>(options(), OSD_NETDEV_PROVIDER);
+ select_module_options<netdev_module>(OSD_NETDEV_PROVIDER);
- m_midi = select_module_options<midi_module *>(options(), OSD_MIDI_PROVIDER);
+ m_midi = &select_module_options<midi_module>(OSD_MIDI_PROVIDER);
- m_output = select_module_options<output_module *>(options(), OSD_OUTPUT_PROVIDER);
- m_output->set_machine(&machine());
+ m_output = &select_module_options<output_module>(OSD_OUTPUT_PROVIDER);
machine().output().set_global_notifier(output_notifier_callback, this);
- m_mod_man.init(*this, options());
-
input_init();
}
@@ -665,10 +666,6 @@ bool osd_common_t::no_sound()
return (strcmp(options().sound(),"none")==0) ? true : false;
}
-void osd_common_t::video_register()
-{
-}
-
bool osd_common_t::input_init()
{
m_keyboard_input->input_init(machine());
@@ -693,17 +690,15 @@ void osd_common_t::window_exit()
void osd_common_t::osd_exit()
{
+ // destroy the renderers before shutting down their parent module
+ for (auto const &window : s_window_list)
+ window->renderer_reset();
+
m_mod_man.exit();
exit_subsystems();
}
-void osd_common_t::video_options_add(const char *name, void *type)
-{
- //m_video_options.add(name, type, false);
- m_video_names.push_back(name);
-}
-
osd_font::ptr osd_common_t::font_alloc()
{
return m_font_module->font_alloc();
diff --git a/src/osd/modules/lib/osdobj_common.h b/src/osd/modules/lib/osdobj_common.h
index d90435a884e..33013d43025 100644
--- a/src/osd/modules/lib/osdobj_common.h
+++ b/src/osd/modules/lib/osdobj_common.h
@@ -190,15 +190,16 @@ public:
// ======================> osd_interface
-class font_module;
-class sound_module;
class debug_module;
-class midi_module;
+class font_module;
class input_module;
-class output_module;
+class midi_module;
class monitor_module;
class osd_watchdog;
class osd_window;
+class output_module;
+class render_module;
+class sound_module;
// description of the currently-running machine
class osd_common_t : public osd_interface, osd_output
@@ -250,7 +251,6 @@ public:
virtual void init_subsystems();
virtual bool video_init();
- virtual void video_register();
virtual bool window_init();
virtual void exit_subsystems();
@@ -259,8 +259,6 @@ public:
virtual void osd_exit();
- virtual void video_options_add(const char *name, void *type);
-
virtual osd_options &options() { return m_options; }
// osd_output interface ...
@@ -273,7 +271,7 @@ public:
virtual void process_events() = 0;
virtual bool has_focus() const = 0;
- static std::list<std::shared_ptr<osd_window> > s_window_list;
+ static const std::list<std::unique_ptr<osd_window> > &window_list() { return s_window_list; }
protected:
virtual bool input_init();
@@ -281,6 +279,8 @@ protected:
virtual void build_slider_list() { }
virtual void update_slider_list() { }
+ static std::list<std::unique_ptr<osd_window> > s_window_list;
+
private:
// internal state
running_machine * m_machine;
@@ -293,26 +293,24 @@ private:
void update_option(const std::string &key, std::vector<std::string_view> const &values);
// FIXME: should be elsewhere
- osd_module *select_module_options(const core_options &opts, const std::string &opt_name)
+ template<class C>
+ C &select_module_options(const std::string &opt_name)
{
- std::string opt_val = opts.exists(opt_name) ? opts.value(opt_name) : "";
- if (opt_val.compare("auto")==0)
+ std::string opt_val = options().exists(opt_name) ? options().value(opt_name) : "";
+ if (opt_val == "auto")
+ {
opt_val = "";
+ }
else if (!m_mod_man.type_has_name(opt_name.c_str(), opt_val.c_str()))
{
osd_printf_warning("Value %s not supported for option %s - falling back to auto\n", opt_val, opt_name);
opt_val = "";
}
- return m_mod_man.select_module(opt_name.c_str(), opt_val.c_str());
- }
-
- template<class C>
- C select_module_options(const core_options &opts, const std::string &opt_name)
- {
- return dynamic_cast<C>(select_module_options(opts, opt_name));
+ return m_mod_man.select_module<C>(*this, options(), opt_name.c_str(), opt_val.c_str());
}
protected:
+ render_module* m_render;
sound_module* m_sound;
debug_module* m_debugger;
midi_module* m_midi;
@@ -326,7 +324,6 @@ protected:
std::vector<ui::menu_item> m_sliders;
private:
- std::vector<std::string_view> m_video_names;
std::unordered_map<std::string, std::string> m_option_descs;
};
diff --git a/src/osd/modules/osdmodule.cpp b/src/osd/modules/osdmodule.cpp
index 8e3d2f0e3c8..0fb43d4331a 100644
--- a/src/osd/modules/osdmodule.cpp
+++ b/src/osd/modules/osdmodule.cpp
@@ -7,6 +7,8 @@
#include "modules/osdmodule.h"
+#include "emucore.h"
+
#include "osdcore.h"
#include <algorithm>
@@ -48,20 +50,62 @@ osd_module *osd_module_manager::get_module_generic(const char *type, const char
return nullptr;
}
-osd_module *osd_module_manager::select_module(const char *type, const char *name)
+osd_module &osd_module_manager::select_module(osd_interface &osd, const osd_options &options, const char *type, const char *name)
{
- osd_module *m = get_module_generic(type, name);
+ // see if a module of this type has already been already selected
+ for (osd_module &existing : m_selected)
+ {
+ if (existing.type() == type)
+ {
+ osd_printf_warning(
+ "Attempt to select %s module %s after selecting module %s\n",
+ type,
+ (name && *name) ? name : "<default>",
+ existing.name());
+ return existing;
+ }
+ }
- // FIXME: check if already exists!
+ // try to start the selected module
+ osd_module *const m = get_module_generic(type, name);
if (m)
- m_selected.emplace_back(*m);
- return m;
-}
+ {
+ //osd_printf_verbose("Attempting to initialize %s module %s\n", type, m->name());
+ if (!m->init(osd, options))
+ {
+ m_selected.emplace_back(*m);
+ return *m;
+ }
+ osd_printf_verbose("Initializing %s module %s failed\n", type, m->name());
+ }
+ else
+ {
+ osd_printf_verbose("Could not find %s module %s\n", type, name ? name : "<default>");
+ }
-void osd_module_manager::init(osd_interface &osd, const osd_options &options)
-{
- for (osd_module &m : m_selected)
- m.init(osd, options);
+ // walk down the list until something works
+ for (auto const &fallback : m_modules)
+ {
+ if ((fallback->type() == type) && (fallback.get() != m))
+ {
+ osd_printf_verbose("Attempting to initialize %s module %s\n", type, fallback->name());
+ if (!fallback->init(osd, options))
+ {
+ osd_printf_warning(
+ m
+ ? "Initializing %s module %s failed, falling back to %s\n"
+ : "Could not find %s module %s, falling back to %s\n",
+ type,
+ m ? m->name() : (name && *name) ? name : "<default>",
+ fallback->name());
+ m_selected.emplace_back(*fallback);
+ return *fallback;
+ }
+ }
+ }
+
+ // can't deal with absence of a module, and at least the "none" module should have worked
+ throw emu_fatalerror("All %s modules failed to initialize", type);
}
void osd_module_manager::exit()
diff --git a/src/osd/modules/osdmodule.h b/src/osd/modules/osdmodule.h
index 04373dc531f..b690f874706 100644
--- a/src/osd/modules/osdmodule.h
+++ b/src/osd/modules/osdmodule.h
@@ -78,17 +78,15 @@ public:
osd_module *get_module_generic(const char *type, const char *name);
template<class C>
- C select_module(const char *type, const char *name = "")
+ C &select_module(osd_interface &osd, const osd_options &options, const char *type, const char *name = "")
{
- return dynamic_cast<C>(select_module(type, name));
+ return dynamic_cast<C &>(select_module(osd, options, type, name));
}
- osd_module *select_module(const char *type, const char *name = "");
+ osd_module &select_module(osd_interface &osd, const osd_options &options, const char *type, const char *name = "");
std::vector<std::string_view> get_module_names(const char *type) const;
- void init(osd_interface &osd, const osd_options &options);
-
void exit();
private:
diff --git a/src/osd/modules/osdwindow.cpp b/src/osd/modules/osdwindow.cpp
index 928c3f2c76b..3b2c92c39ea 100644
--- a/src/osd/modules/osdwindow.cpp
+++ b/src/osd/modules/osdwindow.cpp
@@ -12,25 +12,19 @@
// osd/modules
#include "lib/osdobj_common.h"
#include "monitor/monitor_module.h"
-
-#include "render/drawnone.h"
-#include "render/drawbgfx.h"
-#if (USE_OPENGL)
-#include "render/drawogl.h"
-#endif
-#if defined(OSD_WINDOWS)
-#include "render/drawgdi.h"
-#include "render/drawd3d.h"
-#elif defined(OSD_SDL)
-#include "render/draw13.h"
-#include "render/drawsdl.h"
-#endif
+#include "render/render_module.h"
// emu
#include "main.h"
+#include "render.h"
-osd_window::osd_window(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config &config) :
+osd_window::osd_window(
+ running_machine &machine,
+ render_module &renderprovider,
+ int index,
+ const std::shared_ptr<osd_monitor_info> &monitor,
+ const osd_window_config &config) :
#ifdef OSD_WINDOWS
m_dc(nullptr), m_resize_state(0),
#endif
@@ -41,22 +35,26 @@ osd_window::osd_window(running_machine &machine, int index, std::shared_ptr<osd_
m_fullscreen(false),
m_prescale(1),
m_machine(machine),
+ m_renderprovider(renderprovider),
m_monitor(std::move(monitor)),
m_renderer(nullptr),
- m_main(nullptr),
m_title(
util::string_format(
(video_config.numscreens > 1)
? "%3$s [%4$s] screen %5$d - %1$s %2$s (%6$s%7$sP%8$d)"
: "%3$s [%4$s] - %1$s %2$s (%6$s%7$sP%8$d)",
- emulator_info::get_appname(),
- emulator_info::get_bare_build_version(),
- machine.system().type.fullname(),
- machine.system().name,
- index,
- (sizeof(int) == sizeof(void *)) ? "I" : "",
- (sizeof(long) == sizeof(void *)) ? "L" : (sizeof(long long) == sizeof(void *)) ? "LL" : "",
- sizeof(void *) * 8))
+ emulator_info::get_appname(),
+ emulator_info::get_bare_build_version(),
+ machine.system().type.fullname(),
+ machine.system().name,
+ index,
+ (sizeof(int) == sizeof(void *)) ? "I" : "",
+ (sizeof(long) == sizeof(void *)) ? "L" : (sizeof(long long) == sizeof(void *)) ? "LL" : "",
+ sizeof(void *) * 8))
+{
+}
+
+osd_window::~osd_window()
{
}
@@ -82,36 +80,6 @@ bool osd_window::keepaspect() const
return false;
}
-std::unique_ptr<osd_renderer> osd_renderer::make_for_type(int mode, std::shared_ptr<osd_window> window, int extra_flags)
-{
- switch(mode)
- {
-#if defined(OSD_WINDOWS)
- case VIDEO_MODE_NONE:
- return std::make_unique<renderer_none>(window);
-#endif
- case VIDEO_MODE_BGFX:
- return std::make_unique<renderer_bgfx>(window);
-#if (USE_OPENGL)
- case VIDEO_MODE_OPENGL:
- return std::make_unique<renderer_ogl>(window);
-#endif
-#if defined(OSD_WINDOWS)
- case VIDEO_MODE_GDI:
- return std::make_unique<renderer_gdi>(window);
- case VIDEO_MODE_D3D:
- return std::make_unique<renderer_d3d9>(window);
-#elif defined(OSD_SDL)
- case VIDEO_MODE_SDL2ACCEL:
- return std::make_unique<renderer_sdl2>(window, extra_flags);
- case VIDEO_MODE_SOFT:
- return std::make_unique<renderer_sdl1>(window, extra_flags);
-#endif
- default:
- return nullptr;
- }
-}
-
std::shared_ptr<osd_monitor_info> osd_window::monitor_from_rect(const osd_rect *proposed) const
{
std::shared_ptr<osd_monitor_info> monitor;
@@ -128,9 +96,6 @@ std::shared_ptr<osd_monitor_info> osd_window::monitor_from_rect(const osd_rect *
void osd_window::create_target()
{
- // add us to the list
- osd_common_t::s_window_list.push_back(shared_from_this());
-
// load the layout
m_target = m_machine.render().target_alloc();
@@ -139,6 +104,21 @@ void osd_window::create_target()
set_starting_view(m_index, options.view(), options.view(m_index));
}
+bool osd_window::renderer_interactive() const
+{
+ return m_renderprovider.is_interactive();
+}
+
+bool osd_window::renderer_sdl_needs_opengl() const
+{
+ return m_renderprovider.sdl_needs_opengl();
+}
+
+void osd_window::renderer_create()
+{
+ m_renderer = m_renderprovider.create(*this);
+}
+
void osd_window::set_starting_view(int index, const char *defview, const char *view)
{
// choose non-auto over auto
@@ -154,9 +134,6 @@ void osd_window::set_starting_view(int index, const char *defview, const char *v
void osd_window::destroy()
{
- // remove us from the list
- osd_common_t::s_window_list.remove(shared_from_this());
-
// free the textures etc
complete_destroy();
diff --git a/src/osd/modules/osdwindow.h b/src/osd/modules/osdwindow.h
index 9bf7db4e77c..13baf050cbb 100644
--- a/src/osd/modules/osdwindow.h
+++ b/src/osd/modules/osdwindow.h
@@ -6,13 +6,19 @@
//
//============================================================
-#ifndef __OSDWINDOW__
-#define __OSDWINDOW__
+#ifndef MAME_OSD_MODULES_OSDWINDOW_H
+#define MAME_OSD_MODULES_OSDWINDOW_H
+
+#pragma once
#include "emucore.h"
#include "osdhelper.h"
#include "../frontend/mame/ui/menuitem.h"
+#include <memory>
+#include <string>
+#include <vector>
+
// standard windows headers
#ifdef OSD_WINDOWS
#include <windows.h>
@@ -24,23 +30,12 @@
// TYPE DEFINITIONS
//============================================================
-class osd_options;
+class osd_monitor_info;
+class render_module;
class render_primitive_list;
-enum
-{
- VIDEO_MODE_NONE = 0,
- VIDEO_MODE_GDI,
- VIDEO_MODE_BGFX,
-#if defined(USE_OPENGL) && USE_OPENGL
- VIDEO_MODE_OPENGL,
-#endif
- VIDEO_MODE_SDL2ACCEL,
- VIDEO_MODE_D3D,
- VIDEO_MODE_SOFT,
+class osd_renderer;
- VIDEO_MODE_COUNT
-};
class osd_window_config
{
@@ -54,15 +49,11 @@ public:
int refresh; // decoded refresh
};
-class osd_renderer;
-class osd_monitor_info;
-class osd_window : public std::enable_shared_from_this<osd_window>
+class osd_window
{
public:
- osd_window(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config &config);
-
- virtual ~osd_window() { }
+ virtual ~osd_window();
render_target *target() const { return m_target; }
int fullscreen() const { return m_fullscreen; }
@@ -71,11 +62,7 @@ public:
bool has_renderer() const { return m_renderer != nullptr; }
osd_renderer &renderer() const { return *m_renderer; }
- void set_renderer(std::unique_ptr<osd_renderer> renderer)
- {
- m_renderer = std::move(renderer);
- }
- void renderer_reset() { m_renderer.reset(); }
+ void renderer_reset() { m_renderer.reset(); } // public because OSD object calls it directly during teardown
int index() const { return m_index; }
int prescale() const { return m_prescale; }
@@ -91,9 +78,6 @@ public:
osd_monitor_info *monitor() const { return m_monitor.get(); }
std::shared_ptr<osd_monitor_info> monitor_from_rect(const osd_rect *proposed) const;
- std::shared_ptr<osd_window> main_window() const { return m_main; }
- void set_main_window(std::shared_ptr<osd_window> main) { m_main = main; }
-
void create_target();
void destroy();
@@ -109,6 +93,18 @@ public:
virtual void update() = 0;
virtual void complete_destroy() = 0;
+protected:
+ osd_window(
+ running_machine &machine,
+ render_module &renderprovider,
+ int index,
+ const std::shared_ptr<osd_monitor_info> &monitor,
+ const osd_window_config &config);
+
+ bool renderer_interactive() const;
+ bool renderer_sdl_needs_opengl() const;
+ void renderer_create();
+
private:
void set_starting_view(int index, const char *defview, const char *view);
@@ -127,33 +123,32 @@ private:
protected:
bool m_fullscreen;
int m_prescale;
+
private:
- running_machine &m_machine;
- std::shared_ptr<osd_monitor_info> m_monitor;
- std::unique_ptr<osd_renderer> m_renderer;
- std::shared_ptr<osd_window> m_main;
- const std::string m_title;
+ running_machine &m_machine;
+ render_module &m_renderprovider;
+ std::shared_ptr<osd_monitor_info> m_monitor;
+ std::unique_ptr<osd_renderer> m_renderer;
+ const std::string m_title;
};
template <class TWindowHandle>
class osd_window_t : public osd_window
{
-private:
- TWindowHandle m_platform_window;
public:
- osd_window_t(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config &config)
- : osd_window(machine, index, std::move(monitor), config),
- m_platform_window(nullptr)
- {
- }
-
TWindowHandle platform_window() const { return m_platform_window; }
+protected:
+ using osd_window::osd_window;
+
void set_platform_window(TWindowHandle window)
{
assert(window == nullptr || m_platform_window == nullptr);
m_platform_window = window;
}
+
+private:
+ TWindowHandle m_platform_window = nullptr;
};
@@ -163,31 +158,13 @@ public:
/* Generic flags */
static const int FLAG_NONE = 0x0000;
- static const int FLAG_NEEDS_OPENGL = 0x0001;
- static const int FLAG_HAS_VECTOR_SCREEN = 0x0002;
-
- /* SDL 1.2 flags */
- static const int FLAG_NEEDS_DOUBLEBUF = 0x0100;
- static const int FLAG_NEEDS_ASYNCBLIT = 0x0200;
+ static const int FLAG_HAS_VECTOR_SCREEN = 0x0001;
- osd_renderer(std::shared_ptr<osd_window> window, const int flags)
- : m_sliders_dirty(false), m_window(window), m_flags(flags)
- { }
+ osd_renderer(osd_window &window) : m_sliders_dirty(false), m_window(window), m_flags(0) { }
virtual ~osd_renderer() { }
- std::shared_ptr<osd_window> assert_window() const
- {
- auto win = m_window.lock();
- if (!win)
- throw emu_fatalerror("osd_renderer::assert_window: Window weak_ptr is not available!");
- return win;
- }
-
- std::shared_ptr<osd_window> try_getwindow() const
- {
- return m_window.lock();
- }
+ osd_window &window() const { return m_window; }
bool has_flags(const int flag) const { return ((m_flags & flag)) == flag; }
void set_flags(int aflag) { m_flags |= aflag; }
@@ -209,8 +186,6 @@ public:
virtual void toggle_fsfx() { }
virtual bool sliders_dirty() { return m_sliders_dirty; }
- static std::unique_ptr<osd_renderer> make_for_type(int mode, std::shared_ptr<osd_window> window, int extra_flags = FLAG_NONE);
-
protected:
virtual void build_slider_list() { }
@@ -220,7 +195,7 @@ protected:
std::vector<ui::menu_item> m_sliders;
private:
- std::weak_ptr<osd_window> m_window;
+ osd_window &m_window;
int m_flags;
};
@@ -232,10 +207,6 @@ private:
#define MAX_VIDEO_WINDOWS (4)
-#define VIDEO_SCALE_MODE_NONE (0)
-
-#define GLSL_SHADER_MAX 10
-
//============================================================
// TYPE DEFINITIONS
@@ -249,35 +220,19 @@ struct osd_video_config
int numscreens; // number of screens
// hardware options
- int mode; // output mode
int waitvsync; // spin until vsync
int syncrefresh; // sync only to refresh rate
int switchres; // switch resolutions
// d3d, accel, opengl
int filter; // enable filtering
- //int filter; // enable filtering, disabled if glsl_filter>0
-
- // OpenGL options
- int glsl;
- int glsl_filter; // glsl filtering, >0 disables filter
- char * glsl_shader_mamebm[GLSL_SHADER_MAX]; // custom glsl shader set, mame bitmap
- int glsl_shader_mamebm_num; // custom glsl shader set number, mame bitmap
- char * glsl_shader_scrn[GLSL_SHADER_MAX]; // custom glsl shader set, screen bitmap
- int glsl_shader_scrn_num; // custom glsl shader number, screen bitmap
- int pbo;
- int vbo;
- int allowtexturerect; // allow GL_ARB_texture_rectangle, default: no
- int forcepow2texture; // force power of two textures, default: no
-
- // dd, d3d
+
+ // d3d
int triplebuf; // triple buffer
//============================================================
// SDL - options
//============================================================
- int novideo; // don't draw, for pure CPU benchmarking
-
int centerh;
int centerv;
@@ -289,9 +244,6 @@ struct osd_video_config
// X11 options
int restrictonemonitor; // in fullscreen, confine to Xinerama monitor 0
-
- // YUV options
- int scale_mode;
};
//============================================================
@@ -300,4 +252,4 @@ struct osd_video_config
extern osd_video_config video_config;
-#endif /* __OSDWINDOW__ */
+#endif // MAME_OSD_MODULES_OSDWINDOW_H
diff --git a/src/osd/modules/output/network.cpp b/src/osd/modules/output/network.cpp
index 5f575682c07..0b3729df340 100644
--- a/src/osd/modules/output/network.cpp
+++ b/src/osd/modules/output/network.cpp
@@ -10,6 +10,7 @@
#include "output_module.h"
+#include "modules/lib/osdobj_common.h"
#include "modules/osdmodule.h"
#include "emu.h"
@@ -25,6 +26,7 @@
#include <set>
#include <thread>
+
namespace osd {
namespace {
@@ -193,8 +195,7 @@ public:
output_network() :
osd_module(OSD_OUTPUT_PROVIDER, "network"),
output_module(),
- m_io_context(nullptr),
- m_server(nullptr)
+ m_machine(nullptr)
{
}
@@ -204,6 +205,7 @@ public:
virtual int init(osd_interface &osd, const osd_options &options) override
{
+ m_machine = &downcast<osd_common_t &>(osd).machine();
m_working_thread = std::thread([] (output_network* self) { self->process_output(); }, this);
return 0;
}
@@ -214,8 +216,9 @@ public:
notify("mame_stop", 1);
m_io_context->stop();
m_working_thread.join();
- delete m_server;
- delete m_io_context;
+ m_server.reset();
+ m_io_context.reset();
+ m_machine = nullptr;
}
// output_module
@@ -230,15 +233,18 @@ public:
// implementation
void process_output()
{
- m_io_context = new asio::io_context();
- m_server = new output_network_server(*m_io_context, 8000, machine());
+ m_io_context.reset(new asio::io_context);
+ m_server.reset(new output_network_server(*m_io_context, 8000, machine()));
m_io_context->run();
}
private:
+ running_machine &machine() { return *m_machine; }
+
std::thread m_working_thread;
- asio::io_context *m_io_context;
- output_network_server *m_server;
+ std::unique_ptr<asio::io_context> m_io_context;
+ std::unique_ptr<output_network_server> m_server;
+ running_machine *m_machine;
};
} // anonymous namespace
diff --git a/src/osd/modules/output/output_module.h b/src/osd/modules/output/output_module.h
index 81655c77824..ae86cfe9084 100644
--- a/src/osd/modules/output/output_module.h
+++ b/src/osd/modules/output/output_module.h
@@ -26,17 +26,9 @@ public:
static inline constexpr unsigned IM_MAME_PAUSE = 0;
static inline constexpr unsigned IM_MAME_SAVESTATE = 1;
- output_module(): m_machine(nullptr) { }
-
virtual ~output_module() = default;
virtual void notify(const char *outname, int32_t value) = 0;
-
- void set_machine(running_machine *machine) { m_machine = machine; }
- running_machine &machine() const { return *m_machine; }
-
-private:
- running_machine *m_machine;
};
#endif // MAME_OSD_OUTPUT_OUTPUT_MODULE_H
diff --git a/src/osd/modules/output/win32_output.cpp b/src/osd/modules/output/win32_output.cpp
index f7814d68dab..0d2d355b577 100644
--- a/src/osd/modules/output/win32_output.cpp
+++ b/src/osd/modules/output/win32_output.cpp
@@ -14,12 +14,12 @@
#include "win32_output.h"
-// MAME headers
-#include "emu.h"
-
#include "winmain.h"
#include "winutil.h"
+// MAME headers
+#include "emu.h"
+
// standard windows headers
#include <windows.h>
@@ -71,7 +71,11 @@ class output_win32 : public osd_module, public output_module
{
public:
output_win32()
- : osd_module(OSD_OUTPUT_PROVIDER, "windows"), output_module(), m_output_hwnd(nullptr), m_clientlist(nullptr)
+ : osd_module(OSD_OUTPUT_PROVIDER, "windows")
+ , output_module()
+ , m_output_hwnd(nullptr)
+ , m_clientlist(nullptr)
+ , m_machine(nullptr)
{
}
virtual ~output_win32() { }
@@ -80,21 +84,23 @@ public:
virtual void exit() override;
// output_module
-
virtual void notify(const char *outname, int32_t value) override;
- int create_window_class();
+ running_machine &machine() { return *m_machine; }
+
LRESULT register_client(HWND hwnd, LPARAM id);
LRESULT unregister_client(HWND hwnd, LPARAM id);
LRESULT send_id_string(HWND hwnd, LPARAM id);
private:
+ int create_window_class();
// our HWND
HWND m_output_hwnd;
// client list
registered_client * m_clientlist;
+ running_machine * m_machine;
};
@@ -104,6 +110,8 @@ private:
int output_win32::init(osd_interface &osd, const osd_options &options)
{
+ m_machine = &downcast<osd_common_t &>(osd).machine();
+
int result;
// reset globals
diff --git a/src/osd/modules/render/aviwrite.h b/src/osd/modules/render/aviwrite.h
index 015dcab4acf..4bf08b769db 100644
--- a/src/osd/modules/render/aviwrite.h
+++ b/src/osd/modules/render/aviwrite.h
@@ -6,15 +6,22 @@
//
//============================================================
+#ifndef MAME_RENDER_AVIWRITE_H
+#define MAME_RENDER_AVIWRITE_H
+
#pragma once
-#ifndef __RENDER_AVIWRITE__
-#define __RENDER_AVIWRITE__
+#include "eminline.h" // attotime.h needs this - add it to attotime.h on the next emu.h update
+
+// emu
+#include "attotime.h"
+// lib/util
#include "aviio.h"
#include <string_view>
+
class running_machine;
class avi_write
@@ -49,4 +56,4 @@ private:
attotime m_next_frame_time;
};
-#endif // __RENDER_AVIWRITE__
+#endif // MAME_RENDER_AVIWRITE_H
diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp
index 6559c346f46..156b46464dd 100644
--- a/src/osd/modules/render/bgfx/chainmanager.cpp
+++ b/src/osd/modules/render/bgfx/chainmanager.cpp
@@ -44,9 +44,6 @@
using namespace rapidjson;
-int32_t chain_manager::s_old_chain_selections[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
-bool chain_manager::s_reinit_cookie = false;
-
chain_manager::screen_prim::screen_prim(render_primitive *prim)
{
m_prim = prim;
@@ -61,8 +58,16 @@ chain_manager::screen_prim::screen_prim(render_primitive *prim)
m_flags = prim->flags;
}
-chain_manager::chain_manager(running_machine& machine, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index,
- slider_dirty_notifier& slider_notifier, uint16_t user_prescale, uint16_t max_prescale_size)
+chain_manager::chain_manager(
+ running_machine& machine,
+ const osd_options& options,
+ texture_manager& textures,
+ target_manager& targets,
+ effect_manager& effects,
+ uint32_t window_index,
+ slider_dirty_notifier& slider_notifier,
+ uint16_t user_prescale,
+ uint16_t max_prescale_size)
: m_machine(machine)
, m_options(options)
, m_textures(textures)
@@ -79,23 +84,10 @@ chain_manager::chain_manager(running_machine& machine, osd_options& options, tex
refresh_available_chains();
parse_chain_selections(options.bgfx_screen_chains());
init_texture_converters();
-
- if (s_reinit_cookie)
- {
- for (uint32_t i = 0; i < std::size(s_old_chain_selections); i++)
- {
- set_current_chain(i, s_old_chain_selections[i]);
- }
- }
}
chain_manager::~chain_manager()
{
- for (uint32_t i = 0; i < std::size(s_old_chain_selections); i++)
- {
- s_old_chain_selections[i] = i < m_current_chain.size() ? m_current_chain[i] : -1;
- }
- s_reinit_cookie = true;
destroy_chains();
}
diff --git a/src/osd/modules/render/bgfx/chainmanager.h b/src/osd/modules/render/bgfx/chainmanager.h
index e63fa9d6db5..eb30e6cc835 100644
--- a/src/osd/modules/render/bgfx/chainmanager.h
+++ b/src/osd/modules/render/bgfx/chainmanager.h
@@ -70,7 +70,7 @@ public:
uint32_t m_flags = 0;
};
- chain_manager(running_machine& machine, osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index,
+ chain_manager(running_machine& machine, const osd_options& options, texture_manager& textures, target_manager& targets, effect_manager& effects, uint32_t window_index,
slider_dirty_notifier& slider_notifier, uint16_t user_prescale, uint16_t max_prescale_size);
~chain_manager();
@@ -79,7 +79,7 @@ public:
// Getters
running_machine& machine() const { return m_machine; }
- osd_options& options() const { return m_options; }
+ const osd_options& options() const { return m_options; }
texture_manager& textures() const { return m_textures; }
target_manager& targets() const { return m_targets; }
effect_manager& effects() const { return m_effects; }
@@ -123,7 +123,7 @@ private:
void process_screen_quad(uint32_t view, uint32_t screen, screen_prim &prim, osd_window& window);
running_machine& m_machine;
- osd_options& m_options;
+ const osd_options& m_options;
texture_manager& m_textures;
target_manager& m_targets;
effect_manager& m_effects;
@@ -146,9 +146,6 @@ private:
std::vector<screen_prim> m_screen_prims;
std::vector<uint8_t> m_palette_temp;
- static int32_t s_old_chain_selections[16];
- static bool s_reinit_cookie;
-
static inline constexpr uint32_t CHAIN_NONE = 0;
};
diff --git a/src/osd/modules/render/bgfx/effect.cpp b/src/osd/modules/render/bgfx/effect.cpp
index a7f69e326f9..18b43cca9bf 100644
--- a/src/osd/modules/render/bgfx/effect.cpp
+++ b/src/osd/modules/render/bgfx/effect.cpp
@@ -13,40 +13,40 @@
#include "modules/osdmodule.h"
#include "osdcore.h"
-bgfx_effect::bgfx_effect(std::string name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms)
- : m_name(name)
+#include <utility>
+
+
+bgfx_effect::bgfx_effect(std::string &&name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<std::unique_ptr<bgfx_uniform> > &uniforms)
+ : m_name(std::move(name))
, m_state(state)
{
m_program_handle = bgfx::createProgram(vertex_shader, fragment_shader, false);
- for (int i = 0; i < uniforms.size(); i++)
+ for (auto &uniform : uniforms)
{
- if (m_uniforms[uniforms[i]->name()] != nullptr)
+ const auto existing = m_uniforms.find(uniform->name());
+ if (existing != m_uniforms.end())
{
- osd_printf_verbose("Uniform %s appears to be duplicated in one or more effects, please double-check the effect JSON files.\n", uniforms[i]->name());
- delete uniforms[i];
+ osd_printf_verbose("Uniform %s appears to be duplicated in one or more effects, please double-check the effect JSON files.\n", uniform->name());
+ uniform.reset();
continue;
}
- uniforms[i]->create();
- m_uniforms[uniforms[i]->name()] = uniforms[i];
+ uniform->create();
+ m_uniforms.emplace(uniform->name(), std::move(uniform));
}
}
bgfx_effect::~bgfx_effect()
{
- for (std::pair<std::string, bgfx_uniform*> uniform : m_uniforms)
- {
- delete uniform.second;
- }
m_uniforms.clear();
bgfx::destroy(m_program_handle);
}
void bgfx_effect::submit(int view, uint64_t blend)
{
- for (std::pair<std::string, bgfx_uniform*> uniform_pair : m_uniforms)
+ for (auto &[name, uniform] : m_uniforms)
{
- (uniform_pair.second)->upload();
+ uniform->upload();
}
const uint64_t final_state = (blend != ~0ULL) ? ((m_state & ~BGFX_STATE_BLEND_MASK) | blend) : m_state;
@@ -55,8 +55,8 @@ void bgfx_effect::submit(int view, uint64_t blend)
bgfx::submit(view, m_program_handle);
}
-bgfx_uniform* bgfx_effect::uniform(std::string name)
+bgfx_uniform* bgfx_effect::uniform(const std::string &name)
{
- auto iter = m_uniforms.find(name);
- return iter != m_uniforms.end() ? iter->second : nullptr;
+ const auto iter = m_uniforms.find(name);
+ return (iter != m_uniforms.end()) ? iter->second.get() : nullptr;
}
diff --git a/src/osd/modules/render/bgfx/effect.h b/src/osd/modules/render/bgfx/effect.h
index 6dd88b3585c..07646e6302e 100644
--- a/src/osd/modules/render/bgfx/effect.h
+++ b/src/osd/modules/render/bgfx/effect.h
@@ -6,34 +6,36 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_EFFECT_H
+#define MAME_RENDER_BGFX_EFFECT_H
-#ifndef __DRAWBGFX_EFFECT__
-#define __DRAWBGFX_EFFECT__
+#pragma once
#include <bgfx/bgfx.h>
-#include <vector>
#include <map>
+#include <memory>
#include <string>
+#include <vector>
+
class bgfx_uniform;
class bgfx_effect
{
public:
- bgfx_effect(std::string name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<bgfx_uniform*> uniforms);
+ bgfx_effect(std::string &&name, uint64_t state, bgfx::ShaderHandle vertex_shader, bgfx::ShaderHandle fragment_shader, std::vector<std::unique_ptr<bgfx_uniform> > &uniforms);
~bgfx_effect();
void submit(int view, uint64_t blend = ~0ULL);
- bgfx_uniform *uniform(std::string name);
- bool is_valid() { return m_program_handle.idx != bgfx::kInvalidHandle; }
+ bgfx_uniform *uniform(const std::string &name);
+ bool is_valid() const { return m_program_handle.idx != bgfx::kInvalidHandle; }
private:
std::string m_name;
uint64_t m_state;
bgfx::ProgramHandle m_program_handle;
- std::map<std::string, bgfx_uniform*> m_uniforms;
+ std::map<std::string, std::unique_ptr<bgfx_uniform> > m_uniforms;
};
-#endif // __DRAWBGFX_EFFECT__
+#endif // MAME_RENDER_BGFX_EFFECT_H
diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp
index 18991b3807e..e5e5d1698f6 100644
--- a/src/osd/modules/render/bgfx/effectmanager.cpp
+++ b/src/osd/modules/render/bgfx/effectmanager.cpp
@@ -11,8 +11,11 @@
#include "effectmanager.h"
-#include "effectreader.h"
#include "effect.h"
+#include "effectreader.h"
+#include "shadermanager.h"
+
+#include "path.h"
#include "osdfile.h"
#include "modules/lib/osdobj_common.h"
@@ -25,16 +28,18 @@
#include <bgfx/bgfx.h>
-static bool prepare_effect_document(std::string &name, osd_options &options, rapidjson::Document &document)
+#include <utility>
+
+
+static bool prepare_effect_document(const std::string &name, const osd_options &options, rapidjson::Document &document)
{
std::string full_name = name;
if (full_name.length() < 5 || (full_name.compare(full_name.length() - 5, 5, ".json") != 0))
{
- full_name = full_name + ".json";
+ full_name += ".json";
}
- std::string path = util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, options.bgfx_path());
- path += full_name;
+ const std::string path = util::path_concat(options.bgfx_path(), "effects", full_name);
bx::FileReader reader;
if (!bx::open(&reader, path.c_str()))
@@ -43,49 +48,55 @@ static bool prepare_effect_document(std::string &name, osd_options &options, rap
return false;
}
+ const int32_t size = bx::getSize(&reader);
+ std::unique_ptr<char []> data(new (std::nothrow) char [size + 1]);
+ if (!data)
+ {
+ osd_printf_error("Out of memory reading effect file %s\n", path);
+ bx::close(&reader);
+ return false;
+ }
+
bx::ErrorAssert err;
- int32_t size (bx::getSize(&reader));
- char* data = new char[size + 1];
- bx::read(&reader, reinterpret_cast<void*>(data), size, &err);
+ bx::read(&reader, reinterpret_cast<void*>(data.get()), size, &err);
bx::close(&reader);
data[size] = 0;
- document.Parse<rapidjson::kParseCommentsFlag>(data);
-
- delete [] data;
+ document.Parse<rapidjson::kParseCommentsFlag>(data.get());
+ data.reset();
if (document.HasParseError())
{
std::string error(rapidjson::GetParseError_En(document.GetParseError()));
- osd_printf_error("Unable to parse effect %s. Errors returned:\n", path);
- osd_printf_error("%s\n", error);
+ osd_printf_error("Unable to parse effect %s. Errors returned:\n%s\n", path, error);
return false;
}
return true;
}
+
+// keep constructor and destructor out-of-line so the header works with forward declarations
+
+effect_manager::effect_manager(shader_manager& shaders) : m_shaders(shaders)
+{
+}
+
effect_manager::~effect_manager()
{
- for (std::pair<std::string, bgfx_effect*> effect : m_effects)
- {
- delete effect.second;
- }
- m_effects.clear();
+ // the map will automatically dispose of the effects
}
-bgfx_effect* effect_manager::get_or_load_effect(osd_options &options, std::string name)
+bgfx_effect* effect_manager::get_or_load_effect(const osd_options &options, const std::string &name)
{
- std::map<std::string, bgfx_effect*>::iterator iter = m_effects.find(name);
+ const auto iter = m_effects.find(name);
if (iter != m_effects.end())
- {
- return iter->second;
- }
+ return iter->second.get();
return load_effect(options, name);
}
-bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name)
+bgfx_effect* effect_manager::load_effect(const osd_options &options, const std::string &name)
{
rapidjson::Document document;
if (!prepare_effect_document(name, options, document))
@@ -93,20 +104,18 @@ bgfx_effect* effect_manager::load_effect(osd_options &options, std::string name)
return nullptr;
}
- bgfx_effect* effect = effect_reader::read_from_value(name, document, "Effect '" + name + "': ", options, m_shaders);
+ std::unique_ptr<bgfx_effect> effect = effect_reader::read_from_value(name, document, "Effect '" + name + "': ", options, m_shaders);
- if (effect == nullptr)
+ if (!effect)
{
osd_printf_error("Unable to load effect %s\n", name);
return nullptr;
}
- m_effects[name] = effect;
-
- return effect;
+ return m_effects.emplace(name, std::move(effect)).first->second.get();
}
-bool effect_manager::validate_effect(osd_options &options, std::string name)
+bool effect_manager::validate_effect(const osd_options &options, const std::string &name)
{
rapidjson::Document document;
if (!prepare_effect_document(name, options, document))
diff --git a/src/osd/modules/render/bgfx/effectmanager.h b/src/osd/modules/render/bgfx/effectmanager.h
index 5d8bf3f5c93..697d468dc5c 100644
--- a/src/osd/modules/render/bgfx/effectmanager.h
+++ b/src/osd/modules/render/bgfx/effectmanager.h
@@ -9,34 +9,35 @@
//
//============================================================
-#pragma once
+#ifndef MAME_RENDER_BGFX_EFFECTMANAGER_H
+#define MAME_RENDER_BGFX_EFFECTMANAGER_H
-#ifndef __DRAWBGFX_EFFECT_MANAGER__
-#define __DRAWBGFX_EFFECT_MANAGER__
+#pragma once
#include <map>
+#include <memory>
#include <string>
-#include <bgfx/bgfx.h>
-
-#include "shadermanager.h"
class bgfx_effect;
+class osd_options;
+class shader_manager;
-class effect_manager {
+class effect_manager
+{
public:
- effect_manager(shader_manager& shaders) : m_shaders(shaders) { }
+ effect_manager(shader_manager& shaders);
~effect_manager();
// Getters
- bgfx_effect* get_or_load_effect(osd_options &options, std::string name);
- static bool validate_effect(osd_options &options, std::string name);
+ bgfx_effect* get_or_load_effect(const osd_options &options, const std::string &name);
+ static bool validate_effect(const osd_options &options, const std::string &name);
private:
- bgfx_effect* load_effect(osd_options& options, std::string name);
+ bgfx_effect* load_effect(const osd_options &options, const std::string &name);
- shader_manager& m_shaders;
- std::map<std::string, bgfx_effect*> m_effects;
+ shader_manager &m_shaders;
+ std::map<std::string, std::unique_ptr<bgfx_effect> > m_effects;
};
-#endif // __DRAWBGFX_EFFECT_MANAGER__
+#endif // MAME_RENDER_BGFX_EFFECTMANAGER_H
diff --git a/src/osd/modules/render/bgfx/effectreader.cpp b/src/osd/modules/render/bgfx/effectreader.cpp
index 9840fb58dfd..befdc598537 100644
--- a/src/osd/modules/render/bgfx/effectreader.cpp
+++ b/src/osd/modules/render/bgfx/effectreader.cpp
@@ -8,80 +8,79 @@
#include "effectreader.h"
-#include "effect.h"
#include "blendreader.h"
-#include "depthreader.h"
#include "cullreader.h"
-#include "writereader.h"
+#include "depthreader.h"
+#include "effect.h"
#include "shadermanager.h"
-#include "uniformreader.h"
#include "uniform.h"
+#include "uniformreader.h"
+#include "writereader.h"
-bgfx_effect *effect_reader::read_from_value(std::string name, const Value& value, const std::string &prefix, osd_options &options, shader_manager& shaders)
+#include <utility>
+
+
+std::unique_ptr<bgfx_effect> effect_reader::read_from_value(
+ const std::string &name,
+ const Value &value,
+ const std::string &prefix,
+ const osd_options &options,
+ shader_manager &shaders)
{
uint64_t flags = 0;
std::string vertex_name;
std::string fragment_name;
- bgfx::ShaderHandle vertex_shader = BGFX_INVALID_HANDLE;
- bgfx::ShaderHandle fragment_shader = BGFX_INVALID_HANDLE;
- std::vector<bgfx_uniform *> uniforms;
+ std::vector<std::unique_ptr<bgfx_uniform> > uniforms;
if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms))
{
return nullptr;
}
+ bgfx::ShaderHandle vertex_shader = BGFX_INVALID_HANDLE;
+ bgfx::ShaderHandle fragment_shader = BGFX_INVALID_HANDLE;
+
if (!get_shader_data(value, options, shaders, vertex_name, vertex_shader, fragment_name, fragment_shader))
{
- clear_uniform_list(uniforms);
return nullptr;
}
- bgfx_effect *effect = new bgfx_effect(name, flags, vertex_shader, fragment_shader, uniforms);
- if (effect->is_valid())
- {
- return effect;
- }
-
- delete effect;
+ std::unique_ptr<bgfx_effect> effect(new bgfx_effect(std::string(name), flags, vertex_shader, fragment_shader, uniforms));
+ if (!effect->is_valid())
+ return nullptr;
- return nullptr;
+ return effect;
}
-bool effect_reader::validate_value(const Value& value, const std::string &prefix, osd_options &options)
+bool effect_reader::validate_value(const Value& value, const std::string &prefix, const osd_options &options)
{
if (!validate_parameters(value, prefix))
- {
return false;
- }
uint64_t flags = 0;
std::string vertex_name;
std::string fragment_name;
- std::vector<bgfx_uniform *> uniforms;
+ std::vector<std::unique_ptr<bgfx_uniform> > uniforms;
if (!get_base_effect_data(value, prefix, flags, vertex_name, fragment_name, uniforms))
- {
return false;
- }
if (!shader_manager::is_shader_present(options, vertex_name))
- {
- clear_uniform_list(uniforms);
return false;
- }
if (!shader_manager::is_shader_present(options, fragment_name))
- {
- clear_uniform_list(uniforms);
return false;
- }
return true;
}
-bool effect_reader::get_base_effect_data(const Value& value, const std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
- std::vector<bgfx_uniform *> &uniforms)
+bool effect_reader::get_base_effect_data(
+ const Value& value,
+ const std::string &prefix,
+ uint64_t &flags,
+ std::string &vertex_name,
+ std::string &fragment_name,
+ std::vector<std::unique_ptr<bgfx_uniform> > &uniforms)
{
if (!validate_parameters(value, prefix))
{
@@ -101,12 +100,12 @@ bool effect_reader::get_base_effect_data(const Value& value, const std::string &
const Value& uniform_array = value["uniforms"];
for (uint32_t i = 0; i < uniform_array.Size(); i++)
{
- bgfx_uniform *uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
- if (uniform == nullptr)
+ auto uniform = uniform_reader::read_from_value(uniform_array[i], prefix + "uniforms[" + std::to_string(i) + "]: ");
+ if (!uniform)
{
return false;
}
- uniforms.push_back(uniform);
+ uniforms.emplace_back(std::move(uniform));
}
vertex_name = value["vertex"].GetString();
@@ -127,8 +126,14 @@ bool effect_reader::get_base_effect_data(const Value& value, const std::string &
return true;
}
-bool effect_reader::get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
- std::string &fragment_name, bgfx::ShaderHandle &fragment_shader)
+bool effect_reader::get_shader_data(
+ const Value &value,
+ const osd_options &options,
+ shader_manager &shaders,
+ std::string &vertex_name,
+ bgfx::ShaderHandle &vertex_shader,
+ std::string &fragment_name,
+ bgfx::ShaderHandle &fragment_shader)
{
vertex_shader = shaders.load_shader(options, vertex_name);
if (vertex_shader.idx == bgfx::kInvalidHandle)
@@ -145,14 +150,6 @@ bool effect_reader::get_shader_data(const Value& value, osd_options &options, sh
return true;
}
-void effect_reader::clear_uniform_list(std::vector<bgfx_uniform *> &uniforms)
-{
- for (bgfx_uniform *uniform : uniforms)
- {
- delete uniform;
- }
-}
-
bool effect_reader::validate_parameters(const Value& value, const std::string &prefix)
{
if (!READER_CHECK(value.HasMember("depth"), "%sMust have object value 'depth' (what are our Z-buffer settings?)\n", prefix)) return false;
diff --git a/src/osd/modules/render/bgfx/effectreader.h b/src/osd/modules/render/bgfx/effectreader.h
index 5819de60b01..db590e5eeb3 100644
--- a/src/osd/modules/render/bgfx/effectreader.h
+++ b/src/osd/modules/render/bgfx/effectreader.h
@@ -15,26 +15,28 @@
#include <bgfx/bgfx.h>
+#include <memory>
#include <string>
#include <vector>
+
class bgfx_effect;
class bgfx_uniform;
class osd_options;
class shader_manager;
+
class effect_reader : public state_reader
{
public:
- static bgfx_effect *read_from_value(std::string name, const Value& value, const std::string &prefix, osd_options &options, shader_manager& shaders);
- static bool validate_value(const Value& value, const std::string &prefix, osd_options &options);
+ static std::unique_ptr<bgfx_effect> read_from_value(const std::string &name, const Value& value, const std::string &prefix, const osd_options &options, shader_manager& shaders);
+ static bool validate_value(const Value& value, const std::string &prefix, const osd_options &options);
private:
static bool get_base_effect_data(const Value& value, const std::string &prefix, uint64_t &flags, std::string &vertex_name, std::string &fragment_name,
- std::vector<bgfx_uniform *> &uniforms);
- static bool get_shader_data(const Value& value, osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
+ std::vector<std::unique_ptr<bgfx_uniform> > &uniforms);
+ static bool get_shader_data(const Value& value, const osd_options &options, shader_manager &shaders, std::string &vertex_name, bgfx::ShaderHandle &vertex_shader,
std::string &fragment_name, bgfx::ShaderHandle &fragment_shader);
- static void clear_uniform_list(std::vector<bgfx_uniform *> &uniforms);
static bool validate_parameters(const Value& value, const std::string &prefix);
};
diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp
index 7d4ca4ea259..763a744e4aa 100644
--- a/src/osd/modules/render/bgfx/shadermanager.cpp
+++ b/src/osd/modules/render/bgfx/shadermanager.cpp
@@ -16,11 +16,10 @@
#include "osdfile.h"
#include "modules/lib/osdobj_common.h"
+#include <bx/file.h>
#include <bx/math.h>
#include <bx/readerwriter.h>
-#include <bx/file.h>
-#include <bgfx/bgfx.h>
shader_manager::~shader_manager()
{
@@ -31,7 +30,7 @@ shader_manager::~shader_manager()
m_shaders.clear();
}
-bgfx::ShaderHandle shader_manager::get_or_load_shader(osd_options &options, const std::string &name)
+bgfx::ShaderHandle shader_manager::get_or_load_shader(const osd_options &options, const std::string &name)
{
std::map<std::string, bgfx::ShaderHandle>::iterator iter = m_shaders.find(name);
if (iter != m_shaders.end())
@@ -48,7 +47,7 @@ bgfx::ShaderHandle shader_manager::get_or_load_shader(osd_options &options, cons
return handle;
}
-bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, const std::string &name)
+bgfx::ShaderHandle shader_manager::load_shader(const osd_options &options, const std::string &name)
{
std::string shader_path = make_path_string(options, name);
const bgfx::Memory* mem = load_mem(shader_path + name + ".bin");
@@ -60,7 +59,7 @@ bgfx::ShaderHandle shader_manager::load_shader(osd_options &options, const std::
return BGFX_INVALID_HANDLE;
}
-bool shader_manager::is_shader_present(osd_options &options, const std::string &name)
+bool shader_manager::is_shader_present(const osd_options &options, const std::string &name)
{
std::string shader_path = make_path_string(options, name);
std::string file_name = shader_path + name + ".bin";
@@ -80,7 +79,7 @@ bool shader_manager::is_shader_present(osd_options &options, const std::string &
return false;
}
-std::string shader_manager::make_path_string(osd_options &options, const std::string &name)
+std::string shader_manager::make_path_string(const osd_options &options, const std::string &name)
{
std::string shader_path(options.bgfx_path());
shader_path += PATH_SEPARATOR "shaders" PATH_SEPARATOR;
diff --git a/src/osd/modules/render/bgfx/shadermanager.h b/src/osd/modules/render/bgfx/shadermanager.h
index 604fbd7e3ac..12ac739d35a 100644
--- a/src/osd/modules/render/bgfx/shadermanager.h
+++ b/src/osd/modules/render/bgfx/shadermanager.h
@@ -22,21 +22,23 @@
class osd_options;
-class shader_manager {
+
+class shader_manager
+{
public:
shader_manager() { }
~shader_manager();
// Getters
- bgfx::ShaderHandle get_or_load_shader(osd_options &options, const std::string &name);
- static bgfx::ShaderHandle load_shader(osd_options &options, const std::string &name);
- static bool is_shader_present(osd_options &options, const std::string &name);
+ bgfx::ShaderHandle get_or_load_shader(const osd_options &options, const std::string &name);
+ static bgfx::ShaderHandle load_shader(const osd_options &options, const std::string &name);
+ static bool is_shader_present(const osd_options &options, const std::string &name);
private:
- static std::string make_path_string(osd_options &options, const std::string &name);
+ static std::string make_path_string(const osd_options &options, const std::string &name);
static const bgfx::Memory* load_mem(const std::string &name);
- std::map<std::string, bgfx::ShaderHandle> m_shaders;
+ std::map<std::string, bgfx::ShaderHandle> m_shaders;
};
#endif // MAME_RENDER_BGFX_SHADERMANAGER_H
diff --git a/src/osd/modules/render/bgfx/uniformreader.cpp b/src/osd/modules/render/bgfx/uniformreader.cpp
index 002e6b3959a..d1eab8098c7 100644
--- a/src/osd/modules/render/bgfx/uniformreader.cpp
+++ b/src/osd/modules/render/bgfx/uniformreader.cpp
@@ -10,6 +10,9 @@
#include "uniform.h"
+#include <cstdlib>
+
+
const uniform_reader::string_to_enum uniform_reader::TYPE_NAMES[uniform_reader::TYPE_COUNT] = {
{ "int", bgfx::UniformType::Sampler },
{ "vec4", bgfx::UniformType::Vec4 },
@@ -17,7 +20,7 @@ const uniform_reader::string_to_enum uniform_reader::TYPE_NAMES[uniform_reader::
{ "mat4", bgfx::UniformType::Mat4 }
};
-bgfx_uniform* uniform_reader::read_from_value(const Value& value, const std::string &prefix)
+std::unique_ptr<bgfx_uniform> uniform_reader::read_from_value(const Value& value, const std::string &prefix)
{
if (!validate_parameters(value, prefix))
{
@@ -31,23 +34,18 @@ bgfx_uniform* uniform_reader::read_from_value(const Value& value, const std::str
const Value& value_array = value["values"];
const size_t array_size = value_array.Size() * sizeof(float);
- const size_t alloc_size = (type_size > array_size) ? type_size : array_size;
- auto* data = reinterpret_cast<float*>(new char[alloc_size]);
+ auto* data = reinterpret_cast<float*>(std::malloc(std::max(type_size, array_size)));
unsigned int index = 0;
for (; index < type_size / 4 && index < value_array.Size(); index++)
- {
data[index] = float(value_array[index].GetDouble());
- }
for (; index < type_size / 4; index++)
- {
data[index] = 0.0f;
- }
- bgfx_uniform* uniform = new bgfx_uniform(name, type);
- uniform->set((void*)data, type_size);
- delete [] data;
+ auto uniform = std::make_unique<bgfx_uniform>(name, type);
+ uniform->set(data, type_size);
+ std::free(data);
return uniform;
}
diff --git a/src/osd/modules/render/bgfx/uniformreader.h b/src/osd/modules/render/bgfx/uniformreader.h
index e35fa4cfad0..ebb3a485d63 100644
--- a/src/osd/modules/render/bgfx/uniformreader.h
+++ b/src/osd/modules/render/bgfx/uniformreader.h
@@ -13,12 +13,16 @@
#include "statereader.h"
+#include <memory>
+#include <string>
+
+
class bgfx_uniform;
class uniform_reader : public state_reader
{
public:
- static bgfx_uniform* read_from_value(const Value& value, const std::string &prefix);
+ static std::unique_ptr<bgfx_uniform> read_from_value(const Value& value, const std::string &prefix);
private:
static bool validate_parameters(const Value& value, const std::string &prefix);
diff --git a/src/osd/modules/render/bgfx/view.cpp b/src/osd/modules/render/bgfx/view.cpp
index 6935e19bca7..3a731fc71f8 100644
--- a/src/osd/modules/render/bgfx/view.cpp
+++ b/src/osd/modules/render/bgfx/view.cpp
@@ -13,9 +13,7 @@
#include "target.h"
void bgfx_view::update() {
- std::shared_ptr<osd_window> win = m_renderer->assert_window();
-
- const uint32_t window_index = win->index();
+ const uint32_t window_index = m_renderer->window().index();
const uint32_t width = m_renderer->get_window_width(window_index);
const uint32_t height = m_renderer->get_window_height(window_index);
diff --git a/src/osd/modules/render/bgfx/view.h b/src/osd/modules/render/bgfx/view.h
index 577663ea525..b257eb12ea4 100644
--- a/src/osd/modules/render/bgfx/view.h
+++ b/src/osd/modules/render/bgfx/view.h
@@ -4,12 +4,14 @@
#pragma once
#include "window.h"
+
#include <climits>
class renderer_bgfx;
class bgfx_target;
-class bgfx_view {
+class bgfx_view
+{
public:
bgfx_view(renderer_bgfx *renderer, uint32_t index, bgfx_target *backbuffer, std::vector<uint32_t> &seen_views)
: m_renderer(renderer)
diff --git a/src/osd/modules/render/blit13.h b/src/osd/modules/render/blit13.ipp
index 1ac485bab8d..1ac485bab8d 100644
--- a/src/osd/modules/render/blit13.h
+++ b/src/osd/modules/render/blit13.ipp
diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h
index 2d7548a242a..846d9dac791 100644
--- a/src/osd/modules/render/d3d/d3dcomm.h
+++ b/src/osd/modules/render/d3d/d3dcomm.h
@@ -6,8 +6,22 @@
//
//============================================================
-#ifndef __WIN_D3DCOMM__
-#define __WIN_D3DCOMM__
+#ifndef MAME_RENDER_D3D_D3DCOMM_H
+#define MAME_RENDER_D3D_D3DCOMM_H
+
+#pragma once
+
+// lib/util
+#include "bitmap.h"
+
+#include <windows.h>
+#include <d3d9.h>
+#include <wrl/client.h>
+
+#include <cstring>
+#include <memory>
+#include <vector>
+
//============================================================
// CONSTANTS
@@ -60,10 +74,7 @@ public:
class d3d_texture_manager
{
public:
- d3d_texture_manager(): m_renderer(nullptr), m_yuv_format(), m_texture_caps(0), m_texture_max_aspect(0), m_texture_max_width(0), m_texture_max_height(0), m_default_texture(nullptr)
- { }
-
- d3d_texture_manager(renderer_d3d9 *d3d);
+ d3d_texture_manager(renderer_d3d9 &d3d, IDirect3D9 *d3dobj);
void update_textures();
@@ -82,12 +93,12 @@ public:
texture_info * get_default_texture() const { return m_default_texture; }
- renderer_d3d9 * get_d3d() const { return m_renderer; }
+ renderer_d3d9 & get_d3d() const { return m_renderer; }
- std::vector<std::unique_ptr<texture_info>> m_texture_list; // list of active textures
+ std::vector<std::unique_ptr<texture_info> > m_texture_list; // list of active textures
private:
- renderer_d3d9 * m_renderer;
+ renderer_d3d9 & m_renderer;
D3DFORMAT m_yuv_format; // format to use for YUV textures
DWORD m_texture_caps; // textureCaps field
@@ -104,7 +115,7 @@ private:
class texture_info
{
public:
- texture_info(d3d_texture_manager *manager, const render_texinfo *texsource, int prescale, uint32_t flags);
+ texture_info(d3d_texture_manager &manager, const render_texinfo *texsource, int prescale, uint32_t flags);
~texture_info();
render_texinfo & get_texinfo() { return m_texinfo; }
@@ -125,15 +136,16 @@ public:
int get_cur_frame() const { return m_cur_frame; }
- IDirect3DTexture9 * get_tex() const { return m_d3dtex; }
- IDirect3DSurface9 * get_surface() const { return m_d3dsurface; }
- IDirect3DTexture9 * get_finaltex() const { return m_d3dfinaltex; }
+ IDirect3DTexture9 * get_finaltex() const { return m_d3dfinaltex.Get(); }
vec2f & get_uvstart() { return m_start; }
vec2f & get_uvstop() { return m_stop; }
vec2f & get_rawdims() { return m_rawdims; }
private:
+ using IDirect3DTexture9Ptr = Microsoft::WRL::ComPtr<IDirect3DTexture9>;
+ using IDirect3DSurface9Ptr = Microsoft::WRL::ComPtr<IDirect3DSurface9>;
+
void prescale();
void compute_size(int texwidth, int texheight);
void compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height);
@@ -145,23 +157,23 @@ private:
inline void copyline_yuy16_to_uyvy(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette);
inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette);
- d3d_texture_manager * m_texture_manager; // texture manager pointer
+ d3d_texture_manager & m_texture_manager; // texture manager pointer
- renderer_d3d9 * m_renderer; // renderer pointer
+ renderer_d3d9 & m_renderer; // renderer pointer
- uint32_t m_hash; // hash value for the texture
- uint32_t m_flags; // rendering flags
+ const uint32_t m_hash; // hash value for the texture
+ const uint32_t m_flags; // rendering flags
render_texinfo m_texinfo; // copy of the texture info
+ const int m_type; // what type of texture are we?
vec2f m_start; // beggining UV coordinates
vec2f m_stop; // ending UV coordinates
vec2f m_rawdims; // raw dims of the texture
- int m_type; // what type of texture are we?
int m_xprescale, m_yprescale; // X/Y prescale factor
int m_xborderpix, m_yborderpix; // X/Y border pixels
int m_cur_frame; // what is our current frame?
- IDirect3DTexture9 * m_d3dtex; // Direct3D texture pointer
- IDirect3DSurface9 * m_d3dsurface; // Direct3D offscreen plain surface pointer
- IDirect3DTexture9 * m_d3dfinaltex; // Direct3D final (post-scaled) texture
+ IDirect3DTexture9Ptr m_d3dtex; // Direct3D texture pointer
+ IDirect3DSurface9Ptr m_d3dsurface; // Direct3D offscreen plain surface pointer
+ IDirect3DTexture9Ptr m_d3dfinaltex; // Direct3D final (post-scaled) texture
};
/* poly_info holds information about a single polygon/d3d primitive */
@@ -227,24 +239,14 @@ class d3d_render_target
{
public:
// construction/destruction
- d3d_render_target(): target_width(0), target_height(0), width(0), height(0), screen_index(0), bloom_count(0)
+ d3d_render_target()
+ : target_width(0)
+ , target_height(0)
+ , width(0)
+ , height(0)
+ , screen_index(0)
+ , bloom_count(0)
{
- for (int index = 0; index < MAX_BLOOM_COUNT; index++)
- {
- bloom_texture[index] = nullptr;
- bloom_surface[index] = nullptr;
- }
-
- for (int index = 0; index < 2; index++)
- {
- source_texture[index] = nullptr;
- source_surface[index] = nullptr;
- target_texture[index] = nullptr;
- target_surface[index] = nullptr;
- }
-
- cache_texture = nullptr;
- cache_surface = nullptr;
}
~d3d_render_target();
@@ -262,20 +264,20 @@ public:
int screen_index;
- IDirect3DSurface9 *target_surface[2];
- IDirect3DTexture9 *target_texture[2];
- IDirect3DSurface9 *source_surface[2];
- IDirect3DTexture9 *source_texture[2];
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> target_surface[2];
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> target_texture[2];
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> source_surface[2];
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> source_texture[2];
- IDirect3DSurface9 *cache_surface;
- IDirect3DTexture9 *cache_texture;
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> cache_surface;
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> cache_texture;
- IDirect3DSurface9 *bloom_surface[MAX_BLOOM_COUNT];
- IDirect3DTexture9 *bloom_texture[MAX_BLOOM_COUNT];
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> bloom_surface[MAX_BLOOM_COUNT];
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> bloom_texture[MAX_BLOOM_COUNT];
float bloom_dims[MAX_BLOOM_COUNT][2];
int bloom_count;
};
-#endif
+#endif // MAME_RENDER_D3D_D3DCOMM_H
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index 8c59649f64a..85313f3e9ec 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -50,8 +50,6 @@ class movie_recorder
public:
movie_recorder(running_machine& machine, renderer_d3d9 *d3d, int width, int height)
: m_initialized(false), m_d3d(d3d), m_width(width), m_height(height)
- , m_sys_texture(nullptr), m_sys_surface(nullptr)
- , m_vid_texture(nullptr), m_vid_surface(nullptr)
{
HRESULT result;
@@ -82,17 +80,6 @@ public:
~movie_recorder()
{
- if (m_sys_texture != nullptr)
- m_sys_texture->Release();
-
- if (m_sys_surface != nullptr)
- m_sys_surface->Release();
-
- if (m_vid_texture != nullptr)
- m_vid_texture->Release();
-
- if (m_vid_surface != nullptr)
- m_vid_surface->Release();
}
void record(const char *name)
@@ -109,7 +96,7 @@ public:
return;
// copy the frame from video memory, where it is not accessible, to system memory
- HRESULT result = m_d3d->get_device()->GetRenderTargetData(m_vid_surface, m_sys_surface);
+ HRESULT result = m_d3d->get_device()->GetRenderTargetData(m_vid_surface.Get(), m_sys_surface.Get());
if (FAILED(result))
return;
@@ -144,7 +131,7 @@ public:
m_avi_writer->audio_frame(buffer, samples_this_frame);
}
- IDirect3DSurface9 * target_surface() { return m_vid_surface; }
+ IDirect3DSurface9 * target_surface() { return m_vid_surface.Get(); }
private:
bool m_initialized;
@@ -156,10 +143,10 @@ private:
bitmap_rgb32 m_frame;
int m_width;
int m_height;
- IDirect3DTexture9 * m_sys_texture; // texture in system memory
- IDirect3DSurface9 * m_sys_surface; // surface in system memory
- IDirect3DTexture9 * m_vid_texture; // texture in video memory
- IDirect3DSurface9 * m_vid_surface; // surface in video memory
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> m_sys_texture; // texture in system memory
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> m_sys_surface; // surface in system memory
+ Microsoft::WRL::ComPtr<IDirect3DTexture9> m_vid_texture; // texture in video memory
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> m_vid_surface; // surface in video memory
};
@@ -168,7 +155,6 @@ private:
//============================================================
shaders::shaders() :
- d3dintf(nullptr),
machine(nullptr),
d3d(nullptr),
post_fx_enable(false),
@@ -182,37 +168,12 @@ shaders::shaders() :
lut_texture(nullptr),
ui_lut_texture(nullptr),
options(nullptr),
- black_surface(nullptr),
- black_texture(nullptr),
recording_movie(false),
render_snap(false),
- snap_copy_target(nullptr),
- snap_copy_texture(nullptr),
- snap_target(nullptr),
- snap_texture(nullptr),
snap_width(0),
snap_height(0),
initialized(false),
- backbuffer(nullptr),
curr_effect(nullptr),
- default_effect(nullptr),
- ui_effect(nullptr),
- ui_wrap_effect(nullptr),
- vector_buffer_effect(nullptr),
- prescale_effect(nullptr),
- prescale_point_effect(nullptr),
- post_effect(nullptr),
- distortion_effect(nullptr),
- scanline_effect(nullptr),
- focus_effect(nullptr),
- phosphor_effect(nullptr),
- deconverge_effect(nullptr),
- color_effect(nullptr),
- ntsc_effect(nullptr),
- bloom_effect(nullptr),
- downsample_effect(nullptr),
- vector_effect(nullptr),
- chroma_effect(nullptr),
diffuse_texture(nullptr),
curr_texture(nullptr),
curr_render_target(nullptr),
@@ -229,12 +190,7 @@ shaders::shaders() :
shaders::~shaders()
{
- for (slider* slider : internal_sliders)
- {
- delete slider;
- }
-
- if (options != nullptr)
+ if (options && (&last_options != options))
{
delete options;
options = nullptr;
@@ -251,11 +207,9 @@ void shaders::save_snapshot()
if (!enabled())
return;
- auto win = d3d->assert_window();
-
int width = snap_width;
int height = snap_height;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(width, height);
}
@@ -296,8 +250,7 @@ void shaders::record_movie()
return;
}
- auto win = d3d->assert_window();
- osd_dim wdim = win->get_size();
+ osd_dim wdim = d3d->window().get_size();
recorder = std::make_unique<movie_recorder>(*machine, d3d, wdim.width(), wdim.height());
recorder->record(downcast<windows_options &>(machine->options()).d3d_hlsl_write());
@@ -330,11 +283,9 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
if (!enabled())
return;
- auto win = d3d->assert_window();
-
int width = snap_width;
int height = snap_height;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(width, height);
}
@@ -344,7 +295,7 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
return;
// copy the texture
- HRESULT result = d3d->get_device()->GetRenderTargetData(surface, snap_copy_target);
+ HRESULT result = d3d->get_device()->GetRenderTargetData(surface, snap_copy_target.Get());
if (FAILED(result))
return;
@@ -385,29 +336,10 @@ void shaders::render_snapshot(IDirect3DSurface9 *surface)
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during texture UnlockRect call\n", result);
- if (snap_texture != nullptr)
- {
- snap_texture->Release();
- snap_texture = nullptr;
- }
-
- if (snap_target != nullptr)
- {
- snap_target->Release();
- snap_target = nullptr;
- }
-
- if (snap_copy_texture != nullptr)
- {
- snap_copy_texture->Release();
- snap_copy_texture = nullptr;
- }
-
- if (snap_copy_target != nullptr)
- {
- snap_copy_target->Release();
- snap_copy_target = nullptr;
- }
+ snap_texture.Reset();
+ snap_target.Reset();
+ snap_copy_texture.Reset();
+ snap_copy_target.Reset();
}
@@ -473,7 +405,7 @@ void shaders::set_filter(bool filter_screens)
// shaders::init
//============================================================
-bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer)
+bool shaders::init(IDirect3D9 *d3dobj, running_machine *machine, renderer_d3d9 *renderer)
{
osd_printf_verbose("Direct3D: Initialize HLSL\n");
@@ -505,9 +437,7 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
return false;
}
- d3dintf->post_fx_available = true;
-
- this->d3dintf = d3dintf;
+ this->d3dobj = d3dobj;
this->machine = machine;
this->d3d = renderer;
@@ -518,19 +448,18 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
snap_width = winoptions.d3d_snap_width();
snap_height = winoptions.d3d_snap_height();
- this->options = new hlsl_options;
- this->options->params_init = false;
-
- // copy last options if initialized
if (last_options.params_init)
{
+ // copy last options if initialized
osd_printf_verbose("Direct3D: First restore options\n");
options = &last_options;
}
-
- // read options if not initialized
- if (!options->params_init)
+ else
{
+ // read options if not initialized
+ options = new hlsl_options;
+ options->params_init = false;
+
strncpy(options->shadow_mask_texture, winoptions.screen_shadow_mask_texture(), sizeof(options->shadow_mask_texture));
options->shadow_mask_tile_mode = winoptions.screen_shadow_mask_tile_mode();
options->shadow_mask_alpha = winoptions.screen_shadow_mask_alpha();
@@ -612,6 +541,7 @@ bool shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
osd_printf_verbose("Direct3D: First store options\n");
last_options = *options;
+ delete options;
options = &last_options;
}
@@ -786,7 +716,7 @@ int shaders::create_resources()
return 1;
}
black_texture->GetSurfaceLevel(0, &black_surface);
- result = d3d->get_device()->SetRenderTarget(0, black_surface);
+ result = d3d->get_device()->SetRenderTarget(0, black_surface.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
@@ -794,7 +724,7 @@ int shaders::create_resources()
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
- result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ result = d3d->get_device()->SetRenderTarget(0, backbuffer.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
@@ -819,7 +749,7 @@ int shaders::create_resources()
texture.seqid = 0;
// now create it (no prescale, no wrap)
- auto tex = std::make_unique<texture_info>(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ auto tex = std::make_unique<texture_info>(*d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
shadow_texture = tex.get();
d3d->get_texture_manager()->m_texture_list.push_back(std::move(tex));
}
@@ -842,7 +772,7 @@ int shaders::create_resources()
texture.seqid = 0;
// now create it (no prescale, no wrap)
- auto tex = std::make_unique<texture_info>(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ auto tex = std::make_unique<texture_info>(*d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
lut_texture = tex.get();
d3d->get_texture_manager()->m_texture_list.push_back(std::move(tex));
}
@@ -865,83 +795,66 @@ int shaders::create_resources()
texture.seqid = 0;
// now create it (no prescale, no wrap)
- auto tex = std::make_unique<texture_info>(d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ auto tex = std::make_unique<texture_info>(*d3d->get_texture_manager(), &texture, 1, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
ui_lut_texture = tex.get();
d3d->get_texture_manager()->m_texture_list.push_back(std::move(tex));
}
const char *fx_dir = downcast<windows_options &>(machine->options()).screen_post_fx_dir();
- default_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir);
- ui_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir);
- ui_wrap_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir);
- vector_buffer_effect = new effect(this, d3d->get_device(), "primary.fx", fx_dir);
- post_effect = new effect(this, d3d->get_device(), "post.fx", fx_dir);
- distortion_effect = new effect(this, d3d->get_device(), "distortion.fx", fx_dir);
- prescale_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir);
- prescale_point_effect = new effect(this, d3d->get_device(), "prescale.fx", fx_dir);
- phosphor_effect = new effect(this, d3d->get_device(), "phosphor.fx", fx_dir);
- focus_effect = new effect(this, d3d->get_device(), "focus.fx", fx_dir);
- scanline_effect = new effect(this, d3d->get_device(), "scanline.fx", fx_dir);
- deconverge_effect = new effect(this, d3d->get_device(), "deconverge.fx", fx_dir);
- color_effect = new effect(this, d3d->get_device(), "color.fx", fx_dir);
- ntsc_effect = new effect(this, d3d->get_device(), "ntsc.fx", fx_dir);
- bloom_effect = new effect(this, d3d->get_device(), "bloom.fx", fx_dir);
- downsample_effect = new effect(this, d3d->get_device(), "downsample.fx", fx_dir);
- vector_effect = new effect(this, d3d->get_device(), "vector.fx", fx_dir);
- chroma_effect = new effect(this, d3d->get_device(), "chroma.fx", fx_dir);
-
- if (!default_effect->is_valid() ||
- !ui_effect->is_valid() ||
- !ui_wrap_effect->is_valid() ||
- !vector_buffer_effect->is_valid() ||
- !post_effect->is_valid() ||
- !distortion_effect->is_valid() ||
- !prescale_effect->is_valid() ||
- !prescale_point_effect->is_valid() ||
- !phosphor_effect->is_valid() ||
- !focus_effect->is_valid() ||
- !scanline_effect->is_valid() ||
- !deconverge_effect->is_valid() ||
- !color_effect->is_valid() ||
- !ntsc_effect->is_valid() ||
- !bloom_effect->is_valid() ||
- !downsample_effect->is_valid() ||
- !vector_effect->is_valid() ||
- !chroma_effect->is_valid())
- {
- return 1;
- }
+ default_effect = std::make_unique<effect>(this, d3d->get_device(), "primary.fx", fx_dir);
+ ui_effect = std::make_unique<effect>(this, d3d->get_device(), "primary.fx", fx_dir);
+ ui_wrap_effect = std::make_unique<effect>(this, d3d->get_device(), "primary.fx", fx_dir);
+ vector_buffer_effect = std::make_unique<effect>(this, d3d->get_device(), "primary.fx", fx_dir);
+ post_effect = std::make_unique<effect>(this, d3d->get_device(), "post.fx", fx_dir);
+ distortion_effect = std::make_unique<effect>(this, d3d->get_device(), "distortion.fx", fx_dir);
+ prescale_effect = std::make_unique<effect>(this, d3d->get_device(), "prescale.fx", fx_dir);
+ prescale_point_effect = std::make_unique<effect>(this, d3d->get_device(), "prescale.fx", fx_dir);
+ phosphor_effect = std::make_unique<effect>(this, d3d->get_device(), "phosphor.fx", fx_dir);
+ focus_effect = std::make_unique<effect>(this, d3d->get_device(), "focus.fx", fx_dir);
+ scanline_effect = std::make_unique<effect>(this, d3d->get_device(), "scanline.fx", fx_dir);
+ deconverge_effect = std::make_unique<effect>(this, d3d->get_device(), "deconverge.fx", fx_dir);
+ color_effect = std::make_unique<effect>(this, d3d->get_device(), "color.fx", fx_dir);
+ ntsc_effect = std::make_unique<effect>(this, d3d->get_device(), "ntsc.fx", fx_dir);
+ bloom_effect = std::make_unique<effect>(this, d3d->get_device(), "bloom.fx", fx_dir);
+ downsample_effect = std::make_unique<effect>(this, d3d->get_device(), "downsample.fx", fx_dir);
+ vector_effect = std::make_unique<effect>(this, d3d->get_device(), "vector.fx", fx_dir);
+ chroma_effect = std::make_unique<effect>(this, d3d->get_device(), "chroma.fx", fx_dir);
std::array<effect*, 18> effects = {
- default_effect,
- ui_effect,
- ui_wrap_effect,
- vector_buffer_effect,
- post_effect,
- distortion_effect,
- prescale_effect,
- prescale_point_effect,
- phosphor_effect,
- focus_effect,
- scanline_effect,
- deconverge_effect,
- color_effect,
- ntsc_effect,
- bloom_effect,
- downsample_effect,
- vector_effect,
- chroma_effect
- };
-
- for (int i = 0; i < effects.size(); i++)
- {
- effects[i]->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS);
- effects[i]->add_uniform("TargetScale", uniform::UT_FLOAT, uniform::CU_TARGET_SCALE);
- effects[i]->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
- effects[i]->add_uniform("ScreenCount", uniform::UT_INT, uniform::CU_SCREEN_COUNT);
- effects[i]->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY);
- effects[i]->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN);
+ default_effect.get(),
+ ui_effect.get(),
+ ui_wrap_effect.get(),
+ vector_buffer_effect.get(),
+ post_effect.get(),
+ distortion_effect.get(),
+ prescale_effect.get(),
+ prescale_point_effect.get(),
+ phosphor_effect.get(),
+ focus_effect.get(),
+ scanline_effect.get(),
+ deconverge_effect.get(),
+ color_effect.get(),
+ ntsc_effect.get(),
+ bloom_effect.get(),
+ downsample_effect.get(),
+ vector_effect.get(),
+ chroma_effect.get() };
+
+ for (effect *eff : effects)
+ {
+ if (!eff->is_valid())
+ return 1;
+ }
+
+ for (effect *eff : effects)
+ {
+ eff->add_uniform("TargetDims", uniform::UT_VEC2, uniform::CU_TARGET_DIMS);
+ eff->add_uniform("TargetScale", uniform::UT_FLOAT, uniform::CU_TARGET_SCALE);
+ eff->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
+ eff->add_uniform("ScreenCount", uniform::UT_INT, uniform::CU_SCREEN_COUNT);
+ eff->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY);
+ eff->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN);
}
ntsc_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
@@ -1038,17 +951,14 @@ int shaders::create_resources()
void shaders::begin_draw()
{
- double t;
-
if (!enabled())
- {
return;
- }
curr_target = 0;
- curr_effect = default_effect;
+ curr_effect = default_effect.get();
+
// Update for delta_time
- t = machine->time().as_double();
+ const double t = machine->time().as_double();
delta_t = t - acc_t;
acc_t = t;
@@ -1072,7 +982,7 @@ void shaders::begin_draw()
vector_effect->set_technique("DefaultTechnique");
chroma_effect->set_technique("DefaultTechnique");
- HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer.Get());
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
@@ -1176,15 +1086,15 @@ int shaders::ntsc_pass(d3d_render_target *rt, int source_index, poly_info *poly,
// initial "Diffuse" texture is set in shaders::set_texture()
- set_curr_effect(ntsc_effect);
+ set_curr_effect(ntsc_effect.get());
curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
curr_effect->set_float("SignalOffset", signal_offset);
next_index = rt->next_index(next_index);
- blit(rt->source_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->source_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
- color_effect->set_texture("Diffuse", rt->source_texture[next_index]);
+ color_effect->set_texture("Diffuse", rt->source_texture[next_index].Get());
return next_index;
}
@@ -1233,7 +1143,7 @@ int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, pol
{
int next_index = source_index;
- set_curr_effect(color_effect);
+ set_curr_effect(color_effect.get());
// initial "Diffuse" texture is set in shaders::ntsc_pass() if NTSC processing is enabled
if (!options->yiq_enable)
@@ -1247,7 +1157,7 @@ int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, pol
curr_effect->set_vector("PrimTint", 3, prim_tint);
next_index = rt->next_index(next_index);
- blit(rt->source_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->source_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1256,12 +1166,12 @@ int shaders::prescale_pass(d3d_render_target *rt, int source_index, poly_info *p
{
int next_index = source_index;
- set_curr_effect(filter_screens ? prescale_effect : prescale_point_effect);
+ set_curr_effect(filter_screens ? prescale_effect.get() : prescale_point_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->source_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->source_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1279,12 +1189,12 @@ int shaders::deconverge_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
- set_curr_effect(deconverge_effect);
+ set_curr_effect(deconverge_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1297,7 +1207,6 @@ int shaders::scanline_pass(d3d_render_target *rt, int source_index, poly_info *p
//if (options->scanline_alpha == 0.0f)
//return next_index;
- auto win = d3d->assert_window();
screen_device_enumerator screen_iterator(machine->root_device());
screen_device *screen = screen_iterator.byindex(target_to_screen[curr_target]);
render_container &screen_container = screen->container();
@@ -1308,16 +1217,16 @@ int shaders::scanline_pass(d3d_render_target *rt, int source_index, poly_info *p
float screen_scale[] = { xscale, yscale };
float screen_offset[] = { xoffset, yoffset };
- set_curr_effect(scanline_effect);
+ set_curr_effect(scanline_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
curr_effect->set_vector("ScreenScale", 2, screen_scale);
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
curr_effect->set_float("ScanlineOffset",
curr_texture->get_cur_frame() == 0 ?
0.0f : options->scanline_jitter);
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1331,12 +1240,12 @@ int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *po
return next_index;
}
- set_curr_effect(focus_effect);
+ set_curr_effect(focus_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1352,23 +1261,23 @@ int shaders::phosphor_pass(d3d_render_target *rt, int source_index, poly_info *p
}
// Shader needs time between last update
- set_curr_effect(phosphor_effect);
+ set_curr_effect(phosphor_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
- curr_effect->set_texture("LastPass", rt->cache_texture);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
+ curr_effect->set_texture("LastPass", rt->cache_texture.Get());
curr_effect->set_bool("Passthrough", false);
curr_effect->set_float("DeltaTime", delta_time());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
// Pass along our phosphor'd screen
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
- curr_effect->set_texture("LastPass", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
+ curr_effect->set_texture("LastPass", rt->target_texture[next_index].Get());
curr_effect->set_bool("Passthrough", true);
- blit(rt->cache_surface, false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->cache_surface.Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1377,8 +1286,6 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
{
int next_index = source_index;
- auto win = d3d->assert_window();
-
screen_device_enumerator screen_iterator(machine->root_device());
screen_device *screen = screen_iterator.byindex(target_to_screen[curr_target]);
render_container &screen_container = screen->container();
@@ -1399,11 +1306,11 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
float(back_color_rgb.g()) / 255.0f,
float(back_color_rgb.b()) / 255.0f };
- set_curr_effect(post_effect);
+ set_curr_effect(post_effect.get());
curr_effect->update_uniforms();
curr_effect->set_texture("ShadowTexture", shadow_texture == nullptr ? nullptr : shadow_texture->get_finaltex());
curr_effect->set_int("ShadowTileMode", options->shadow_mask_tile_mode);
- curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
+ curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index].Get());
curr_effect->set_vector("BackColor", 3, back_color);
curr_effect->set_vector("ScreenScale", 2, screen_scale);
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
@@ -1412,7 +1319,7 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
curr_effect->set_bool("PrepareBloom", prepare_bloom);
next_index = rt->next_index(next_index);
- blit(prepare_bloom ? rt->source_surface[next_index] : rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(prepare_bloom ? rt->source_surface[next_index].Get() : rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1421,11 +1328,11 @@ int shaders::chroma_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
int next_index = source_index;
- set_curr_effect(chroma_effect);
+ set_curr_effect(chroma_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1439,7 +1346,7 @@ int shaders::downsample_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
- set_curr_effect(downsample_effect);
+ set_curr_effect(downsample_effect.get());
curr_effect->update_uniforms();
for (int bloom_index = 0; bloom_index < rt->bloom_count; bloom_index++)
@@ -1447,10 +1354,10 @@ int shaders::downsample_pass(d3d_render_target *rt, int source_index, poly_info
curr_effect->set_vector("TargetDims", 2, rt->bloom_dims[bloom_index]);
curr_effect->set_texture("DiffuseTexture",
bloom_index == 0
- ? rt->source_texture[next_index]
- : rt->bloom_texture[bloom_index - 1]);
+ ? rt->source_texture[next_index].Get()
+ : rt->bloom_texture[bloom_index - 1].Get());
- blit(rt->bloom_surface[bloom_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->bloom_surface[bloom_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
}
return next_index;
@@ -1466,7 +1373,7 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly
return next_index;
}
- set_curr_effect(bloom_effect);
+ set_curr_effect(bloom_effect.get());
curr_effect->update_uniforms();
curr_effect->set_float("Level0Weight", options->bloom_level0_weight);
@@ -1483,22 +1390,22 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly
curr_effect->set_float("BloomScale", options->bloom_scale);
curr_effect->set_vector("BloomOverdrive", 3, options->bloom_overdrive);
- curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
+ curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index].Get());
char name[14] = "BloomTexture*";
for (int index = 1; index < rt->bloom_count; index++)
{
name[12] = 'A' + index - 1;
- curr_effect->set_texture(name, rt->bloom_texture[index - 1]);
+ curr_effect->set_texture(name, rt->bloom_texture[index - 1].Get());
}
for (int index = rt->bloom_count; index < MAX_BLOOM_COUNT; index++)
{
name[12] = 'A' + index - 1;
- curr_effect->set_texture(name, black_texture);
+ curr_effect->set_texture(name, black_texture.Get());
}
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1519,12 +1426,12 @@ int shaders::distortion_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
- set_curr_effect(distortion_effect);
+ set_curr_effect(distortion_effect.get());
curr_effect->update_uniforms();
- curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
+ curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index].Get());
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], false, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), false, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1533,14 +1440,14 @@ int shaders::vector_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
int next_index = source_index;
- set_curr_effect(vector_effect);
+ set_curr_effect(vector_effect.get());
curr_effect->update_uniforms();
curr_effect->set_float("LengthRatio", options->vector_length_ratio);
curr_effect->set_float("LengthScale", options->vector_length_scale);
curr_effect->set_float("BeamSmooth", options->vector_beam_smooth);
// we need to clear the vector render target here
- blit(rt->target_surface[next_index], true, poly->type(), vertnum, poly->count());
+ blit(rt->target_surface[next_index].Get(), true, poly->type(), vertnum, poly->count());
return next_index;
}
@@ -1549,16 +1456,16 @@ int shaders::vector_buffer_pass(d3d_render_target *rt, int source_index, poly_in
{
int next_index = source_index;
- set_curr_effect(vector_buffer_effect);
+ set_curr_effect(vector_buffer_effect.get());
curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
curr_effect->set_texture("LutTexture", lut_texture == nullptr ? nullptr : lut_texture->get_finaltex());
// we need to clear the vector render target here
next_index = rt->next_index(next_index);
- blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index].Get(), true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1569,14 +1476,14 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
d3d->set_blendmode(PRIMFLAG_GET_BLENDMODE(poly->flags()));
- set_curr_effect(default_effect);
+ set_curr_effect(default_effect.get());
curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index].Get());
curr_effect->set_texture("LutTexture", lut_texture == nullptr ? nullptr : lut_texture->get_finaltex());
- blit(backbuffer, false, poly->type(), vertnum, poly->count());
+ blit(backbuffer.Get(), false, poly->type(), vertnum, poly->count());
if (recording_movie)
{
@@ -1588,9 +1495,9 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
if (render_snap)
{
// we need to clear the snap render target here
- blit(snap_target, true, poly->type(), vertnum, poly->count());
+ blit(snap_target.Get(), true, poly->type(), vertnum, poly->count());
- render_snapshot(snap_target);
+ render_snapshot(snap_target.Get());
render_snap = false;
}
@@ -1602,7 +1509,7 @@ void shaders::ui_pass(poly_info *poly, int vertnum)
{
d3d->set_blendmode(PRIMFLAG_GET_BLENDMODE(poly->flags()));
- set_curr_effect(PRIMFLAG_GET_TEXWRAP(poly->flags()) ? ui_wrap_effect : ui_effect);
+ set_curr_effect(PRIMFLAG_GET_TEXWRAP(poly->flags()) ? ui_wrap_effect.get() : ui_effect.get());
curr_effect->set_texture("Diffuse", diffuse_texture->get_finaltex());
curr_effect->update_uniforms();
@@ -1626,8 +1533,6 @@ void shaders::render_quad(poly_info *poly, int vertnum)
curr_texture = poly->texture();
curr_poly = poly;
- auto win = d3d->assert_window();
-
if (PRIMFLAG_GET_SCREENTEX(poly->flags()))
{
if (curr_texture == nullptr)
@@ -1687,7 +1592,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
int source_width = int(poly->prim_width() + 0.5f);
int source_height = int(poly->prim_height() + 0.5f);
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(source_width, source_height);
}
@@ -1704,7 +1609,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = vector_pass(rt, next_index, poly, vertnum);
- HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer);
+ HRESULT result = d3d->get_device()->SetRenderTarget(0, backbuffer.Get());
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call\n", result);
@@ -1718,7 +1623,7 @@ void shaders::render_quad(poly_info *poly, int vertnum)
int source_width = int(poly->prim_width() + 0.5f);
int source_height = int(poly->prim_height() + 0.5f);
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(source_width, source_height);
}
@@ -1783,7 +1688,7 @@ void shaders::end_draw()
return;
}
- backbuffer->Release();
+ backbuffer->Release(); // TODO: where's the matching AddRef that requires this explicit Release?
}
@@ -1798,8 +1703,6 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, int width
return nullptr;
}
- auto win = d3d->assert_window();
-
int source_width = width;
int source_height = height;
int source_screen = screen;
@@ -1807,7 +1710,7 @@ d3d_render_target* shaders::get_texture_target(render_primitive *prim, int width
int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(target_width, target_height);
}
@@ -1838,8 +1741,6 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim, int screen
return nullptr;
}
- auto win = d3d->assert_window();
-
int source_width = int(prim->get_quad_width() + 0.5f);
int source_height = int(prim->get_quad_height() + 0.5f);
int source_screen = screen;
@@ -1847,7 +1748,7 @@ d3d_render_target* shaders::get_vector_target(render_primitive *prim, int screen
int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(source_width, source_height);
std::swap(target_width, target_height);
@@ -1879,8 +1780,6 @@ bool shaders::create_vector_target(render_primitive *prim, int screen)
return false;
}
- auto win = d3d->assert_window();
-
int source_width = int(prim->get_quad_width() + 0.5f);
int source_height = int(prim->get_quad_height() + 0.5f);
int source_screen = screen;
@@ -1888,7 +1787,7 @@ bool shaders::create_vector_target(render_primitive *prim, int screen)
int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
std::swap(source_width, source_height);
std::swap(target_width, target_height);
@@ -1934,8 +1833,6 @@ bool shaders::create_texture_target(render_primitive *prim, int width, int heigh
return false;
}
- auto win = d3d->assert_window();
-
int source_width = width;
int source_height = height;
int source_screen = screen;
@@ -1943,7 +1840,7 @@ bool shaders::create_texture_target(render_primitive *prim, int width, int heigh
int target_height = int(prim->get_full_quad_height() + 0.5f);
target_width *= oversampling_enable ? 2 : 1;
target_height *= oversampling_enable ? 2 : 1;
- if (win->swap_xy())
+ if (d3d->window().swap_xy())
{
// source texture is already swapped
std::swap(target_width, target_height);
@@ -1981,58 +1878,29 @@ void shaders::delete_resources()
m_render_target_list.clear();
- delete downsample_effect;
- delete bloom_effect;
- delete vector_effect;
- delete default_effect;
- delete ui_effect;
- delete vector_buffer_effect;
- delete post_effect;
- delete distortion_effect;
- delete prescale_effect;
- delete prescale_point_effect;
- delete phosphor_effect;
- delete focus_effect;
- delete scanline_effect;
- delete deconverge_effect;
- delete color_effect;
- delete ntsc_effect;
- delete chroma_effect;
-
- downsample_effect = nullptr;
- bloom_effect = nullptr;
- vector_effect = nullptr;
- default_effect = nullptr;
- ui_effect = nullptr;
- vector_buffer_effect = nullptr;
- post_effect = nullptr;
- distortion_effect = nullptr;
- prescale_effect = nullptr;
- prescale_point_effect = nullptr;
- phosphor_effect = nullptr;
- focus_effect = nullptr;
- scanline_effect = nullptr;
- deconverge_effect = nullptr;
- color_effect = nullptr;
- ntsc_effect = nullptr;
- chroma_effect = nullptr;
-
- if (backbuffer)
- {
- backbuffer->Release();
- backbuffer = nullptr;
- }
-
- if (black_surface)
- {
- black_surface->Release();
- black_surface = nullptr;
- }
- if (black_texture)
- {
- black_texture->Release();
- black_texture = nullptr;
- }
+ downsample_effect.reset();
+ bloom_effect.reset();
+ vector_effect.reset();
+ default_effect.reset();
+ ui_effect.reset();
+ ui_wrap_effect.reset();
+ vector_buffer_effect.reset();
+ post_effect.reset();
+ distortion_effect.reset();
+ prescale_effect.reset();
+ prescale_point_effect.reset();
+ phosphor_effect.reset();
+ focus_effect.reset();
+ scanline_effect.reset();
+ deconverge_effect.reset();
+ color_effect.reset();
+ ntsc_effect.reset();
+ chroma_effect.reset();
+
+ backbuffer.Reset();
+
+ black_surface.Reset();
+ black_texture.Reset();
shadow_bitmap.reset();
lut_bitmap.reset();
@@ -2396,10 +2264,6 @@ void shaders::init_slider_list()
m_sliders.clear();
m_core_sliders.clear();
- for (slider* slider : internal_sliders)
- {
- delete slider;
- }
internal_sliders.clear();
const screen_device *first_screen = screen_device_enumerator(machine->root_device()).first();
@@ -2432,28 +2296,27 @@ void shaders::init_slider_list()
for (int j = 0; j < count; j++)
{
- auto* slider_arg = new slider(desc, get_slider_option(desc->id, j), &options->params_dirty);
- internal_sliders.push_back(slider_arg);
+ slider &slider_arg = *internal_sliders.emplace_back(std::make_unique<slider>(desc, get_slider_option(desc->id, j), &options->params_dirty));
std::string name = desc->name;
switch (desc->slider_type)
{
case SLIDER_VEC2:
{
- std::string names[2] = { " X", " Y" };
- name = name + names[j];
+ char const *const names[2] = { " X", " Y" };
+ name += names[j];
break;
}
case SLIDER_COLOR:
{
- std::string names[3] = { " Red", " Green", " Blue" };
- name = name + names[j];
+ char const *const names[3] = { " Red", " Green", " Blue" };
+ name += names[j];
break;
}
default:
break;
}
- std::unique_ptr<slider_state> core_slider = slider_alloc(std::move(name), desc->minval, desc->defval, desc->maxval, desc->step, slider_arg);
+ std::unique_ptr<slider_state> core_slider = slider_alloc(std::move(name), desc->minval, desc->defval, desc->maxval, desc->step, &slider_arg);
ui::menu_item item(ui::menu_item_type::SLIDER, core_slider.get());
item.set_text(core_slider->description);
@@ -2488,8 +2351,7 @@ void uniform::update()
hlsl_options *options = shadersys->options;
renderer_d3d9 *d3d = shadersys->d3d;
- auto win = d3d->assert_window();
- const screen_device *first_screen = screen_device_enumerator(win->machine().root_device()).first();
+ const screen_device *first_screen = screen_device_enumerator(d3d->window().machine().root_device()).first();
bool vector_screen =
first_screen != nullptr &&
@@ -2505,7 +2367,7 @@ void uniform::update()
}
case CU_SCREEN_COUNT:
{
- int screen_count = win->target()->current_view().visible_screen_count();
+ int screen_count = d3d->window().target()->current_view().visible_screen_count();
m_shader->set_int("ScreenCount", screen_count);
break;
}
@@ -2568,7 +2430,7 @@ void uniform::update()
case CU_SWAP_XY:
{
- m_shader->set_bool("SwapXY", win->swap_xy());
+ m_shader->set_bool("SwapXY", d3d->window().swap_xy());
break;
}
case CU_VECTOR_SCREEN:
diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h
index aa990e3c30c..f06deca2a57 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.h
+++ b/src/osd/modules/render/d3d/d3dhlsl.h
@@ -13,8 +13,11 @@
#include "../frontend/mame/ui/slider.h"
#include "modules/lib/osdlib.h"
-#include <vector>
+#include <wrl/client.h>
+
#include <map>
+#include <memory>
+#include <vector>
//============================================================
// TYPE DEFINITIONS
@@ -308,9 +311,9 @@ public:
shaders();
~shaders();
- bool init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *renderer);
+ bool init(IDirect3D9 *d3dobj, running_machine *machine, renderer_d3d9 *renderer);
- bool enabled() { return post_fx_enable && d3dintf->post_fx_available; }
+ bool enabled() { return post_fx_enable && d3d->post_fx_available(); }
void toggle() { post_fx_enable = initialized && !post_fx_enable; }
void begin_frame(render_primitive_list *primlist);
@@ -348,6 +351,10 @@ public:
void *get_slider_option(int id, int index = 0);
private:
+ using IDirect3D9Ptr = Microsoft::WRL::ComPtr<IDirect3D9>;
+ using IDirect3DTexture9Ptr = Microsoft::WRL::ComPtr<IDirect3DTexture9>;
+ using IDirect3DSurface9Ptr = Microsoft::WRL::ComPtr<IDirect3DSurface9>;
+
void set_curr_effect(effect *curr_effect);
void blit(IDirect3DSurface9 *dst, bool clear_dst, D3DPRIMITIVETYPE prim_type, uint32_t prim_index, uint32_t prim_count);
@@ -376,7 +383,7 @@ private:
int screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
void ui_pass(poly_info *poly, int vertnum);
- d3d_base * d3dintf; // D3D interface
+ IDirect3D9Ptr d3dobj; // D3D interface
running_machine * machine;
renderer_d3d9 * d3d; // D3D renderer
@@ -398,43 +405,43 @@ private:
texture_info * ui_lut_texture;
hlsl_options * options; // current options
- IDirect3DSurface9 * black_surface; // black dummy surface
- IDirect3DTexture9 * black_texture; // black dummy texture
+ IDirect3DSurface9Ptr black_surface; // black dummy surface
+ IDirect3DTexture9Ptr black_texture; // black dummy texture
bool recording_movie; // ongoing movie recording
std::unique_ptr<movie_recorder> recorder; // HLSL post-render movie recorder
bool render_snap; // whether or not to take HLSL post-render snapshot
- IDirect3DSurface9 * snap_copy_target; // snapshot destination surface in system memory
- IDirect3DTexture9 * snap_copy_texture; // snapshot destination surface in system memory
- IDirect3DSurface9 * snap_target; // snapshot upscaled surface
- IDirect3DTexture9 * snap_texture; // snapshot upscaled texture
+ IDirect3DSurface9Ptr snap_copy_target; // snapshot destination surface in system memory
+ IDirect3DTexture9Ptr snap_copy_texture; // snapshot destination surface in system memory
+ IDirect3DSurface9Ptr snap_target; // snapshot upscaled surface
+ IDirect3DTexture9Ptr snap_texture; // snapshot upscaled texture
int snap_width; // snapshot width
int snap_height; // snapshot height
bool initialized; // whether or not we're initialized
// HLSL effects
- IDirect3DSurface9 * backbuffer; // pointer to our device's backbuffer
+ IDirect3DSurface9Ptr backbuffer; // pointer to our device's backbuffer
effect * curr_effect; // pointer to the currently active effect object
- effect * default_effect; // pointer to the primary-effect object
- effect * ui_effect; // pointer to the UI-element effect object
- effect * ui_wrap_effect; // pointer to the UI-element effect object with texture wrapping
- effect * vector_buffer_effect; // pointer to the vector-buffering effect object
- effect * prescale_effect; // pointer to the prescale-effect object
- effect * prescale_point_effect; // pointer to the prescale-effect object with point filtering
- effect * post_effect; // pointer to the post-effect object
- effect * distortion_effect; // pointer to the distortion-effect object
- effect * scanline_effect;
- effect * focus_effect; // pointer to the focus-effect object
- effect * phosphor_effect; // pointer to the phosphor-effect object
- effect * deconverge_effect; // pointer to the deconvergence-effect object
- effect * color_effect; // pointer to the color-effect object
- effect * ntsc_effect; // pointer to the NTSC effect object
- effect * bloom_effect; // pointer to the bloom composite effect
- effect * downsample_effect; // pointer to the bloom downsample effect
- effect * vector_effect; // pointer to the vector-effect object
- effect * chroma_effect;
+ std::unique_ptr<effect> default_effect; // pointer to the primary-effect object
+ std::unique_ptr<effect> ui_effect; // pointer to the UI-element effect object
+ std::unique_ptr<effect> ui_wrap_effect; // pointer to the UI-element effect object with texture wrapping
+ std::unique_ptr<effect> vector_buffer_effect; // pointer to the vector-buffering effect object
+ std::unique_ptr<effect> prescale_effect; // pointer to the prescale-effect object
+ std::unique_ptr<effect> prescale_point_effect; // pointer to the prescale-effect object with point filtering
+ std::unique_ptr<effect> post_effect; // pointer to the post-effect object
+ std::unique_ptr<effect> distortion_effect; // pointer to the distortion-effect object
+ std::unique_ptr<effect> scanline_effect;
+ std::unique_ptr<effect> focus_effect; // pointer to the focus-effect object
+ std::unique_ptr<effect> phosphor_effect; // pointer to the phosphor-effect object
+ std::unique_ptr<effect> deconverge_effect; // pointer to the deconvergence-effect object
+ std::unique_ptr<effect> color_effect; // pointer to the color-effect object
+ std::unique_ptr<effect> ntsc_effect; // pointer to the NTSC effect object
+ std::unique_ptr<effect> bloom_effect; // pointer to the bloom composite effect
+ std::unique_ptr<effect> downsample_effect; // pointer to the bloom downsample effect
+ std::unique_ptr<effect> vector_effect; // pointer to the vector-effect object
+ std::unique_ptr<effect> chroma_effect;
texture_info * diffuse_texture;
bool filter_screens;
@@ -444,9 +451,9 @@ private:
std::vector<std::unique_ptr<d3d_render_target>> m_render_target_list;
- std::vector<slider*> internal_sliders;
+ std::vector<std::unique_ptr<slider> > internal_sliders;
std::vector<ui::menu_item> m_sliders;
- std::vector<std::unique_ptr<slider_state>> m_core_sliders;
+ std::vector<std::unique_ptr<slider_state> > m_core_sliders;
static slider_desc s_sliders[];
static hlsl_options last_options; // last used options
diff --git a/src/osd/modules/render/draw13.cpp b/src/osd/modules/render/draw13.cpp
index 29310ea3f2e..9b426c6c4f2 100644
--- a/src/osd/modules/render/draw13.cpp
+++ b/src/osd/modules/render/draw13.cpp
@@ -2,7 +2,7 @@
// copyright-holders: Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
-// draw13.c - SDL 2.0 drawing implementation
+// draw13.cpp - SDL 2.0 drawing implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
@@ -10,8 +10,11 @@
//
//============================================================
-#include "emu.h"
-#include "draw13.h"
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
+
+#if defined(OSD_SDL)
// OSD headers
#include "sdlopts.h"
@@ -20,9 +23,190 @@
// lib/util
#include "options.h"
+// emu
+#include "emucore.h"
+#include "render.h"
+
+// standard SDL headers
+#include <SDL2/SDL.h>
+
// standard C headers
+#include <algorithm>
#include <cmath>
#include <cstdio>
+#include <iterator>
+
+
+namespace osd {
+
+namespace {
+
+struct quad_setup_data
+{
+ quad_setup_data() = default;
+
+ void compute(const render_primitive &prim, const int prescale);
+
+ int32_t dudx = 0, dvdx = 0, dudy = 0, dvdy = 0;
+ int32_t startu = 0, startv = 0;
+ int32_t rotwidth = 0, rotheight = 0;
+};
+
+//============================================================
+// Textures
+//============================================================
+
+class renderer_sdl2;
+struct copy_info_t;
+
+/* texture_info holds information about a texture */
+class texture_info
+{
+ friend class simple_list<texture_info>;
+public:
+ texture_info(renderer_sdl2 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const uint32_t flags);
+ ~texture_info();
+
+ void set_data(const render_texinfo &texsource, const uint32_t flags);
+ void render_quad(const render_primitive &prim, const int x, const int y);
+ bool matches(const render_primitive &prim, const quad_setup_data &setup);
+
+ copy_info_t const *compute_size_type();
+
+ void *m_pixels; // pixels for the texture
+ int m_pitch;
+
+ copy_info_t const *m_copyinfo;
+ quad_setup_data m_setup;
+
+ osd_ticks_t m_last_access;
+
+ int raw_width() const { return m_texinfo.width; }
+ int raw_height() const { return m_texinfo.height; }
+
+ texture_info *next() { return m_next; }
+ const render_texinfo &texinfo() const { return m_texinfo; }
+ render_texinfo &texinfo() { return m_texinfo; }
+
+ HashT hash() const { return m_hash; }
+ uint32_t flags() const { return m_flags; }
+ // FIXME:
+ bool is_pixels_owned() const;
+
+private:
+ void set_coloralphamode(SDL_Texture *texture_id, const render_color *color);
+
+ Uint32 m_sdl_access;
+ renderer_sdl2 * m_renderer;
+ render_texinfo m_texinfo; // copy of the texture info
+ HashT m_hash; // hash value for the texture (must be >= pointer size)
+ uint32_t m_flags; // rendering flags
+
+ SDL_Texture * m_texture_id;
+ bool m_is_rotated;
+
+ int m_format; // texture format
+ SDL_BlendMode m_sdl_blendmode;
+
+ texture_info * m_next; // next texture in the list
+};
+
+// inline functions and macros
+#include "blit13.ipp"
+
+//============================================================
+// TEXCOPY FUNCS
+//============================================================
+
+enum SDL_TEXFORMAT_E
+{
+ SDL_TEXFORMAT_ARGB32 = 0,
+ SDL_TEXFORMAT_RGB32,
+ SDL_TEXFORMAT_RGB32_PALETTED,
+ SDL_TEXFORMAT_YUY16,
+ SDL_TEXFORMAT_YUY16_PALETTED,
+ SDL_TEXFORMAT_PALETTE16,
+ SDL_TEXFORMAT_RGB15,
+ SDL_TEXFORMAT_RGB15_PALETTED,
+ SDL_TEXFORMAT_PALETTE16A,
+ SDL_TEXFORMAT_PALETTE16_ARGB1555,
+ SDL_TEXFORMAT_RGB15_ARGB1555,
+ SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555,
+ SDL_TEXFORMAT_LAST = SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555
+};
+
+struct copy_info_t
+{
+ int src_fmt;
+ Uint32 dst_fmt;
+ const blit_base *blitter;
+ Uint32 bm_mask;
+ const char *srcname;
+ const char *dstname;
+ /* Statistics */
+ mutable uint64_t pixel_count;
+ mutable int64_t time;
+ mutable int samples;
+ mutable int perf;
+ /* list */
+ copy_info_t *next;
+};
+
+/* renderer_sdl2 is the information about SDL for the current screen */
+class renderer_sdl2 : public osd_renderer
+{
+public:
+ renderer_sdl2(
+ osd_window &window,
+ copy_info_t const *const (&blit_info)[SDL_TEXFORMAT_LAST + 1]);
+
+ virtual ~renderer_sdl2()
+ {
+ destroy_all_textures();
+ SDL_DestroyRenderer(m_sdl_renderer);
+ m_sdl_renderer = nullptr;
+ }
+
+ virtual int create() override;
+ virtual int draw(const int update) override;
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
+ virtual render_primitive_list *get_primitives() override;
+
+ int RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat);
+
+ SDL_Renderer *m_sdl_renderer;
+ copy_info_t const *const (&m_blit_info)[SDL_TEXFORMAT_LAST + 1];
+
+private:
+ void render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y);
+
+ texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
+ texture_info *texture_update(const render_primitive &prim);
+
+ void destroy_all_textures();
+
+ int32_t m_blittimer;
+
+ simple_list<texture_info> m_texlist; // list of active textures
+
+ float m_last_hofs;
+ float m_last_vofs;
+
+ int m_width;
+ int m_height;
+
+ osd_dim m_blit_dim;
+
+ struct
+ {
+ Uint32 format;
+ int status;
+ } fmt_support[30];
+
+ // Stats
+ int64_t m_last_blit_time;
+ int64_t m_last_blit_pixels;
+};
//============================================================
@@ -57,9 +241,12 @@ static inline bool is_transparent(const float &a)
// CONSTRUCTOR & DESTRUCTOR
//============================================================
-renderer_sdl2::renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags)
- : osd_renderer(window, FLAG_NEEDS_OPENGL | extra_flags)
+renderer_sdl2::renderer_sdl2(
+ osd_window &window,
+ copy_info_t const *const (&blit_info)[SDL_TEXFORMAT_LAST + 1])
+ : osd_renderer(window)
, m_sdl_renderer(nullptr)
+ , m_blit_info(blit_info)
, m_blittimer(0)
, m_last_hofs(0)
, m_last_vofs(0)
@@ -74,112 +261,8 @@ renderer_sdl2::renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags
fmt_support[i].format = 0;
fmt_support[i].status = 0;
}
-
- if (!s_blit_info_initialized)
- {
- /* On OSX, calling this from drawsdl2_init will
- * prohibit fullscreen toggling. It is than not possible
- * to toggle from fullscreen to window mode.
- */
- expand_copy_info(s_blit_info_default);
- s_blit_info_initialized = true;
- }
}
-
-//============================================================
-// STATIC VARIABLES
-//============================================================
-
-#define BM_ALL (UINT32_MAX)
-//( SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD)
-
-#define ENTRY(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, 0}
-#define ENTRY_BM(a,b,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0}
-#define ENTRY_LR(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1}
-
-const copy_info_t renderer_sdl2::s_blit_info_default[] =
-{
- /* no rotation */
- ENTRY(ARGB32, ARGB8888, argb32_argb32),
- ENTRY_LR(ARGB32, RGB888, argb32_rgb32),
- /* Entry primarily for directfb */
- ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_ADD),
- ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_MOD),
- ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_NONE),
-
- ENTRY(RGB32, ARGB8888, rgb32_argb32),
- ENTRY(RGB32, RGB888, rgb32_rgb32),
-
- ENTRY(RGB32_PALETTED, ARGB8888, rgb32pal_argb32),
- ENTRY(RGB32_PALETTED, RGB888, rgb32pal_argb32),
-
- ENTRY(YUY16, UYVY, yuv16_uyvy),
- ENTRY(YUY16, YUY2, yuv16_yuy2),
- ENTRY(YUY16, YVYU, yuv16_yvyu),
- ENTRY(YUY16, ARGB8888, yuv16_argb32),
- ENTRY(YUY16, RGB888, yuv16_argb32),
-
- ENTRY(YUY16_PALETTED, UYVY, yuv16pal_uyvy),
- ENTRY(YUY16_PALETTED, YUY2, yuv16pal_yuy2),
- ENTRY(YUY16_PALETTED, YVYU, yuv16pal_yvyu),
- ENTRY(YUY16_PALETTED, ARGB8888, yuv16pal_argb32),
- ENTRY(YUY16_PALETTED, RGB888, yuv16pal_argb32),
-
- ENTRY(PALETTE16, ARGB8888, pal16_argb32),
- ENTRY(PALETTE16, RGB888, pal16_argb32),
-
- ENTRY(RGB15, RGB555, rgb15_rgb555),
- ENTRY(RGB15, ARGB1555, rgb15_argb1555),
- ENTRY(RGB15, ARGB8888, rgb15_argb32),
- ENTRY(RGB15, RGB888, rgb15_argb32),
-
- ENTRY(RGB15_PALETTED, ARGB8888, rgb15pal_argb32),
- ENTRY(RGB15_PALETTED, RGB888, rgb15pal_argb32),
-
- ENTRY(PALETTE16A, ARGB8888, pal16a_argb32),
- ENTRY(PALETTE16A, RGB888, pal16a_rgb32),
-
- /* rotation */
- ENTRY(ARGB32, ARGB8888, rot_argb32_argb32),
- ENTRY_LR(ARGB32, RGB888, rot_argb32_rgb32),
- /* Entry primarily for directfb */
- ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_ADD),
- ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_MOD),
- ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_NONE),
-
- ENTRY(RGB32, ARGB8888, rot_rgb32_argb32),
- ENTRY(RGB32, RGB888, rot_argb32_argb32),
-
- ENTRY(RGB32_PALETTED, ARGB8888, rot_rgb32pal_argb32),
- ENTRY(RGB32_PALETTED, RGB888, rot_rgb32pal_argb32),
-
- ENTRY(YUY16, ARGB8888, rot_yuv16_argb32rot),
- ENTRY(YUY16, RGB888, rot_yuv16_argb32rot),
-
- ENTRY(YUY16_PALETTED, ARGB8888, rot_yuv16pal_argb32rot),
- ENTRY(YUY16_PALETTED, RGB888, rot_yuv16pal_argb32rot),
-
- ENTRY(PALETTE16, ARGB8888, rot_pal16_argb32),
- ENTRY(PALETTE16, RGB888, rot_pal16_argb32),
-
- ENTRY(RGB15, RGB555, rot_rgb15_argb1555),
- ENTRY(RGB15, ARGB1555, rot_rgb15_argb1555),
- ENTRY(RGB15, ARGB8888, rot_rgb15_argb32),
- ENTRY(RGB15, RGB888, rot_rgb15_argb32),
-
- ENTRY(RGB15_PALETTED, ARGB8888, rot_rgb15pal_argb32),
- ENTRY(RGB15_PALETTED, RGB888, rot_rgb15pal_argb32),
-
- ENTRY(PALETTE16A, ARGB8888, rot_pal16a_argb32),
- ENTRY(PALETTE16A, RGB888, rot_pal16a_rgb32),
-
-{ -1 },
-};
-
-copy_info_t* renderer_sdl2::s_blit_info[SDL_TEXFORMAT_LAST+1] = { nullptr };
-bool renderer_sdl2::s_blit_info_initialized = false;
-
//============================================================
// INLINES
//============================================================
@@ -274,7 +357,7 @@ void renderer_sdl2::render_quad(texture_info *texture, const render_primitive &p
if (texture)
{
- copy_info_t *copyinfo = texture->m_copyinfo;
+ copy_info_t const *copyinfo = texture->m_copyinfo;
copyinfo->time -= osd_ticks();
texture->render_quad(prim, x, y);
copyinfo->time += osd_ticks();
@@ -326,59 +409,6 @@ int renderer_sdl2::RendererSupportsFormat(Uint32 format, Uint32 access, const ch
return 0;
}
-//============================================================
-// drawsdl_init
-//============================================================
-
-void renderer_sdl2::add_list(copy_info_t **head, const copy_info_t *element, Uint32 bm)
-{
- copy_info_t *newci = new copy_info_t;
- *newci = *element;
-
- newci->bm_mask = bm;
- newci->next = *head;
- *head = newci;
-}
-
-void renderer_sdl2::expand_copy_info(const copy_info_t *list)
-{
- for (const copy_info_t *bi = list; bi->src_fmt != -1; bi++)
- {
- if (bi->bm_mask == BM_ALL)
- {
- add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_NONE);
- add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_ADD);
- add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_MOD);
- add_list(&s_blit_info[bi->src_fmt], bi, SDL_BLENDMODE_BLEND);
- }
- else
- {
- add_list(&s_blit_info[bi->src_fmt], bi, bi->bm_mask);
- }
- }
-}
-
-// FIXME: machine only used to access options.
-void renderer_sdl2::init(running_machine &machine)
-{
- osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n");
-
-#if USE_OPENGL
- // Load the GL library now - else MT will fail
- const char *stemp = downcast<sdl_options &>(machine.options()).gl_lib();
-#else
- const char *stemp = nullptr;
-#endif
- if (stemp != nullptr && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
- stemp = nullptr;
-
- // No fatalerror here since not all video drivers support GL !
- if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==nullptr
- osd_printf_warning("Warning: Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
- else
- osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
-}
-
//============================================================
// sdl_info::create
@@ -431,12 +461,10 @@ int renderer_sdl2::create()
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
}
- auto win = assert_window();
-
if (video_config.waitvsync)
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
else
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_ACCELERATED);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_ACCELERATED);
if (!m_sdl_renderer)
{
@@ -480,15 +508,11 @@ int renderer_sdl2::xy_to_render_target(int x, int y, int *xt, int *yt)
void renderer_sdl2::destroy_all_textures()
{
- auto win = assert_window();
- if (win == nullptr)
- return;
-
- if(win->m_primlist)
+ if (window().m_primlist)
{
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
m_texlist.reset();
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
}
else
m_texlist.reset();
@@ -504,13 +528,7 @@ int renderer_sdl2::draw(int update)
float vofs, hofs;
int blit_pixels = 0;
- if (video_config.novideo)
- {
- return 0;
- }
-
- auto win = assert_window();
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
{
@@ -557,10 +575,10 @@ int renderer_sdl2::draw(int update)
m_last_hofs = hofs;
m_last_vofs = vofs;
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// now draw
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
Uint8 sr, sg, sb, sa;
@@ -590,7 +608,7 @@ int renderer_sdl2::draw(int update)
}
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
m_last_blit_pixels = blit_pixels;
m_last_blit_time = -osd_ticks();
@@ -609,22 +627,23 @@ int renderer_sdl2::draw(int update)
// texture_compute_size and type
//============================================================
-copy_info_t *texture_info::compute_size_type()
+copy_info_t const *texture_info::compute_size_type()
{
- copy_info_t *result = nullptr;
+ copy_info_t const *result = nullptr;
int maxperf = 0;
- for (copy_info_t *bi = renderer_sdl2::s_blit_info[m_format]; bi != nullptr; bi = bi->next)
+ for (copy_info_t const *bi = m_renderer->m_blit_info[m_format]; bi != nullptr; bi = bi->next)
{
- if ((m_is_rotated == bi->blitter->m_is_rot)
- && (m_sdl_blendmode == bi->bm_mask))
+ if ((m_is_rotated == bi->blitter->m_is_rot) && (m_sdl_blendmode == bi->bm_mask))
{
if (m_renderer->RendererSupportsFormat(bi->dst_fmt, m_sdl_access, bi->dstname))
{
- int perf = bi->perf;
+ int const perf = bi->perf;
if (perf == 0)
+ {
return bi;
- else if (perf > (maxperf * 102) / 100)
+ }
+ else if (perf > ((maxperf * 102) / 100))
{
result = bi;
maxperf = perf;
@@ -636,15 +655,14 @@ copy_info_t *texture_info::compute_size_type()
if (result)
return result;
- /* try last resort handlers */
- for (copy_info_t *bi = renderer_sdl2::s_blit_info[m_format]; bi != nullptr; bi = bi->next)
+ // try last resort handlers
+ for (copy_info_t const *bi = m_renderer->m_blit_info[m_format]; bi != nullptr; bi = bi->next)
{
- if ((m_is_rotated == bi->blitter->m_is_rot)
- && (m_sdl_blendmode == bi->bm_mask))
+ if ((m_is_rotated == bi->blitter->m_is_rot) && (m_sdl_blendmode == bi->bm_mask))
if (m_renderer->RendererSupportsFormat(bi->dst_fmt, m_sdl_access, bi->dstname))
return bi;
}
- //FIXME: crash implement a -do nothing handler */
+ //FIXME: crash implement a -do nothing handler
return nullptr;
}
@@ -897,32 +915,6 @@ texture_info *renderer_sdl2::texture_find(const render_primitive &prim, const qu
}
//============================================================
-// exit
-//============================================================
-
-void renderer_sdl2::exit()
-{
- if (s_blit_info_initialized)
- {
- for (int i = 0; i <= SDL_TEXFORMAT_LAST; i++)
- {
- for (copy_info_t *bi = s_blit_info[i]; bi != nullptr; )
- {
- if (bi->pixel_count)
- osd_printf_verbose("%s -> %s %s blendmode 0x%02x, %d samples: %d KPixel/sec\n", bi->srcname, bi->dstname,
- bi->blitter->m_is_rot ? "rot" : "norot", bi->bm_mask, bi->samples,
- (int) bi->perf);
- copy_info_t *freeme = bi;
- bi = bi->next;
- delete freeme;
- }
- s_blit_info[i] = nullptr;
- }
- s_blit_info_initialized = false;
- }
-}
-
-//============================================================
// texture_update
//============================================================
@@ -931,8 +923,7 @@ texture_info * renderer_sdl2::texture_update(const render_primitive &prim)
quad_setup_data setup;
texture_info *texture;
- auto win = assert_window();
- setup.compute(prim, win->prescale());
+ setup.compute(prim, window().prescale());
texture = texture_find(prim, setup);
@@ -959,16 +950,251 @@ texture_info * renderer_sdl2::texture_update(const render_primitive &prim)
render_primitive_list *renderer_sdl2::get_primitives()
{
- auto win = assert_window();
- if (win == nullptr)
- return nullptr;
-
- osd_dim nd = win->get_size();
+ osd_dim nd = window().get_size();
if (nd != m_blit_dim)
{
m_blit_dim = nd;
notify_changed();
}
- win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
- return &win->target()->get_primitives();
+ window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
+}
+
+
+class video_sdl2 : public osd_module, public render_module
+{
+public:
+ video_sdl2()
+ : osd_module(OSD_RENDERER_PROVIDER, "accel")
+ , m_blit_info_initialized(false)
+ , m_gllib_loaded(false)
+ {
+ std::fill(std::begin(m_blit_info), std::end(m_blit_info), nullptr);
+ }
+ ~video_sdl2()
+ {
+ free_copy_info();
+ }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override { free_copy_info(); }
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE | FLAG_SDL_NEEDS_OPENGL; }
+
+private:
+ static inline constexpr Uint32 BM_ALL = UINT32_MAX; // SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND | SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD
+
+ void expand_copy_info();
+ void free_copy_info();
+
+ static void add_list(copy_info_t *&head, copy_info_t const &element, Uint32 bm);
+
+ copy_info_t *m_blit_info[SDL_TEXFORMAT_LAST + 1];
+ bool m_blit_info_initialized;
+ bool m_gllib_loaded;
+
+ static copy_info_t const s_blit_info_default[];
+};
+
+int video_sdl2::init(osd_interface &osd, osd_options const &options)
+{
+ osd_printf_verbose("Using SDL native texturing driver (SDL 2.0+)\n");
+
+ // Load the GL library now - else MT will fail
+ char const *libname = nullptr;
+#if USE_OPENGL
+ libname = dynamic_cast<sdl_options const &>(options).gl_lib();
+ if (libname && (!*libname || !std::strcmp(libname, OSDOPTVAL_AUTO)))
+ libname = nullptr;
+#endif
+
+ if (!m_gllib_loaded)
+ {
+ // No fatalerror here since not all video drivers support GL!
+ if (SDL_GL_LoadLibrary(libname) != 0)
+ {
+ osd_printf_error("Unable to load OpenGL shared library: %s\n", libname ? libname : "<default>");
+ m_gllib_loaded = true;
+ }
+ else
+ {
+ osd_printf_verbose("Loaded OpenGL shared library: %s\n", libname ? libname : "<default>");
+ }
+ }
+
+ return 0;
+}
+
+std::unique_ptr<osd_renderer> video_sdl2::create(osd_window &window)
+{
+ if (!m_blit_info_initialized)
+ {
+ // On macOS, calling this from drawsdl2_init will prohibit fullscreen toggling.
+ // It is than not possible to toggle from fullscreen to window mode.
+ expand_copy_info();
+ m_blit_info_initialized = true;
+ }
+
+ return std::make_unique<renderer_sdl2>(window, m_blit_info);
}
+
+void video_sdl2::expand_copy_info()
+{
+ for (const copy_info_t *bi = s_blit_info_default; bi->src_fmt != -1; bi++)
+ {
+ if (bi->bm_mask == BM_ALL)
+ {
+ add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_NONE);
+ add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_ADD);
+ add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_MOD);
+ add_list(m_blit_info[bi->src_fmt], *bi, SDL_BLENDMODE_BLEND);
+ }
+ else
+ {
+ add_list(m_blit_info[bi->src_fmt], *bi, bi->bm_mask);
+ }
+ }
+}
+
+void video_sdl2::free_copy_info()
+{
+ if (m_blit_info_initialized)
+ {
+ for (int i = 0; i <= SDL_TEXFORMAT_LAST; i++)
+ {
+ for (copy_info_t *bi = m_blit_info[i]; bi != nullptr; )
+ {
+ if (bi->pixel_count)
+ {
+ osd_printf_verbose(
+ "%s -> %s %s blendmode 0x%02x, %d samples: %d KPixel/sec\n",
+ bi->srcname,
+ bi->dstname,
+ bi->blitter->m_is_rot ? "rot" : "norot",
+ bi->bm_mask,
+ bi->samples,
+ bi->perf);
+ }
+ copy_info_t *freeme = bi;
+ bi = bi->next;
+ delete freeme;
+ }
+ m_blit_info[i] = nullptr;
+ }
+ m_blit_info_initialized = false;
+ }
+}
+
+void video_sdl2::add_list(copy_info_t *&head, copy_info_t const &element, Uint32 bm)
+{
+ copy_info_t *const newci = new copy_info_t(element);
+
+ newci->bm_mask = bm;
+ newci->next = head;
+ head = newci;
+}
+
+
+//============================================================
+// STATIC VARIABLES
+//============================================================
+
+#define ENTRY(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, 0}
+#define ENTRY_BM(a,b,f,bm) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, bm, #a, #b, 0, 0, 0, 0}
+#define ENTRY_LR(a,b,f) { SDL_TEXFORMAT_ ## a, SDL_PIXELFORMAT_ ## b, &texcopy_ ## f, BM_ALL, #a, #b, 0, 0, 0, -1}
+
+copy_info_t const video_sdl2::s_blit_info_default[] =
+{
+ /* no rotation */
+ ENTRY(ARGB32, ARGB8888, argb32_argb32),
+ ENTRY_LR(ARGB32, RGB888, argb32_rgb32),
+ /* Entry primarily for directfb */
+ ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_ADD),
+ ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_MOD),
+ ENTRY_BM(ARGB32, RGB888, argb32_rgb32, SDL_BLENDMODE_NONE),
+
+ ENTRY(RGB32, ARGB8888, rgb32_argb32),
+ ENTRY(RGB32, RGB888, rgb32_rgb32),
+
+ ENTRY(RGB32_PALETTED, ARGB8888, rgb32pal_argb32),
+ ENTRY(RGB32_PALETTED, RGB888, rgb32pal_argb32),
+
+ ENTRY(YUY16, UYVY, yuv16_uyvy),
+ ENTRY(YUY16, YUY2, yuv16_yuy2),
+ ENTRY(YUY16, YVYU, yuv16_yvyu),
+ ENTRY(YUY16, ARGB8888, yuv16_argb32),
+ ENTRY(YUY16, RGB888, yuv16_argb32),
+
+ ENTRY(YUY16_PALETTED, UYVY, yuv16pal_uyvy),
+ ENTRY(YUY16_PALETTED, YUY2, yuv16pal_yuy2),
+ ENTRY(YUY16_PALETTED, YVYU, yuv16pal_yvyu),
+ ENTRY(YUY16_PALETTED, ARGB8888, yuv16pal_argb32),
+ ENTRY(YUY16_PALETTED, RGB888, yuv16pal_argb32),
+
+ ENTRY(PALETTE16, ARGB8888, pal16_argb32),
+ ENTRY(PALETTE16, RGB888, pal16_argb32),
+
+ ENTRY(RGB15, RGB555, rgb15_rgb555),
+ ENTRY(RGB15, ARGB1555, rgb15_argb1555),
+ ENTRY(RGB15, ARGB8888, rgb15_argb32),
+ ENTRY(RGB15, RGB888, rgb15_argb32),
+
+ ENTRY(RGB15_PALETTED, ARGB8888, rgb15pal_argb32),
+ ENTRY(RGB15_PALETTED, RGB888, rgb15pal_argb32),
+
+ ENTRY(PALETTE16A, ARGB8888, pal16a_argb32),
+ ENTRY(PALETTE16A, RGB888, pal16a_rgb32),
+
+ /* rotation */
+ ENTRY(ARGB32, ARGB8888, rot_argb32_argb32),
+ ENTRY_LR(ARGB32, RGB888, rot_argb32_rgb32),
+ /* Entry primarily for directfb */
+ ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_ADD),
+ ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_MOD),
+ ENTRY_BM(ARGB32, RGB888, rot_argb32_rgb32, SDL_BLENDMODE_NONE),
+
+ ENTRY(RGB32, ARGB8888, rot_rgb32_argb32),
+ ENTRY(RGB32, RGB888, rot_argb32_argb32),
+
+ ENTRY(RGB32_PALETTED, ARGB8888, rot_rgb32pal_argb32),
+ ENTRY(RGB32_PALETTED, RGB888, rot_rgb32pal_argb32),
+
+ ENTRY(YUY16, ARGB8888, rot_yuv16_argb32rot),
+ ENTRY(YUY16, RGB888, rot_yuv16_argb32rot),
+
+ ENTRY(YUY16_PALETTED, ARGB8888, rot_yuv16pal_argb32rot),
+ ENTRY(YUY16_PALETTED, RGB888, rot_yuv16pal_argb32rot),
+
+ ENTRY(PALETTE16, ARGB8888, rot_pal16_argb32),
+ ENTRY(PALETTE16, RGB888, rot_pal16_argb32),
+
+ ENTRY(RGB15, RGB555, rot_rgb15_argb1555),
+ ENTRY(RGB15, ARGB1555, rot_rgb15_argb1555),
+ ENTRY(RGB15, ARGB8888, rot_rgb15_argb32),
+ ENTRY(RGB15, RGB888, rot_rgb15_argb32),
+
+ ENTRY(RGB15_PALETTED, ARGB8888, rot_rgb15pal_argb32),
+ ENTRY(RGB15_PALETTED, RGB888, rot_rgb15pal_argb32),
+
+ ENTRY(PALETTE16A, ARGB8888, rot_pal16a_argb32),
+ ENTRY(PALETTE16A, RGB888, rot_pal16a_rgb32),
+
+ { -1 },
+};
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // defined(OSD_SDL)
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_sdl2, OSD_RENDERER_PROVIDER, "accel") } }
+
+#endif // defined(OSD_SDL)
+
+
+MODULE_DEFINITION(RENDERER_SDL2, osd::video_sdl2)
diff --git a/src/osd/modules/render/draw13.h b/src/osd/modules/render/draw13.h
deleted file mode 100644
index 4015acca416..00000000000
--- a/src/osd/modules/render/draw13.h
+++ /dev/null
@@ -1,215 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
-//============================================================
-//
-// draw13.h - SDL 2.0 drawing implementation
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#ifndef MAME_OSD_MODULES_RENDER_DRAW13_H
-#define MAME_OSD_MODULES_RENDER_DRAW13_H
-
-#pragma once
-
-// OSD headers
-#ifndef OSD_WINDOWS
-#include "window.h"
-#else
-#include "../windows/window.h"
-typedef uint64_t HashT;
-#endif
-
-// standard SDL headers
-#include <SDL2/SDL.h>
-
-#include "emucore.h"
-#include "render.h"
-
-struct quad_setup_data
-{
- quad_setup_data()
- : dudx(0)
- , dvdx(0)
- , dudy(0)
- , dvdy(0)
- , startu(0)
- , startv(0)
- , rotwidth(0)
- , rotheight(0)
- {
- }
-
- void compute(const render_primitive &prim, const int prescale);
-
- int32_t dudx, dvdx, dudy, dvdy;
- int32_t startu, startv;
- int32_t rotwidth, rotheight;
-};
-
-//============================================================
-// Textures
-//============================================================
-
-class renderer_sdl2;
-struct copy_info_t;
-
-/* texture_info holds information about a texture */
-class texture_info
-{
- friend class simple_list<texture_info>;
-public:
- texture_info(renderer_sdl2 *renderer, const render_texinfo &texsource, const quad_setup_data &setup, const uint32_t flags);
- ~texture_info();
-
- void set_data(const render_texinfo &texsource, const uint32_t flags);
- void render_quad(const render_primitive &prim, const int x, const int y);
- bool matches(const render_primitive &prim, const quad_setup_data &setup);
-
- copy_info_t *compute_size_type();
-
- void *m_pixels; // pixels for the texture
- int m_pitch;
-
- copy_info_t *m_copyinfo;
- quad_setup_data m_setup;
-
- osd_ticks_t m_last_access;
-
- int raw_width() const { return m_texinfo.width; }
- int raw_height() const { return m_texinfo.height; }
-
- texture_info *next() { return m_next; }
- const render_texinfo &texinfo() const { return m_texinfo; }
- render_texinfo &texinfo() { return m_texinfo; }
-
- HashT hash() const { return m_hash; }
- uint32_t flags() const { return m_flags; }
- // FIXME:
- bool is_pixels_owned() const;
-
-private:
- void set_coloralphamode(SDL_Texture *texture_id, const render_color *color);
-
- Uint32 m_sdl_access;
- renderer_sdl2 * m_renderer;
- render_texinfo m_texinfo; // copy of the texture info
- HashT m_hash; // hash value for the texture (must be >= pointer size)
- uint32_t m_flags; // rendering flags
-
- SDL_Texture * m_texture_id;
- bool m_is_rotated;
-
- int m_format; // texture format
- SDL_BlendMode m_sdl_blendmode;
-
- texture_info * m_next; // next texture in the list
-};
-
-//============================================================
-// TEXCOPY FUNCS
-//============================================================
-
-enum SDL_TEXFORMAT_E
-{
- SDL_TEXFORMAT_ARGB32 = 0,
- SDL_TEXFORMAT_RGB32,
- SDL_TEXFORMAT_RGB32_PALETTED,
- SDL_TEXFORMAT_YUY16,
- SDL_TEXFORMAT_YUY16_PALETTED,
- SDL_TEXFORMAT_PALETTE16,
- SDL_TEXFORMAT_RGB15,
- SDL_TEXFORMAT_RGB15_PALETTED,
- SDL_TEXFORMAT_PALETTE16A,
- SDL_TEXFORMAT_PALETTE16_ARGB1555,
- SDL_TEXFORMAT_RGB15_ARGB1555,
- SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555,
- SDL_TEXFORMAT_LAST = SDL_TEXFORMAT_RGB15_PALETTED_ARGB1555
-};
-
-#include "blit13.h"
-
-struct copy_info_t
-{
- int src_fmt;
- Uint32 dst_fmt;
- const blit_base *blitter;
- Uint32 bm_mask;
- const char *srcname;
- const char *dstname;
- /* Statistics */
- uint64_t pixel_count;
- int64_t time;
- int samples;
- int perf;
- /* list */
- copy_info_t *next;
-};
-
-/* renderer_sdl2 is the information about SDL for the current screen */
-class renderer_sdl2 : public osd_renderer
-{
-public:
- renderer_sdl2(std::shared_ptr<osd_window> window, int extra_flags);
-
- virtual ~renderer_sdl2()
- {
- destroy_all_textures();
- SDL_DestroyRenderer(m_sdl_renderer);
- m_sdl_renderer = nullptr;
- }
-
- static void init(running_machine &machine);
- static void exit();
-
- virtual int create() override;
- virtual int draw(const int update) override;
- virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
- virtual render_primitive_list *get_primitives() override;
-
- int RendererSupportsFormat(Uint32 format, Uint32 access, const char *sformat);
-
- SDL_Renderer * m_sdl_renderer;
-
- static copy_info_t* s_blit_info[SDL_TEXFORMAT_LAST+1];
-
-private:
- void expand_copy_info(const copy_info_t *list);
- void add_list(copy_info_t **head, const copy_info_t *element, Uint32 bm);
-
- void render_quad(texture_info *texture, const render_primitive &prim, const int x, const int y);
-
- texture_info *texture_find(const render_primitive &prim, const quad_setup_data &setup);
- texture_info *texture_update(const render_primitive &prim);
-
- void destroy_all_textures();
-
- int32_t m_blittimer;
-
-
- simple_list<texture_info> m_texlist; // list of active textures
-
- float m_last_hofs;
- float m_last_vofs;
-
- int m_width;
- int m_height;
-
- osd_dim m_blit_dim;
-
- struct
- {
- Uint32 format;
- int status;
- } fmt_support[30];
-
- // Stats
- int64_t m_last_blit_time;
- int64_t m_last_blit_pixels;
-
- static bool s_blit_info_initialized;
- static const copy_info_t s_blit_info_default[];
-};
-
-#endif // MAME_OSD_MODULES_RENDER_DRAW13_H
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp
index d42f4739d26..aa4cf95f7be 100644
--- a/src/osd/modules/render/drawbgfx.cpp
+++ b/src/osd/modules/render/drawbgfx.cpp
@@ -5,24 +5,7 @@
// drawbgfx.cpp - BGFX renderer
//
//============================================================
-#include <bx/math.h>
-#include <bx/readerwriter.h>
-#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
-// standard windows headers
-#include <windows.h>
-#if defined(SDLMAME_WIN32)
-#include <SDL2/SDL_syswm.h>
-#endif
-#else
-#if defined(OSD_MAC)
-extern void *GetOSWindow(void *wincontroller);
-#else
-#include <SDL2/SDL_syswm.h>
-#endif
-#endif
-
-#include "emu.h"
#include "drawbgfx.h"
// render/bgfx
@@ -41,8 +24,10 @@ extern void *GetOSWindow(void *wincontroller);
// render
#include "aviwrite.h"
#include "bgfxutil.h"
+#include "render_module.h"
// emu
+#include "emu.h"
#include "config.h"
#include "render.h"
#include "rendutil.h"
@@ -54,6 +39,23 @@ extern void *GetOSWindow(void *wincontroller);
#include "modules/lib/osdobj_common.h"
#include "window.h"
+#include <bx/math.h>
+#include <bx/readerwriter.h>
+
+#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
+// standard windows headers
+#include <windows.h>
+#if defined(SDLMAME_WIN32)
+#include <SDL2/SDL_syswm.h>
+#endif
+#else
+#if defined(OSD_MAC)
+extern void *GetOSWindow(void *wincontroller);
+#else
+#include <SDL2/SDL_syswm.h>
+#endif
+#endif
+
#include <bgfx/bgfx.h>
#include <bgfx/platform.h>
@@ -63,274 +65,447 @@ extern void *GetOSWindow(void *wincontroller);
//============================================================
-// DEBUGGING
+// OSD MODULE
//============================================================
-//============================================================
-// CONSTANTS
-//============================================================
+namespace osd {
-uint16_t const renderer_bgfx::CACHE_SIZE = 1024;
-uint32_t const renderer_bgfx::PACKABLE_SIZE = 128;
-uint32_t const renderer_bgfx::WHITE_HASH = 0x87654321;
-char const *const renderer_bgfx::WINDOW_PREFIX = "Window 0, ";
+namespace {
-//============================================================
-// MACROS
-//============================================================
+class video_bgfx : public osd_module, public render_module
+{
+public:
+ video_bgfx()
+ : osd_module(OSD_RENDERER_PROVIDER, "bgfx")
+ , m_options(nullptr)
+ , m_max_texture_size(0)
+ , m_bgfx_library_initialized(false)
+ {
+ }
+ ~video_bgfx() { exit(); }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE; }
+
+private:
+ void load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
+ void save_config(config_type cfg_type, util::xml::data_node *parentnode);
+
+ bool init_bgfx_library(osd_window &window);
+
+ static bool set_platform_data(bgfx::PlatformData &platform_data, osd_window const &window);
+
+ util::notifier<util::xml::data_node const &> m_load_notifier;
+ util::notifier<util::xml::data_node &> m_save_notifier;
+ util::xml::file::ptr m_persistent_settings;
+ osd_options const *m_options;
+ uint32_t m_max_texture_size;
+ bool m_bgfx_library_initialized;
+};
-#define GIBBERISH (0)
-#define SCENE_VIEW (0)
//============================================================
-// STATICS
+// video_bgfx::init
//============================================================
-uint32_t renderer_bgfx::s_current_view = 0;
-bool renderer_bgfx::s_bgfx_library_initialized = false;
-uint32_t renderer_bgfx::s_width[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-uint32_t renderer_bgfx::s_height[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-uint32_t renderer_bgfx::s_max_texture_size = 16384; // Relatively safe default on modern GPUs
+int video_bgfx::init(osd_interface &osd, osd_options const &options)
+{
+ m_options = &options;
+ m_persistent_settings = util::xml::file::create();
+
+ // Check that BGFX directory exists
+ char const *const bgfx_path = options.bgfx_path();
+ osd::directory::ptr directory = osd::directory::open(bgfx_path);
+ if (!directory)
+ {
+ osd_printf_error("Unable to find the BGFX path %s, please install it or fix the bgfx_path setting to use the BGFX renderer.\n", bgfx_path);
+ return -1;
+ }
+ directory.reset();
+
+ // Verify baseline shaders
+ const bool gui_opaque_valid = effect_manager::validate_effect(options, "gui_opaque");
+ const bool gui_blend_valid = effect_manager::validate_effect(options, "gui_blend");
+ const bool gui_multiply_valid = effect_manager::validate_effect(options, "gui_multiply");
+ const bool gui_add_valid = effect_manager::validate_effect(options, "gui_add");
+ const bool all_gui_valid = gui_opaque_valid && gui_blend_valid && gui_multiply_valid && gui_add_valid;
+
+ const bool screen_opaque_valid = effect_manager::validate_effect(options, "screen_opaque");
+ const bool screen_blend_valid = effect_manager::validate_effect(options, "screen_blend");
+ const bool screen_multiply_valid = effect_manager::validate_effect(options, "screen_multiply");
+ const bool screen_add_valid = effect_manager::validate_effect(options, "screen_add");
+ const bool all_screen_valid = screen_opaque_valid && screen_blend_valid && screen_multiply_valid && screen_add_valid;
+
+ if (!all_gui_valid || !all_screen_valid)
+ {
+ osd_printf_error("BGFX: Unable to load required shaders. Please update the %s folder or adjust your bgfx_path setting.\n", options.bgfx_path());
+ return -1;
+ }
+
+ m_max_texture_size = 16384; // Relatively safe default on modern GPUs
+
+ // Register configuration handlers - do this last because it can't be undone
+ downcast<osd_common_t &>(osd).machine().configuration().config_register(
+ "bgfx",
+ configuration_manager::load_delegate(&video_bgfx::load_config, this),
+ configuration_manager::save_delegate(&video_bgfx::save_config, this));
+
+ return 0;
+}
+
//============================================================
-// renderer_bgfx - constructor
+// video_bgfx::exit
//============================================================
-renderer_bgfx::renderer_bgfx(std::shared_ptr<osd_window> w)
- : osd_renderer(w, FLAG_NONE)
- , m_options(downcast<osd_options &>(w->machine().options()))
- , m_framebuffer(nullptr)
- , m_texture_cache(nullptr)
- , m_dimensions(0, 0)
- , m_textures(nullptr)
- , m_targets(nullptr)
- , m_shaders(nullptr)
- , m_effects(nullptr)
- , m_chains(nullptr)
- , m_ortho_view(nullptr)
- , m_max_view(0)
- , m_view_width(1)
- , m_view_height(1)
- , m_avi_view(nullptr)
- , m_avi_writer(nullptr)
- , m_avi_target(nullptr)
+void video_bgfx::exit()
{
+ if (m_bgfx_library_initialized)
+ {
+ osd_printf_verbose("Shutting down BGFX library\n");
+ imguiDestroy();
+ bgfx::shutdown();
+ m_bgfx_library_initialized = false;
+ }
+ m_max_texture_size = 0;
+ m_persistent_settings.reset();
+ m_options = nullptr;
}
+
//============================================================
-// renderer_bgfx - destructor
+// video_bgfx::create
//============================================================
-renderer_bgfx::~renderer_bgfx()
+std::unique_ptr<osd_renderer> video_bgfx::create(osd_window &window)
{
- bgfx::reset(0, 0, BGFX_RESET_NONE);
-
- if (m_avi_writer != nullptr && m_avi_writer->recording())
+ // hacky - reinitialise when window 0 is created
+ // this is the cause of the fullscreen toggle crash on Linux
+ if ((window.index() == 0) && m_bgfx_library_initialized)
{
- m_avi_writer->stop();
+ osd_printf_verbose("Shutting down BGFX library to recreate window 0\n");
+ imguiDestroy();
+ bgfx::shutdown();
+ m_bgfx_library_initialized = false;
+ m_max_texture_size = 0;
+ }
- m_targets->destroy_target("avibuffer0");
- m_avi_target = nullptr;
+ // start BGFX if this is the first window
+ if (!m_bgfx_library_initialized)
+ {
+ osd_printf_verbose("Initializing BGFX library\n");
+ assert(window.index() == 0); // bad things will happen otherwise
+ if (!init_bgfx_library(window))
+ {
+ osd_printf_error("BGFX library initialization failed\n");
+ return nullptr;
+ }
+ m_bgfx_library_initialized = true;
+ }
- bgfx::destroy(m_avi_texture);
+ return std::make_unique<renderer_bgfx>(
+ window,
+ *m_options,
+ m_load_notifier,
+ m_save_notifier,
+ *m_persistent_settings,
+ m_max_texture_size);
+}
- delete m_avi_writer;
- delete [] m_avi_data;
- delete m_avi_view;
- }
- // Cleanup.
- if (m_ortho_view)
- delete m_ortho_view;
+//============================================================
+// video_bgfx::load_config
+//============================================================
- delete m_chains;
- delete m_effects;
- delete m_shaders;
- delete m_textures;
- delete m_targets;
+void video_bgfx::load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
+{
+ if ((cfg_type == config_type::SYSTEM) && parentnode)
+ m_load_notifier(*parentnode);
}
+//============================================================
+// video_bgfx::save_config
+//============================================================
+
+void video_bgfx::save_config(config_type cfg_type, util::xml::data_node *parentnode)
+{
+ if (cfg_type == config_type::SYSTEM)
+ m_save_notifier(*parentnode);
+}
+
//============================================================
-// renderer_bgfx::init_bgfx_library
+// video_bgfx::init_bgfx_library
//============================================================
-void renderer_bgfx::init_bgfx_library()
+bool video_bgfx::init_bgfx_library(osd_window &window)
{
- std::string backend(m_options.bgfx_backend());
+ osd_dim const wdim = window.get_size();
bgfx::Init init;
init.type = bgfx::RendererType::Count;
init.vendorId = BGFX_PCI_ID_NONE;
- init.resolution.width = s_width[0];
- init.resolution.height = s_height[0];
+ init.resolution.width = wdim.width();
+ init.resolution.height = wdim.height();
init.resolution.numBackBuffers = 1;
init.resolution.reset = BGFX_RESET_NONE;
- init.platformData = m_platform_data;
- if (backend == "auto")
+ if (!set_platform_data(init.platformData, window))
{
+ osd_printf_error("Setting BGFX platform data failed\n");
+ return false;
}
+
+ std::string_view const backend(m_options->bgfx_backend());
+ if (backend == "auto")
+ ; // do nothing
else if (backend == "dx9" || backend == "d3d9")
- {
init.type = bgfx::RendererType::Direct3D9;
- }
else if (backend == "dx11" || backend == "d3d11")
- {
init.type = bgfx::RendererType::Direct3D11;
- }
else if (backend == "dx12" || backend == "d3d12")
- {
init.type = bgfx::RendererType::Direct3D12;
- }
else if (backend == "gles")
- {
init.type = bgfx::RendererType::OpenGLES;
- }
else if (backend == "glsl" || backend == "opengl")
- {
init.type = bgfx::RendererType::OpenGL;
- }
else if (backend == "vulkan")
- {
init.type = bgfx::RendererType::Vulkan;
- }
else if (backend == "metal")
- {
init.type = bgfx::RendererType::Metal;
- }
else
- {
- osd_printf_verbose("Unknown backend type '%s', going with auto-detection.\n", backend.c_str());
- }
+ osd_printf_warning("Unknown BGFX backend type '%s', going with auto-detection.\n", backend);
+
+ if (!bgfx::init(init))
+ return false;
- bgfx::init(init);
- bgfx::reset(s_width[0], s_height[0], video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
- // Enable debug text if requested.
- bool bgfx_debug = m_options.bgfx_debug();
+ bgfx::reset(wdim.width(), wdim.height(), video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
+
+ // Enable debug text if requested
+ bool bgfx_debug = m_options->bgfx_debug();
bgfx::setDebug(bgfx_debug ? BGFX_DEBUG_STATS : BGFX_DEBUG_TEXT);
- const bgfx::Caps* caps = bgfx::getCaps();
- s_max_texture_size = caps->limits.maxTextureSize;
+ // Get actual maximum texture size
+ bgfx::Caps const *const caps = bgfx::getCaps();
+ m_max_texture_size = caps->limits.maxTextureSize;
ScreenVertex::init();
imguiCreate();
-}
+ return true;
+}
//============================================================
-// Utilities for setting up window handles
+// Utility for setting up window handle
//============================================================
-#ifdef OSD_WINDOWS
-inline void winSetHwnd(bgfx::PlatformData &platform_data, ::HWND _window)
+bool video_bgfx::set_platform_data(bgfx::PlatformData &platform_data, osd_window const &window)
{
- platform_data.ndt = NULL;
- platform_data.nwh = _window;
- platform_data.context = NULL;
- platform_data.backBuffer = NULL;
- platform_data.backBufferDS = NULL;
- bgfx::setPlatformData(platform_data);
-}
+#if defined(OSD_WINDOWS)
+ platform_data.ndt = nullptr;
+ platform_data.nwh = dynamic_cast<win_window_info const &>(window).platform_window();
#elif defined(OSD_MAC)
-inline void macSetWindow(bgfx::PlatformData &platform_data, void *_window)
-{
- platform_data.ndt = NULL;
- platform_data.nwh = GetOSWindow(_window);
- platform_data.context = NULL;
- platform_data.backBuffer = NULL;
- platform_data.backBufferDS = NULL;
+ platform_data.ndt = nullptr;
+ platform_data.nwh = GetOSWindow(dynamic_cast<mac_window_info const &>(window).platform_window());
+#else // defined(OSD_*)
+ SDL_SysWMinfo wmi;
+ SDL_VERSION(&wmi.version);
+ if (!SDL_GetWindowWMInfo(dynamic_cast<sdl_window_info const &>(window).platform_window(), &wmi))
+ {
+ osd_printf_error("Error getting SDL window info: %s\n", SDL_GetError());
+ return false;
+ }
+
+#if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
+ platform_data.ndt = wmi.info.x11.display;
+ platform_data.nwh = (void *)uintptr_t(wmi.info.x11.window);
+#elif BX_PLATFORM_OSX
+ platform_data.ndt = nullptr;
+ platform_data.nwh = wmi.info.cocoa.window;
+#elif BX_PLATFORM_WINDOWS
+ platform_data.ndt = nullptr;
+ platform_data.nwh = wmi.info.win.window;
+#else // BX_PLATFORM_*
+#error "Unsupported BX platform"
+#endif // BX_PLATFORM_*
+#endif // defined(OSD_*)
+
+ platform_data.context = nullptr;
+ platform_data.backBuffer = nullptr;
+ platform_data.backBufferDS = nullptr;
bgfx::setPlatformData(platform_data);
+
+ return true;
}
-#elif defined(OSD_SDL)
-static void* sdlNativeWindowHandle(SDL_Window* _window)
+
+} // anonymous namespace
+
+} // namespace osd
+
+MODULE_DEFINITION(RENDERER_BGFX, osd::video_bgfx)
+
+
+
+//============================================================
+// CONSTANTS
+//============================================================
+
+uint16_t const renderer_bgfx::CACHE_SIZE = 1024;
+uint32_t const renderer_bgfx::PACKABLE_SIZE = 128;
+uint32_t const renderer_bgfx::WHITE_HASH = 0x87654321;
+char const *const renderer_bgfx::WINDOW_PREFIX = "Window 0, ";
+
+
+
+//============================================================
+// MACROS
+//============================================================
+
+#define GIBBERISH (0)
+#define SCENE_VIEW (0)
+
+
+
+//============================================================
+// STATICS
+//============================================================
+
+uint32_t renderer_bgfx::s_current_view = 0;
+uint32_t renderer_bgfx::s_width[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+uint32_t renderer_bgfx::s_height[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+
+
+//============================================================
+// helper for getting native platform window
+//============================================================
+
+#ifdef OSD_SDL
+static void *sdlNativeWindowHandle(SDL_Window *window)
{
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
- if (!SDL_GetWindowWMInfo(_window, &wmi))
- {
+ if (!SDL_GetWindowWMInfo(window, &wmi))
return nullptr;
- }
-# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD || BX_PLATFORM_RPI
+#if BX_PLATFORM_LINUX || BX_PLATFORM_BSD || BX_PLATFORM_RPI
return (void*)wmi.info.x11.window;
-# elif BX_PLATFORM_OSX
+#elif BX_PLATFORM_OSX
return wmi.info.cocoa.window;
-# elif BX_PLATFORM_WINDOWS
+#elif BX_PLATFORM_WINDOWS
return wmi.info.win.window;
-# elif BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_ANDROID
+#elif BX_PLATFORM_EMSCRIPTEN || BX_PLATFORM_ANDROID
return nullptr;
-# endif // BX_PLATFORM_
+#endif // BX_PLATFORM_*
}
+#endif // OSD_SDL
-inline bool sdlSetWindow(bgfx::PlatformData &platform_data, SDL_Window* _window)
+
+
+//============================================================
+// renderer_bgfx - constructor
+//============================================================
+
+renderer_bgfx::renderer_bgfx(
+ osd_window &window,
+ const osd_options &options,
+ util::notifier<util::xml::data_node const &> &load_notifier,
+ util::notifier<util::xml::data_node &> &save_notifier,
+ util::xml::data_node &persistent_settings,
+ uint32_t max_texsize)
+ : osd_renderer(window)
+ , m_options(options)
+ , m_max_texture_size(max_texsize)
+ , m_framebuffer(nullptr)
+ , m_texture_cache(nullptr)
+ , m_dimensions(0, 0)
+ , m_max_view(0)
+ , m_view_width(1)
+ , m_view_height(1)
+ , m_avi_view(nullptr)
+ , m_avi_writer(nullptr)
+ , m_avi_target(nullptr)
+ , m_load_sub(load_notifier.subscribe(delegate<void (util::xml::data_node const &)>(&renderer_bgfx::load_config, this)))
+ , m_save_sub(save_notifier.subscribe(delegate<void (util::xml::data_node &)>(&renderer_bgfx::save_config, this)))
+ , m_persistent_settings(persistent_settings)
{
- SDL_SysWMinfo wmi;
- SDL_VERSION(&wmi.version);
- if (!SDL_GetWindowWMInfo(_window, &wmi) )
+ // load settings if recreated after fullscreen toggle
+ util::xml::data_node *windownode = m_persistent_settings.get_child("window");
+ while (windownode)
{
- return false;
+ if (windownode->get_attribute_int("index", -1) != window.index())
+ {
+ windownode = windownode->get_next_sibling("window");
+ }
+ else
+ {
+ if (!m_config)
+ {
+ m_config = util::xml::file::create();
+ windownode->copy_into(*m_config);
+ }
+ std::exchange(windownode, windownode->get_next_sibling("window"))->delete_node();
+ }
}
-
-# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
- platform_data.ndt = wmi.info.x11.display;
- platform_data.nwh = (void*)(uintptr_t)wmi.info.x11.window;
-# elif BX_PLATFORM_OSX
- platform_data.ndt = NULL;
- platform_data.nwh = wmi.info.cocoa.window;
-# elif BX_PLATFORM_WINDOWS
- platform_data.ndt = NULL;
- platform_data.nwh = wmi.info.win.window;
-# endif // BX_PLATFORM_
- platform_data.context = NULL;
- platform_data.backBuffer = NULL;
- platform_data.backBufferDS = NULL;
- bgfx::setPlatformData(platform_data);
-
- return true;
}
-#endif
//============================================================
-// renderer_bgfx::create
+// renderer_bgfx - destructor
//============================================================
-int renderer_bgfx::create()
+renderer_bgfx::~renderer_bgfx()
{
- std::shared_ptr<osd_window> win = assert_window();
- osd_dim wdim = win->get_size();
- const uint32_t width = wdim.width();
- const uint32_t height = wdim.height();
- s_width[win->index()] = width;
- s_height[win->index()] = height;
- m_dimensions = wdim;
+ // persist settings across fullscreen toggle
+ if (m_chains)
+ m_chains->save_config(m_persistent_settings);
+ else if (m_config)
+ m_config->get_first_child()->copy_into(m_persistent_settings);
- if (s_bgfx_library_initialized)
- exit();
+ bgfx::reset(0, 0, BGFX_RESET_NONE);
- if (win->index() == 0)
+ if (m_avi_writer != nullptr && m_avi_writer->recording())
{
-#ifdef OSD_WINDOWS
- winSetHwnd(m_platform_data, std::static_pointer_cast<win_window_info>(win)->platform_window());
-#elif defined(OSD_MAC)
- macSetWindow(m_platform_data, std::static_pointer_cast<mac_window_info>(win)->platform_window());
-#else
- sdlSetWindow(m_platform_data, std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window());
-#endif
+ m_avi_writer->stop();
+
+ m_targets->destroy_target("avibuffer0");
+ m_avi_target = nullptr;
- init_bgfx_library();
+ bgfx::destroy(m_avi_texture);
+
+ delete m_avi_writer;
+ delete [] m_avi_data;
+ delete m_avi_view;
}
+}
+
+
+
+//============================================================
+// renderer_bgfx::create
+//============================================================
+
+int renderer_bgfx::create()
+{
+ const osd_dim wdim = window().get_size();
+ s_width[window().index()] = wdim.width();
+ s_height[window().index()] = wdim.height();
+ m_dimensions = wdim;
// finish creating the renderer
- m_textures = new texture_manager();
- m_targets = new target_manager(*m_textures);
+ m_textures = std::make_unique<texture_manager>();
+ m_targets = std::make_unique<target_manager>(*m_textures);
- m_shaders = new shader_manager();
- m_effects = new effect_manager(*m_shaders);
+ m_shaders = std::make_unique<shader_manager>();
+ m_effects = std::make_unique<effect_manager>(*m_shaders);
// Create program from shaders.
m_gui_effect[0] = m_effects->get_or_load_effect(m_options, "gui_opaque");
@@ -343,23 +518,32 @@ int renderer_bgfx::create()
m_screen_effect[2] = m_effects->get_or_load_effect(m_options, "screen_multiply");
m_screen_effect[3] = m_effects->get_or_load_effect(m_options, "screen_add");
- if (win->index() != 0)
+ if (window().index() != 0)
{
#ifdef OSD_WINDOWS
- m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), s_width[win->index()], s_height[win->index()]);
+ m_framebuffer = m_targets->create_backbuffer(dynamic_cast<win_window_info &>(window()).platform_window(), s_width[window().index()], s_height[window().index()]);
#elif defined(OSD_MAC)
- m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()), s_width[win->index()], s_height[win->index()]);
+ m_framebuffer = m_targets->create_backbuffer(GetOSWindow(dynamic_cast<mac_window_info &>(window()).platform_window()), s_width[window().index()], s_height[window().index()]);
#else
- m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), s_width[win->index()], s_height[win->index()]);
+ m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(dynamic_cast<sdl_window_info &>(window()).platform_window()), s_width[window().index()], s_height[window().index()]);
#endif
- bgfx::touch(win->index());
+ bgfx::touch(window().index());
if (m_ortho_view)
m_ortho_view->set_backbuffer(m_framebuffer);
}
- const uint32_t max_prescale_size = std::min(2u * std::max(width, height), s_max_texture_size);
- m_chains = new chain_manager(win->machine(), m_options, *m_textures, *m_targets, *m_effects, win->index(), *this, win->prescale(), max_prescale_size);
+ const uint32_t max_prescale_size = std::min(2u * std::max(wdim.width(), wdim.height()), m_max_texture_size);
+ m_chains = std::make_unique<chain_manager>(
+ window().machine(),
+ m_options,
+ *m_textures,
+ *m_targets,
+ *m_effects,
+ window().index(),
+ *this,
+ window().prescale(),
+ max_prescale_size);
m_sliders_dirty = true;
uint32_t flags = BGFX_SAMPLER_U_CLAMP | BGFX_SAMPLER_V_CLAMP | BGFX_SAMPLER_MIN_POINT | BGFX_SAMPLER_MAG_POINT | BGFX_SAMPLER_MIP_POINT;
@@ -368,12 +552,6 @@ int renderer_bgfx::create()
memset(m_white, 0xff, sizeof(uint32_t) * 16 * 16);
m_texinfo.push_back(rectangle_packer::packable_rectangle(WHITE_HASH, PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32), 16, 16, 16, nullptr, m_white));
- // Register configuration handlers
- win->machine().configuration().config_register(
- "bgfx",
- configuration_manager::load_delegate(&renderer_bgfx::load_config, this),
- configuration_manager::save_delegate(&renderer_bgfx::save_config, this));
-
return 0;
}
@@ -385,16 +563,12 @@ int renderer_bgfx::create()
void renderer_bgfx::record()
{
- std::shared_ptr<osd_window> win = assert_window();
-
- if (win->index() > 0)
- {
+ if (window().index() > 0)
return;
- }
if (m_avi_writer == nullptr)
{
- m_avi_writer = new avi_write(win->machine(), s_width[0], s_height[0]);
+ m_avi_writer = new avi_write(window().machine(), s_width[0], s_height[0]);
m_avi_data = new uint8_t[s_width[0] * s_height[0] * 4];
m_avi_bitmap.allocate(s_width[0], s_height[0]);
}
@@ -421,47 +595,6 @@ void renderer_bgfx::record()
}
}
-bool renderer_bgfx::init(running_machine &machine)
-{
- osd_options &options = downcast<osd_options &>(machine.options());
- const char *bgfx_path = options.bgfx_path();
-
- osd::directory::ptr directory = osd::directory::open(bgfx_path);
- if (directory == nullptr)
- {
- osd_printf_error("Unable to find the BGFX path %s, please install it or fix the bgfx_path setting to use the BGFX renderer.\n", bgfx_path);
- return true;
- }
-
- // Verify baseline shaders.
- const bool gui_opaque_valid = effect_manager::validate_effect(options, "gui_opaque");
- const bool gui_blend_valid = effect_manager::validate_effect(options, "gui_blend");
- const bool gui_multiply_valid = effect_manager::validate_effect(options, "gui_multiply");
- const bool gui_add_valid = effect_manager::validate_effect(options, "gui_add");
- const bool all_gui_valid = gui_opaque_valid && gui_blend_valid && gui_multiply_valid && gui_add_valid;
-
- const bool screen_opaque_valid = effect_manager::validate_effect(options, "screen_opaque");
- const bool screen_blend_valid = effect_manager::validate_effect(options, "screen_blend");
- const bool screen_multiply_valid = effect_manager::validate_effect(options, "screen_multiply");
- const bool screen_add_valid = effect_manager::validate_effect(options, "screen_add");
- const bool all_screen_valid = screen_opaque_valid && screen_blend_valid && screen_multiply_valid && screen_add_valid;
-
- if (!all_gui_valid || !all_screen_valid)
- {
- osd_printf_error("BGFX: Unable to load required shaders. Please update the %s folder or adjust your bgfx_path setting.\n", options.bgfx_path());
- return true;
- }
-
- return false;
-}
-
-void renderer_bgfx::exit()
-{
- imguiDestroy();
- bgfx::shutdown();
- s_bgfx_library_initialized = false;
-}
-
//============================================================
// drawsdl_xy_to_render_target
//============================================================
@@ -891,16 +1024,13 @@ uint32_t renderer_bgfx::u32Color(uint32_t r, uint32_t g, uint32_t b, uint32_t a
int renderer_bgfx::draw(int update)
{
- std::shared_ptr<osd_window> win = assert_window();
-
- int window_index = win->index();
+ int window_index = window().index();
m_seen_views.clear();
- if (m_ortho_view) {
+ if (m_ortho_view)
m_ortho_view->set_index(UINT_MAX);
- }
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
s_width[window_index] = wdim.width();
s_height[window_index] = wdim.height();
@@ -910,9 +1040,9 @@ int renderer_bgfx::draw(int update)
s_current_view = 0;
}
- win->m_primlist->acquire_lock();
- uint32_t num_screens = m_chains->update_screen_textures(s_current_view, win->m_primlist->first(), *win.get());
- win->m_primlist->release_lock();
+ window().m_primlist->acquire_lock();
+ uint32_t num_screens = m_chains->update_screen_textures(s_current_view, window().m_primlist->first(), window());
+ window().m_primlist->release_lock();
bool skip_frame = update_dimensions();
if (skip_frame)
@@ -935,7 +1065,7 @@ int renderer_bgfx::draw(int update)
m_config.reset();
}
- uint32_t chain_view_count = m_chains->process_screen_chains(s_current_view, *win.get());
+ uint32_t chain_view_count = m_chains->process_screen_chains(s_current_view, window());
s_current_view += chain_view_count;
}
@@ -948,12 +1078,12 @@ int renderer_bgfx::draw(int update)
s_current_view = m_max_view;
}
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// Mark our texture atlas as dirty if we need to do so
bool atlas_valid = update_atlas();
- render_primitive *prim = win->m_primlist->first();
+ render_primitive *prim = window().m_primlist->first();
std::vector<void*> sources;
while (prim != nullptr)
{
@@ -1002,7 +1132,7 @@ int renderer_bgfx::draw(int update)
}
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
@@ -1020,7 +1150,7 @@ int renderer_bgfx::draw(int update)
}
}
- if (win->index() == osd_common_t::s_window_list.size() - 1)
+ if (window().index() == osd_common_t::window_list().size() - 1)
{
bgfx::frame();
}
@@ -1050,8 +1180,7 @@ void renderer_bgfx::update_recording()
void renderer_bgfx::add_audio_to_recording(const int16_t *buffer, int samples_this_frame)
{
- std::shared_ptr<osd_window> win = assert_window();
- if (m_avi_writer != nullptr && m_avi_writer->recording() && win->index() == 0)
+ if (m_avi_writer != nullptr && m_avi_writer->recording() && window().index() == 0)
{
m_avi_writer->audio_frame(buffer, samples_this_frame);
}
@@ -1059,9 +1188,7 @@ void renderer_bgfx::add_audio_to_recording(const int16_t *buffer, int samples_th
bool renderer_bgfx::update_dimensions()
{
- std::shared_ptr<osd_window> win = assert_window();
-
- const uint32_t window_index = win->index();
+ const uint32_t window_index = window().index();
const uint32_t width = s_width[window_index];
const uint32_t height = s_height[window_index];
@@ -1070,15 +1197,15 @@ bool renderer_bgfx::update_dimensions()
bgfx::reset(width, height, video_config.waitvsync ? BGFX_RESET_VSYNC : BGFX_RESET_NONE);
m_dimensions = osd_dim(width, height);
- if (win->index() != 0)
+ if (window().index() != 0)
{
delete m_framebuffer;
#ifdef OSD_WINDOWS
- m_framebuffer = m_targets->create_backbuffer(std::static_pointer_cast<win_window_info>(win)->platform_window(), width, height);
+ m_framebuffer = m_targets->create_backbuffer(dynamic_cast<win_window_info &>(window()).platform_window(), width, height);
#elif defined(OSD_MAC)
- m_framebuffer = m_targets->create_backbuffer(GetOSWindow(std::static_pointer_cast<mac_window_info>(win)->platform_window()), width, height);
+ m_framebuffer = m_targets->create_backbuffer(GetOSWindow(dynamic_cast<mac_window_info &>(window()).platform_window()), width, height);
#else
- m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window()), width, height);
+ m_framebuffer = m_targets->create_backbuffer(sdlNativeWindowHandle(dynamic_cast<sdl_window_info &>(window()).platform_window()), width, height);
#endif
if (m_ortho_view)
{
@@ -1100,7 +1227,7 @@ void renderer_bgfx::setup_ortho_view()
{
if (!m_ortho_view)
{
- m_ortho_view = new bgfx_ortho_view(this, 0, m_framebuffer, m_seen_views);
+ m_ortho_view = std::make_unique<bgfx_ortho_view>(this, 0, m_framebuffer, m_seen_views);
}
if (m_ortho_view->get_index() == UINT_MAX)
{
@@ -1113,10 +1240,6 @@ void renderer_bgfx::setup_ortho_view()
render_primitive_list *renderer_bgfx::get_primitives()
{
- auto win = try_getwindow();
- if (win == nullptr)
- return nullptr;
-
// determines whether the screen container is transformed by the chain's shaders
bool chain_transform = false;
@@ -1127,12 +1250,12 @@ render_primitive_list *renderer_bgfx::get_primitives()
chain_transform = chain->transform();
}
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (wdim.width() > 0 && wdim.height() > 0)
- win->target()->set_bounds(wdim.width(), wdim.height(), win->pixel_aspect());
+ window().target()->set_bounds(wdim.width(), wdim.height(), window().pixel_aspect());
- win->target()->set_transform_container(!chain_transform);
- return &win->target()->get_primitives();
+ window().target()->set_transform_container(!chain_transform);
+ return &window().target()->get_primitives();
}
renderer_bgfx::buffer_status renderer_bgfx::buffer_primitives(bool atlas_valid, render_primitive** prim, bgfx::TransientVertexBuffer* buffer, int32_t screen, int window_index)
@@ -1307,9 +1430,8 @@ bool renderer_bgfx::check_for_dirty_atlas()
{
bool atlas_dirty = false;
- std::shared_ptr<osd_window> win = assert_window();
std::map<uint32_t, rectangle_packer::packable_rectangle> acquired_infos;
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
bool pack = prim.packable(PACKABLE_SIZE);
if (prim.type == render_primitive::QUAD && prim.texture.base != nullptr && pack)
@@ -1410,33 +1532,31 @@ uint32_t renderer_bgfx::get_window_height(uint32_t index) const
}
-void renderer_bgfx::load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
+void renderer_bgfx::load_config(util::xml::data_node const &parentnode)
{
- if ((cfg_type == config_type::SYSTEM) && parentnode)
+ util::xml::data_node const *windownode = parentnode.get_child("window");
+ while (windownode)
{
- auto const win = try_getwindow();
- if (win)
+ if (windownode->get_attribute_int("index", -1) != window().index())
{
- util::xml::data_node const *windownode = parentnode->get_child("window");
- while (windownode)
- {
- if (windownode->get_attribute_int("index", -1) != win->index())
- {
- windownode = windownode->get_next_sibling("window");
- continue;
- }
-
- m_config = util::xml::file::create();
- windownode->copy_into(*m_config);
- break;
- }
+ windownode = windownode->get_next_sibling("window");
+ continue;
}
+
+ if (!m_config)
+ m_config = util::xml::file::create();
+ else
+ m_config->get_first_child()->delete_node();
+ windownode->copy_into(*m_config);
+ break;
}
}
-void renderer_bgfx::save_config(config_type cfg_type, util::xml::data_node *parentnode)
+void renderer_bgfx::save_config(util::xml::data_node &parentnode)
{
- if (cfg_type == config_type::SYSTEM)
- m_chains->save_config(*parentnode);
+ if (m_config)
+ m_config->get_first_child()->copy_into(parentnode);
+ else
+ m_chains->save_config(parentnode);
}
diff --git a/src/osd/modules/render/drawbgfx.h b/src/osd/modules/render/drawbgfx.h
index 15b0d6e158b..14e076843a7 100644
--- a/src/osd/modules/render/drawbgfx.h
+++ b/src/osd/modules/render/drawbgfx.h
@@ -5,8 +5,6 @@
#pragma once
-#include <bgfx/bgfx.h>
-
#include "binpacker.h"
#include "bgfx/chain.h"
#include "bgfx/chainmanager.h"
@@ -15,6 +13,10 @@
#include "modules/osdwindow.h"
+#include "notifier.h"
+
+#include <bgfx/bgfx.h>
+
#include <map>
#include <memory>
#include <vector>
@@ -35,12 +37,15 @@ class avi_write;
class renderer_bgfx : public osd_renderer, public slider_dirty_notifier
{
public:
- renderer_bgfx(std::shared_ptr<osd_window> w);
+ renderer_bgfx(
+ osd_window &window,
+ const osd_options &options,
+ util::notifier<util::xml::data_node const &> &load_notifier,
+ util::notifier<util::xml::data_node &> &save_notifier,
+ util::xml::data_node &persistent_settings,
+ uint32_t max_texsize);
virtual ~renderer_bgfx();
- static bool init(running_machine &machine);
- static void exit();
-
virtual int create() override;
virtual int draw(const int update) override;
@@ -73,8 +78,6 @@ private:
BUFFER_DONE
};
- void init_bgfx_library();
-
void vertex(ScreenVertex* vertex, float x, float y, float z, uint32_t rgba, float u, float v);
void render_avi_quad();
void update_recording();
@@ -103,11 +106,11 @@ private:
void process_atlas_packs(std::vector<std::vector<rectangle_packer::packed_rectangle>>& packed);
uint32_t get_texture_hash(render_primitive *prim);
- void load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
- void save_config(config_type cfg_type, util::xml::data_node *parentnode);
+ void load_config(util::xml::data_node const &parentnode);
+ void save_config(util::xml::data_node &parentnode);
- osd_options& m_options;
- bgfx::PlatformData m_platform_data;
+ const osd_options& m_options;
+ const uint32_t m_max_texture_size;
bgfx_target *m_framebuffer;
bgfx_texture *m_texture_cache;
@@ -115,11 +118,11 @@ private:
// Original display_mode
osd_dim m_dimensions;
- texture_manager *m_textures;
- target_manager *m_targets;
- shader_manager *m_shaders;
- effect_manager *m_effects;
- chain_manager *m_chains;
+ std::unique_ptr<texture_manager> m_textures;
+ std::unique_ptr<target_manager> m_targets;
+ std::unique_ptr<shader_manager> m_shaders;
+ std::unique_ptr<effect_manager> m_effects;
+ std::unique_ptr<chain_manager> m_chains;
bgfx_effect *m_gui_effect[4];
bgfx_effect *m_screen_effect[4];
@@ -130,7 +133,7 @@ private:
rectangle_packer m_packer;
uint32_t m_white[16*16];
- bgfx_view *m_ortho_view;
+ std::unique_ptr<bgfx_view> m_ortho_view;
uint32_t m_max_view;
uint16_t m_view_width;
uint16_t m_view_height;
@@ -141,17 +144,19 @@ private:
bgfx::TextureHandle m_avi_texture;
bitmap_rgb32 m_avi_bitmap;
uint8_t *m_avi_data;
+
std::unique_ptr<util::xml::file> m_config;
+ const util::notifier_subscription m_load_sub;
+ const util::notifier_subscription m_save_sub;
+ util::xml::data_node &m_persistent_settings;
static const uint16_t CACHE_SIZE;
static const uint32_t PACKABLE_SIZE;
static const uint32_t WHITE_HASH;
static uint32_t s_current_view;
- static bool s_bgfx_library_initialized;
static uint32_t s_width[16];
static uint32_t s_height[16];
- static uint32_t s_max_texture_size;
};
#endif // MAME_RENDER_DRAWBGFX_H
diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp
index f9f03d9efc0..4bc646408b3 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -13,21 +13,120 @@
#include "rendutil.h"
#include "screen.h"
-#include "aviio.h"
-
// MAMEOS headers
-#include "winmain.h"
-#include "window.h"
#include "drawd3d.h"
-#include "modules/render/d3d/d3dhlsl.h"
+
+#include "d3d/d3dhlsl.h"
+
+#include "render_module.h"
+
+// from OSD implementation
+#include "window.h"
+#include "winmain.h"
+
+// general OSD headers
#include "modules/monitor/monitor_module.h"
+
+// lib/util
+#include "aviio.h"
+
#include <utility>
+
+//============================================================
+// OSD MODULE
+//============================================================
+
+namespace osd {
+
+namespace {
+
+class video_d3d : public osd_module, public render_module
+{
+public:
+ video_d3d()
+ : osd_module(OSD_RENDERER_PROVIDER, "d3d")
+ , m_options(nullptr)
+ {
+ }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE; }
+
+private:
+ using d3d9_create_fn = IDirect3D9 *(WINAPI *)(UINT);
+
+ dynamic_module::ptr m_d3d9_dll;
+ Microsoft::WRL::ComPtr<IDirect3D9> m_d3dobj;
+ osd_options const *m_options;
+};
+
+
//============================================================
-// TYPE DEFINITIONS
+// video_d3d::init
//============================================================
-typedef IDirect3D9* (WINAPI *d3d9_create_fn)(UINT);
+int video_d3d::init(osd_interface &osd, osd_options const &options)
+{
+ m_options = &options;
+
+ m_d3d9_dll = dynamic_module::open({ "d3d9.dll" });
+ auto const d3d9_create_ptr = m_d3d9_dll->bind<d3d9_create_fn>("Direct3DCreate9");
+ if (!d3d9_create_ptr)
+ {
+ osd_printf_warning("Direct3D: Could not find Direct3DCreate9 function in d3d9.dll\n");
+ m_d3d9_dll.reset();
+ m_options = nullptr;
+ return -1;
+ }
+
+ m_d3dobj.Attach((d3d9_create_ptr)(D3D_SDK_VERSION));
+ if (!m_d3dobj)
+ {
+ osd_printf_warning("Direct3D: Unable to initialize Direct3D 9\n");
+ m_d3d9_dll.reset();
+ m_options = nullptr;
+ return -1;
+ }
+
+ osd_printf_verbose("Direct3D: Using Direct3D 9\n");
+
+ return 0;
+}
+
+
+//============================================================
+// video_d3d::exit
+//============================================================
+
+void video_d3d::exit()
+{
+ m_d3dobj.Reset();
+ m_d3d9_dll.reset();
+ m_options = nullptr;
+}
+
+
+//============================================================
+// video_d3d::create
+//============================================================
+
+std::unique_ptr<osd_renderer> video_d3d::create(osd_window &window)
+{
+ return std::make_unique<renderer_d3d9>(window, m_d3dobj);
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+MODULE_DEFINITION(RENDERER_D3D, osd::video_d3d)
+
//============================================================
@@ -116,13 +215,6 @@ static inline uint32_t ycc_to_rgb(uint8_t y, uint8_t cb, uint8_t cr)
//============================================================
-// drawd3d_init
-//============================================================
-
-static d3d_base *d3dintf = nullptr; // FIX ME
-
-
-//============================================================
// drawd3d_window_init
//============================================================
@@ -174,60 +266,22 @@ void renderer_d3d9::save()
render_primitive_list *renderer_d3d9::get_primitives()
{
RECT client;
- auto win = try_getwindow();
- if (win == nullptr)
- return nullptr;
-
- HWND hWnd = std::static_pointer_cast<win_window_info>(win)->platform_window();
+ HWND hWnd = dynamic_cast<win_window_info &>(window()).platform_window();
if (IsIconic(hWnd))
return nullptr;
- GetClientRectExceptMenu(hWnd, &client, win->fullscreen());
+ GetClientRectExceptMenu(hWnd, &client, window().fullscreen());
if (rect_width(&client) > 0 && rect_height(&client) > 0)
{
- win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect());
- win->target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh());
+ window().target()->set_bounds(rect_width(&client), rect_height(&client), window().pixel_aspect());
+ window().target()->set_max_update_rate((get_refresh() == 0) ? get_origmode().RefreshRate : get_refresh());
}
if (m_shaders != nullptr)
{
// do not transform primitives (scale, offset) if shaders are enabled, the shaders will handle the transformation
- win->target()->set_transform_container(!m_shaders->enabled());
+ window().target()->set_transform_container(!m_shaders->enabled());
}
- return &win->target()->get_primitives();
-}
-
-
-//============================================================
-// renderer_d3d9::init
-//============================================================
-
-bool renderer_d3d9::init(running_machine &machine)
-{
- d3dintf = new d3d_base;
-
- d3dintf->d3d9_dll = osd::dynamic_module::open({ "d3d9.dll" });
-
- d3d9_create_fn d3d9_create_ptr = d3dintf->d3d9_dll->bind<d3d9_create_fn>("Direct3DCreate9");
- if (d3d9_create_ptr == nullptr)
- {
- delete d3dintf;
- d3dintf = nullptr;
- osd_printf_verbose("Direct3D: Unable to find Direct3D 9 runtime library\n");
- return true;
- }
-
- d3dintf->d3dobj = (*d3d9_create_ptr)(D3D_SDK_VERSION);
- if (d3dintf->d3dobj == nullptr)
- {
- delete d3dintf;
- d3dintf = nullptr;
- osd_printf_verbose("Direct3D: Unable to initialize Direct3D 9\n");
- return true;
- }
-
- osd_printf_verbose("Direct3D: Using Direct3D 9\n");
-
- return false;
+ return &window().target()->get_primitives();
}
@@ -412,14 +466,12 @@ void renderer_d3d9::reset_render_states()
m_last_wrap = (D3DTEXTUREADDRESS)-1;
}
-d3d_texture_manager::d3d_texture_manager(renderer_d3d9 *d3d)
+d3d_texture_manager::d3d_texture_manager(renderer_d3d9 &d3d, IDirect3D9 *d3dobj)
+ : m_renderer(d3d)
+ , m_default_texture(nullptr)
{
- m_renderer = d3d;
-
- m_default_texture = nullptr;
-
D3DCAPS9 caps;
- HRESULT result = d3dintf->d3dobj->GetDeviceCaps(d3d->get_adapter(), D3DDEVTYPE_HAL, &caps);
+ HRESULT result = d3dobj->GetDeviceCaps(d3d.get_adapter(), D3DDEVTYPE_HAL, &caps);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during GetDeviceCaps call\n", result);
@@ -431,27 +483,23 @@ d3d_texture_manager::d3d_texture_manager(renderer_d3d9 *d3d)
// pick a YUV texture format
m_yuv_format = D3DFMT_UYVY;
- result = d3dintf->d3dobj->CheckDeviceFormat(d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
+ result = d3dobj->CheckDeviceFormat(d3d.get_adapter(), D3DDEVTYPE_HAL, d3d.get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
if (FAILED(result))
{
m_yuv_format = D3DFMT_YUY2;
- result = d3dintf->d3dobj->CheckDeviceFormat(d3d->get_adapter(), D3DDEVTYPE_HAL, d3d->get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
+ result = d3dobj->CheckDeviceFormat(d3d.get_adapter(), D3DDEVTYPE_HAL, d3d.get_pixel_format(), 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
if (FAILED(result))
m_yuv_format = D3DFMT_A8R8G8B8;
}
osd_printf_verbose("Direct3D: YUV format = %s\n", (m_yuv_format == D3DFMT_YUY2) ? "YUY2" : (m_yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB");
- auto win = d3d->assert_window();
-
// set the max texture size
- win->target()->set_max_texture_size(m_texture_max_width, m_texture_max_height);
- osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)m_texture_max_width, (int)m_texture_max_height);
+ d3d.window().target()->set_max_texture_size(m_texture_max_width, m_texture_max_height);
+ osd_printf_verbose("Direct3D: Max texture size = %dx%d\n", m_texture_max_width, m_texture_max_height);
}
void d3d_texture_manager::create_resources()
{
- auto win = m_renderer->assert_window();
-
m_default_bitmap.allocate(8, 8);
m_default_bitmap.fill(rgb_t(0xff,0xff,0xff,0xff));
@@ -470,7 +518,7 @@ void d3d_texture_manager::create_resources()
texture.old_id = ~0ULL;
// now create it
- auto tex = std::make_unique<texture_info>(this, &texture, win->prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
+ auto tex = std::make_unique<texture_info>(*this, &texture, m_renderer.window().prescale(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
m_default_texture = tex.get();
m_texture_list.push_back(std::move(tex));
}
@@ -479,7 +527,6 @@ void d3d_texture_manager::create_resources()
void d3d_texture_manager::delete_resources()
{
// is part of m_texlist and will be free'd there
- //delete m_default_texture;
m_default_texture = nullptr;
// free all textures
@@ -518,11 +565,35 @@ texture_info *d3d_texture_manager::find_texinfo(const render_texinfo *texinfo, u
return nullptr;
}
-renderer_d3d9::renderer_d3d9(std::shared_ptr<osd_window> window)
- : osd_renderer(window, FLAG_NONE), m_adapter(0), m_width(0), m_height(0), m_refresh(0), m_create_error_count(0), m_device(nullptr), m_gamma_supported(0), m_pixformat(),
- m_vertexbuf(nullptr), m_lockedbuf(nullptr), m_numverts(0), m_vectorbatch(nullptr), m_batchindex(0), m_numpolys(0), m_toggle(false),
- m_screen_format(), m_last_texture(nullptr), m_last_texture_flags(0), m_last_blendenable(0), m_last_blendop(0), m_last_blendsrc(0), m_last_blenddst(0), m_last_filter(0),
- m_last_wrap(), m_last_modmode(0), m_shaders(nullptr), m_texture_manager()
+renderer_d3d9::renderer_d3d9(osd_window &window, const IDirect3D9Ptr &d3dobj)
+ : osd_renderer(window)
+ , m_d3dobj(d3dobj)
+ , m_adapter(0)
+ , m_width(0)
+ , m_height(0)
+ , m_refresh(0)
+ , m_create_error_count(0)
+ , m_post_fx_available(true)
+ , m_gamma_supported(0)
+ , m_pixformat()
+ , m_lockedbuf(nullptr)
+ , m_numverts(0)
+ , m_vectorbatch(nullptr)
+ , m_batchindex(0)
+ , m_numpolys(0)
+ , m_toggle(false)
+ , m_screen_format()
+ , m_last_texture(nullptr)
+ , m_last_texture_flags(0)
+ , m_last_blendenable(0)
+ , m_last_blendop(0)
+ , m_last_blendsrc(0)
+ , m_last_blenddst(0)
+ , m_last_filter(0)
+ , m_last_wrap()
+ , m_last_modmode(0)
+ , m_shaders(nullptr)
+ , m_texture_manager()
{
}
@@ -537,8 +608,7 @@ int renderer_d3d9::initialize()
}
// create the device immediately for the full screen case (defer for window mode in update_window_size())
- auto win = assert_window();
- if (win->fullscreen() && device_create(std::static_pointer_cast<win_window_info>(win->main_window())->platform_window()))
+ if (window().fullscreen() && device_create(dynamic_cast<win_window_info &>(window()).main_window()->platform_window()))
{
return false;
}
@@ -548,10 +618,8 @@ int renderer_d3d9::initialize()
int renderer_d3d9::pre_window_draw_check()
{
- auto win = assert_window();
-
// if we're in the middle of resizing, leave things alone
- if (win->m_resize_state == RESIZE_STATE_RESIZING)
+ if (window().m_resize_state == RESIZE_STATE_RESIZING)
return 0;
// check if shaders should be toggled
@@ -575,7 +643,7 @@ int renderer_d3d9::pre_window_draw_check()
}
// if we have a device, check the cooperative level
- if (m_device != nullptr)
+ if (m_device)
{
if (device_test_cooperative())
{
@@ -584,14 +652,14 @@ int renderer_d3d9::pre_window_draw_check()
}
// in window mode, we need to track the window size
- if (!win->fullscreen() || m_device == nullptr)
+ if (!window().fullscreen() || !m_device)
{
// if the size changes, skip this update since the render target will be out of date
if (update_window_size())
return 0;
// if we have no device, after updating the size, return an error so GDI can try
- if (m_device == nullptr)
+ if (!m_device)
return 1;
}
@@ -600,18 +668,16 @@ int renderer_d3d9::pre_window_draw_check()
void d3d_texture_manager::update_textures()
{
- auto win = m_renderer->assert_window();
-
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *m_renderer.window().m_primlist)
{
if (prim.texture.base != nullptr)
{
texture_info *texture = find_texinfo(&prim.texture, prim.flags);
if (texture == nullptr)
{
- int prescale = m_renderer->get_shaders()->enabled() ? 1 : win->prescale();
+ int prescale = m_renderer.get_shaders()->enabled() ? 1 : m_renderer.window().prescale();
- auto tex = std::make_unique<texture_info>(this, &prim.texture, prescale, prim.flags);
+ auto tex = std::make_unique<texture_info>(*this, &prim.texture, prescale, prim.flags);
texture = tex.get();
m_texture_list.push_back(std::move(tex));
}
@@ -627,21 +693,21 @@ void d3d_texture_manager::update_textures()
}
}
- if (!m_renderer->get_shaders()->enabled())
+ if (!m_renderer.get_shaders()->enabled())
{
return;
}
int screen_index = 0;
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *m_renderer.window().m_primlist)
{
if (PRIMFLAG_GET_SCREENTEX(prim.flags))
{
- if (!m_renderer->get_shaders()->get_texture_target(&prim, prim.texture.width, prim.texture.height, screen_index))
+ if (!m_renderer.get_shaders()->get_texture_target(&prim, prim.texture.width, prim.texture.height, screen_index))
{
- if (!m_renderer->get_shaders()->create_texture_target(&prim, prim.texture.width, prim.texture.height, screen_index))
+ if (!m_renderer.get_shaders()->create_texture_target(&prim, prim.texture.width, prim.texture.height, screen_index))
{
- d3dintf->post_fx_available = false;
+ m_renderer.set_post_fx_unavailable();
break;
}
}
@@ -649,11 +715,11 @@ void d3d_texture_manager::update_textures()
}
else if (PRIMFLAG_GET_VECTORBUF(prim.flags))
{
- if (!m_renderer->get_shaders()->get_vector_target(&prim, screen_index))
+ if (!m_renderer.get_shaders()->get_vector_target(&prim, screen_index))
{
- if (!m_renderer->get_shaders()->create_vector_target(&prim, screen_index))
+ if (!m_renderer.get_shaders()->create_vector_target(&prim, screen_index))
{
- d3dintf->post_fx_available = false;
+ m_renderer.set_post_fx_unavailable();
break;
}
}
@@ -664,13 +730,11 @@ void d3d_texture_manager::update_textures()
void renderer_d3d9::begin_frame()
{
- auto win = assert_window();
-
HRESULT result = m_device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0xff,0,0,0), 0, 0);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device clear call\n", result);
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// first update any textures
m_texture_manager->update_textures();
@@ -681,16 +745,14 @@ void renderer_d3d9::begin_frame()
osd_printf_verbose("Direct3D: Error %08lX during device BeginScene call\n", result);
if (m_shaders->enabled())
- m_shaders->begin_frame(win->m_primlist);
+ m_shaders->begin_frame(window().m_primlist);
}
void renderer_d3d9::process_primitives()
{
- auto win = assert_window();
-
// loop over line primitives
int vector_count = 0;
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
if (prim.type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim.flags))
{
@@ -699,7 +761,7 @@ void renderer_d3d9::process_primitives()
}
// Rotating index for vector time offsets
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
switch (prim.type)
{
@@ -730,9 +792,7 @@ void renderer_d3d9::process_primitives()
void renderer_d3d9::end_frame()
{
- auto win = assert_window();
-
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
// flush any pending polygons
primitive_flush_pending();
@@ -753,8 +813,6 @@ void renderer_d3d9::end_frame()
void renderer_d3d9::update_presentation_parameters()
{
- auto win = assert_window();
-
memset(&m_presentation, 0, sizeof(m_presentation));
m_presentation.BackBufferWidth = m_width;
m_presentation.BackBufferHeight = m_height;
@@ -762,14 +820,14 @@ void renderer_d3d9::update_presentation_parameters()
m_presentation.BackBufferCount = video_config.triplebuf ? 2 : 1;
m_presentation.MultiSampleType = D3DMULTISAMPLE_NONE;
m_presentation.SwapEffect = D3DSWAPEFFECT_DISCARD;
- m_presentation.hDeviceWindow = std::static_pointer_cast<win_window_info>(win)->platform_window();
- m_presentation.Windowed = !win->fullscreen();
+ m_presentation.hDeviceWindow = dynamic_cast<win_window_info &>(window()).platform_window();
+ m_presentation.Windowed = !window().fullscreen();
m_presentation.EnableAutoDepthStencil = FALSE;
m_presentation.AutoDepthStencilFormat = D3DFMT_D16;
m_presentation.Flags = 0;
m_presentation.FullScreen_RefreshRateInHz = m_refresh;
m_presentation.PresentationInterval = (
- (video_config.triplebuf && win->fullscreen())
+ (video_config.triplebuf && window().fullscreen())
|| video_config.waitvsync
|| video_config.syncrefresh)
? D3DPRESENT_INTERVAL_ONE
@@ -784,13 +842,11 @@ void renderer_d3d9::update_gamma_ramp()
return;
}
- auto win = assert_window();
-
// set the gamma if we need to
- if (win->fullscreen())
+ if (window().fullscreen())
{
// only set the gamma if it's not 1.0
- auto &options = downcast<windows_options &>(win->machine().options());
+ auto &options = downcast<windows_options &>(window().machine().options());
float brightness = options.full_screen_brightness();
float contrast = options.full_screen_contrast();
float gamma = options.full_screen_gamma();
@@ -820,27 +876,23 @@ int renderer_d3d9::device_create(HWND hwnd)
HWND device_hwnd = GetAncestor(hwnd, GA_ROOT);
// if a device exists, free it
- if (m_device != nullptr)
- {
+ if (m_device)
device_delete();
- }
// verify the caps
if (!device_verify_caps())
- {
return 1;
- }
- m_texture_manager = std::make_unique<d3d_texture_manager>(this);
+ m_texture_manager = std::make_unique<d3d_texture_manager>(*this, m_d3dobj.Get());
// try for XRGB first
m_screen_format = D3DFMT_X8R8G8B8;
- HRESULT result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, m_screen_format);
+ HRESULT result = m_d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, m_screen_format);
if (FAILED(result))
{
// if not, try for ARGB
m_screen_format = D3DFMT_A8R8G8B8;
- result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, m_screen_format);
+ result = m_d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, m_screen_format);
if (FAILED(result))
{
osd_printf_error("Error: unable to configure a screen texture format\n");
@@ -852,8 +904,13 @@ int renderer_d3d9::device_create(HWND hwnd)
update_presentation_parameters();
// create the D3D device
- result = d3dintf->d3dobj->CreateDevice(
- m_adapter, D3DDEVTYPE_HAL, device_hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &m_presentation, &m_device);
+ result = m_d3dobj->CreateDevice(
+ m_adapter,
+ D3DDEVTYPE_HAL,
+ device_hwnd,
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE,
+ &m_presentation,
+ &m_device);
if (FAILED(result))
{
// if we got a "DEVICELOST" error, it may be transitory; count it and only fail if
@@ -886,16 +943,13 @@ int renderer_d3d9::device_create(HWND hwnd)
int renderer_d3d9::device_create_resources()
{
- auto win = assert_window();
-
// create shaders only once
- if (m_shaders == nullptr)
- {
- m_shaders = new shaders;
- }
+ if (!m_shaders)
+ m_shaders = std::make_unique<shaders>();
- if (m_shaders->init(d3dintf, &win->machine(), this))
+ if (m_shaders->init(m_d3dobj.Get(), &window().machine(), this))
{
+ m_post_fx_available = true;
m_shaders->init_slider_list();
m_sliders_dirty = true;
}
@@ -909,12 +963,12 @@ int renderer_d3d9::device_create_resources()
// allocate a vertex buffer to use
HRESULT result = m_device->CreateVertexBuffer(
- sizeof(vertex) * VERTEX_BUFFER_SIZE,
- D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
- VERTEX_BASE_FORMAT | ((m_shaders->enabled())
- ? D3DFVF_XYZW
- : D3DFVF_XYZRHW),
- D3DPOOL_DEFAULT, &m_vertexbuf, nullptr);
+ sizeof(vertex) * VERTEX_BUFFER_SIZE,
+ D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
+ VERTEX_BASE_FORMAT | (m_shaders->enabled() ? D3DFVF_XYZW : D3DFVF_XYZRHW),
+ D3DPOOL_DEFAULT,
+ &m_vertexbuf,
+ nullptr);
if (FAILED(result))
{
osd_printf_error("Error creating vertex buffer (%08X)\n", (uint32_t)result);
@@ -923,9 +977,7 @@ int renderer_d3d9::device_create_resources()
// set the vertex format
result = m_device->SetFVF(
- (D3DFORMAT)(VERTEX_BASE_FORMAT | ((m_shaders->enabled())
- ? D3DFVF_XYZW
- : D3DFVF_XYZRHW)));
+ D3DFORMAT(VERTEX_BASE_FORMAT | (m_shaders->enabled() ? D3DFVF_XYZW : D3DFVF_XYZRHW)));
if (FAILED(result))
{
osd_printf_error("Error setting vertex format (%08X)\n", (uint32_t)result);
@@ -977,24 +1029,6 @@ int renderer_d3d9::device_create_resources()
renderer_d3d9::~renderer_d3d9()
{
device_delete();
-
- // todo: throws error when switching from full screen to window mode
- //if (m_shaders != nullptr)
- //{
- // // delete the HLSL interface
- // delete m_shaders;
- // m_shaders = nullptr;
- //}
-}
-
-void renderer_d3d9::exit()
-{
- if (d3dintf != nullptr)
- {
- d3dintf->d3dobj->Release();
- delete d3dintf;
- d3dintf = nullptr;
- }
}
void renderer_d3d9::device_delete()
@@ -1007,11 +1041,7 @@ void renderer_d3d9::device_delete()
m_texture_manager.reset();
// free the device itself
- if (m_device != nullptr)
- {
- m_device->Release();
- m_device = nullptr;
- }
+ m_device.Reset();
}
@@ -1021,22 +1051,14 @@ void renderer_d3d9::device_delete()
void renderer_d3d9::device_delete_resources()
{
- if (m_shaders != nullptr)
- {
+ if (m_shaders)
m_shaders->delete_resources();
- }
- if (m_texture_manager != nullptr)
- {
+ if (m_texture_manager)
m_texture_manager->delete_resources();
- }
// free the vertex buffer
- if (m_vertexbuf != nullptr)
- {
- m_vertexbuf->Release();
- m_vertexbuf = nullptr;
- }
+ m_vertexbuf.Reset();
}
@@ -1049,7 +1071,7 @@ bool renderer_d3d9::device_verify_caps()
bool success = true;
D3DCAPS9 caps;
- HRESULT result = d3dintf->d3dobj->GetDeviceCaps(m_adapter, D3DDEVTYPE_HAL, &caps);
+ HRESULT result = m_d3dobj->GetDeviceCaps(m_adapter, D3DDEVTYPE_HAL, &caps);
if (FAILED(result))
{
osd_printf_verbose("Direct3D: Error %08lX during GetDeviceCaps call\n", result);
@@ -1059,7 +1081,7 @@ bool renderer_d3d9::device_verify_caps()
if (caps.MaxPixelShader30InstructionSlots < 512)
{
osd_printf_verbose("Direct3D: Warning - Device does not support Pixel Shader 3.0, falling back to non-PS rendering\n");
- d3dintf->post_fx_available = false;
+ set_post_fx_unavailable();
}
// verify presentation capabilities
@@ -1114,7 +1136,7 @@ bool renderer_d3d9::device_verify_caps()
}
// verify texture formats
- result = d3dintf->d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
+ result = m_d3dobj->CheckDeviceFormat(m_adapter, D3DDEVTYPE_HAL, m_pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
if (FAILED(result))
{
osd_printf_error("Direct3D Error: Your graphics card does not support the A8R8G8B8 texture format.\n");
@@ -1190,7 +1212,7 @@ int renderer_d3d9::config_adapter_mode()
// get the identifier
D3DADAPTER_IDENTIFIER9 id;
- HRESULT result = d3dintf->d3dobj->GetAdapterIdentifier(m_adapter, 0, &id);
+ HRESULT result = m_d3dobj->GetAdapterIdentifier(m_adapter, 0, &id);
if (FAILED(result))
{
osd_printf_error("Error getting identifier for adapter #%d\n", m_adapter);
@@ -1200,22 +1222,20 @@ int renderer_d3d9::config_adapter_mode()
osd_printf_verbose("Direct3D: Configuring adapter #%d = %s\n", m_adapter, id.Description);
// get the current display mode
- result = d3dintf->d3dobj->GetAdapterDisplayMode(m_adapter, &m_origmode);
+ result = m_d3dobj->GetAdapterDisplayMode(m_adapter, &m_origmode);
if (FAILED(result))
{
osd_printf_error("Error getting mode for adapter #%d\n", m_adapter);
return 1;
}
- auto win = assert_window();
-
- // choose a resolution: window mode case
- if (!win->fullscreen() || !video_config.switchres)
+ if (!window().fullscreen() || !video_config.switchres)
{
- RECT client;
+ // choose a resolution: window mode case
// bounds are from the window client rect
- GetClientRectExceptMenu(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client, win->fullscreen());
+ RECT client;
+ GetClientRectExceptMenu(dynamic_cast<win_window_info &>(window()).platform_window(), &client, window().fullscreen());
m_width = client.right - client.left;
m_height = client.bottom - client.top;
@@ -1226,14 +1246,14 @@ int renderer_d3d9::config_adapter_mode()
// make sure it's a pixel format we can get behind
if (m_pixformat != D3DFMT_X1R5G5B5 && m_pixformat != D3DFMT_R5G6B5 && m_pixformat != D3DFMT_X8R8G8B8)
{
- osd_printf_error("Device %s currently in an unsupported mode\n", win->monitor()->devicename());
+ osd_printf_error("Device %s currently in an unsupported mode\n", window().monitor()->devicename());
return 1;
}
}
-
- // choose a resolution: full screen mode case
else
{
+ // choose a resolution: full screen mode case
+
// default to the current mode exactly
m_width = m_origmode.Width;
m_height = m_origmode.Height;
@@ -1246,10 +1266,10 @@ int renderer_d3d9::config_adapter_mode()
}
// see if we can handle the device type
- result = d3dintf->d3dobj->CheckDeviceType(m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !win->fullscreen());
+ result = m_d3dobj->CheckDeviceType(m_adapter, D3DDEVTYPE_HAL, m_pixformat, m_pixformat, !window().fullscreen());
if (FAILED(result))
{
- osd_printf_error("Proposed video mode not supported on device %s\n", win->monitor()->devicename());
+ osd_printf_error("Proposed video mode not supported on device %s\n", window().monitor()->devicename());
return 1;
}
@@ -1263,18 +1283,16 @@ int renderer_d3d9::config_adapter_mode()
int renderer_d3d9::get_adapter_for_monitor()
{
- int maxadapter = d3dintf->d3dobj->GetAdapterCount();
-
- auto win = assert_window();
+ int maxadapter = m_d3dobj->GetAdapterCount();
// iterate over adapters until we error or find a match
for (int adapternum = 0; adapternum < maxadapter; adapternum++)
{
// get the monitor for this adapter
- HMONITOR curmonitor = d3dintf->d3dobj->GetAdapterMonitor(adapternum);
+ HMONITOR curmonitor = m_d3dobj->GetAdapterMonitor(adapternum);
// if we match the proposed monitor, this is it
- if (curmonitor == reinterpret_cast<HMONITOR>(win->monitor()->oshandle()))
+ if (curmonitor == reinterpret_cast<HMONITOR>(window().monitor()->oshandle()))
{
return adapternum;
}
@@ -1295,10 +1313,8 @@ void renderer_d3d9::pick_best_mode()
int32_t minwidth, minheight;
float best_score = 0.0f;
- auto win = assert_window();
-
// determine the refresh rate of the primary screen
- const screen_device *primary_screen = screen_device_enumerator(win->machine().root_device()).first();
+ const screen_device *primary_screen = screen_device_enumerator(window().machine().root_device()).first();
if (primary_screen != nullptr)
{
target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
@@ -1308,14 +1324,14 @@ void renderer_d3d9::pick_best_mode()
// note: technically we should not be calling this from an alternate window
// thread; however, it is only done during init time, and the init code on
// the main thread is waiting for us to finish, so it is safe to do so here
- win->target()->compute_minimum_size(minwidth, minheight);
+ window().target()->compute_minimum_size(minwidth, minheight);
// use those as the target for now
int32_t target_width = minwidth;
int32_t target_height = minheight;
// determine the maximum number of modes
- int maxmodes = d3dintf->d3dobj->GetAdapterModeCount(m_adapter, D3DFMT_X8R8G8B8);
+ int maxmodes = m_d3dobj->GetAdapterModeCount(m_adapter, D3DFMT_X8R8G8B8);
// enumerate all the video modes and find the best match
osd_printf_verbose("Direct3D: Selecting video mode...\n");
@@ -1323,7 +1339,7 @@ void renderer_d3d9::pick_best_mode()
{
// check this mode
D3DDISPLAYMODE mode;
- HRESULT result = d3dintf->d3dobj->EnumAdapterModes(m_adapter, D3DFMT_X8R8G8B8, modenum, &mode);
+ HRESULT result = m_d3dobj->EnumAdapterModes(m_adapter, D3DFMT_X8R8G8B8, modenum, &mode);
if (FAILED(result))
break;
@@ -1343,7 +1359,7 @@ void renderer_d3d9::pick_best_mode()
size_score *= 0.1f;
// if we're looking for a particular mode, that's a winner
- if (mode.Width == win->m_win_config.width && mode.Height == win->m_win_config.height)
+ if (mode.Width == window().m_win_config.width && mode.Height == window().m_win_config.height)
size_score = 2.0f;
// compute refresh score
@@ -1354,7 +1370,7 @@ void renderer_d3d9::pick_best_mode()
refresh_score *= 0.1f;
// if we're looking for a particular refresh, make sure it matches
- if (mode.RefreshRate == win->m_win_config.refresh)
+ if (mode.RefreshRate == window().m_win_config.refresh)
refresh_score = 2.0f;
// weight size and refresh equally
@@ -1381,33 +1397,31 @@ void renderer_d3d9::pick_best_mode()
bool renderer_d3d9::update_window_size()
{
- auto win = assert_window();
-
// get the current window bounds
RECT client;
- GetClientRectExceptMenu(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client, win->fullscreen());
+ GetClientRectExceptMenu(dynamic_cast<win_window_info &>(window()).platform_window(), &client, window().fullscreen());
// if we have a device and matching width/height, nothing to do
- if (m_device != nullptr && rect_width(&client) == m_width && rect_height(&client) == m_height)
+ if (m_device && rect_width(&client) == m_width && rect_height(&client) == m_height)
{
// clear out any pending resizing if the area didn't change
- if (win->m_resize_state == RESIZE_STATE_PENDING)
- win->m_resize_state = RESIZE_STATE_NORMAL;
+ if (window().m_resize_state == RESIZE_STATE_PENDING)
+ window().m_resize_state = RESIZE_STATE_NORMAL;
return false;
}
// if we're in the middle of resizing, leave it alone as well
- if (win->m_resize_state == RESIZE_STATE_RESIZING)
+ if (window().m_resize_state == RESIZE_STATE_RESIZING)
return false;
// set the new bounds and create the device again
m_width = rect_width(&client);
m_height = rect_height(&client);
- if (device_create(std::static_pointer_cast<win_window_info>(win->main_window())->platform_window()))
+ if (device_create(dynamic_cast<win_window_info &>(window()).main_window()->platform_window()))
return false;
// reset the resize state to normal, and indicate we made a change
- win->m_resize_state = RESIZE_STATE_NORMAL;
+ window().m_resize_state = RESIZE_STATE_NORMAL;
return true;
}
@@ -1418,8 +1432,6 @@ bool renderer_d3d9::update_window_size()
void renderer_d3d9::batch_vectors(int vector_count)
{
- auto win = assert_window();
-
float quad_width = 0.0f;
float quad_height = 0.0f;
float target_width = 0.0f;
@@ -1432,7 +1444,7 @@ void renderer_d3d9::batch_vectors(int vector_count)
uint32_t tint = 0xffffffff;
uint32_t cached_flags = 0;
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
switch (prim.type)
{
@@ -1476,15 +1488,15 @@ void renderer_d3d9::batch_vectors(int vector_count)
if (m_shaders->enabled())
{
bool orientation_swap_xy =
- (win->machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
+ (window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool rotation_swap_xy =
- (win->target()->orientation() & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
+ (window().target()->orientation() & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
bool swap_xy = orientation_swap_xy ^ rotation_swap_xy;
- bool rotation_0 = win->target()->orientation() == ROT0;
- bool rotation_90 = win->target()->orientation() == ROT90;
- bool rotation_180 = win->target()->orientation() == ROT180;
- bool rotation_270 = win->target()->orientation() == ROT270;
+ bool rotation_0 = window().target()->orientation() == ROT0;
+ bool rotation_90 = window().target()->orientation() == ROT90;
+ bool rotation_180 = window().target()->orientation() == ROT180;
+ bool rotation_270 = window().target()->orientation() == ROT270;
bool flip_x =
((rotation_0 || rotation_270) && orientation_swap_xy) ||
((rotation_180 || rotation_270) && !orientation_swap_xy);
@@ -1828,7 +1840,7 @@ void renderer_d3d9::primitive_flush_pending()
m_lockedbuf = nullptr;
// set the stream
- result = m_device->SetStreamSource(0, m_vertexbuf, 0, sizeof(vertex));
+ result = m_device->SetStreamSource(0, m_vertexbuf.Get(), 0, sizeof(vertex));
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetStreamSource call\n", result);
@@ -1931,19 +1943,6 @@ void renderer_d3d9::set_sliders_dirty()
texture_info::~texture_info()
{
- if (m_d3dfinaltex != nullptr)
- {
- if (m_d3dtex == m_d3dfinaltex)
- m_d3dtex = nullptr;
-
- m_d3dfinaltex->Release();
- }
-
- if (m_d3dtex != nullptr)
- m_d3dtex->Release();
-
- if (m_d3dsurface != nullptr)
- m_d3dsurface->Release();
}
@@ -1951,74 +1950,53 @@ texture_info::~texture_info()
// texture_info constructor
//============================================================
-texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* texsource, int prescale, uint32_t flags)
+texture_info::texture_info(d3d_texture_manager &manager, const render_texinfo* texsource, int prescale, uint32_t flags)
+ : m_texture_manager(manager)
+ , m_renderer(manager.get_d3d())
+ , m_hash(manager.texture_compute_hash(texsource, flags))
+ , m_flags(flags)
+ , m_texinfo(*texsource)
+ , m_type(!PRIMFLAG_GET_SCREENTEX(flags) ? TEXTURE_TYPE_PLAIN : TEXTURE_TYPE_DYNAMIC) // required to compute texture size
+ , m_xprescale(prescale)
+ , m_yprescale(prescale)
{
HRESULT result;
- // fill in the core data
- m_texture_manager = manager;
- m_renderer = m_texture_manager->get_d3d();
- m_hash = m_texture_manager->texture_compute_hash(texsource, flags);
- m_flags = flags;
- m_texinfo = *texsource;
- m_xprescale = prescale;
- m_yprescale = prescale;
-
- m_d3dtex = nullptr;
- m_d3dsurface = nullptr;
- m_d3dfinaltex = nullptr;
-
- // determine texture type, required to compute texture size
- if (!PRIMFLAG_GET_SCREENTEX(flags))
- {
- m_type = TEXTURE_TYPE_PLAIN;
- }
- else
- {
- m_type = TEXTURE_TYPE_DYNAMIC;
- }
-
// compute the size
compute_size(texsource->width, texsource->height);
- // non-screen textures are easy
if (!PRIMFLAG_GET_SCREENTEX(flags))
{
+ // non-screen textures are easy
assert(PRIMFLAG_TEXFORMAT(flags) != TEXFORMAT_YUY16);
- result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex, nullptr);
+ result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_d3dtex, nullptr);
if (FAILED(result))
goto error;
+
m_d3dfinaltex = m_d3dtex;
}
-
- // screen textures are allocated differently
else
{
+ // screen textures are allocated differently
D3DFORMAT format;
DWORD usage = D3DUSAGE_DYNAMIC;
D3DPOOL pool = D3DPOOL_DEFAULT;
- int maxdim = std::max(m_renderer->get_presentation()->BackBufferWidth, m_renderer->get_presentation()->BackBufferHeight);
+ int maxdim = std::max(m_renderer.get_presentation()->BackBufferWidth, m_renderer.get_presentation()->BackBufferHeight);
// pick the format
if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_YUY16)
- {
- format = m_texture_manager->get_yuv_format();
- }
+ format = m_texture_manager.get_yuv_format();
else if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_ARGB32)
- {
format = D3DFMT_A8R8G8B8;
- }
else
- {
- format = m_renderer->get_screen_format();
- }
+ format = m_renderer.get_screen_format();
// don't prescale above screen size
while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale >= 2 * maxdim)
{
m_xprescale--;
}
- while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale > manager->get_max_texture_width())
+ while (m_xprescale > 1 && m_rawdims.c.x * m_xprescale > manager.get_max_texture_width())
{
m_xprescale--;
}
@@ -2026,62 +2004,51 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
{
m_yprescale--;
}
- while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale > manager->get_max_texture_height())
+ while (m_yprescale > 1 && m_rawdims.c.y * m_yprescale > manager.get_max_texture_height())
{
m_yprescale--;
}
- auto win = m_renderer->assert_window();
-
- int prescale = win->prescale();
+ const int prescale = m_renderer.window().prescale();
if (m_xprescale != prescale || m_yprescale != prescale)
- {
osd_printf_verbose("Direct3D: adjusting prescale from %dx%d to %dx%d\n", prescale, prescale, m_xprescale, m_yprescale);
- }
// loop until we allocate something or error
for (int attempt = 0; attempt < 2; attempt++)
{
// second attempt is always 1:1
if (attempt == 1)
- {
m_xprescale = m_yprescale = 1;
- }
- // screen textures with no prescaling are pretty easy
if (m_xprescale == 1 && m_yprescale == 1)
{
- result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
+ // screen textures with no prescaling are pretty easy
+ result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
if (result == D3D_OK)
{
m_d3dfinaltex = m_d3dtex;
break;
}
}
- // screen textures with prescaling require two allocations
else
{
- result = m_renderer->get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
+ // screen textures with prescaling require two allocations
+ result = m_renderer.get_device()->CreateTexture(m_rawdims.c.x, m_rawdims.c.y, 1, usage, format, pool, &m_d3dtex, nullptr);
if (FAILED(result))
- {
continue;
- }
// for the target surface, we allocate a render target texture
- int scwidth = m_rawdims.c.x * m_xprescale;
- int scheight = m_rawdims.c.y * m_yprescale;
+ const int scwidth = m_rawdims.c.x * m_xprescale;
+ const int scheight = m_rawdims.c.y * m_yprescale;
// target surfaces typically cannot be YCbCr, so we always pick RGB in that case
- D3DFORMAT finalfmt = (format != m_texture_manager->get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
+ const D3DFORMAT finalfmt = (format != m_texture_manager.get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
- result = m_renderer->get_device()->CreateTexture(scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex, nullptr);
+ result = m_renderer.get_device()->CreateTexture(scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex, nullptr);
if (result == D3D_OK)
- {
break;
- }
- m_d3dtex->Release();
- m_d3dtex = nullptr;
+ m_d3dtex.Reset();
}
}
}
@@ -2092,12 +2059,10 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
return;
error:
- d3dintf->post_fx_available = false;
+ m_renderer.set_post_fx_unavailable();
osd_printf_error("Direct3D: Critical warning: A texture failed to allocate. Expect things to get bad quickly.\n");
- if (m_d3dsurface != nullptr)
- m_d3dsurface->Release();
- if (m_d3dtex != nullptr)
- m_d3dtex->Release();
+ m_d3dsurface.Reset();
+ m_d3dtex.Reset();
}
@@ -2111,11 +2076,11 @@ void texture_info::compute_size_subroutine(int texwidth, int texheight, int* p_w
int finalwidth = texwidth;
// adjust the aspect ratio if we need to
- while (finalwidth < finalheight && finalheight / finalwidth > m_texture_manager->get_max_texture_aspect())
+ while (finalwidth < finalheight && finalheight / finalwidth > m_texture_manager.get_max_texture_aspect())
{
finalwidth *= 2;
}
- while (finalheight < finalwidth && finalwidth / finalheight > m_texture_manager->get_max_texture_aspect())
+ while (finalheight < finalwidth && finalwidth / finalheight > m_texture_manager.get_max_texture_aspect())
{
finalheight *= 2;
}
@@ -2137,7 +2102,7 @@ void texture_info::compute_size(int texwidth, int texheight)
m_xborderpix = 0;
m_yborderpix = 0;
- bool shaders_enabled = m_renderer->get_shaders()->enabled();
+ bool shaders_enabled = m_renderer.get_shaders()->enabled();
bool wrap_texture = (m_flags & PRIMFLAG_TEXWRAP_MASK) == PRIMFLAG_TEXWRAP_MASK;
// skip border when shaders are enabled
@@ -2161,7 +2126,7 @@ void texture_info::compute_size(int texwidth, int texheight)
compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
// if we added pixels for the border, and that just barely pushed us over, take it back
- if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
+ if (finalwidth > m_texture_manager.get_max_texture_width() || finalheight > m_texture_manager.get_max_texture_height())
{
finalheight = texheight;
finalwidth = texwidth;
@@ -2174,10 +2139,18 @@ void texture_info::compute_size(int texwidth, int texheight)
}
// if we're above the max width/height, do what?
- if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
+ if (finalwidth > m_texture_manager.get_max_texture_width() || finalheight > m_texture_manager.get_max_texture_height())
{
static bool printed = false;
- if (!printed) osd_printf_warning("Texture too big! (wanted: %dx%d, max is %dx%d)\n", finalwidth, finalheight, (int)m_texture_manager->get_max_texture_width(), (int)m_texture_manager->get_max_texture_height());
+ if (!printed)
+ {
+ osd_printf_warning(
+ "Texture too big! (wanted: %dx%d, max is %dx%d)\n",
+ finalwidth,
+ finalheight,
+ m_texture_manager.get_max_texture_width(),
+ m_texture_manager.get_max_texture_height());
+ }
printed = true;
}
@@ -2430,9 +2403,9 @@ void texture_info::set_data(const render_texinfo *texsource, uint32_t flags)
break;
case TEXFORMAT_YUY16:
- if (m_texture_manager->get_yuv_format() == D3DFMT_YUY2)
+ if (m_texture_manager.get_yuv_format() == D3DFMT_YUY2)
copyline_yuy16_to_yuy2((uint16_t *)dst, (uint16_t *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette);
- else if (m_texture_manager->get_yuv_format() == D3DFMT_UYVY)
+ else if (m_texture_manager.get_yuv_format() == D3DFMT_UYVY)
copyline_yuy16_to_uyvy((uint16_t *)dst, (uint16_t *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette);
else
copyline_yuy16_to_argb((uint32_t *)dst, (uint16_t *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette);
@@ -2467,7 +2440,6 @@ void texture_info::set_data(const render_texinfo *texsource, uint32_t flags)
void texture_info::prescale()
{
- IDirect3DSurface9 *scale_surface;
HRESULT result;
int i;
@@ -2476,39 +2448,39 @@ void texture_info::prescale()
return;
// for all cases, we need to get the surface of the render target
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> scale_surface;
result = m_d3dfinaltex->GetSurfaceLevel(0, &scale_surface);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during texture GetSurfaceLevel call\n", result);
// if we have an offscreen plain surface, we can just StretchRect to it
- IDirect3DSurface9 *backbuffer;
-
- assert(m_d3dtex != nullptr);
+ assert(m_d3dtex);
// first remember the original render target and set the new one
- result = m_renderer->get_device()->GetRenderTarget(0, &backbuffer);
+ Microsoft::WRL::ComPtr<IDirect3DSurface9> backbuffer;
+ result = m_renderer.get_device()->GetRenderTarget(0, &backbuffer);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device GetRenderTarget call\n", result);
- result = m_renderer->get_device()->SetRenderTarget(0, scale_surface);
+ result = m_renderer.get_device()->SetRenderTarget(0, scale_surface.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 1\n", result);
- m_renderer->reset_render_states();
+ m_renderer.reset_render_states();
// start the scene
- result = m_renderer->get_device()->BeginScene();
+ result = m_renderer.get_device()->BeginScene();
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device BeginScene call\n", result);
// configure the rendering pipeline
- m_renderer->set_filter(FALSE);
- m_renderer->set_blendmode(BLENDMODE_NONE);
- result = m_renderer->get_device()->SetTexture(0, m_d3dtex);
+ m_renderer.set_filter(FALSE);
+ m_renderer.set_blendmode(BLENDMODE_NONE);
+ result = m_renderer.get_device()->SetTexture(0, m_d3dtex.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetTexture call\n", result);
// lock the vertex buffer
vertex *lockedbuf;
- result = m_renderer->get_vertex_buffer()->Lock(0, 0, (VOID **)&lockedbuf, D3DLOCK_DISCARD);
+ result = m_renderer.get_vertex_buffer()->Lock(0, 0, (VOID **)&lockedbuf, D3DLOCK_DISCARD);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during vertex buffer lock call\n", result);
@@ -2541,32 +2513,32 @@ void texture_info::prescale()
}
// unlock the vertex buffer
- result = m_renderer->get_vertex_buffer()->Unlock();
+ result = m_renderer.get_vertex_buffer()->Unlock();
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during vertex buffer unlock call\n", result);
// set the stream and draw the triangle strip
- result = m_renderer->get_device()->SetStreamSource(0, m_renderer->get_vertex_buffer(), 0, sizeof(vertex));
+ result = m_renderer.get_device()->SetStreamSource(0, m_renderer.get_vertex_buffer(), 0, sizeof(vertex));
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetStreamSource call\n", result);
- result = m_renderer->get_device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
+ result = m_renderer.get_device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device DrawPrimitive call\n", result);
// end the scene
- result = m_renderer->get_device()->EndScene();
+ result = m_renderer.get_device()->EndScene();
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device end_scene call\n", result);
// reset the render target and release our reference to the backbuffer
- result = m_renderer->get_device()->SetRenderTarget(0, backbuffer);
+ result = m_renderer.get_device()->SetRenderTarget(0, backbuffer.Get());
if (FAILED(result))
osd_printf_verbose("Direct3D: Error %08lX during device SetRenderTarget call 2\n", result);
- backbuffer->Release();
- m_renderer->reset_render_states();
+ backbuffer.Reset();
+ m_renderer.reset_render_states();
// release our reference to the target surface
- scale_surface->Release();
+ scale_surface.Reset();
}
@@ -2576,35 +2548,6 @@ void texture_info::prescale()
d3d_render_target::~d3d_render_target()
{
- for (int index = 0; index < MAX_BLOOM_COUNT; index++)
- {
- if (bloom_texture[index] != nullptr)
- bloom_texture[index]->Release();
-
- if (bloom_surface[index] != nullptr)
- bloom_surface[index]->Release();
- }
-
- for (int index = 0; index < 2; index++)
- {
- if (source_texture[index] != nullptr)
- source_texture[index]->Release();
-
- if (source_surface[index] != nullptr)
- source_surface[index]->Release();
-
- if (target_texture[index] != nullptr)
- target_texture[index]->Release();
-
- if (target_surface[index] != nullptr)
- target_surface[index]->Release();
- }
-
- if (cache_texture != nullptr)
- cache_texture->Release();
-
- if (cache_surface != nullptr)
- cache_surface->Release();
}
@@ -2645,9 +2588,7 @@ bool d3d_render_target::init(renderer_d3d9 *d3d, int source_width, int source_he
cache_texture->GetSurfaceLevel(0, &cache_surface);
- auto win = d3d->assert_window();
-
- const screen_device *first_screen = screen_device_enumerator(win->machine().root_device()).first();
+ const screen_device *first_screen = screen_device_enumerator(d3d->window().machine().root_device()).first();
bool vector_screen =
first_screen != nullptr &&
first_screen->screen_type() == SCREEN_TYPE_VECTOR;
diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h
index 2fa4a30873c..3ab7651d87c 100644
--- a/src/osd/modules/render/drawd3d.h
+++ b/src/osd/modules/render/drawd3d.h
@@ -10,20 +10,24 @@
#pragma once
+#include "d3d/d3dcomm.h"
-#ifdef OSD_WINDOWS
+#include "modules/lib/osdlib.h"
+#include "modules/osdwindow.h"
+
+#include "sliderdirtynotifier.h"
#include <windows.h>
#include <tchar.h>
#include <mmsystem.h>
#include <d3d9.h>
#include <d3dx9.h>
-#include <cmath>
#undef interface
-#include "d3d/d3dcomm.h"
-#include "sliderdirtynotifier.h"
-#include "modules/lib/osdlib.h"
+#include <memory>
+#include <vector>
+#include <cmath>
+
//============================================================
// CONSTANTS
@@ -36,15 +40,6 @@
// TYPE DEFINITIONS
//============================================================
-struct d3d_base
-{
- // internal objects
- IDirect3D9 *d3dobj;
- bool post_fx_available;
-
- osd::dynamic_module::ptr d3d9_dll;
-};
-
class shaders;
struct hlsl_options;
@@ -52,11 +47,10 @@ struct hlsl_options;
class renderer_d3d9 : public osd_renderer, public slider_dirty_notifier
{
public:
- renderer_d3d9(std::shared_ptr<osd_window> window);
- virtual ~renderer_d3d9();
+ using IDirect3D9Ptr = Microsoft::WRL::ComPtr<IDirect3D9>;
- static bool init(running_machine &machine);
- static void exit();
+ renderer_d3d9(osd_window &window, const IDirect3D9Ptr &d3dobj);
+ virtual ~renderer_d3d9();
virtual int create() override;
virtual render_primitive_list *get_primitives() override;
@@ -113,11 +107,13 @@ public:
vec2f get_dims() const { return vec2f(m_width, m_height); }
int get_height() const { return m_height; }
int get_refresh() const { return m_refresh; }
+ bool post_fx_available() const { return m_post_fx_available; }
+ void set_post_fx_unavailable() { m_post_fx_available = false; }
- IDirect3DDevice9 * get_device() const { return m_device; }
+ IDirect3DDevice9 * get_device() const { return m_device.Get(); }
D3DPRESENT_PARAMETERS * get_presentation() { return &m_presentation; }
- IDirect3DVertexBuffer9 *get_vertex_buffer() const { return m_vertexbuf; }
+ IDirect3DVertexBuffer9 *get_vertex_buffer() const { return m_vertexbuf.Get(); }
void set_toggle(bool toggle) { m_toggle = toggle; }
@@ -125,27 +121,32 @@ public:
D3DFORMAT get_pixel_format() const { return m_pixformat; }
D3DDISPLAYMODE get_origmode() const { return m_origmode; }
- uint32_t get_last_texture_flags() const { return m_last_texture_flags; }
+ uint32_t get_last_texture_flags() const { return m_last_texture_flags; }
d3d_texture_manager * get_texture_manager() const { return m_texture_manager.get(); }
texture_info * get_default_texture();
- shaders * get_shaders() const { return m_shaders; }
+ shaders * get_shaders() const { return m_shaders.get(); }
private:
+ using IDirect3DDevice9Ptr = Microsoft::WRL::ComPtr<IDirect3DDevice9>;
+ using IDirect3DVertexBuffer9Ptr = Microsoft::WRL::ComPtr<IDirect3DVertexBuffer9>;
+
+ const IDirect3D9Ptr m_d3dobj; // Direct3D 9 API object
int m_adapter; // ordinal adapter number
int m_width; // current width
int m_height; // current height
int m_refresh; // current refresh rate
int m_create_error_count; // number of consecutive create errors
+ bool m_post_fx_available;
- IDirect3DDevice9 * m_device; // pointer to the Direct3DDevice object
+ IDirect3DDevice9Ptr m_device; // pointer to the Direct3DDevice object
int m_gamma_supported; // is full screen gamma supported?
D3DPRESENT_PARAMETERS m_presentation; // set of presentation parameters
D3DDISPLAYMODE m_origmode; // original display mode for the adapter
D3DFORMAT m_pixformat; // pixel format we are using
- IDirect3DVertexBuffer9 *m_vertexbuf; // pointer to the vertex buffer object
+ IDirect3DVertexBuffer9Ptr m_vertexbuf; // pointer to the vertex buffer object
vertex * m_lockedbuf; // pointer to the locked vertex buffer
int m_numverts; // number of accumulated vertices
@@ -160,20 +161,18 @@ private:
D3DFORMAT m_screen_format; // format to use for screen textures
texture_info * m_last_texture; // previous texture
- uint32_t m_last_texture_flags; // previous texture flags
+ uint32_t m_last_texture_flags; // previous texture flags
int m_last_blendenable; // previous blendmode
int m_last_blendop; // previous blendmode
int m_last_blendsrc; // previous blendmode
int m_last_blenddst; // previous blendmode
int m_last_filter; // previous texture filter
- uint32_t m_last_wrap; // previous wrap state
+ uint32_t m_last_wrap; // previous wrap state
int m_last_modmode; // previous texture modulation
- shaders * m_shaders; // HLSL interface
+ std::unique_ptr<shaders> m_shaders; // HLSL interface
std::unique_ptr<d3d_texture_manager> m_texture_manager; // texture manager
};
-#endif // OSD_WINDOWS
-
#endif // MAME_OSD_MODULES_RENDER_DRAWD3D_H
diff --git a/src/osd/modules/render/drawgdi.cpp b/src/osd/modules/render/drawgdi.cpp
index 32dac94c24a..69ac20434b3 100644
--- a/src/osd/modules/render/drawgdi.cpp
+++ b/src/osd/modules/render/drawgdi.cpp
@@ -2,21 +2,53 @@
// copyright-holders:Aaron Giles
//============================================================
//
-// drawgdi.c - Win32 GDI drawing
+// drawgdi.cpp - Win32 GDI drawing
//
//============================================================
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
+
+#if defined(OSD_WINDOWS)
+
+#include "window.h"
+
+// emu
#include "emu.h"
-#include "drawgdi.h"
#include "rendersw.hxx"
-//============================================================
-// destructor
-//============================================================
+// standard windows headers
+#include <windows.h>
+
+
+namespace osd {
+
+namespace {
-renderer_gdi::~renderer_gdi()
+// renderer_gdi is the information for the current screen
+class renderer_gdi : public osd_renderer
{
-}
+public:
+ renderer_gdi(osd_window &window)
+ : osd_renderer(window)
+ , m_bmdata(nullptr)
+ , m_bmsize(0)
+ {
+ }
+
+ virtual int create() override;
+ virtual render_primitive_list *get_primitives() override;
+ virtual int draw(const int update) override;
+ virtual void save() override {}
+ virtual void record() override {}
+ virtual void toggle_fsfx() override {}
+
+private:
+ BITMAPINFO m_bminfo;
+ std::unique_ptr<uint8_t []> m_bmdata;
+ size_t m_bmsize;
+};
//============================================================
// renderer_gdi::create
@@ -34,6 +66,7 @@ int renderer_gdi::create()
m_bminfo.bmiHeader.biYPelsPerMeter = 0;
m_bminfo.bmiHeader.biClrUsed = 0;
m_bminfo.bmiHeader.biClrImportant = 0;
+
return 0;
}
@@ -43,16 +76,12 @@ int renderer_gdi::create()
render_primitive_list *renderer_gdi::get_primitives()
{
- auto win = try_getwindow();
- if (win == nullptr)
+ osd_dim const dimensions = window().get_size();
+ if ((dimensions.width() <= 0) || (dimensions.height() <= 0))
return nullptr;
- RECT client;
- GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client);
- if ((rect_width(&client) == 0) || (rect_height(&client) == 0))
- return nullptr;
- win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect());
- return &win->target()->get_primitives();
+ window().target()->set_bounds(dimensions.width(), dimensions.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
}
//============================================================
@@ -61,23 +90,22 @@ render_primitive_list *renderer_gdi::get_primitives()
int renderer_gdi::draw(const int update)
{
- auto win = assert_window();
-
// we don't have any special resize behaviors
- if (win->m_resize_state == RESIZE_STATE_PENDING)
- win->m_resize_state = RESIZE_STATE_NORMAL;
+ if (window().m_resize_state == RESIZE_STATE_PENDING)
+ window().m_resize_state = RESIZE_STATE_NORMAL;
// get the target bounds
RECT bounds;
- GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &bounds);
+ GetClientRect(dynamic_cast<win_window_info &>(window()).platform_window(), &bounds);
// compute width/height/pitch of target
- int width = rect_width(&bounds);
- int height = rect_height(&bounds);
- int pitch = (width + 3) & ~3;
+ osd_dim const dimensions = window().get_size();
+ int const width = dimensions.width();
+ int const height = dimensions.height();
+ int const pitch = (width + 3) & ~3;
// make sure our temporary bitmap is big enough
- if (pitch * height * 4 > m_bmsize)
+ if ((pitch * height * 4) > m_bmsize)
{
m_bmsize = pitch * height * 4 * 2;
m_bmdata.reset();
@@ -85,9 +113,9 @@ int renderer_gdi::draw(const int update)
}
// draw the primitives to the bitmap
- win->m_primlist->acquire_lock();
- software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, m_bmdata.get(), width, height, pitch);
- win->m_primlist->release_lock();
+ window().m_primlist->acquire_lock();
+ software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, m_bmdata.get(), width, height, pitch);
+ window().m_primlist->release_lock();
// fill in bitmap-specific info
m_bminfo.bmiHeader.biWidth = pitch;
@@ -95,8 +123,43 @@ int renderer_gdi::draw(const int update)
// blit to the screen
StretchDIBits(
- win->m_dc, 0, 0, width, height,
+ window().m_dc, 0, 0, width, height,
0, 0, width, height,
m_bmdata.get(), &m_bminfo, DIB_RGB_COLORS, SRCCOPY);
+
return 0;
}
+
+
+class video_gdi : public osd_module, public render_module
+{
+public:
+ video_gdi() : osd_module(OSD_RENDERER_PROVIDER, "gdi") { }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override { return 0; }
+ virtual void exit() override { }
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE; }
+};
+
+std::unique_ptr<osd_renderer> video_gdi::create(osd_window &window)
+{
+ return std::make_unique<renderer_gdi>(window);
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // defined(OSD_WINDOWS)
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_gdi, OSD_RENDERER_PROVIDER, "gdi") } }
+
+#endif // defined(OSD_WINDOWS)
+
+
+MODULE_DEFINITION(RENDERER_GDI, osd::video_gdi)
diff --git a/src/osd/modules/render/drawgdi.h b/src/osd/modules/render/drawgdi.h
deleted file mode 100644
index 0dfc4bf2641..00000000000
--- a/src/osd/modules/render/drawgdi.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// drawgdi.h - Win32 GDI drawing
-//
-//============================================================
-#ifndef MAME_OSD_MODULES_RENDER_DRAWGDI_H
-#define MAME_OSD_MODULES_RENDER_DRAWGDI_H
-
-#pragma once
-
-
-// standard windows headers
-#include <windows.h>
-
-// MAME headers
-
-// MAMEOS headers
-#include "window.h"
-
-
-//============================================================
-// TYPE DEFINITIONS
-//============================================================
-
-/* renderer_gdi is the information for the current screen */
-class renderer_gdi : public osd_renderer
-{
-public:
- renderer_gdi(std::shared_ptr<osd_window> window)
- : osd_renderer(window, FLAG_NONE)
- , m_bmdata(nullptr)
- , m_bmsize(0)
- {
- }
- virtual ~renderer_gdi();
-
- static bool init(running_machine &machine) { return false; }
- static void exit() { }
-
- virtual int create() override;
- virtual render_primitive_list *get_primitives() override;
- virtual int draw(const int update) override;
- virtual void save() override {}
- virtual void record() override {}
- virtual void toggle_fsfx() override {}
-
-private:
- BITMAPINFO m_bminfo;
- std::unique_ptr<uint8_t []> m_bmdata;
- size_t m_bmsize;
-};
-
-#endif // MAME_OSD_MODULES_RENDER_DRAWGDI_H
diff --git a/src/osd/modules/render/drawnone.cpp b/src/osd/modules/render/drawnone.cpp
index 6f591879038..0f9fa36bd7a 100644
--- a/src/osd/modules/render/drawnone.cpp
+++ b/src/osd/modules/render/drawnone.cpp
@@ -6,25 +6,77 @@
//
//============================================================
-// standard windows headers
-#include <windows.h>
+#include "render_module.h"
-#include "drawnone.h"
+#include "modules/lib/osdobj_common.h"
+#include "modules/osdmodule.h"
+#include "modules/osdwindow.h"
-//============================================================
-// drawnone_window_get_primitives
-//============================================================
+#include "emu.h" // FIXME: only here for main.h, won't be necessary soon
+#include "main.h"
+#include "render.h"
+
+#include <memory>
+
+
+namespace osd {
+
+namespace {
+
+class renderer_none : public osd_renderer
+{
+public:
+ renderer_none(osd_window &window) : osd_renderer(window) { }
+
+ virtual int create() override { return 0; }
+ virtual render_primitive_list *get_primitives() override;
+ virtual int draw(const int update) override { return 0; }
+ virtual void save() override { }
+ virtual void record() override { }
+ virtual void toggle_fsfx() override { }
+};
render_primitive_list *renderer_none::get_primitives()
{
- auto win = try_getwindow();
- if (win == nullptr)
+ osd_dim const dimensions = window().get_size();
+ if ((dimensions.width() <= 0) || (dimensions.height() <= 0))
return nullptr;
- RECT client;
- GetClientRect(std::static_pointer_cast<win_window_info>(win)->platform_window(), &client);
- if ((rect_width(&client) == 0) || (rect_height(&client) == 0))
- return nullptr;
- win->target()->set_bounds(rect_width(&client), rect_height(&client), win->pixel_aspect());
- return &win->target()->get_primitives();
+ window().target()->set_bounds(dimensions.width(), dimensions.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
}
+
+
+class video_none : public osd_module, public render_module
+{
+public:
+ video_none() : osd_module(OSD_RENDERER_PROVIDER, "none") { }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override { }
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return 0; }
+};
+
+int video_none::init(osd_interface &osd, osd_options const &options)
+{
+ if (!emulator_info::standalone() && (options.seconds_to_run() == 0))
+ osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
+
+ return 0;
+}
+
+std::unique_ptr<osd_renderer> video_none::create(osd_window &window)
+{
+ return std::make_unique<renderer_none>(window);
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+MODULE_DEFINITION(RENDERER_NONE, osd::video_none)
diff --git a/src/osd/modules/render/drawnone.h b/src/osd/modules/render/drawnone.h
deleted file mode 100644
index c884f969204..00000000000
--- a/src/osd/modules/render/drawnone.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// drawnone.h - stub "nothing" drawer
-//
-//============================================================
-
-#ifndef __DRAWNONE__
-#define __DRAWNONE__
-
-#include "window.h"
-
-class renderer_none : public osd_renderer
-{
-public:
- renderer_none(std::shared_ptr<osd_window> window)
- : osd_renderer(window, FLAG_NONE) { }
-
- virtual ~renderer_none() { }
-
- static bool init(running_machine &machine) { return false; }
- static void exit() { }
-
- virtual int create() override { return 0; }
- virtual render_primitive_list *get_primitives() override;
- virtual int draw(const int update) override { return 0; }
- virtual void save() override { }
- virtual void record() override { }
- virtual void toggle_fsfx() override { }
-};
-
-#endif // __DRAWNONE__
diff --git a/src/osd/modules/render/drawogl.cpp b/src/osd/modules/render/drawogl.cpp
index 9e200f3817c..7489af2f612 100644
--- a/src/osd/modules/render/drawogl.cpp
+++ b/src/osd/modules/render/drawogl.cpp
@@ -12,37 +12,61 @@
//
//============================================================
-// standard C headers
-#include <cmath>
-#include <cstdio>
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
-// MAME headers
+#if USE_OPENGL
+
+// will be picked up from specific OSD implementation
+#include "window.h"
+
+// OSD common headers
+#include "modules/lib/osdlib.h"
+#include "modules/lib/osdobj_common.h"
+#include "modules/opengl/gl_shader_mgr.h"
+#include "modules/opengl/gl_shader_tool.h"
#include "osdcomm.h"
-#include "emu.h"
-#include "emuopts.h"
-#ifdef OSD_MAC
+// OSD headers
+#if defined(OSD_WINDOWS)
+typedef uint64_t HashT;
+#include "winglcontext.h"
+#elif defined(OSD_MAC)
#define GL_SILENCE_DEPRECATION (1)
+#include "osdmac.h"
+#else
+#include "osdsdl.h"
+#include "sdlglcontext.h"
#endif
+// emu
+#include "emucore.h"
+#include "emuopts.h"
+#include "render.h"
+
+
#if !defined(OSD_WINDOWS) && !defined(OSD_MAC)
+
// standard SDL headers
#define TOBEMIGRATED 1
#include <SDL2/SDL.h>
-#endif
-#include "modules/lib/osdlib.h"
-#include "modules/lib/osdobj_common.h"
+#endif // !defined(OSD_WINDOWS && !defined(OSD_MAC)
-// OpenGL headers
-#include "modules/opengl/osd_opengl.h"
-#include "modules/opengl/gl_shader_tool.h"
-#include "modules/opengl/gl_shader_mgr.h"
+// standard C headers
+#include <cmath>
+#include <cstdio>
+#include <memory>
+#include <utility>
+
#if defined(SDLMAME_MACOSX) || defined(OSD_MAC)
+
#include <cstring>
#include <cstdio>
+
#include <sys/types.h>
#include <sys/sysctl.h>
@@ -72,7 +96,13 @@ typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum m_target, GLuint r
typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum m_target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum m_target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
-#endif
+
+#endif // defined(SDLMAME_MACOSX) || defined(OSD_MAC)
+
+
+namespace osd {
+
+namespace {
// make sure the extensions compile OK everywhere
#ifndef GL_TEXTURE_STORAGE_HINT_APPLE
@@ -128,7 +158,261 @@ typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuin
#define GL_DEPTH_COMPONENT32 0x81A7
#endif
-#include "drawogl.h"
+
+//============================================================
+// Configuration
+//============================================================
+
+#define GLSL_SHADER_MAX 10
+
+struct ogl_video_config
+{
+ ogl_video_config() = default;
+
+ bool vbo = false;
+ bool pbo = false;
+ bool allowtexturerect = false; // allow GL_ARB_texture_rectangle, default: no
+ bool forcepow2texture = false; // force power of two textures, default: no
+ bool glsl = false;
+ int glsl_filter = 0; // glsl filtering, >0 disables filter
+ std::string glsl_shader_mamebm[GLSL_SHADER_MAX]; // custom glsl shader set, mame bitmap
+ int glsl_shader_mamebm_num = 0; // custom glsl shader set number, mame bitmap
+ std::string glsl_shader_scrn[GLSL_SHADER_MAX]; // custom glsl shader set, screen bitmap
+ int glsl_shader_scrn_num = 0; // custom glsl shader number, screen bitmap
+};
+
+
+//============================================================
+// Textures
+//============================================================
+
+/* ogl_texture_info holds information about a texture */
+class ogl_texture_info
+{
+public:
+ ogl_texture_info()
+ : hash(0), flags(0), rawwidth(0), rawheight(0),
+ rawwidth_create(0), rawheight_create(0),
+ type(0), format(0), borderpix(0), xprescale(0), yprescale(0), nocopy(0),
+ texture(0), texTarget(0), texpow2(0), mpass_dest_idx(0), pbo(0), data(nullptr),
+ data_own(0), texCoordBufferName(0)
+ {
+ for (int i=0; i<2; i++)
+ {
+ mpass_textureunit[i] = 0;
+ mpass_texture_mamebm[i] = 0;
+ mpass_fbo_mamebm[i] = 0;
+ mpass_texture_scrn[i] = 0;
+ mpass_fbo_scrn[i] = 0;
+ }
+ for (int i=0; i<8; i++)
+ texCoord[i] = 0.0f;
+ }
+
+ HashT hash; // hash value for the texture (must be >= pointer size)
+ uint32_t flags; // rendering flags
+ render_texinfo texinfo; // copy of the texture info
+ int rawwidth, rawheight; // raw width/height of the texture
+ int rawwidth_create; // raw width/height, pow2 compatible, if needed
+ int rawheight_create; // (create and initial set the texture, not for copy!)
+ int type; // what type of texture are we?
+ int format; // texture format
+ int borderpix; // do we have a 1 pixel border?
+ int xprescale; // what is our X prescale factor?
+ int yprescale; // what is our Y prescale factor?
+ int nocopy; // must the texture date be copied?
+
+ uint32_t texture; // OpenGL texture "name"/ID
+
+ GLenum texTarget; // OpenGL texture target
+ int texpow2; // Is this texture pow2
+
+ uint32_t mpass_dest_idx; // Multipass dest idx [0..1]
+ uint32_t mpass_textureunit[2]; // texture unit names for GLSL
+
+ uint32_t mpass_texture_mamebm[2];// Multipass OpenGL texture "name"/ID for the shader
+ uint32_t mpass_fbo_mamebm[2]; // framebuffer object for this texture, multipass
+ uint32_t mpass_texture_scrn[2]; // Multipass OpenGL texture "name"/ID for the shader
+ uint32_t mpass_fbo_scrn[2]; // framebuffer object for this texture, multipass
+
+ uint32_t pbo; // pixel buffer object for this texture (DYNAMIC only!)
+ uint32_t *data; // pixels for the texture
+ int data_own; // do we own / allocated it ?
+ GLfloat texCoord[8];
+ GLuint texCoordBufferName;
+
+};
+
+// renderer_ogl is the information about OpenGL for the current screen
+class renderer_ogl : public osd_renderer
+{
+public:
+ renderer_ogl(osd_window &window, ogl_video_config const &ogl_config)
+ : osd_renderer(window)
+ , m_ogl_config(ogl_config)
+ , m_blittimer(0)
+ , m_width(0)
+ , m_height(0)
+ , m_blit_dim(0, 0)
+ , m_initialized(0)
+ , m_last_blendmode(0)
+ , m_texture_max_width(0)
+ , m_texture_max_height(0)
+ , m_texpoweroftwo(0)
+ , m_usevbo(0)
+ , m_usepbo(0)
+ , m_usefbo(0)
+ , m_useglsl(0)
+ , m_glsl(nullptr)
+ , m_glsl_program_num(0)
+ , m_glsl_program_mb2sc(0)
+ , m_usetexturerect(0)
+ , m_init_context(0)
+ , m_last_hofs(0.0f)
+ , m_last_vofs(0.0f)
+ , m_surf_w(0)
+ , m_surf_h(0)
+ {
+ for (int i=0; i < HASH_SIZE + OVERFLOW_SIZE; i++)
+ m_texhash[i] = nullptr;
+ for (int i=0; i < 2*GLSL_SHADER_MAX; i++)
+ m_glsl_program[i] = 0;
+ for (int i=0; i < 8; i++)
+ m_texVerticex[i] = 0.0f;
+ }
+ virtual ~renderer_ogl()
+ {
+ // free the memory in the window
+ destroy_all_textures();
+ }
+
+ virtual int create() override;
+ virtual int draw(const int update) override;
+
+#ifndef OSD_WINDOWS
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
+#endif
+ virtual render_primitive_list *get_primitives() override
+ {
+ osd_dim nd = window().get_size();
+ if (nd != m_blit_dim)
+ {
+ m_blit_dim = nd;
+ notify_changed();
+ }
+ if ((m_blit_dim.width() == 0) || (m_blit_dim.height() == 0))
+ return nullptr;
+ window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
+ }
+
+#ifdef OSD_WINDOWS
+ virtual void save() override { }
+ virtual void record() override { }
+ virtual void toggle_fsfx() override { }
+#endif
+
+private:
+ static const uint32_t HASH_SIZE = ((1 << 10) + 1);
+ static const uint32_t OVERFLOW_SIZE = (1 << 10);
+
+ void destroy_all_textures();
+
+ void loadGLExtensions();
+ void initialize_gl();
+ void set_blendmode(int blendmode);
+ HashT texture_compute_hash(const render_texinfo *texture, uint32_t flags);
+ void texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ void texture_compute_size_subroutine(ogl_texture_info *texture, uint32_t flags,
+ uint32_t width, uint32_t height,
+ int* p_width, int* p_height, int* p_width_create, int* p_height_create);
+ void texture_compute_size_type(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ ogl_texture_info *texture_create(const render_texinfo *texsource, uint32_t flags);
+ int texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
+ ogl_texture_info *texture_find(const render_primitive *prim);
+ void texture_coord_update(ogl_texture_info *texture, const render_primitive *prim, int shaderIdx);
+ void texture_mpass_flip(ogl_texture_info *texture, int shaderIdx);
+ void texture_shader_update(ogl_texture_info *texture, render_container *container, int shaderIdx);
+ ogl_texture_info * texture_update(const render_primitive *prim, int shaderIdx);
+ void texture_disable(ogl_texture_info * texture);
+ void texture_all_disable();
+
+ int gl_checkFramebufferStatus() const;
+ int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height) const;
+ void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags) const;
+
+ ogl_video_config const &m_ogl_config;
+
+ int32_t m_blittimer;
+ int m_width;
+ int m_height;
+ osd_dim m_blit_dim;
+
+ std::unique_ptr<osd_gl_context> m_gl_context;
+
+ int m_initialized; // is everything well initialized, i.e. all GL stuff etc.
+ // 3D info (GL mode only)
+ ogl_texture_info * m_texhash[HASH_SIZE + OVERFLOW_SIZE];
+ int m_last_blendmode; // previous blendmode
+ int32_t m_texture_max_width; // texture maximum width
+ int32_t m_texture_max_height; // texture maximum height
+ int m_texpoweroftwo; // must textures be power-of-2 sized?
+ int m_usevbo; // runtime check if VBO is available
+ int m_usepbo; // runtime check if PBO is available
+ int m_usefbo; // runtime check if FBO is available
+ int m_useglsl; // runtime check if GLSL is available
+
+ glsl_shader_info *m_glsl; // glsl_shader_info
+
+ GLhandleARB m_glsl_program[2*GLSL_SHADER_MAX]; // GLSL programs, or 0
+ int m_glsl_program_num; // number of GLSL programs
+ int m_glsl_program_mb2sc; // GLSL program idx, which transforms
+ // the mame-bitmap. screen-bitmap (size/rotation/..)
+ // All progs <= glsl_program_mb2sc using the mame bitmap
+ // as input, otherwise the screen bitmap.
+ // All progs >= glsl_program_mb2sc using the screen bitmap
+ // as output, otherwise the mame bitmap.
+ int m_usetexturerect; // use ARB_texture_rectangle for non-power-of-2, general use
+
+ int m_init_context; // initialize context before next draw
+
+ float m_last_hofs;
+ float m_last_vofs;
+
+ // Static vars from draogl_window_dra
+ int32_t m_surf_w;
+ int32_t m_surf_h;
+ GLfloat m_texVerticex[8];
+
+ // OGL 1.3
+#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
+ PFNGLACTIVETEXTUREARBPROC m_glActiveTexture = nullptr;
+#else
+ PFNGLACTIVETEXTUREPROC m_glActiveTexture = nullptr;
+#endif
+
+ // VBO
+ PFNGLGENBUFFERSPROC m_glGenBuffers = nullptr;
+ PFNGLDELETEBUFFERSPROC m_glDeleteBuffers = nullptr;
+ PFNGLBINDBUFFERPROC m_glBindBuffer = nullptr;
+ PFNGLBUFFERDATAPROC m_glBufferData = nullptr;
+ PFNGLBUFFERSUBDATAPROC m_glBufferSubData = nullptr;
+
+ // PBO
+ PFNGLMAPBUFFERPROC m_glMapBuffer = nullptr;
+ PFNGLUNMAPBUFFERPROC m_glUnmapBuffer = nullptr;
+
+ // FBO
+ PFNGLISFRAMEBUFFEREXTPROC m_glIsFramebuffer = nullptr;
+ PFNGLBINDFRAMEBUFFEREXTPROC m_glBindFramebuffer = nullptr;
+ PFNGLDELETEFRAMEBUFFERSEXTPROC m_glDeleteFramebuffers = nullptr;
+ PFNGLGENFRAMEBUFFERSEXTPROC m_glGenFramebuffers = nullptr;
+ PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC m_glCheckFramebufferStatus = nullptr;
+ PFNGLFRAMEBUFFERTEXTURE2DEXTPROC m_glFramebufferTexture2D = nullptr;
+
+ static bool s_shown_video_info;
+};
+
//============================================================
// DEBUGGING
@@ -241,101 +525,19 @@ void renderer_ogl::set_blendmode(int blendmode)
}
}
-//============================================================
-// STATIC VARIABLES
-//============================================================
-
-// OGL 1.3
-#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
-static PFNGLACTIVETEXTUREARBPROC pfn_glActiveTexture = nullptr;
-#else
-static PFNGLACTIVETEXTUREPROC pfn_glActiveTexture = nullptr;
-#endif
-
-// VBO
-static PFNGLGENBUFFERSPROC pfn_glGenBuffers = nullptr;
-static PFNGLDELETEBUFFERSPROC pfn_glDeleteBuffers = nullptr;
-static PFNGLBINDBUFFERPROC pfn_glBindBuffer = nullptr;
-static PFNGLBUFFERDATAPROC pfn_glBufferData = nullptr;
-static PFNGLBUFFERSUBDATAPROC pfn_glBufferSubData = nullptr;
-
-// PBO
-static PFNGLMAPBUFFERPROC pfn_glMapBuffer = nullptr;
-static PFNGLUNMAPBUFFERPROC pfn_glUnmapBuffer = nullptr;
-
-// FBO
-static PFNGLISFRAMEBUFFEREXTPROC pfn_glIsFramebuffer = nullptr;
-static PFNGLBINDFRAMEBUFFEREXTPROC pfn_glBindFramebuffer = nullptr;
-static PFNGLDELETEFRAMEBUFFERSEXTPROC pfn_glDeleteFramebuffers = nullptr;
-static PFNGLGENFRAMEBUFFERSEXTPROC pfn_glGenFramebuffers = nullptr;
-static PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC pfn_glCheckFramebufferStatus = nullptr;
-static PFNGLFRAMEBUFFERTEXTURE2DEXTPROC pfn_glFramebufferTexture2D = nullptr;
-
static int glsl_shader_feature = GLSL_SHADER_FEAT_PLAIN;
//============================================================
-// Textures
-//============================================================
-
-static void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags);
-
-//============================================================
// Static Variables
//============================================================
bool renderer_ogl::s_shown_video_info = false;
-bool renderer_ogl::s_dll_loaded = false;
-
-void renderer_ogl::init(running_machine &machine)
-{
- s_dll_loaded = false;
-
- load_gl_lib(machine);
-#if defined(OSD_WINDOWS)
- osd_printf_verbose("Using Windows OpenGL driver\n");
-#else
- osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
-#endif
-}
-
-//============================================================
-// CONSTRUCTOR & DESTRUCTOR
-//============================================================
-
-renderer_ogl::~renderer_ogl()
-{
- // free the memory in the window
- destroy_all_textures();
-
- delete m_gl_context;
- m_gl_context = nullptr;
-}
-
-void renderer_ogl::exit()
-{
- for (int i = 0; i < video_config.glsl_shader_mamebm_num; i++)
- {
- if (nullptr != video_config.glsl_shader_mamebm[i])
- {
- free(video_config.glsl_shader_mamebm[i]);
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- }
- for (int i =0; i < video_config.glsl_shader_scrn_num; i++)
- {
- if (nullptr != video_config.glsl_shader_scrn[i])
- {
- free(video_config.glsl_shader_scrn[i]);
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
-}
//============================================================
// Load the OGL function addresses
//============================================================
-static void loadgl_functions(osd_gl_context *context)
+static void loadgl_functions(osd_gl_context &context)
{
#ifdef USE_DISPATCH_GL
@@ -346,7 +548,7 @@ static void loadgl_functions(osd_gl_context *context)
*/
#define OSD_GL(ret,func,params) \
- if (!( func = (ret (APIENTRY *)params) context->getProcAddress( #func ) )) \
+ if (!( func = (ret (APIENTRY *)params) context.getProcAddress( #func ) )) \
{ err_count++; osd_printf_error("GL function %s not found!\n", #func ); }
#define OSD_GL_UNUSED(ret,func,params)
@@ -361,45 +563,6 @@ static void loadgl_functions(osd_gl_context *context)
#endif
}
-//============================================================
-// Load GL library
-//============================================================
-
-#ifdef USE_DISPATCH_GL
-osd_gl_dispatch *gl_dispatch = nullptr;
-#endif
-
-void renderer_ogl::load_gl_lib(running_machine &machine)
-{
- if (!s_dll_loaded)
- {
-#ifndef OSD_WINDOWS
-#ifdef USE_DISPATCH_GL
- /*
- * directfb and and x11 use this env var
- * SDL_VIDEO_GL_DRIVER
- */
- const char *stemp;
-
- stemp = downcast<sdl_options &>(machine.options()).gl_lib();
- if (stemp != nullptr && strcmp(stemp, OSDOPTVAL_AUTO) == 0)
- stemp = nullptr;
-
- if (SDL_GL_LoadLibrary(stemp) != 0) // Load library (default for e==nullptr
- {
- fatalerror("Unable to load opengl library: %s\n", stemp ? stemp : "<default>");
- }
- osd_printf_verbose("Loaded opengl shared library: %s\n", stemp ? stemp : "<default>");
- /* FIXME: must be freed as well */
-#endif
-#endif
-#ifdef USE_DISPATCH_GL
- gl_dispatch = new osd_gl_dispatch;
-#endif
- s_dll_loaded = true;
- }
-}
-
void renderer_ogl::initialize_gl()
{
int has_and_allow_texturerect = 0;
@@ -425,7 +588,7 @@ void renderer_ogl::initialize_gl()
m_usefbo = 0;
m_useglsl = 0;
- if (video_config.allowtexturerect && (strstr(extstr, "GL_ARB_texture_rectangle") || strstr(extstr, "GL_EXT_texture_rectangle")))
+ if (m_ogl_config.allowtexturerect && (strstr(extstr, "GL_ARB_texture_rectangle") || strstr(extstr, "GL_EXT_texture_rectangle")))
{
has_and_allow_texturerect = 1;
if (!s_shown_video_info)
@@ -435,7 +598,7 @@ void renderer_ogl::initialize_gl()
}
// does this card support non-power-of-two sized textures? (they're faster, so use them if possible)
- if ( !video_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two"))
+ if ( !m_ogl_config.forcepow2texture && strstr(extstr, "GL_ARB_texture_non_power_of_two"))
{
if (!s_shown_video_info)
{
@@ -465,7 +628,7 @@ void renderer_ogl::initialize_gl()
if (strstr(extstr, "GL_ARB_vertex_buffer_object"))
{
- m_usevbo = video_config.vbo;
+ m_usevbo = m_ogl_config.vbo;
if (!s_shown_video_info)
{
if(m_usevbo)
@@ -479,7 +642,7 @@ void renderer_ogl::initialize_gl()
{
if( m_usevbo )
{
- m_usepbo = video_config.pbo;
+ m_usepbo = m_ogl_config.pbo;
if (!s_shown_video_info)
{
if(m_usepbo)
@@ -522,7 +685,7 @@ void renderer_ogl::initialize_gl()
strstr(extstr, "GL_ARB_fragment_shader")
)
{
- m_useglsl = video_config.glsl;
+ m_useglsl = m_ogl_config.glsl;
if (!s_shown_video_info)
{
if(m_useglsl)
@@ -562,16 +725,14 @@ void renderer_ogl::initialize_gl()
int renderer_ogl::create()
{
- auto win = assert_window();
-
// create renderer
#if defined(OSD_WINDOWS)
- m_gl_context = new win_gl_context(std::static_pointer_cast<win_window_info>(win)->platform_window());
+ m_gl_context.reset(new win_gl_context(dynamic_cast<win_window_info &>(window()).platform_window()));
#elif defined(OSD_MAC)
// TODO
-// m_gl_context = new mac_gl_context(std::static_pointer_cast<mac_window_info>(win)->platform_window());
+// m_gl_context.reset(new mac_gl_context(dynamic_cast<mac_window_info &>(window()).platform_window()));
#else
- m_gl_context = new sdl_gl_context(std::static_pointer_cast<sdl_window_info>(win)->platform_window());
+ m_gl_context.reset(new sdl_gl_context(dynamic_cast<sdl_window_info &>(window()).platform_window()));
#endif
if (m_gl_context->LastErrorMsg() != nullptr)
{
@@ -580,7 +741,6 @@ int renderer_ogl::create()
}
m_gl_context->SetSwapInterval(video_config.waitvsync ? 1 : 0);
-
m_blittimer = 0;
m_surf_w = 0;
m_surf_h = 0;
@@ -595,10 +755,9 @@ int renderer_ogl::create()
/* load any GL function addresses
* this must be done here because we need a context
*/
- loadgl_functions(m_gl_context);
+ loadgl_functions(*m_gl_context);
initialize_gl();
-
m_init_context = 0;
osd_printf_verbose("Leave renderer_ogl::create\n");
@@ -628,27 +787,15 @@ int renderer_ogl::xy_to_render_target(int x, int y, int *xt, int *yt)
void renderer_ogl::destroy_all_textures()
{
- ogl_texture_info *texture = nullptr;
- bool lock=false;
- int i;
- if ( !m_initialized )
- return;
-
- auto win = try_getwindow();
-
- // During destroy this can get called
- // and the window is no longer available
- if (win == nullptr)
+ if (!m_initialized)
return;
m_gl_context->MakeCurrent();
- if(win->m_primlist)
- {
- lock=true;
- win->m_primlist->acquire_lock();
- }
+ bool const lock = bool(window().m_primlist);
+ if (lock)
+ window().m_primlist->acquire_lock();
glFinish();
@@ -656,41 +803,39 @@ void renderer_ogl::destroy_all_textures()
glFinish();
glDisableClientState(GL_VERTEX_ARRAY);
- i=0;
- while (i<HASH_SIZE+OVERFLOW_SIZE)
+ for (int i = 0; i < (HASH_SIZE + OVERFLOW_SIZE); ++i)
{
- texture = m_texhash[i];
- m_texhash[i] = nullptr;
- if (texture != nullptr)
+ ogl_texture_info *const texture = std::exchange(m_texhash[i], nullptr);
+ if (texture)
{
- if(m_usevbo)
+ if (m_usevbo)
{
- pfn_glDeleteBuffers( 1, &(texture->texCoordBufferName) );
+ m_glDeleteBuffers( 1, &(texture->texCoordBufferName) );
texture->texCoordBufferName=0;
}
- if(m_usepbo && texture->pbo)
+ if (m_usepbo && texture->pbo)
{
- pfn_glDeleteBuffers( 1, (GLuint *)&(texture->pbo) );
+ m_glDeleteBuffers( 1, (GLuint *)&(texture->pbo) );
texture->pbo=0;
}
- if( m_glsl_program_num > 1 )
+ if (m_glsl_program_num > 1)
{
assert(m_usefbo);
- pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
+ m_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
glDeleteTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
}
- if ( m_glsl_program_mb2sc < m_glsl_program_num - 1 )
+ if (m_glsl_program_mb2sc < m_glsl_program_num - 1)
{
assert(m_usefbo);
- pfn_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
+ m_glDeleteFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
glDeleteTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
}
glDeleteTextures(1, (GLuint *)&texture->texture);
- if ( texture->data_own )
+ if (texture->data_own)
{
free(texture->data);
texture->data=nullptr;
@@ -698,9 +843,9 @@ void renderer_ogl::destroy_all_textures()
}
delete texture;
}
- i++;
}
- if ( m_useglsl )
+
+ if (m_useglsl)
{
glsl_shader_free(m_glsl);
m_glsl = nullptr;
@@ -709,7 +854,7 @@ void renderer_ogl::destroy_all_textures()
m_initialized = 0;
if (lock)
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
}
//============================================================
// loadGLExtensions
@@ -747,55 +892,55 @@ void renderer_ogl::loadGLExtensions()
// VBO:
if( m_usevbo )
{
- pfn_glGenBuffers = (PFNGLGENBUFFERSPROC) m_gl_context->getProcAddress("glGenBuffers");
- pfn_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) m_gl_context->getProcAddress("glDeleteBuffers");
- pfn_glBindBuffer = (PFNGLBINDBUFFERPROC) m_gl_context->getProcAddress("glBindBuffer");
- pfn_glBufferData = (PFNGLBUFFERDATAPROC) m_gl_context->getProcAddress("glBufferData");
- pfn_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) m_gl_context->getProcAddress("glBufferSubData");
+ m_glGenBuffers = (PFNGLGENBUFFERSPROC) m_gl_context->getProcAddress("glGenBuffers");
+ m_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) m_gl_context->getProcAddress("glDeleteBuffers");
+ m_glBindBuffer = (PFNGLBINDBUFFERPROC) m_gl_context->getProcAddress("glBindBuffer");
+ m_glBufferData = (PFNGLBUFFERDATAPROC) m_gl_context->getProcAddress("glBufferData");
+ m_glBufferSubData = (PFNGLBUFFERSUBDATAPROC) m_gl_context->getProcAddress("glBufferSubData");
}
// PBO:
if ( m_usepbo )
{
- pfn_glMapBuffer = (PFNGLMAPBUFFERPROC) m_gl_context->getProcAddress("glMapBuffer");
- pfn_glUnmapBuffer= (PFNGLUNMAPBUFFERPROC) m_gl_context->getProcAddress("glUnmapBuffer");
+ m_glMapBuffer = (PFNGLMAPBUFFERPROC) m_gl_context->getProcAddress("glMapBuffer");
+ m_glUnmapBuffer= (PFNGLUNMAPBUFFERPROC) m_gl_context->getProcAddress("glUnmapBuffer");
}
// FBO:
if ( m_usefbo )
{
- pfn_glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glIsFramebufferEXT");
- pfn_glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glBindFramebufferEXT");
- pfn_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glDeleteFramebuffersEXT");
- pfn_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glGenFramebuffersEXT");
- pfn_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) m_gl_context->getProcAddress("glCheckFramebufferStatusEXT");
- pfn_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) m_gl_context->getProcAddress("glFramebufferTexture2DEXT");
+ m_glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glIsFramebufferEXT");
+ m_glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC) m_gl_context->getProcAddress("glBindFramebufferEXT");
+ m_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glDeleteFramebuffersEXT");
+ m_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC) m_gl_context->getProcAddress("glGenFramebuffersEXT");
+ m_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) m_gl_context->getProcAddress("glCheckFramebufferStatusEXT");
+ m_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) m_gl_context->getProcAddress("glFramebufferTexture2DEXT");
}
if ( m_usevbo &&
- ( !pfn_glGenBuffers || !pfn_glDeleteBuffers ||
- !pfn_glBindBuffer || !pfn_glBufferData || !pfn_glBufferSubData
+ ( !m_glGenBuffers || !m_glDeleteBuffers ||
+ !m_glBindBuffer || !m_glBufferData || !m_glBufferSubData
) )
{
m_usepbo=false;
if (_once)
{
osd_printf_warning("OpenGL: VBO not supported, missing: ");
- if (!pfn_glGenBuffers)
+ if (!m_glGenBuffers)
{
osd_printf_warning("glGenBuffers, ");
}
- if (!pfn_glDeleteBuffers)
+ if (!m_glDeleteBuffers)
{
osd_printf_warning("glDeleteBuffers");
}
- if (!pfn_glBindBuffer)
+ if (!m_glBindBuffer)
{
osd_printf_warning("glBindBuffer, ");
}
- if (!pfn_glBufferData)
+ if (!m_glBufferData)
{
osd_printf_warning("glBufferData, ");
}
- if (!pfn_glBufferSubData)
+ if (!m_glBufferSubData)
{
osd_printf_warning("glBufferSubData, ");
}
@@ -811,17 +956,17 @@ void renderer_ogl::loadGLExtensions()
}
}
- if ( m_usepbo && ( !pfn_glMapBuffer || !pfn_glUnmapBuffer ) )
+ if ( m_usepbo && ( !m_glMapBuffer || !m_glUnmapBuffer ) )
{
m_usepbo=false;
if (_once)
{
osd_printf_warning("OpenGL: PBO not supported, missing: ");
- if (!pfn_glMapBuffer)
+ if (!m_glMapBuffer)
{
osd_printf_warning("glMapBuffer, ");
}
- if (!pfn_glUnmapBuffer)
+ if (!m_glUnmapBuffer)
{
osd_printf_warning("glUnmapBuffer, ");
}
@@ -830,37 +975,37 @@ void renderer_ogl::loadGLExtensions()
}
if ( m_usefbo &&
- ( !pfn_glIsFramebuffer || !pfn_glBindFramebuffer || !pfn_glDeleteFramebuffers ||
- !pfn_glGenFramebuffers || !pfn_glCheckFramebufferStatus || !pfn_glFramebufferTexture2D
+ ( !m_glIsFramebuffer || !m_glBindFramebuffer || !m_glDeleteFramebuffers ||
+ !m_glGenFramebuffers || !m_glCheckFramebufferStatus || !m_glFramebufferTexture2D
))
{
m_usefbo=false;
if (_once)
{
osd_printf_warning("OpenGL: FBO not supported, missing: ");
- if (!pfn_glIsFramebuffer)
+ if (!m_glIsFramebuffer)
{
- osd_printf_warning("pfn_glIsFramebuffer, ");
+ osd_printf_warning("m_glIsFramebuffer, ");
}
- if (!pfn_glBindFramebuffer)
+ if (!m_glBindFramebuffer)
{
- osd_printf_warning("pfn_glBindFramebuffer, ");
+ osd_printf_warning("m_glBindFramebuffer, ");
}
- if (!pfn_glDeleteFramebuffers)
+ if (!m_glDeleteFramebuffers)
{
- osd_printf_warning("pfn_glDeleteFramebuffers, ");
+ osd_printf_warning("m_glDeleteFramebuffers, ");
}
- if (!pfn_glGenFramebuffers)
+ if (!m_glGenFramebuffers)
{
- osd_printf_warning("pfn_glGenFramebuffers, ");
+ osd_printf_warning("m_glGenFramebuffers, ");
}
- if (!pfn_glCheckFramebufferStatus)
+ if (!m_glCheckFramebufferStatus)
{
- osd_printf_warning("pfn_glCheckFramebufferStatus, ");
+ osd_printf_warning("m_glCheckFramebufferStatus, ");
}
- if (!pfn_glFramebufferTexture2D)
+ if (!m_glFramebufferTexture2D)
{
- osd_printf_warning("pfn_glFramebufferTexture2D, ");
+ osd_printf_warning("m_glFramebufferTexture2D, ");
}
osd_printf_warning("\n");
}
@@ -899,11 +1044,11 @@ void renderer_ogl::loadGLExtensions()
if ( m_useglsl )
{
#if defined(GL_ARB_multitexture) && !defined(OSD_MAC)
- pfn_glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) m_gl_context->getProcAddress("glActiveTextureARB");
+ m_glActiveTexture = (PFNGLACTIVETEXTUREARBPROC) m_gl_context->getProcAddress("glActiveTextureARB");
#else
- pfn_glActiveTexture = (PFNGLACTIVETEXTUREPROC) m_gl_context->getProcAddress("glActiveTexture");
+ m_glActiveTexture = (PFNGLACTIVETEXTUREPROC) m_gl_context->getProcAddress("glActiveTexture");
#endif
- if (!pfn_glActiveTexture)
+ if (!m_glActiveTexture)
{
if (_once)
{
@@ -915,7 +1060,7 @@ void renderer_ogl::loadGLExtensions()
if ( m_useglsl )
{
- m_glsl = glsl_shader_init(m_gl_context);
+ m_glsl = glsl_shader_init(m_gl_context.get());
m_useglsl = (m_glsl != nullptr ? 1 : 0);
if ( ! m_useglsl )
@@ -927,9 +1072,9 @@ void renderer_ogl::loadGLExtensions()
}
}
- if ( m_useglsl )
+ if (m_useglsl)
{
- if (assert_window()->prescale() != 1 )
+ if (window().prescale() != 1 )
{
m_useglsl = 0;
if (_once)
@@ -939,7 +1084,7 @@ void renderer_ogl::loadGLExtensions()
}
}
- if ( m_useglsl )
+ if (m_useglsl)
{
int i;
video_config.filter = false;
@@ -947,7 +1092,7 @@ void renderer_ogl::loadGLExtensions()
m_glsl_program_num = 0;
m_glsl_program_mb2sc = 0;
- for(i=0; i<video_config.glsl_shader_mamebm_num; i++)
+ for(i=0; i<m_ogl_config.glsl_shader_mamebm_num; i++)
{
if ( !m_usefbo && m_glsl_program_num==1 )
{
@@ -958,50 +1103,50 @@ void renderer_ogl::loadGLExtensions()
break;
}
- if ( glsl_shader_add_mamebm(m_glsl, video_config.glsl_shader_mamebm[i], m_glsl_program_num) )
+ if ( glsl_shader_add_mamebm(m_glsl, m_ogl_config.glsl_shader_mamebm[i].c_str(), m_glsl_program_num) )
{
osd_printf_error("OpenGL: GLSL loading mame bitmap shader %d failed (%s)\n",
- i, video_config.glsl_shader_mamebm[i]);
+ i, m_ogl_config.glsl_shader_mamebm[i]);
} else {
glsl_shader_feature = GLSL_SHADER_FEAT_CUSTOM;
if (_once)
{
osd_printf_verbose("OpenGL: GLSL using mame bitmap shader filter %d: '%s'\n",
- m_glsl_program_num, video_config.glsl_shader_mamebm[i]);
+ m_glsl_program_num, m_ogl_config.glsl_shader_mamebm[i]);
}
m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
m_glsl_program_num++;
}
}
- if ( video_config.glsl_shader_scrn_num > 0 && m_glsl_program_num==0 )
+ if ( m_ogl_config.glsl_shader_scrn_num > 0 && m_glsl_program_num==0 )
{
osd_printf_verbose("OpenGL: GLSL cannot use screen bitmap shader without bitmap shader\n");
}
- for(i=0; m_usefbo && m_glsl_program_num>0 && i<video_config.glsl_shader_scrn_num; i++)
+ for(i=0; m_usefbo && m_glsl_program_num>0 && i<m_ogl_config.glsl_shader_scrn_num; i++)
{
- if ( glsl_shader_add_scrn(m_glsl, video_config.glsl_shader_scrn[i],
+ if ( glsl_shader_add_scrn(m_glsl, m_ogl_config.glsl_shader_scrn[i].c_str(),
m_glsl_program_num-1-m_glsl_program_mb2sc) )
{
osd_printf_error("OpenGL: GLSL loading screen bitmap shader %d failed (%s)\n",
- i, video_config.glsl_shader_scrn[i]);
+ i, m_ogl_config.glsl_shader_scrn[i]);
} else {
if (_once)
{
osd_printf_verbose("OpenGL: GLSL using screen bitmap shader filter %d: '%s'\n",
- m_glsl_program_num, video_config.glsl_shader_scrn[i]);
+ m_glsl_program_num, m_ogl_config.glsl_shader_scrn[i]);
}
m_glsl_program_num++;
}
}
if ( 0==m_glsl_program_num &&
- 0 <= video_config.glsl_filter && video_config.glsl_filter < GLSL_SHADER_FEAT_INT_NUMBER )
+ 0 <= m_ogl_config.glsl_filter && m_ogl_config.glsl_filter < GLSL_SHADER_FEAT_INT_NUMBER )
{
m_glsl_program_mb2sc = m_glsl_program_num; // the last mame_bitmap (mb) shader does it.
m_glsl_program_num++;
- glsl_shader_feature = video_config.glsl_filter;
+ glsl_shader_feature = m_ogl_config.glsl_filter;
if (_once)
{
@@ -1031,16 +1176,7 @@ int renderer_ogl::draw(const int update)
float vofs, hofs;
int pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE;
-#ifdef TOBEMIGRATED
- if (video_config.novideo)
- {
- return 0;
- }
-#endif
-
- auto win = assert_window();
-
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height))
{
@@ -1192,16 +1328,15 @@ int renderer_ogl::draw(const int update)
hofs = (cw - m_blit_dim.width()) / 2.0f;
}
}
-#else
#endif
m_last_hofs = hofs;
m_last_vofs = vofs;
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
// now draw
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
int i;
@@ -1407,7 +1542,7 @@ int renderer_ogl::draw(const int update)
pendingPrimitive=GL_NO_PRIMITIVE;
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
m_init_context = 0;
m_gl_context->SwapBuffer();
@@ -1543,9 +1678,8 @@ void renderer_ogl::texture_compute_size_subroutine(ogl_texture_info *texture, ui
while (texture->yprescale > 1 && height_create * texture->yprescale > m_texture_max_height)
texture->yprescale--;
- auto win = assert_window();
- if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != win->prescale() || texture->yprescale != win->prescale()))
- osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", win->prescale(), win->prescale(), texture->xprescale, texture->yprescale);
+ if (PRIMFLAG_GET_SCREENTEX(flags) && (texture->xprescale != window().prescale() || texture->yprescale != window().prescale()))
+ osd_printf_warning("SDL: adjusting prescale from %dx%d to %dx%d\n", window().prescale(), window().prescale(), texture->xprescale, texture->yprescale);
width *= texture->xprescale;
height *= texture->yprescale;
@@ -1640,10 +1774,9 @@ void renderer_ogl::texture_compute_size_type(const render_texinfo *texsource, og
// texture_create
//============================================================
-static int gl_checkFramebufferStatus()
+int renderer_ogl::gl_checkFramebufferStatus() const
{
- GLenum status;
- status=(GLenum)pfn_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+ GLenum const status = (GLenum)m_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
return 0;
@@ -1683,10 +1816,10 @@ static int gl_checkFramebufferStatus()
return -1;
}
-static int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height)
+int renderer_ogl::texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t fbo_name, int width, int height) const
{
- pfn_glActiveTexture(text_unit);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_name);
+ m_glActiveTexture(text_unit);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo_name);
glBindTexture(GL_TEXTURE_2D, text_name);
{
GLint _width, _height;
@@ -1708,7 +1841,7 @@ static int texture_fbo_create(uint32_t text_unit, uint32_t text_name, uint32_t f
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- pfn_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ m_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, text_name, 0);
if ( gl_checkFramebufferStatus() )
@@ -1789,7 +1922,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
{
// multipass mode
// GL_TEXTURE2/GL_TEXTURE3
- pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
+ m_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_mamebm[0]);
glGenTextures(2, (GLuint *)&texture->mpass_texture_mamebm[0]);
for (i=0; i<2; i++)
@@ -1803,7 +1936,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
}
}
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
osd_printf_verbose("GL texture: mpass mame-bmp 2x %dx%d (pow2 %dx%d)\n",
texture->rawwidth, texture->rawheight, texture->rawwidth_create, texture->rawheight_create);
@@ -1813,7 +1946,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
{
// multipass mode
// GL_TEXTURE2/GL_TEXTURE3
- pfn_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
+ m_glGenFramebuffers(2, (GLuint *)&texture->mpass_fbo_scrn[0]);
glGenTextures(2, (GLuint *)&texture->mpass_texture_scrn[0]);
for (i=0; i<2; i++)
@@ -1834,7 +1967,7 @@ int renderer_ogl::texture_shader_create(const render_texinfo *texsource, ogl_tex
// GL_TEXTURE0
// get a name for this texture
glGenTextures(1, (GLuint *)&texture->texture);
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture->texture);
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth_create);
@@ -1907,9 +2040,8 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
texture->texinfo.seqid = -1; // force set data
if (PRIMFLAG_GET_SCREENTEX(flags))
{
- auto win = assert_window();
- texture->xprescale = win->prescale();
- texture->yprescale = win->prescale();
+ texture->xprescale = window().prescale();
+ texture->yprescale = window().prescale();
}
else
{
@@ -2028,12 +2160,12 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
assert(m_usepbo);
// create the PBO
- pfn_glGenBuffers(1, (GLuint *)&texture->pbo);
+ m_glGenBuffers(1, (GLuint *)&texture->pbo);
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
// set up the PBO dimension, ..
- pfn_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
+ m_glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
texture->rawwidth * texture->rawheight * sizeof(uint32_t),
nullptr, GL_STREAM_DRAW);
}
@@ -2063,10 +2195,10 @@ ogl_texture_info *renderer_ogl::texture_create(const render_texinfo *texsource,
if (m_usevbo)
{
// Generate And Bind The Texture Coordinate Buffer
- pfn_glGenBuffers( 1, &(texture->texCoordBufferName) );
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
+ m_glGenBuffers( 1, &(texture->texCoordBufferName) );
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
// Load The Data
- pfn_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW );
+ m_glBufferData( GL_ARRAY_BUFFER_ARB, 4*2*sizeof(GLfloat), texture->texCoord, GL_STREAM_DRAW );
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) nullptr ); // we are using ARB VBO buffers
}
else
@@ -2327,14 +2459,14 @@ static inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, in
// texture_set_data
//============================================================
-static void texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags)
+void renderer_ogl::texture_set_data(ogl_texture_info *texture, const render_texinfo *texsource, uint32_t flags) const
{
if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
assert(texture->pbo);
assert(!texture->nocopy);
- texture->data = (uint32_t *) pfn_glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
+ texture->data = (uint32_t *) m_glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY);
}
// note that nocopy and borderpix are mutually exclusive, IOW
@@ -2401,7 +2533,7 @@ static void texture_set_data(ogl_texture_info *texture, const render_texinfo *te
if ( texture->type == TEXTURE_TYPE_SHADER )
{
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->texTarget, texture->texture);
if (texture->nocopy)
@@ -2420,7 +2552,7 @@ static void texture_set_data(ogl_texture_info *texture, const render_texinfo *te
glPixelStorei(GL_UNPACK_ROW_LENGTH, texture->rawwidth);
// unmap the buffer from the CPU space so it can DMA
- pfn_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
+ m_glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
// kick off the DMA
glTexSubImage2D(texture->texTarget, 0, 0, 0, texture->rawwidth, texture->rawheight,
@@ -2575,7 +2707,7 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
GL_CHECK_ERROR_NORMAL();
}
- pfn_glActiveTexture(texture->mpass_textureunit[mpass_src_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[mpass_src_idx]);
if ( shaderIdx<=m_glsl_program_mb2sc )
{
glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[mpass_src_idx]);
@@ -2584,22 +2716,22 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
{
glBindTexture(texture->texTarget, texture->mpass_texture_scrn[mpass_src_idx]);
}
- pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
glBindTexture(texture->texTarget, 0);
- pfn_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
+ m_glActiveTexture(texture->mpass_textureunit[texture->mpass_dest_idx]);
if ( shaderIdx<m_glsl_program_num-1 )
{
if ( shaderIdx>=m_glsl_program_mb2sc )
{
glBindTexture(texture->texTarget, texture->mpass_texture_scrn[texture->mpass_dest_idx]);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_scrn[texture->mpass_dest_idx]);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_scrn[texture->mpass_dest_idx]);
}
else
{
glBindTexture(texture->texTarget, texture->mpass_texture_mamebm[texture->mpass_dest_idx]);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_mamebm[texture->mpass_dest_idx]);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, texture->mpass_fbo_mamebm[texture->mpass_dest_idx]);
}
if ( shaderIdx==0 )
@@ -2620,7 +2752,7 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
else
{
glBindTexture(texture->texTarget, 0);
- pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
if ( m_glsl_program_mb2sc == m_glsl_program_num-1 )
{
@@ -2628,7 +2760,7 @@ void renderer_ogl::texture_mpass_flip(ogl_texture_info *texture, int shaderIdx)
GL_CHECK_ERROR_NORMAL();
}
- pfn_glActiveTexture(GL_TEXTURE0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->texTarget, 0);
}
}
@@ -2676,7 +2808,7 @@ ogl_texture_info * renderer_ogl::texture_update(const render_primitive *prim, in
else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
assert ( m_usepbo ) ;
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, texture->pbo);
glEnable(texture->texTarget);
}
else
@@ -2716,9 +2848,9 @@ ogl_texture_info * renderer_ogl::texture_update(const render_primitive *prim, in
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if(m_usevbo)
{
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, texture->texCoordBufferName );
// Load The Data
- pfn_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord );
+ m_glBufferSubData( GL_ARRAY_BUFFER_ARB, 0, 4*2*sizeof(GLfloat), texture->texCoord );
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) nullptr ); // we are using ARB VBO buffers
}
else
@@ -2736,11 +2868,14 @@ void renderer_ogl::texture_disable(ogl_texture_info * texture)
{
assert ( m_useglsl );
pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
- } else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
+ }
+ else if ( texture->type == TEXTURE_TYPE_DYNAMIC )
{
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glDisable(texture->texTarget);
- } else {
+ }
+ else
+ {
glDisable(texture->texTarget);
}
}
@@ -2751,18 +2886,18 @@ void renderer_ogl::texture_all_disable()
{
pfn_glUseProgramObjectARB(0); // back to fixed function pipeline
- pfn_glActiveTexture(GL_TEXTURE3);
+ m_glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE2);
+ if ( m_usefbo ) m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE1);
+ if ( m_usefbo ) m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- pfn_glActiveTexture(GL_TEXTURE0);
+ if ( m_usefbo ) m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ m_glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
- if ( m_usefbo ) pfn_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ if ( m_usefbo ) m_glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
@@ -2775,10 +2910,143 @@ void renderer_ogl::texture_all_disable()
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if(m_usevbo)
{
- pfn_glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); // unbind ..
+ m_glBindBuffer( GL_ARRAY_BUFFER_ARB, 0); // unbind ..
}
if ( m_usepbo )
{
- pfn_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ m_glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0);
}
}
+
+
+class video_opengl : public osd_module, public render_module
+{
+public:
+ video_opengl()
+ : osd_module(OSD_RENDERER_PROVIDER, "opengl")
+#ifdef USE_DISPATCH_GL
+ , m_dll_loaded(false)
+#endif
+ {
+ }
+ ~video_opengl() { exit(); }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE | FLAG_SDL_NEEDS_OPENGL; }
+
+private:
+ ogl_video_config m_ogl_config;
+#ifdef USE_DISPATCH_GL
+ std::unique_ptr<osd_gl_dispatch> m_gl_dispatch;
+ bool m_dll_loaded;
+#endif
+};
+
+int video_opengl::init(osd_interface &osd, osd_options const &options)
+{
+ m_ogl_config.vbo = options.gl_vbo();
+ m_ogl_config.pbo = options.gl_pbo();
+ m_ogl_config.allowtexturerect = !options.gl_no_texture_rect();
+ m_ogl_config.forcepow2texture = options.gl_force_pow2_texture();
+ m_ogl_config.glsl = options.gl_glsl();
+ if (m_ogl_config.glsl)
+ {
+ m_ogl_config.glsl_filter = options.glsl_filter();
+
+ m_ogl_config.glsl_shader_mamebm_num = 0;
+ for (int i = 0; i < GLSL_SHADER_MAX; i++)
+ {
+ char const *const stemp = options.shader_mame(i);
+ if (stemp && *stemp && strcmp(stemp, OSDOPTVAL_NONE))
+ m_ogl_config.glsl_shader_mamebm[m_ogl_config.glsl_shader_mamebm_num++] = stemp;
+ }
+
+ m_ogl_config.glsl_shader_scrn_num = 0;
+ for (int i = 0; i < GLSL_SHADER_MAX; i++)
+ {
+ char const *const stemp = options.shader_screen(i);
+ if (stemp && *stemp && strcmp(stemp, OSDOPTVAL_NONE))
+ m_ogl_config.glsl_shader_scrn[m_ogl_config.glsl_shader_scrn_num++] = stemp;
+ }
+ }
+ else
+ {
+ m_ogl_config.glsl_filter = 0;
+
+ m_ogl_config.glsl_shader_mamebm_num = 0;
+ for (std::string &s : m_ogl_config.glsl_shader_mamebm)
+ s.clear();
+
+ m_ogl_config.glsl_shader_scrn_num = 0;
+ for (std::string &s : m_ogl_config.glsl_shader_scrn)
+ s.clear();
+ }
+
+#if defined(USE_DISPATCH_GL)
+#if defined(OSD_SDL)
+ if (!m_dll_loaded)
+ {
+ // directfb and and x11 use this env var: SDL_VIDEO_GL_DRIVER
+ char const *libname = dynamic_cast<sdl_options const &>(options).gl_lib();
+ if (libname && (!*libname || !std::strcmp(libname, OSDOPTVAL_AUTO)))
+ libname = nullptr;
+
+ if (SDL_GL_LoadLibrary(libname) != 0)
+ {
+ osd_printf_error("Unable to load OpenGL shared library: %s\n", libname ? libname : "<default>");
+ return -1;
+ }
+
+ osd_printf_verbose("Loaded OpenGL shared library: %s\n", libname ? libname : "<default>");
+ }
+#endif // defined(OSD_SDL)
+ m_dll_loaded = true;
+ m_gl_dispatch = std::make_unique<osd_gl_dispatch>();
+#endif // defined(USE_DISPATCH_GL)
+
+#if defined(OSD_WINDOWS)
+ osd_printf_verbose("Using Windows OpenGL driver\n");
+#else // defined(OSD_WINDOWS)
+ osd_printf_verbose("Using SDL multi-window OpenGL driver (SDL 2.0+)\n");
+#endif // defined(OSD_WINDOWS)
+
+ return 0;
+}
+
+void video_opengl::exit()
+{
+#if defined(USE_DISPATCH_GL)
+#if defined(OSD_SDL)
+ if (m_dll_loaded)
+ SDL_GL_UnloadLibrary();
+#endif // defined(OSD_SDL)
+ m_gl_dispatch.reset();
+ m_dll_loaded = false;
+#endif // defined(USE_DISPATCH_GL)
+
+ m_ogl_config = ogl_video_config();
+}
+
+std::unique_ptr<osd_renderer> video_opengl::create(osd_window &window)
+{
+ return std::make_unique<renderer_ogl>(window, m_ogl_config);
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // USE_OPENGL
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_opengl, OSD_RENDERER_PROVIDER, "opengl") } }
+
+#endif // USE_OPENGL
+
+
+MODULE_DEFINITION(RENDERER_OPENGL, osd::video_opengl)
diff --git a/src/osd/modules/render/drawogl.h b/src/osd/modules/render/drawogl.h
deleted file mode 100644
index 61b9794353c..00000000000
--- a/src/osd/modules/render/drawogl.h
+++ /dev/null
@@ -1,244 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
-//============================================================
-//
-// drawogl.h - SDL software and OpenGL implementation
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-#ifndef MAME_OSD_MODULES_RENDER_DRAWOGL_H
-#define MAME_OSD_MODULES_RENDER_DRAWOGL_H
-
-#pragma once
-
-// OSD headers
-#ifndef OSD_WINDOWS
-#ifdef OSD_MAC
-#include "osdmac.h"
-#else
-#include "osdsdl.h"
-#endif
-#include "window.h"
-#else
-#include "../windows/window.h"
-typedef uint64_t HashT;
-#endif
-
-#if defined(OSD_WINDOWS)
-#include "winglcontext.h"
-#elif defined (OSD_MAC)
-#else
-#include "sdlglcontext.h"
-#endif
-
-#include "modules/opengl/gl_shader_mgr.h"
-
-#include "emucore.h"
-#include "render.h"
-
-//============================================================
-// Textures
-//============================================================
-
-/* ogl_texture_info holds information about a texture */
-class ogl_texture_info
-{
-public:
- ogl_texture_info()
- : hash(0), flags(0), rawwidth(0), rawheight(0),
- rawwidth_create(0), rawheight_create(0),
- type(0), format(0), borderpix(0), xprescale(0), yprescale(0), nocopy(0),
- texture(0), texTarget(0), texpow2(0), mpass_dest_idx(0), pbo(0), data(nullptr),
- data_own(0), texCoordBufferName(0)
- {
- for (int i=0; i<2; i++)
- {
- mpass_textureunit[i] = 0;
- mpass_texture_mamebm[i] = 0;
- mpass_fbo_mamebm[i] = 0;
- mpass_texture_scrn[i] = 0;
- mpass_fbo_scrn[i] = 0;
- }
- for (int i=0; i<8; i++)
- texCoord[i] = 0.0f;
- }
-
- HashT hash; // hash value for the texture (must be >= pointer size)
- uint32_t flags; // rendering flags
- render_texinfo texinfo; // copy of the texture info
- int rawwidth, rawheight; // raw width/height of the texture
- int rawwidth_create; // raw width/height, pow2 compatible, if needed
- int rawheight_create; // (create and initial set the texture, not for copy!)
- int type; // what type of texture are we?
- int format; // texture format
- int borderpix; // do we have a 1 pixel border?
- int xprescale; // what is our X prescale factor?
- int yprescale; // what is our Y prescale factor?
- int nocopy; // must the texture date be copied?
-
- uint32_t texture; // OpenGL texture "name"/ID
-
- GLenum texTarget; // OpenGL texture target
- int texpow2; // Is this texture pow2
-
- uint32_t mpass_dest_idx; // Multipass dest idx [0..1]
- uint32_t mpass_textureunit[2]; // texture unit names for GLSL
-
- uint32_t mpass_texture_mamebm[2];// Multipass OpenGL texture "name"/ID for the shader
- uint32_t mpass_fbo_mamebm[2]; // framebuffer object for this texture, multipass
- uint32_t mpass_texture_scrn[2]; // Multipass OpenGL texture "name"/ID for the shader
- uint32_t mpass_fbo_scrn[2]; // framebuffer object for this texture, multipass
-
- uint32_t pbo; // pixel buffer object for this texture (DYNAMIC only!)
- uint32_t *data; // pixels for the texture
- int data_own; // do we own / allocated it ?
- GLfloat texCoord[8];
- GLuint texCoordBufferName;
-
-};
-
-/* renderer_ogl is the information about OpenGL for the current screen */
-class renderer_ogl : public osd_renderer
-{
-public:
- renderer_ogl(std::shared_ptr<osd_window> window)
- : osd_renderer(window, FLAG_NEEDS_OPENGL)
- , m_blittimer(0)
- , m_width(0)
- , m_height(0)
- , m_blit_dim(0, 0)
- , m_gl_context(nullptr)
- , m_initialized(0)
- , m_last_blendmode(0)
- , m_texture_max_width(0)
- , m_texture_max_height(0)
- , m_texpoweroftwo(0)
- , m_usevbo(0)
- , m_usepbo(0)
- , m_usefbo(0)
- , m_useglsl(0)
- , m_glsl(nullptr)
- , m_glsl_program_num(0)
- , m_glsl_program_mb2sc(0)
- , m_usetexturerect(0)
- , m_init_context(0)
- , m_last_hofs(0.0f)
- , m_last_vofs(0.0f)
- , m_surf_w(0)
- , m_surf_h(0)
- {
- for (int i=0; i < HASH_SIZE + OVERFLOW_SIZE; i++)
- m_texhash[i] = nullptr;
- for (int i=0; i < 2*GLSL_SHADER_MAX; i++)
- m_glsl_program[i] = 0;
- for (int i=0; i < 8; i++)
- m_texVerticex[i] = 0.0f;
- }
- virtual ~renderer_ogl();
-
- static void init(running_machine &machine);
- static void exit();
-
- virtual int create() override;
- virtual int draw(const int update) override;
-
-#ifndef OSD_WINDOWS
- virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
-#endif
- virtual render_primitive_list *get_primitives() override
- {
- auto win = try_getwindow();
- if (win == nullptr)
- return nullptr;
-
- osd_dim nd = win->get_size();
- if (nd != m_blit_dim)
- {
- m_blit_dim = nd;
- notify_changed();
- }
- if ((m_blit_dim.width() == 0) || (m_blit_dim.height() == 0))
- return nullptr;
- win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
- return &win->target()->get_primitives();
- }
-
-#ifdef OSD_WINDOWS
- virtual void save() override { }
- virtual void record() override { }
- virtual void toggle_fsfx() override { }
-#endif
-
-private:
- static const uint32_t HASH_SIZE = ((1 << 10) + 1);
- static const uint32_t OVERFLOW_SIZE = (1 << 10);
-
- void destroy_all_textures();
-
- static void load_gl_lib(running_machine &machine);
- void loadGLExtensions();
- void initialize_gl();
- void set_blendmode(int blendmode);
- HashT texture_compute_hash(const render_texinfo *texture, uint32_t flags);
- void texture_compute_type_subroutine(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
- void texture_compute_size_subroutine(ogl_texture_info *texture, uint32_t flags,
- uint32_t width, uint32_t height,
- int* p_width, int* p_height, int* p_width_create, int* p_height_create);
- void texture_compute_size_type(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
- ogl_texture_info *texture_create(const render_texinfo *texsource, uint32_t flags);
- int texture_shader_create(const render_texinfo *texsource, ogl_texture_info *texture, uint32_t flags);
- ogl_texture_info *texture_find(const render_primitive *prim);
- void texture_coord_update(ogl_texture_info *texture, const render_primitive *prim, int shaderIdx);
- void texture_mpass_flip(ogl_texture_info *texture, int shaderIdx);
- void texture_shader_update(ogl_texture_info *texture, render_container *container, int shaderIdx);
- ogl_texture_info * texture_update(const render_primitive *prim, int shaderIdx);
- void texture_disable(ogl_texture_info * texture);
- void texture_all_disable();
-
- int32_t m_blittimer;
- int m_width;
- int m_height;
- osd_dim m_blit_dim;
-
- osd_gl_context *m_gl_context;
-
- int m_initialized; // is everything well initialized, i.e. all GL stuff etc.
- // 3D info (GL mode only)
- ogl_texture_info * m_texhash[HASH_SIZE + OVERFLOW_SIZE];
- int m_last_blendmode; // previous blendmode
- int32_t m_texture_max_width; // texture maximum width
- int32_t m_texture_max_height; // texture maximum height
- int m_texpoweroftwo; // must textures be power-of-2 sized?
- int m_usevbo; // runtime check if VBO is available
- int m_usepbo; // runtime check if PBO is available
- int m_usefbo; // runtime check if FBO is available
- int m_useglsl; // runtime check if GLSL is available
-
- glsl_shader_info *m_glsl; // glsl_shader_info
-
- GLhandleARB m_glsl_program[2*GLSL_SHADER_MAX]; // GLSL programs, or 0
- int m_glsl_program_num; // number of GLSL programs
- int m_glsl_program_mb2sc; // GLSL program idx, which transforms
- // the mame-bitmap. screen-bitmap (size/rotation/..)
- // All progs <= glsl_program_mb2sc using the mame bitmap
- // as input, otherwise the screen bitmap.
- // All progs >= glsl_program_mb2sc using the screen bitmap
- // as output, otherwise the mame bitmap.
- int m_usetexturerect; // use ARB_texture_rectangle for non-power-of-2, general use
-
- int m_init_context; // initialize context before next draw
-
- float m_last_hofs;
- float m_last_vofs;
-
- // Static vars from draogl_window_dra
- int32_t m_surf_w;
- int32_t m_surf_h;
- GLfloat m_texVerticex[8];
-
- static bool s_shown_video_info;
- static bool s_dll_loaded;
-};
-
-#endif // MAME_OSD_MODULES_RENDER_DRAWOGL_H
diff --git a/src/osd/modules/render/drawsdl.cpp b/src/osd/modules/render/drawsdl.cpp
index 3d51b85c9a4..46aa098a7bc 100644
--- a/src/osd/modules/render/drawsdl.cpp
+++ b/src/osd/modules/render/drawsdl.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
//============================================================
//
-// drawsdl.c - SDL software and OpenGL implementation
+// drawsdl.cpp - SDL software and OpenGL implementation
//
// SDLMAME by Olivier Galibert and R. Belmont
//
@@ -10,25 +10,37 @@
//
//============================================================
-#include "drawsdl.h"
+#include "render_module.h"
+
+#include "modules/osdmodule.h"
+
+#if defined(OSD_SDL)
+
+// from specific OSD implementation
+#include "sdlopts.h"
+#include "window.h"
+
+// general OSD headers
+#include "modules/monitor/monitor_module.h"
// MAME headers
#include "emucore.h"
+#include "render.h"
#include "rendersw.hxx"
-#include "ui/uimain.h"
+//#include "ui/uimain.h"
-// osd headers
-#include "modules/monitor/monitor_module.h"
+#include <SDL2/SDL.h>
// standard C headers
#include <cmath>
#include <cstdio>
+#include <memory>
-//============================================================
-// DEBUGGING
-//============================================================
+namespace osd {
+
+namespace {
//============================================================
// CONSTANTS
@@ -38,6 +50,76 @@
#define DRAW2_SCALEMODE_LINEAR "1"
#define DRAW2_SCALEMODE_BEST "2"
+
+struct sdl_scale_mode
+{
+ const char *name;
+ int is_scale; /* Scale mode? */
+ int is_yuv; /* Yuv mode? */
+ int mult_w; /* Width multiplier */
+ int mult_h; /* Height multiplier */
+ const char *sdl_scale_mode_hint; /* what to use as a hint ? */
+ int pixel_format; /* Pixel/Overlay format */
+ void (*yuv_blit)(const uint16_t *bitmap, uint8_t *ptr, const int pitch, const uint32_t *lookup, const int width, const int height);
+};
+
+
+// renderer_sdl1 is the information about SDL for the current screen
+class renderer_sdl1 : public osd_renderer
+{
+public:
+
+ renderer_sdl1(osd_window &w, sdl_scale_mode const &scale_mode)
+ : osd_renderer(w)
+ , m_scale_mode(scale_mode)
+ , m_sdl_renderer(nullptr)
+ , m_texture_id(nullptr)
+ , m_yuv_lookup()
+ , m_yuv_bitmap()
+ //, m_hw_scale_width(0)
+ //, m_hw_scale_height(0)
+ , m_last_hofs(0)
+ , m_last_vofs(0)
+ , m_blit_dim(0, 0)
+ , m_last_dim(0, 0)
+ {
+ }
+ virtual ~renderer_sdl1();
+
+ virtual int create() override;
+ virtual int draw(const int update) override;
+ virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
+ virtual render_primitive_list *get_primitives() override;
+
+private:
+ void show_info(struct SDL_RendererInfo *render_info);
+
+ void destroy_all_textures();
+ void yuv_init();
+ void setup_texture(const osd_dim &size);
+ void yuv_lookup_set(unsigned int pen, unsigned char red,
+ unsigned char green, unsigned char blue);
+
+ int32_t m_blittimer;
+
+ sdl_scale_mode const &m_scale_mode;
+ SDL_Renderer *m_sdl_renderer;
+ SDL_Texture *m_texture_id;
+
+ // YUV overlay
+ std::unique_ptr<uint32_t []> m_yuv_lookup;
+ std::unique_ptr<uint16_t []> m_yuv_bitmap;
+
+ // if we leave scaling to SDL and the underlying driver, this
+ // is the render_target_width/height to use
+
+ int m_last_hofs;
+ int m_last_vofs;
+ osd_dim m_blit_dim;
+ osd_dim m_last_dim;
+};
+
+
//============================================================
// PROTOTYPES
//============================================================
@@ -53,84 +135,41 @@ static void yuv_RGB_to_YUY2(const uint16_t *bitmap, uint8_t *ptr, const int pitc
static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pitch, \
const uint32_t *lookup, const int width, const int height);
-// Static declarations
-
-static const sdl_scale_mode scale_modes[] =
-{
- { "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, nullptr },
- { "hwblit", 1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, nullptr },
- { "hwbest", 1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, nullptr },
- /* SDL1.2 uses interpolation as well */
- { "yv12", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
- { "yv12x2", 1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
- { "yuy2", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
- { "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
- { nullptr }
-};
-
-int drawsdl_scale_mode(const char *s)
-{
- const sdl_scale_mode *sm = scale_modes;
- int index;
-
- index = 0;
- while (sm->name != nullptr)
- {
- if (strcmp(sm->name, s) == 0)
- return index;
- index++;
- sm++;
- }
- return -1;
-}
-
-//============================================================
-// drawsdl_init
-//============================================================
-
-void renderer_sdl1::init(running_machine &machine)
-{
- osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
-}
-
//============================================================
// setup_texture for window
//============================================================
void renderer_sdl1::setup_texture(const osd_dim &size)
{
- const sdl_scale_mode *sdl_sm = &scale_modes[video_config.scale_mode];
SDL_DisplayMode mode;
uint32_t fmt;
- auto win = assert_window();
-
// Determine preferred pixelformat and set up yuv if necessary
- SDL_GetCurrentDisplayMode(win->monitor()->oshandle(), &mode);
+ SDL_GetCurrentDisplayMode(window().monitor()->oshandle(), &mode);
m_yuv_bitmap.reset();
- fmt = (sdl_sm->pixel_format ? sdl_sm->pixel_format : mode.format);
+ fmt = (m_scale_mode.pixel_format ? m_scale_mode.pixel_format : mode.format);
- if (sdl_sm->is_scale)
+ if (m_scale_mode.is_scale)
{
int m_hw_scale_width = 0;
int m_hw_scale_height = 0;
- win->target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
- if (win->prescale())
+ window().target()->compute_minimum_size(m_hw_scale_width, m_hw_scale_height);
+ if (window().prescale())
{
- m_hw_scale_width *= win->prescale();
- m_hw_scale_height *= win->prescale();
+ m_hw_scale_width *= window().prescale();
+ m_hw_scale_height *= window().prescale();
/* This must be a multiple of 2 */
m_hw_scale_width = (m_hw_scale_width + 1) & ~1;
}
- if (sdl_sm->is_yuv)
+ if (m_scale_mode.is_yuv)
m_yuv_bitmap = std::make_unique<uint16_t []>(m_hw_scale_width * m_hw_scale_height);
- int w = m_hw_scale_width * sdl_sm->mult_w;
- int h = m_hw_scale_height * sdl_sm->mult_h;
+ int w = m_hw_scale_width * m_scale_mode.mult_w;
+ int h = m_hw_scale_height * m_scale_mode.mult_h;
m_texture_id = SDL_CreateTexture(m_sdl_renderer, fmt, SDL_TEXTUREACCESS_STREAMING, w, h);
@@ -179,26 +218,23 @@ void renderer_sdl1::show_info(struct SDL_RendererInfo *render_info)
int renderer_sdl1::create()
{
- const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
-
- auto win = assert_window();
// create renderer
/* set hints ... */
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, sm->sdl_scale_mode_hint);
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, m_scale_mode.sdl_scale_mode_hint);
if (video_config.waitvsync)
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
else
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_ACCELERATED);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_ACCELERATED);
if (!m_sdl_renderer)
{
if (video_config.waitvsync)
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_SOFTWARE);
else
- m_sdl_renderer = SDL_CreateRenderer(std::dynamic_pointer_cast<sdl_window_info>(win)->platform_window(), -1, SDL_RENDERER_SOFTWARE);
+ m_sdl_renderer = SDL_CreateRenderer(dynamic_cast<sdl_window_info &>(window()).platform_window(), -1, SDL_RENDERER_SOFTWARE);
}
if (!m_sdl_renderer)
@@ -213,18 +249,18 @@ int renderer_sdl1::create()
// Check scale mode
- if (sm->pixel_format)
+ if (m_scale_mode.pixel_format)
{
int i;
int found = 0;
for (i=0; i < render_info.num_texture_formats; i++)
- if (sm->pixel_format == render_info.texture_formats[i])
+ if (m_scale_mode.pixel_format == render_info.texture_formats[i])
found = 1;
if (!found)
{
- fatalerror("window: Scale mode %s not supported!", sm->name);
+ fatalerror("window: Scale mode %s not supported!", m_scale_mode.name);
}
}
@@ -285,7 +321,6 @@ void renderer_sdl1::destroy_all_textures()
int renderer_sdl1::draw(int update)
{
- const sdl_scale_mode *sm = &scale_modes[video_config.scale_mode];
uint8_t *surfptr;
int32_t pitch;
Uint32 rmask, gmask, bmask;
@@ -293,14 +328,7 @@ int renderer_sdl1::draw(int update)
int32_t vofs, hofs, blitwidth, blitheight, ch, cw;
int bpp;
- if (video_config.novideo)
- {
- return 0;
- }
-
- auto win = assert_window();
-
- osd_dim wdim = win->get_size();
+ osd_dim wdim = window().get_size();
if (has_flags(FI_CHANGED) || (wdim != m_last_dim))
{
destroy_all_textures();
@@ -367,15 +395,15 @@ int renderer_sdl1::draw(int update)
m_last_hofs = hofs;
m_last_vofs = vofs;
- win->m_primlist->acquire_lock();
+ window().m_primlist->acquire_lock();
int mamewidth, mameheight;
Uint32 fmt = 0;
int access = 0;
SDL_QueryTexture(m_texture_id, &fmt, &access, &mamewidth, &mameheight);
- mamewidth /= sm->mult_w;
- mameheight /= sm->mult_h;
+ mamewidth /= m_scale_mode.mult_w;
+ mameheight /= m_scale_mode.mult_h;
//printf("w h %d %d %d %d\n", mamewidth, mameheight, blitwidth, blitheight);
// rescale bounds
@@ -385,7 +413,7 @@ int renderer_sdl1::draw(int update)
// FIXME: this could be a lot easier if we get the primlist here!
// Bounds would be set fit for purpose and done!
- for (render_primitive &prim : *win->m_primlist)
+ for (render_primitive &prim : *window().m_primlist)
{
prim.bounds.x0 = floor(fw * prim.bounds.x0 + 0.5f);
prim.bounds.x1 = floor(fw * prim.bounds.x1 + 0.5f);
@@ -394,32 +422,32 @@ int renderer_sdl1::draw(int update)
}
// render to it
- if (!sm->is_yuv)
+ if (!m_scale_mode.is_yuv)
{
switch (rmask)
{
case 0xff000000:
- software_renderer<uint32_t, 0,0,0, 24,16,8>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
+ software_renderer<uint32_t, 0,0,0, 24,16,8>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x0000ff00:
- software_renderer<uint32_t, 0,0,0, 8,16,24>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
+ software_renderer<uint32_t, 0,0,0, 8,16,24>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x00ff0000:
- software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
+ software_renderer<uint32_t, 0,0,0, 16,8,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0x000000ff:
- software_renderer<uint32_t, 0,0,0, 0,8,16>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
+ software_renderer<uint32_t, 0,0,0, 0,8,16>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 4);
break;
case 0xf800:
- software_renderer<uint16_t, 3,2,3, 11,5,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
+ software_renderer<uint16_t, 3,2,3, 11,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
break;
case 0x7c00:
- software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*win->m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
+ software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, surfptr, mamewidth, mameheight, pitch / 2);
break;
default:
@@ -431,11 +459,11 @@ int renderer_sdl1::draw(int update)
{
assert (m_yuv_bitmap != nullptr);
assert (surfptr != nullptr);
- software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*win->m_primlist, m_yuv_bitmap.get(), mamewidth, mameheight, mamewidth);
- sm->yuv_blit(m_yuv_bitmap.get(), surfptr, pitch, m_yuv_lookup.get(), mamewidth, mameheight);
+ software_renderer<uint16_t, 3,3,3, 10,5,0>::draw_primitives(*window().m_primlist, m_yuv_bitmap.get(), mamewidth, mameheight, mamewidth);
+ m_scale_mode.yuv_blit(m_yuv_bitmap.get(), surfptr, pitch, m_yuv_lookup.get(), mamewidth, mameheight);
}
- win->m_primlist->release_lock();
+ window().m_primlist->release_lock();
// unlock and flip
SDL_UnlockTexture(m_texture_id);
@@ -663,16 +691,98 @@ static void yuv_RGB_to_YUY2X2(const uint16_t *bitmap, uint8_t *ptr, const int pi
render_primitive_list *renderer_sdl1::get_primitives()
{
- auto win = try_getwindow();
- if (win == nullptr)
- return nullptr;
-
- osd_dim nd = win->get_size();
+ osd_dim nd = window().get_size();
if (nd != m_blit_dim)
{
m_blit_dim = nd;
notify_changed();
}
- win->target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), win->pixel_aspect());
- return &win->target()->get_primitives();
+ window().target()->set_bounds(m_blit_dim.width(), m_blit_dim.height(), window().pixel_aspect());
+ return &window().target()->get_primitives();
+}
+
+
+class video_sdl1 : public osd_module, public render_module
+{
+public:
+ video_sdl1()
+ : osd_module(OSD_RENDERER_PROVIDER, "soft")
+ , m_scale_mode(-1)
+ {
+ }
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override { }
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) override;
+
+protected:
+ virtual unsigned flags() const override { return FLAG_INTERACTIVE | FLAG_SDL_NEEDS_OPENGL; }
+
+private:
+ static int get_scale_mode(char const *modestr);
+
+ int m_scale_mode;
+
+ static sdl_scale_mode const s_scale_modes[];
+};
+
+int video_sdl1::init(osd_interface &osd, osd_options const &options)
+{
+ osd_printf_verbose("Using SDL multi-window soft driver (SDL 2.0+)\n");
+
+ // yuv settings ...
+ char const *const modestr = dynamic_cast<sdl_options const &>(options).scale_mode();
+ m_scale_mode = get_scale_mode(modestr);
+ if (m_scale_mode < 0)
+ {
+ osd_printf_warning("Invalid yuvmode value %s; reverting to none\n", modestr);
+ m_scale_mode = 0;
+ }
+
+ return 0;
}
+
+std::unique_ptr<osd_renderer> video_sdl1::create(osd_window &window)
+{
+ return std::make_unique<renderer_sdl1>(window, s_scale_modes[m_scale_mode]);
+}
+
+int video_sdl1::get_scale_mode(char const *modestr)
+{
+ const sdl_scale_mode *sm = s_scale_modes;
+ int index = 0;
+ while (sm->name)
+ {
+ if (!strcmp(sm->name, modestr))
+ return index;
+ index++;
+ sm++;
+ }
+ return -1;
+}
+
+sdl_scale_mode const video_sdl1::s_scale_modes[] = {
+ { "none", 0, 0, 1, 1, DRAW2_SCALEMODE_NEAREST, 0, nullptr },
+ { "hwblit", 1, 0, 1, 1, DRAW2_SCALEMODE_LINEAR, 0, nullptr },
+ { "hwbest", 1, 0, 1, 1, DRAW2_SCALEMODE_BEST, 0, nullptr },
+ /* SDL1.2 uses interpolation as well */
+ { "yv12", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12 },
+ { "yv12x2", 1, 1, 2, 2, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YV12, yuv_RGB_to_YV12X2 },
+ { "yuy2", 1, 1, 1, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2 },
+ { "yuy2x2", 1, 1, 2, 1, DRAW2_SCALEMODE_BEST, SDL_PIXELFORMAT_YUY2, yuv_RGB_to_YUY2X2 },
+ { nullptr } };
+
+} // anonymous namespace
+
+} // namespace osd
+
+
+#else // defined(OSD_SDL)
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(video_sdl1, OSD_RENDERER_PROVIDER, "soft") } }
+
+#endif // defined(OSD_SDL)
+
+
+MODULE_DEFINITION(RENDERER_SDL1, osd::video_sdl1)
diff --git a/src/osd/modules/render/drawsdl.h b/src/osd/modules/render/drawsdl.h
deleted file mode 100644
index cc07b848c91..00000000000
--- a/src/osd/modules/render/drawsdl.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Couriersud, Olivier Galibert, R. Belmont
-//============================================================
-//
-// drawsdl.h - SDL software and OpenGL implementation
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-// yuvmodes by Couriersud
-//
-//============================================================
-
-#ifndef MAME_OSD_MODULES_RENDER_DRAWSDL_H
-#define MAME_OSD_MODULES_RENDER_DRAWSDL_H
-
-#pragma once
-
-// OSD headers
-#include "window.h"
-
-#include <SDL2/SDL.h>
-
-#include <memory>
-
-
-/* renderer_sdl1 is the information about SDL for the current screen */
-class renderer_sdl1 : public osd_renderer
-{
-public:
-
- renderer_sdl1(std::shared_ptr<osd_window> w, int extra_flags)
- : osd_renderer(w, FLAG_NEEDS_OPENGL | extra_flags)
- , m_sdl_renderer(nullptr)
- , m_texture_id(nullptr)
- , m_yuv_lookup()
- , m_yuv_bitmap()
- //, m_hw_scale_width(0)
- //, m_hw_scale_height(0)
- , m_last_hofs(0)
- , m_last_vofs(0)
- , m_blit_dim(0, 0)
- , m_last_dim(0, 0)
- {
- }
- virtual ~renderer_sdl1();
-
- static void init(running_machine &machine);
- static void exit() { }
-
- virtual int create() override;
- virtual int draw(const int update) override;
- virtual int xy_to_render_target(const int x, const int y, int *xt, int *yt) override;
- virtual render_primitive_list *get_primitives() override;
-
-private:
- void show_info(struct SDL_RendererInfo *render_info);
-
- void destroy_all_textures();
- void yuv_init();
- void setup_texture(const osd_dim &size);
- void yuv_lookup_set(unsigned int pen, unsigned char red,
- unsigned char green, unsigned char blue);
-
- int32_t m_blittimer;
-
- SDL_Renderer *m_sdl_renderer;
- SDL_Texture *m_texture_id;
-
- // YUV overlay
- std::unique_ptr<uint32_t []> m_yuv_lookup;
- std::unique_ptr<uint16_t []> m_yuv_bitmap;
-
- // if we leave scaling to SDL and the underlying driver, this
- // is the render_target_width/height to use
-
- int m_last_hofs;
- int m_last_vofs;
- osd_dim m_blit_dim;
- osd_dim m_last_dim;
-};
-
-struct sdl_scale_mode
-{
- const char *name;
- int is_scale; /* Scale mode? */
- int is_yuv; /* Yuv mode? */
- int mult_w; /* Width multiplier */
- int mult_h; /* Height multiplier */
- const char *sdl_scale_mode_hint; /* what to use as a hint ? */
- int pixel_format; /* Pixel/Overlay format */
- void (*yuv_blit)(const uint16_t *bitmap, uint8_t *ptr, const int pitch, const uint32_t *lookup, const int width, const int height);
-};
-
-#endif // MAME_OSD_MODULES_RENDER_DRAWSDL_H
diff --git a/src/osd/modules/render/render_module.h b/src/osd/modules/render/render_module.h
new file mode 100644
index 00000000000..b22f35fdb3c
--- /dev/null
+++ b/src/osd/modules/render/render_module.h
@@ -0,0 +1,38 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+#ifndef MAME_OSD_MODULES_RENDER_RENDER_MODULE_H
+#define MAME_OSD_MODULES_RENDER_RENDER_MODULE_H
+
+#pragma once
+
+#include "osdepend.h"
+#include "modules/osdmodule.h"
+
+#include <memory>
+
+
+#define OSD_RENDERER_PROVIDER "video"
+
+
+class osd_renderer;
+class osd_window;
+
+
+class render_module
+{
+public:
+ virtual ~render_module() = default;
+
+ virtual std::unique_ptr<osd_renderer> create(osd_window &window) = 0;
+
+ bool is_interactive() const { return flags() & FLAG_INTERACTIVE; }
+ bool sdl_needs_opengl() const { return flags() & FLAG_SDL_NEEDS_OPENGL; }
+
+protected:
+ static inline constexpr unsigned FLAG_INTERACTIVE = 1;
+ static inline constexpr unsigned FLAG_SDL_NEEDS_OPENGL = 2;
+
+ virtual unsigned flags() const = 0;
+};
+
+#endif // MAME_OSD_MODULES_RENDER_RENDER_MODULE_H
diff --git a/src/osd/modules/sound/coreaudio_sound.cpp b/src/osd/modules/sound/coreaudio_sound.cpp
index 53e2a30d521..408fe9e3991 100644
--- a/src/osd/modules/sound/coreaudio_sound.cpp
+++ b/src/osd/modules/sound/coreaudio_sound.cpp
@@ -8,10 +8,11 @@
#include "sound_module.h"
#include "modules/osdmodule.h"
-#include "modules/lib/osdobj_common.h"
#ifdef SDLMAME_MACOSX
+#include "modules/lib/osdobj_common.h"
+
#include <AvailabilityMacros.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioUnit/AudioUnit.h>
@@ -36,6 +37,8 @@ public:
sound_module(),
m_graph(nullptr),
m_node_count(0),
+ m_sample_rate(0),
+ m_audio_latency(0),
m_sample_bytes(0),
m_headroom(0),
m_buffer_size(0),
@@ -166,14 +169,16 @@ private:
unsigned m_node_count;
node_detail m_node_details[EFFECT_COUNT_MAX + 2];
- uint32_t m_sample_bytes;
- uint32_t m_headroom;
- uint32_t m_buffer_size;
+ int m_sample_rate;
+ int m_audio_latency;
+ uint32_t m_sample_bytes;
+ uint32_t m_headroom;
+ uint32_t m_buffer_size;
std::unique_ptr<int8_t []> m_buffer;
- uint32_t m_playpos;
- uint32_t m_writepos;
+ uint32_t m_playpos;
+ uint32_t m_writepos;
bool m_in_underrun;
- int32_t m_scale;
+ int32_t m_scale;
unsigned m_overflows;
unsigned m_underflows;
};
@@ -184,7 +189,9 @@ int sound_coreaudio::init(osd_interface &osd, const osd_options &options)
OSStatus err;
// Don't bother with any of this if sound is disabled
- if (sample_rate() == 0)
+ m_sample_rate = options.sample_rate();
+ m_audio_latency = options.audio_latency();
+ if (m_sample_rate == 0)
return 0;
// Create the output graph
@@ -194,7 +201,7 @@ int sound_coreaudio::init(osd_interface &osd, const osd_options &options)
// Set audio stream format for two-channel native-endian 16-bit packed linear PCM
AudioStreamBasicDescription format;
- format.mSampleRate = sample_rate();
+ format.mSampleRate = m_sample_rate;
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kAudioFormatFlagsNativeEndian
| kLinearPCMFormatFlagIsSignedInteger
@@ -219,8 +226,8 @@ int sound_coreaudio::init(osd_interface &osd, const osd_options &options)
m_sample_bytes = format.mBytesPerFrame;
// Allocate buffer
- m_headroom = m_sample_bytes * (clamped_latency() * sample_rate() / 40);
- m_buffer_size = m_sample_bytes * std::max<uint32_t>(sample_rate() * (clamped_latency() + 3) / 40, 256U);
+ m_headroom = m_sample_bytes * (clamped_latency() * m_sample_rate / 40);
+ m_buffer_size = m_sample_bytes * std::max<uint32_t>(m_sample_rate * (clamped_latency() + 3) / 40, 256U);
try
{
m_buffer = std::make_unique<int8_t []>(m_buffer_size);
@@ -285,7 +292,7 @@ void sound_coreaudio::exit()
void sound_coreaudio::update_audio_stream(bool is_throttled, int16_t const *buffer, int samples_this_frame)
{
- if ((sample_rate() == 0) || !m_buffer)
+ if ((m_sample_rate == 0) || !m_buffer)
return;
uint32_t const bytes_this_frame = samples_this_frame * m_sample_bytes;
@@ -1010,10 +1017,10 @@ OSStatus sound_coreaudio::render_callback(
} // namespace osd
-#else /* SDLMAME_MACOSX */
+#else // SDLMAME_MACOSX
namespace osd { namespace { MODULE_NOT_SUPPORTED(sound_coreaudio, OSD_SOUND_PROVIDER, "coreaudio") } }
-#endif
+#endif // SDLMAME_MACOSX
MODULE_DEFINITION(SOUND_COREAUDIO, osd::sound_coreaudio)
diff --git a/src/osd/modules/sound/direct_sound.cpp b/src/osd/modules/sound/direct_sound.cpp
index dd598af94d1..f214215f1d9 100644
--- a/src/osd/modules/sound/direct_sound.cpp
+++ b/src/osd/modules/sound/direct_sound.cpp
@@ -15,11 +15,11 @@
#include "emuopts.h"
// osd headers
+#include "modules/lib/osdobj_common.h"
#include "osdepend.h"
#include "osdcore.h"
#ifdef SDLMAME_WIN32
-#include "modules/lib/osdobj_common.h"
#include "sdl/window.h"
#include <SDL2/SDL_syswm.h>
#else
@@ -207,10 +207,11 @@ private:
class sound_direct_sound : public osd_module, public sound_module
{
public:
-
sound_direct_sound() :
osd_module(OSD_SOUND_PROVIDER, "dsound"),
sound_module(),
+ m_sample_rate(0),
+ m_audio_latency(0),
m_bytes_per_sample(0),
m_primary_buffer(),
m_stream_buffer(),
@@ -219,7 +220,6 @@ public:
m_buffer_overflows(0)
{
}
- virtual ~sound_direct_sound() { }
virtual int init(osd_interface &osd, osd_options const &options) override;
virtual void exit() override;
@@ -237,6 +237,10 @@ private:
// DirectSound objects
Microsoft::WRL::ComPtr<IDirectSound> m_dsound;
+ // configuration
+ int m_sample_rate;
+ int m_audio_latency;
+
// descriptors and formats
uint32_t m_bytes_per_sample;
@@ -257,10 +261,14 @@ private:
int sound_direct_sound::init(osd_interface &osd, osd_options const &options)
{
- // attempt to initialize DirectSound
- // don't make it fatal if we can't -- we'll just run without sound
- dsound_init();
+ m_sample_rate = options.sample_rate();
+ m_audio_latency = options.audio_latency();
m_buffer_underflows = m_buffer_overflows = 0;
+
+ // attempt to initialize DirectSound
+ if (dsound_init() != DS_OK)
+ return -1;
+
return 0;
}
@@ -407,10 +415,14 @@ HRESULT sound_direct_sound::dsound_init()
#ifdef SDLMAME_WIN32
SDL_SysWMinfo wminfo;
SDL_VERSION(&wminfo.version);
- SDL_GetWindowWMInfo(std::dynamic_pointer_cast<sdl_window_info>(osd_common_t::s_window_list.front())->platform_window(), &wminfo);
+ if (!SDL_GetWindowWMInfo(dynamic_cast<sdl_window_info &>(*osd_common_t::window_list().front()).platform_window(), &wminfo))
+ {
+ result = DSERR_UNSUPPORTED; // just so it has something to return
+ goto error;
+ }
HWND const window = wminfo.info.win.window;
#else // SDLMAME_WIN32
- HWND const window = std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window();
+ HWND const window = dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window();
#endif // SDLMAME_WIN32
result = m_dsound->SetCooperativeLevel(window, DSSCL_PRIORITY);
}
@@ -426,7 +438,7 @@ HRESULT sound_direct_sound::dsound_init()
stream_format.wBitsPerSample = 16;
stream_format.wFormatTag = WAVE_FORMAT_PCM;
stream_format.nChannels = 2;
- stream_format.nSamplesPerSec = sample_rate();
+ stream_format.nSamplesPerSec = m_sample_rate;
stream_format.nBlockAlign = stream_format.wBitsPerSample * stream_format.nChannels / 8;
stream_format.nAvgBytesPerSec = stream_format.nSamplesPerSec * stream_format.nBlockAlign;
@@ -567,4 +579,5 @@ namespace osd { namespace { MODULE_NOT_SUPPORTED(sound_direct_sound, OSD_SOUND_P
#endif // defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
+
MODULE_DEFINITION(SOUND_DSOUND, osd::sound_direct_sound)
diff --git a/src/osd/modules/sound/js_sound.cpp b/src/osd/modules/sound/js_sound.cpp
index e3f61296537..7375d014141 100644
--- a/src/osd/modules/sound/js_sound.cpp
+++ b/src/osd/modules/sound/js_sound.cpp
@@ -11,7 +11,7 @@
#include "sound_module.h"
#include "modules/osdmodule.h"
-#if (defined(SDLMAME_EMSCRIPTEN))
+#if defined(SDLMAME_EMSCRIPTEN)
#include "emscripten.h"
@@ -19,8 +19,7 @@ class sound_js : public osd_module, public sound_module
{
public:
- sound_js()
- : osd_module(OSD_SOUND_PROVIDER, "js"), sound_module()
+ sound_js() : osd_module(OSD_SOUND_PROVIDER, "js"), sound_module()
{
}
virtual ~sound_js() { }
@@ -32,23 +31,28 @@ public:
virtual void update_audio_stream(bool is_throttled, const int16_t *buffer, int samples_this_frame)
{
- EM_ASM_ARGS({
- // Forward audio stream update on to JS backend implementation.
- jsmame_update_audio_stream($0, $1);
- }, (unsigned int)buffer, samples_this_frame);
+ EM_ASM_ARGS(
+ {
+ // Forward audio stream update on to JS backend implementation.
+ jsmame_update_audio_stream($0, $1);
+ },
+ (unsigned int)buffer,
+ samples_this_frame);
}
+
virtual void set_mastervolume(int attenuation)
{
- EM_ASM_ARGS({
- // Forward volume update on to JS backend implementation.
- jsmame_set_mastervolume($0);
- }, attenuation);
+ EM_ASM_ARGS(
+ {
+ // Forward volume update on to JS backend implementation.
+ jsmame_set_mastervolume($0);
+ },
+ attenuation);
}
-
};
-#else /* SDLMAME_EMSCRIPTEN */
+#else // SDLMAME_EMSCRIPTEN
MODULE_NOT_SUPPORTED(sound_js, OSD_SOUND_PROVIDER, "js")
-#endif
+#endif // SDLMAME_EMSCRIPTEN
MODULE_DEFINITION(SOUND_JS, sound_js)
diff --git a/src/osd/modules/sound/pa_sound.cpp b/src/osd/modules/sound/pa_sound.cpp
index 8d2b71a03c2..d5bb96a25af 100644
--- a/src/osd/modules/sound/pa_sound.cpp
+++ b/src/osd/modules/sound/pa_sound.cpp
@@ -157,6 +157,8 @@ private:
PaStream* m_pa_stream;
PaError err;
+ int m_sample_rate;
+ int m_audio_latency;
int m_attenuation;
audio_buffer<s16>* m_ab;
@@ -179,6 +181,10 @@ private:
int sound_pa::init(osd_interface &osd, osd_options const &options)
{
+ m_sample_rate = options.sample_rate();
+ if (!m_sample_rate)
+ return 0;
+
PaStreamParameters stream_params;
const PaStreamInfo* stream_info;
const PaHostApiInfo* api_info;
@@ -187,9 +193,6 @@ int sound_pa::init(osd_interface &osd, osd_options const &options)
unsigned long frames_per_callback = paFramesPerBufferUnspecified;
double callback_interval;
- if (!sample_rate())
- return 0;
-
m_attenuation = options.volume();
m_underflows = 0;
m_overflows = 0;
@@ -199,7 +202,7 @@ int sound_pa::init(osd_interface &osd, osd_options const &options)
m_skip_threshold_ticks = 0;
m_osd_tps = osd_ticks_per_second();
m_buffer_min_ct = INT_MAX;
- m_audio_latency = std::clamp<int>(m_audio_latency, LATENCY_MIN, LATENCY_MAX);
+ m_audio_latency = std::clamp<int>(options.audio_latency(), LATENCY_MIN, LATENCY_MAX);
try {
m_ab = new audio_buffer<s16>(m_sample_rate, 2);
@@ -371,7 +374,7 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples)
int adjust = m_buffer_min_ct - m_skip_threshold / 2;
// if adjustment is less than two milliseconds, don't bother
- if (adjust / 2 > sample_rate() / 500) {
+ if (adjust / 2 > m_sample_rate / 500) {
m_ab->increment_playpos(adjust);
m_has_overflowed = true;
}
@@ -398,7 +401,7 @@ int sound_pa::callback(s16* output_buffer, size_t number_of_samples)
void sound_pa::update_audio_stream(bool is_throttled, const s16 *buffer, int samples_this_frame)
{
- if (!sample_rate())
+ if (!m_sample_rate)
return;
#if LOG_BUFCNT
@@ -433,7 +436,7 @@ void sound_pa::set_mastervolume(int attenuation)
void sound_pa::exit()
{
- if (!sample_rate())
+ if (!m_sample_rate)
return;
#if LOG_BUFCNT
diff --git a/src/osd/modules/sound/pulse_sound.cpp b/src/osd/modules/sound/pulse_sound.cpp
index ced2cd66a59..a0b316bee84 100644
--- a/src/osd/modules/sound/pulse_sound.cpp
+++ b/src/osd/modules/sound/pulse_sound.cpp
@@ -296,24 +296,26 @@ int sound_pulse::init(osd_interface &osd, osd_options const &options)
if(res != 'r')
return 1;
+ const int sample_rate = options.sample_rate();
+
pa_sample_spec ss;
#ifdef LSB_FIRST
ss.format = PA_SAMPLE_S16LE;
#else
ss.format = PA_SAMPLE_S16BE;
#endif
- ss.rate = sample_rate();
+ ss.rate = sample_rate;
ss.channels = 2;
m_stream = pa_stream_new(m_context, "main output", &ss, nullptr);
pa_stream_set_state_callback(m_stream, i_stream_notify, this);
pa_stream_set_write_callback(m_stream, i_stream_write_request, this);
pa_buffer_attr battr;
- battr.fragsize = sample_rate() / 1000;
+ battr.fragsize = sample_rate / 1000;
battr.maxlength = uint32_t(-1);
- battr.minreq = sample_rate() / 1000;
+ battr.minreq = sample_rate / 1000;
battr.prebuf = uint32_t(-1);
- battr.tlength = sample_rate() / 1000;
+ battr.tlength = sample_rate / 1000;
err = pa_stream_connect_playback(m_stream, nullptr, &battr, PA_STREAM_ADJUST_LATENCY, nullptr, nullptr);
if(err)
diff --git a/src/osd/modules/sound/sdl_sound.cpp b/src/osd/modules/sound/sdl_sound.cpp
index cae544fa016..ba7082312ea 100644
--- a/src/osd/modules/sound/sdl_sound.cpp
+++ b/src/osd/modules/sound/sdl_sound.cpp
@@ -14,6 +14,7 @@
#if (defined(OSD_SDL) || defined(USE_SDL_SOUND))
+#include "modules/lib/osdobj_common.h"
#include "osdcore.h"
// standard sdl header
@@ -50,10 +51,16 @@ public:
sound_sdl() :
osd_module(OSD_SOUND_PROVIDER, "sdl"), sound_module(),
+ sample_rate(0),
+ sdl_xfer_samples(SDL_XFER_SAMPLES),
stream_in_initialized(0),
- attenuation(0), buf_locked(0), stream_buffer(nullptr), stream_buffer_size(0), buffer_underflows(0), buffer_overflows(0)
+ attenuation(0),
+ buf_locked(0),
+ stream_buffer(nullptr),
+ stream_buffer_size(0),
+ buffer_underflows(0),
+ buffer_overflows(0)
{
- sdl_xfer_samples = SDL_XFER_SAMPLES;
}
virtual ~sound_sdl() { }
@@ -91,6 +98,7 @@ private:
int sdl_create_buffers();
void sdl_destroy_buffers();
+ int sample_rate;
int sdl_xfer_samples;
int stream_in_initialized;
int attenuation;
@@ -244,10 +252,9 @@ void sound_sdl::copy_sample_data(bool is_throttled, const int16_t *data, int byt
void sound_sdl::update_audio_stream(bool is_throttled, const int16_t *buffer, int samples_this_frame)
{
// if nothing to do, don't do it
- if (sample_rate() == 0 || !stream_buffer)
+ if (sample_rate == 0 || !stream_buffer)
return;
-
if (!stream_in_initialized)
{
// Fill in some zeros to prevent an initial buffer underflow
@@ -345,7 +352,8 @@ int sound_sdl::init(osd_interface &osd, const osd_options &options)
sound_log = std::make_unique<std::ofstream>(SDLMAME_SOUND_LOG);
// skip if sound disabled
- if (sample_rate() != 0)
+ sample_rate = options.sample_rate();
+ if (sample_rate != 0)
{
if (SDL_InitSubSystem(SDL_INIT_AUDIO))
{
@@ -361,7 +369,7 @@ int sound_sdl::init(osd_interface &osd, const osd_options &options)
stream_in_initialized = 0;
// set up the audio specs
- aspec.freq = sample_rate();
+ aspec.freq = sample_rate;
aspec.format = AUDIO_S16SYS; // keep endian independent
aspec.channels = n_channels;
aspec.samples = sdl_xfer_samples;
@@ -377,10 +385,10 @@ int sound_sdl::init(osd_interface &osd, const osd_options &options)
sdl_xfer_samples = obtained.samples;
// pin audio latency
- audio_latency = std::clamp(m_audio_latency, 1, MAX_AUDIO_LATENCY);
+ audio_latency = std::clamp(options.audio_latency(), 1, MAX_AUDIO_LATENCY);
// compute the buffer sizes
- stream_buffer_size = (sample_rate() * 2 * sizeof(int16_t) * (2 + audio_latency)) / 30;
+ stream_buffer_size = (sample_rate * 2 * sizeof(int16_t) * (2 + audio_latency)) / 30;
stream_buffer_size = (stream_buffer_size / 1024) * 1024;
if (stream_buffer_size < 1024)
stream_buffer_size = 1024;
@@ -414,7 +422,7 @@ int sound_sdl::init(osd_interface &osd, const osd_options &options)
void sound_sdl::exit()
{
// if nothing to do, don't do it
- if (sample_rate() == 0)
+ if (sample_rate == 0)
return;
osd_printf_verbose("sdl_kill: closing audio\n");
diff --git a/src/osd/modules/sound/sound_module.h b/src/osd/modules/sound/sound_module.h
index d741c732622..088da5ea8d0 100644
--- a/src/osd/modules/sound/sound_module.h
+++ b/src/osd/modules/sound/sound_module.h
@@ -20,18 +20,10 @@
class sound_module
{
public:
- sound_module() : m_sample_rate(0), m_audio_latency(1) { }
-
virtual ~sound_module() = default;
virtual void update_audio_stream(bool is_throttled, const int16_t *buffer, int samples_this_frame) = 0;
virtual void set_mastervolume(int attenuation) = 0;
-
- int sample_rate() const { return m_sample_rate; }
-
- // FIXME: these should be set by the implementation on initialisation, not by the OSD object
- int m_sample_rate;
- int m_audio_latency;
};
#endif // MAME_OSD_SOUND_SOUND_MODULE_H
diff --git a/src/osd/modules/sound/xaudio2_sound.cpp b/src/osd/modules/sound/xaudio2_sound.cpp
index 97803b58e4e..e2d4b2ab1c3 100644
--- a/src/osd/modules/sound/xaudio2_sound.cpp
+++ b/src/osd/modules/sound/xaudio2_sound.cpp
@@ -10,14 +10,14 @@
#include "modules/osdmodule.h"
-#if defined(OSD_WINDOWS)
-
-// MAME headers
-#include "winutil.h"
+#if defined(OSD_WINDOWS) | defined(SDLMAME_WIN32)
+// OSD headers
#include "modules/lib/osdlib.h"
+#include "modules/lib/osdobj_common.h"
#include "osdcore.h"
#include "osdepend.h"
+#include "windows/winutil.h"
// stdlib includes
#include <algorithm>
@@ -34,8 +34,6 @@
// XAudio2 include
#include <xaudio2.h>
-#undef interface
-
namespace osd {
@@ -186,29 +184,6 @@ public:
// The main class for the XAudio2 sound module implementation
class sound_xaudio2 : public osd_module, public sound_module, public IXAudio2VoiceCallback
{
-private:
- Microsoft::WRL::ComPtr<IXAudio2> m_xAudio2;
- mastering_voice_ptr m_masterVoice;
- src_voice_ptr m_sourceVoice;
- DWORD m_sample_bytes;
- std::unique_ptr<BYTE[]> m_buffer;
- DWORD m_buffer_size;
- DWORD m_buffer_count;
- DWORD m_writepos;
- std::mutex m_buffer_lock;
- HANDLE m_hEventBufferCompleted;
- HANDLE m_hEventDataAvailable;
- HANDLE m_hEventExiting;
- std::thread m_audioThread;
- std::queue<xaudio2_buffer> m_queue;
- std::unique_ptr<bufferpool> m_buffer_pool;
- uint32_t m_overflows;
- uint32_t m_underflows;
- BOOL m_in_underflow;
- BOOL m_initialized;
- OSD_DYNAMIC_API(xaudio2, "XAudio2_9.dll", "XAudio2_8.dll");
- OSD_DYNAMIC_API_FN(xaudio2, HRESULT, WINAPI, XAudio2Create, IXAudio2 **, uint32_t, XAUDIO2_PROCESSOR);
-
public:
sound_xaudio2() :
osd_module(OSD_SOUND_PROVIDER, "xaudio2"),
@@ -216,6 +191,8 @@ public:
m_xAudio2(nullptr),
m_masterVoice(nullptr),
m_sourceVoice(nullptr),
+ m_sample_rate(0),
+ m_audio_latency(0),
m_sample_bytes(0),
m_buffer(nullptr),
m_buffer_size(0),
@@ -232,8 +209,6 @@ public:
{
}
- virtual ~sound_xaudio2() { }
-
bool probe() override;
int init(osd_interface &osd, osd_options const &options) override;
void exit() override;
@@ -242,6 +217,7 @@ public:
void update_audio_stream(bool is_throttled, int16_t const *buffer, int samples_this_frame) override;
void set_mastervolume(int attenuation) override;
+private:
// Xaudio callbacks
void STDAPICALLTYPE OnVoiceProcessingPassStart(uint32_t bytes_required) override;
void STDAPICALLTYPE OnVoiceProcessingPassEnd() override {}
@@ -251,7 +227,6 @@ public:
void STDAPICALLTYPE OnVoiceError(void* pBufferContext, HRESULT error) override {}
void STDAPICALLTYPE OnBufferEnd(void *pBufferContext) override;
-private:
void create_buffers(const WAVEFORMATEX &format);
HRESULT create_voices(const WAVEFORMATEX &format);
void process_audio();
@@ -259,6 +234,31 @@ private:
void submit_needed();
void roll_buffer();
BOOL submit_next_queued();
+
+ Microsoft::WRL::ComPtr<IXAudio2> m_xAudio2;
+ mastering_voice_ptr m_masterVoice;
+ src_voice_ptr m_sourceVoice;
+ int m_sample_rate;
+ int m_audio_latency;
+ DWORD m_sample_bytes;
+ std::unique_ptr<BYTE[]> m_buffer;
+ DWORD m_buffer_size;
+ DWORD m_buffer_count;
+ DWORD m_writepos;
+ std::mutex m_buffer_lock;
+ HANDLE m_hEventBufferCompleted;
+ HANDLE m_hEventDataAvailable;
+ HANDLE m_hEventExiting;
+ std::thread m_audioThread;
+ std::queue<xaudio2_buffer> m_queue;
+ std::unique_ptr<bufferpool> m_buffer_pool;
+ uint32_t m_overflows;
+ uint32_t m_underflows;
+ BOOL m_in_underflow;
+ BOOL m_initialized;
+
+ OSD_DYNAMIC_API(xaudio2, "XAudio2_9.dll", "XAudio2_8.dll");
+ OSD_DYNAMIC_API_FN(xaudio2, HRESULT, WINAPI, XAudio2Create, IXAudio2 **, uint32_t, XAUDIO2_PROCESSOR);
};
//============================================================
@@ -276,12 +276,7 @@ bool sound_xaudio2::probe()
int sound_xaudio2::init(osd_interface &osd, osd_options const &options)
{
- HRESULT result;
- WAVEFORMATEX format = {0};
- auto init_start = std::chrono::system_clock::now();
- std::chrono::milliseconds init_time;
-
- CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+ auto const init_start = std::chrono::system_clock::now();
// Make sure our XAudio2Create entrypoint is bound
if (!OSD_DYNAMIC_API_TEST(XAudio2Create))
@@ -290,6 +285,15 @@ int sound_xaudio2::init(osd_interface &osd, osd_options const &options)
return 1;
}
+ HRESULT result;
+ std::chrono::milliseconds init_time;
+ WAVEFORMATEX format = { 0 };
+
+ m_sample_rate = options.sample_rate();
+ m_audio_latency = options.audio_latency();
+
+ CoInitializeEx(nullptr, COINIT_MULTITHREADED);
+
// Create the IXAudio2 object
HR_GOERR(OSD_DYNAMIC_CALL(XAudio2Create, m_xAudio2.GetAddressOf(), 0, XAUDIO2_DEFAULT_PROCESSOR));
@@ -297,7 +301,7 @@ int sound_xaudio2::init(osd_interface &osd, osd_options const &options)
format.wBitsPerSample = 16;
format.wFormatTag = WAVE_FORMAT_PCM;
format.nChannels = 2;
- format.nSamplesPerSec = sample_rate();
+ format.nSamplesPerSec = m_sample_rate;
format.nBlockAlign = format.wBitsPerSample * format.nChannels / 8;
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
@@ -316,10 +320,10 @@ int sound_xaudio2::init(osd_interface &osd, osd_options const &options)
HR_GOERR(m_sourceVoice->Start());
// Start the thread listening
- m_audioThread = std::thread([](sound_xaudio2* self) { self->process_audio(); }, this);
+ m_audioThread = std::thread([] (sound_xaudio2 *self) { self->process_audio(); }, this);
init_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - init_start);
- osd_printf_verbose("Sound: XAudio2 initialized. %d ms.\n", static_cast<int>(init_time.count()));
+ osd_printf_verbose("Sound: XAudio2 initialized. %d ms.\n", init_time.count());
m_initialized = TRUE;
return 0;
@@ -382,7 +386,7 @@ void sound_xaudio2::update_audio_stream(
int16_t const *buffer,
int samples_this_frame)
{
- if (!m_initialized || sample_rate() == 0 || !m_buffer)
+ if (!m_initialized || m_sample_rate == 0 || !m_buffer)
return;
uint32_t const bytes_this_frame = samples_this_frame * m_sample_bytes;
@@ -533,7 +537,7 @@ HRESULT sound_xaudio2::create_voices(const WAVEFORMATEX &format)
m_xAudio2->CreateMasteringVoice(
&temp_master_voice,
format.nChannels,
- sample_rate()));
+ m_sample_rate));
m_masterVoice = mastering_voice_ptr(temp_master_voice);
diff --git a/src/osd/sdl/osdsdl.cpp b/src/osd/sdl/osdsdl.cpp
index 7af11bf2d04..633abff3a3d 100644
--- a/src/osd/sdl/osdsdl.cpp
+++ b/src/osd/sdl/osdsdl.cpp
@@ -134,23 +134,22 @@ void osd_sdl_info()
}
-std::shared_ptr<sdl_window_info> window_from_id(Uint32 id)
+sdl_window_info *window_from_id(Uint32 id)
{
SDL_Window const *const sdl_window = SDL_GetWindowFromID(id);
- auto &windows = osd_common_t::s_window_list;
auto const window = std::find_if(
- windows.begin(),
- windows.end(),
- [sdl_window] (std::shared_ptr<osd_window> w)
+ osd_common_t::window_list().begin(),
+ osd_common_t::window_list().end(),
+ [sdl_window] (std::unique_ptr<osd_window> const &w)
{
- return std::static_pointer_cast<sdl_window_info>(w)->platform_window() == sdl_window;
+ return dynamic_cast<sdl_window_info &>(*w).platform_window() == sdl_window;
});
- if (window == windows.end())
+ if (window == osd_common_t::window_list().end())
return nullptr;
- return std::static_pointer_cast<sdl_window_info>(*window);
+ return &static_cast<sdl_window_info &>(**window);
}
} // anonymous namespace
@@ -164,7 +163,7 @@ std::shared_ptr<sdl_window_info> window_from_id(Uint32 id)
sdl_osd_interface::sdl_osd_interface(sdl_options &options) :
osd_common_t(options),
m_options(options),
- m_focus_window(),
+ m_focus_window(nullptr),
m_mouse_over_window(0),
m_modifier_keys(0),
m_last_click_time(std::chrono::steady_clock::time_point::min()),
@@ -422,18 +421,6 @@ void sdl_osd_interface::customize_input_type_list(std::vector<input_type_entry>
}
-void sdl_osd_interface::video_register()
-{
- video_options_add("soft", nullptr);
- video_options_add("accel", nullptr);
-#if USE_OPENGL
- video_options_add("opengl", nullptr);
-#endif
- video_options_add("bgfx", nullptr);
- //video_options_add("auto", nullptr); // making d3d video default one
-}
-
-
void sdl_osd_interface::poll_inputs()
{
m_keyboard_input->poll_if_necessary();
@@ -501,21 +488,21 @@ void sdl_osd_interface::process_events()
if (event.key.keysym.sym < 0x20)
{
// push control characters - they don't arrive as text input events
- machine().ui_input().push_char_event(osd_common_t::s_window_list.front()->target(), event.key.keysym.sym);
+ machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), event.key.keysym.sym);
}
else if (m_modifier_keys & MODIFIER_KEY_CTRL)
{
// SDL filters out control characters for text input, so they are decoded here
if (event.key.keysym.sym >= 0x40 && event.key.keysym.sym < 0x7f)
{
- machine().ui_input().push_char_event(osd_common_t::s_window_list.front()->target(), event.key.keysym.sym & 0x1f);
+ machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), event.key.keysym.sym & 0x1f);
}
else if (m_modifier_keys & MODIFIER_KEY_SHIFT)
{
if (event.key.keysym.sym == SDLK_6) // Ctrl-^ (RS)
- machine().ui_input().push_char_event(osd_common_t::s_window_list.front()->target(), 0x1e);
+ machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), 0x1e);
else if (event.key.keysym.sym == SDLK_MINUS) // Ctrl-_ (US)
- machine().ui_input().push_char_event(osd_common_t::s_window_list.front()->target(), 0x1f);
+ machine().ui_input().push_char_event(osd_common_t::window_list().front()->target(), 0x1f);
}
}
break;
@@ -688,7 +675,7 @@ void sdl_osd_interface::process_textinput_event(SDL_Event const &event)
if (*event.text.text)
{
auto const window = focus_window(event.text);
- //printf("Focus window is %p - wl %p\n", window, osd_common_t::s_window_list);
+ //printf("Focus window is %p - wl %p\n", window, osd_common_t::window_list().front().get());
if (window != nullptr)
{
auto ptr = event.text.text;
@@ -716,11 +703,11 @@ void sdl_osd_interface::check_osd_inputs()
// check for toggling fullscreen mode
if (machine().ui_input().pressed(IPT_OSD_1))
{
- for (auto curwin : osd_common_t::s_window_list)
- std::static_pointer_cast<sdl_window_info>(curwin)->toggle_full_screen();
+ for (auto const &curwin : osd_common_t::window_list())
+ dynamic_cast<sdl_window_info &>(*curwin).toggle_full_screen();
}
- auto window = osd_common_t::s_window_list.front();
+ auto const &window = osd_common_t::window_list().front();
if (USE_OPENGL)
{
@@ -733,10 +720,10 @@ void sdl_osd_interface::check_osd_inputs()
}
if (machine().ui_input().pressed(IPT_OSD_6))
- std::static_pointer_cast<sdl_window_info>(window)->modify_prescale(-1);
+ dynamic_cast<sdl_window_info &>(*window).modify_prescale(-1);
if (machine().ui_input().pressed(IPT_OSD_7))
- std::static_pointer_cast<sdl_window_info>(window)->modify_prescale(1);
+ dynamic_cast<sdl_window_info &>(*window).modify_prescale(1);
if (machine().ui_input().pressed(IPT_OSD_8))
window->renderer().record();
@@ -748,7 +735,7 @@ sdl_window_info *sdl_osd_interface::focus_window(T const &event) const
{
// FIXME: SDL does not properly report the window for certain OS.
if (false)
- return window_from_id(event.windowID).get();
+ return window_from_id(event.windowID);
else
- return m_focus_window.get();
+ return m_focus_window;
}
diff --git a/src/osd/sdl/osdsdl.h b/src/osd/sdl/osdsdl.h
index 61b4d3faf03..80499f96236 100644
--- a/src/osd/sdl/osdsdl.h
+++ b/src/osd/sdl/osdsdl.h
@@ -150,8 +150,6 @@ public:
// input overridables
virtual void customize_input_type_list(std::vector<input_type_entry> &typelist) override;
- virtual void video_register() override;
-
virtual bool video_init() override;
virtual bool window_init() override;
@@ -199,7 +197,7 @@ private:
template <typename T> sdl_window_info *focus_window(T const &event) const;
sdl_options &m_options;
- std::shared_ptr<sdl_window_info> m_focus_window;
+ sdl_window_info *m_focus_window;
int m_mouse_over_window;
uint8_t m_modifier_keys;
diff --git a/src/osd/sdl/video.cpp b/src/osd/sdl/video.cpp
index fb0384e3f81..7c549b16dc5 100644
--- a/src/osd/sdl/video.cpp
+++ b/src/osd/sdl/video.cpp
@@ -14,6 +14,7 @@
#include "osdsdl.h"
#include "modules/lib/osdlib.h"
#include "modules/monitor/monitor_module.h"
+#include "modules/render/render_module.h"
// MAME headers
#include "emu.h"
@@ -65,12 +66,16 @@ bool sdl_osd_interface::video_init()
get_resolution(options().resolution(), options().resolution(index), &conf, true);
// create window ...
- std::shared_ptr<sdl_window_info> win = std::make_shared<sdl_window_info>(machine(), index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf);
-
+ auto win = std::make_unique<sdl_window_info>(machine(), *m_render, index, m_monitor_module->pick_monitor(reinterpret_cast<osd_options &>(options()), index), &conf);
if (win->window_init())
return false;
+
+ s_window_list.emplace_back(std::move(win));
}
+ if (m_render->is_interactive())
+ SDL_RaiseWindow(dynamic_cast<sdl_window_info &>(*osd_common_t::s_window_list.front()).platform_window());
+
return true;
}
@@ -95,7 +100,7 @@ void sdl_osd_interface::update(bool skip_redraw)
if (!skip_redraw)
{
// profiler_mark(PROFILER_BLIT);
- for (auto window : osd_common_t::s_window_list)
+ for (auto const &window : osd_common_t::window_list())
window->update();
// profiler_mark(PROFILER_END);
}
@@ -111,8 +116,6 @@ void sdl_osd_interface::update(bool skip_redraw)
void sdl_osd_interface::extract_video_config()
{
- const char *stemp;
-
video_config.perftest = options().video_fps();
// global options: extract the data
@@ -128,47 +131,6 @@ void sdl_osd_interface::extract_video_config()
if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)
video_config.windowed = true;
- // default to working video please
- video_config.novideo = 0;
-
- // video options: extract the data
- stemp = options().video();
- if (strcmp(stemp, "auto") == 0)
- {
-#if (defined SDLMAME_EMSCRIPTEN)
- stemp = "soft";
-#else
- stemp = "bgfx";
-#endif
- }
- if (strcmp(stemp, SDLOPTVAL_SOFT) == 0)
- video_config.mode = VIDEO_MODE_SOFT;
- else if (strcmp(stemp, OSDOPTVAL_NONE) == 0)
- {
- video_config.mode = VIDEO_MODE_SOFT;
- video_config.novideo = 1;
-
- if (!emulator_info::standalone() && options().seconds_to_run() == 0)
- osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
- }
-#if (USE_OPENGL)
- else if (strcmp(stemp, SDLOPTVAL_OPENGL) == 0)
- video_config.mode = VIDEO_MODE_OPENGL;
-#endif
- else if ((strcmp(stemp, SDLOPTVAL_SDL2ACCEL) == 0))
- {
- video_config.mode = VIDEO_MODE_SDL2ACCEL;
- }
- else if (strcmp(stemp, SDLOPTVAL_BGFX) == 0)
- {
- video_config.mode = VIDEO_MODE_BGFX;
- }
- else
- {
- osd_printf_warning("Invalid video value %s; reverting to software\n", stemp);
- video_config.mode = VIDEO_MODE_SOFT;
- }
-
video_config.switchres = options().switch_res();
video_config.centerh = options().centerh();
video_config.centerv = options().centerv();
@@ -185,64 +147,7 @@ void sdl_osd_interface::extract_video_config()
osd_printf_warning("Invalid prescale option, reverting to '1'\n");
video_config.prescale = 1;
}
- #if (USE_OPENGL)
- // default to working video please
- video_config.forcepow2texture = options().gl_force_pow2_texture();
- video_config.allowtexturerect = !(options().gl_no_texture_rect());
- video_config.vbo = options().gl_vbo();
- video_config.pbo = options().gl_pbo();
- video_config.glsl = options().gl_glsl();
- if ( video_config.glsl )
- {
- int i;
-
- video_config.glsl_filter = options().glsl_filter();
-
- video_config.glsl_shader_mamebm_num=0;
-
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- stemp = options().shader_mame(i);
- if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
- {
- video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1);
- strcpy(video_config.glsl_shader_mamebm[i], stemp);
- video_config.glsl_shader_mamebm_num++;
- } else {
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- }
-
- video_config.glsl_shader_scrn_num=0;
-
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- stemp = options().shader_screen(i);
- if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
- {
- video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1);
- strcpy(video_config.glsl_shader_scrn[i], stemp);
- video_config.glsl_shader_scrn_num++;
- } else {
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
- } else {
- int i;
- video_config.glsl_filter = 0;
- video_config.glsl_shader_mamebm_num=0;
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- video_config.glsl_shader_scrn_num=0;
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
-
- #endif /* USE_OPENGL */
+
// misc options: sanity check values
// global options: sanity check values
@@ -251,19 +156,6 @@ void sdl_osd_interface::extract_video_config()
osd_printf_warning("Invalid numscreens value %d; reverting to 1\n", video_config.numscreens);
video_config.numscreens = 1;
}
- // yuv settings ...
- stemp = options().scale_mode();
- video_config.scale_mode = drawsdl_scale_mode(stemp);
- if (video_config.scale_mode < 0)
- {
- osd_printf_warning("Invalid yuvmode value %s; reverting to none\n", stemp);
- video_config.scale_mode = VIDEO_SCALE_MODE_NONE;
- }
- if ( (video_config.mode != VIDEO_MODE_SOFT) && (video_config.scale_mode != VIDEO_SCALE_MODE_NONE) )
- {
- osd_printf_warning("scalemode is only for -video soft, overriding\n");
- video_config.scale_mode = VIDEO_SCALE_MODE_NONE;
- }
}
diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp
index 08dfb5cddfc..dc7f3f2ad32 100644
--- a/src/osd/sdl/window.cpp
+++ b/src/osd/sdl/window.cpp
@@ -18,13 +18,7 @@
// OSD headers
#include "window.h"
#include "osdsdl.h"
-#include "modules/render/drawbgfx.h"
-#include "modules/render/drawsdl.h"
-#include "modules/render/draw13.h"
#include "modules/monitor/monitor_common.h"
-#if (USE_OPENGL)
-#include "modules/render/drawogl.h"
-#endif
// standard SDL headers
#include <SDL2/SDL.h>
@@ -83,60 +77,10 @@ bool sdl_osd_interface::window_init()
{
osd_printf_verbose("Enter sdlwindow_init\n");
- // initialize the renderer
- const int fallbacks[VIDEO_MODE_COUNT] = {
- -1, // NONE -> no fallback
- -1, // No GDI on Linux
-#if defined(USE_OPENGL) && USE_OPENGL
- VIDEO_MODE_OPENGL, // BGFX -> OpenGL
- -1, // OpenGL -> no fallback
-#else
- VIDEO_MODE_SDL2ACCEL, // BGFX -> SDL2Accel
-#endif
- -1, // SDL2ACCEL -> no fallback
- -1, // No D3D on Linux
- -1, // SOFT -> no fallback
- };
-
- int current_mode = video_config.mode;
- while (current_mode != VIDEO_MODE_NONE)
- {
- bool error = false;
- switch(current_mode)
- {
- case VIDEO_MODE_BGFX:
- error = renderer_bgfx::init(machine());
- break;
-#if defined(USE_OPENGL) && USE_OPENGL
- case VIDEO_MODE_OPENGL:
- renderer_ogl::init(machine());
- break;
-#endif
- case VIDEO_MODE_SDL2ACCEL:
- renderer_sdl2::init(machine());
- break;
- case VIDEO_MODE_SOFT:
- renderer_sdl1::init(machine());
- break;
- default:
- fatalerror("Unknown video mode.");
- break;
- }
- if (error)
- {
- current_mode = fallbacks[current_mode];
- }
- else
- {
- break;
- }
- }
- video_config.mode = current_mode;
-
- /* We may want to set a number of the hints SDL2 provides.
- * The code below will document which hints were set.
- */
- const char * hints[] = { SDL_HINT_FRAMEBUFFER_ACCELERATION,
+ // We may want to set a number of the hints SDL2 provides.
+ // The code below will document which hints were set.
+ char const *const hints[] = {
+ SDL_HINT_FRAMEBUFFER_ACCELERATION,
SDL_HINT_RENDER_DRIVER, SDL_HINT_RENDER_OPENGL_SHADERS,
SDL_HINT_RENDER_SCALE_QUALITY,
SDL_HINT_RENDER_VSYNC,
@@ -158,14 +102,13 @@ bool sdl_osd_interface::window_init()
SDL_HINT_WINRT_PRIVACY_POLICY_URL, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL,
SDL_HINT_WINRT_HANDLE_BACK_BUTTON,
#endif
- nullptr
- };
+ };
osd_printf_verbose("\nHints:\n");
- for (int i = 0; hints[i] != nullptr; i++)
+ for (auto const hintname : hints)
{
- char const *const hint(SDL_GetHint(hints[i]));
- osd_printf_verbose("\t%-40s %s\n", hints[i], hint ? hint : "(NULL)");
+ char const *const hintvalue(SDL_GetHint(hintname));
+ osd_printf_verbose("\t%-40s %s\n", hintname, hintvalue ? hintvalue : "(NULL)");
}
// set up the window list
@@ -176,7 +119,7 @@ bool sdl_osd_interface::window_init()
void sdl_osd_interface::update_slider_list()
{
- for (auto window : osd_common_t::s_window_list)
+ for (auto const &window : osd_common_t::window_list())
{
// check if any window has dirty sliders
if (window->renderer().sliders_dirty())
@@ -191,7 +134,7 @@ void sdl_osd_interface::build_slider_list()
{
m_sliders.clear();
- for (auto window : osd_common_t::s_window_list)
+ for (auto const &window : osd_common_t::window_list())
{
std::vector<ui::menu_item> window_sliders = window->renderer().get_slider_list();
m_sliders.insert(m_sliders.end(), window_sliders.begin(), window_sliders.end());
@@ -208,33 +151,14 @@ void sdl_osd_interface::window_exit()
osd_printf_verbose("Enter sdlwindow_exit\n");
// free all the windows
+ m_focus_window = nullptr;
while (!osd_common_t::s_window_list.empty())
{
- auto window = osd_common_t::s_window_list.front();
-
- // Part of destroy removes the window from the list
+ auto window = std::move(osd_common_t::s_window_list.back());
+ s_window_list.pop_back();
window->destroy();
}
- switch (video_config.mode)
- {
- case VIDEO_MODE_SDL2ACCEL:
- renderer_sdl1::exit();
- break;
- case VIDEO_MODE_SOFT:
- renderer_sdl1::exit();
- break;
- case VIDEO_MODE_BGFX:
- renderer_bgfx::exit();
- break;
-#if (USE_OPENGL)
- case VIDEO_MODE_OPENGL:
- renderer_ogl::exit();
- break;
-#endif
- default:
- break;
- }
osd_printf_verbose("Leave sdlwindow_exit\n");
}
@@ -336,11 +260,8 @@ void sdl_window_info::toggle_full_screen()
}
SDL_DestroyWindow(platform_window());
set_platform_window(nullptr);
-
downcast<sdl_osd_interface &>(machine().osd()).release_keys();
- set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
-
// toggle the window mode
set_fullscreen(!fullscreen());
@@ -368,8 +289,8 @@ void sdl_window_info::modify_prescale(int dir)
}
else
{
- notify_changed();
m_prescale = new_prescale;
+ notify_changed();
}
machine().ui().popup_time(1, "Prescale %d", prescale());
}
@@ -432,8 +353,6 @@ int sdl_window_info::window_init()
create_target();
- set_renderer(osd_renderer::make_for_type(video_config.mode, static_cast<osd_window*>(this)->shared_from_this()));
-
int result = complete_create();
// handle error conditions
@@ -465,8 +384,9 @@ void sdl_window_info::complete_destroy()
SDL_SetWindowFullscreen(platform_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode
}
+ renderer_reset();
SDL_DestroyWindow(platform_window());
- // release all keys ...
+ set_platform_window(nullptr);
downcast<sdl_osd_interface &>(machine().osd()).release_keys();
}
@@ -666,13 +586,15 @@ int sdl_window_info::complete_create()
*
*/
osd_printf_verbose("Enter sdl_info::create\n");
- if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL) && !video_config.novideo)
+ if (renderer_sdl_needs_opengl())
{
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
m_extra_flags = SDL_WINDOW_OPENGL;
}
else
+ {
m_extra_flags = 0;
+ }
// We need to workaround an issue in SDL 2.0.4 for OS X where setting the
// relative mode on the mouse in fullscreen mode makes mouse events stop
@@ -771,7 +693,7 @@ int sdl_window_info::complete_create()
if (sdlwindow == nullptr )
{
- if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL))
+ if (renderer_sdl_needs_opengl())
osd_printf_error("OpenGL not supported on this driver: %s\n", SDL_GetError());
else
osd_printf_error("Window creation failed: %s\n", SDL_GetError());
@@ -779,6 +701,7 @@ int sdl_window_info::complete_create()
}
set_platform_window(sdlwindow);
+ renderer_create();
if (fullscreen() && video_config.switchres)
{
@@ -817,24 +740,6 @@ int sdl_window_info::complete_create()
SDL_SetWindowGrab(platform_window(), SDL_TRUE);
#endif
- // set main window
- if (index() > 0)
- {
- for (auto w : osd_common_t::s_window_list)
- {
- if (w->index() == 0)
- {
- set_main_window(std::dynamic_pointer_cast<osd_window>(w));
- break;
- }
- }
- }
- else
- {
- // We must be the main window
- set_main_window(shared_from_this());
- }
-
// update monitor resolution after mode change to ensure proper pixel aspect
monitor()->refresh();
if (fullscreen() && video_config.switchres)
@@ -1146,10 +1051,11 @@ osd_dim sdl_window_info::get_max_bounds(int constrain)
sdl_window_info::sdl_window_info(
running_machine &a_machine,
+ render_module &renderprovider,
int index,
- std::shared_ptr<osd_monitor_info> a_monitor,
+ const std::shared_ptr<osd_monitor_info> &a_monitor,
const osd_window_config *config)
- : osd_window_t(a_machine, index, std::move(a_monitor), *config)
+ : osd_window_t(a_machine, renderprovider, index, std::move(a_monitor), *config)
, m_startmaximized(0)
// Following three are used by input code to defer resizes
, m_minimum_dim(0, 0)
diff --git a/src/osd/sdl/window.h b/src/osd/sdl/window.h
index f2e2905606f..77477176b51 100644
--- a/src/osd/sdl/window.h
+++ b/src/osd/sdl/window.h
@@ -37,7 +37,11 @@ typedef uintptr_t HashT;
class sdl_window_info : public osd_window_t<SDL_Window*>
{
public:
- sdl_window_info(running_machine &a_machine, int index, std::shared_ptr<osd_monitor_info> a_monitor,
+ sdl_window_info(
+ running_machine &a_machine,
+ render_module &renderprovider,
+ int index,
+ const std::shared_ptr<osd_monitor_info> &a_monitor,
const osd_window_config *config);
~sdl_window_info();
@@ -98,37 +102,4 @@ private:
};
-struct osd_draw_callbacks
-{
- osd_renderer *(*create)(osd_window *window);
-};
-
-//============================================================
-// PROTOTYPES
-//============================================================
-
-//============================================================
-// PROTOTYPES - drawsdl.c
-//============================================================
-
-int drawsdl_scale_mode(const char *s);
-
-//============================================================
-// PROTOTYPES - drawogl.c
-//============================================================
-
-int drawogl_init(running_machine &machine, osd_draw_callbacks *callbacks);
-
-//============================================================
-// PROTOTYPES - draw13.c
-//============================================================
-
-int drawsdl2_init(running_machine &machine, osd_draw_callbacks *callbacks);
-
-//============================================================
-// PROTOTYPES - drawbgfx.c
-//============================================================
-
-int drawbgfx_init(running_machine &machine, osd_draw_callbacks *callbacks);
-
#endif // MAME_OSD_SDL_WINDOW_H
diff --git a/src/osd/windows/video.cpp b/src/osd/windows/video.cpp
index e5ed5b99e3d..d40da254ffe 100644
--- a/src/osd/windows/video.cpp
+++ b/src/osd/windows/video.cpp
@@ -6,8 +6,9 @@
//
//============================================================
-#include "modules/monitor/monitor_module.h"
#include "modules/osdwindow.h"
+#include "modules/monitor/monitor_module.h"
+#include "modules/render/render_module.h"
// MAME headers
#include "emu.h"
@@ -62,11 +63,17 @@ bool windows_osd_interface::video_init()
auto &options = downcast<windows_options &>(machine().options());
for (int index = 0; index < video_config.numscreens; index++)
{
- win_window_info::create(machine(), index, m_monitor_module->pick_monitor(options, index), &windows[index]);
+ auto window = win_window_info::create(
+ machine(),
+ *m_render,
+ index,
+ m_monitor_module->pick_monitor(options, index),
+ &windows[index]);
+ s_window_list.emplace_back(std::move(window));
}
- if (video_config.mode != VIDEO_MODE_NONE)
- SetForegroundWindow(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window());
+ if (m_render->is_interactive())
+ SetForegroundWindow(dynamic_cast<win_window_info &>(*osd_common_t::s_window_list.front()).platform_window());
return true;
}
@@ -146,8 +153,6 @@ void windows_osd_interface::check_osd_inputs()
void windows_osd_interface::extract_video_config()
{
- const char *stemp;
-
// global options: extract the data
video_config.windowed = options().window();
video_config.prescale = options().prescale();
@@ -165,31 +170,6 @@ void windows_osd_interface::extract_video_config()
get_resolution(default_resolution, options().resolution(2), &windows[2], TRUE);
get_resolution(default_resolution, options().resolution(3), &windows[3], TRUE);
- // video options: extract the data
- stemp = options().video();
- if (strcmp(stemp, "d3d") == 0)
- video_config.mode = VIDEO_MODE_D3D;
- else if (strcmp(stemp, "auto") == 0)
- video_config.mode = VIDEO_MODE_D3D;
- else if (strcmp(stemp, "gdi") == 0)
- video_config.mode = VIDEO_MODE_GDI;
- else if (strcmp(stemp, "bgfx") == 0)
- video_config.mode = VIDEO_MODE_BGFX;
- else if (strcmp(stemp, "none") == 0)
- {
- video_config.mode = VIDEO_MODE_NONE;
- if (!emulator_info::standalone() && options().seconds_to_run() == 0)
- osd_printf_warning("Warning: -video none doesn't make much sense without -seconds_to_run\n");
- }
-#if (USE_OPENGL)
- else if (strcmp(stemp, "opengl") == 0)
- video_config.mode = VIDEO_MODE_OPENGL;
-#endif
- else
- {
- osd_printf_warning("Invalid video value %s; reverting to gdi\n", stemp);
- video_config.mode = VIDEO_MODE_GDI;
- }
video_config.waitvsync = options().wait_vsync();
video_config.syncrefresh = options().sync_refresh();
video_config.triplebuf = options().triple_buffer();
@@ -200,65 +180,6 @@ void windows_osd_interface::extract_video_config()
osd_printf_warning("Invalid prescale option, reverting to '1'\n");
video_config.prescale = 1;
}
- #if (USE_OPENGL)
- // default to working video please
- video_config.forcepow2texture = options().gl_force_pow2_texture();
- video_config.allowtexturerect = !(options().gl_no_texture_rect());
- video_config.vbo = options().gl_vbo();
- video_config.pbo = options().gl_pbo();
- video_config.glsl = options().gl_glsl();
- if ( video_config.glsl )
- {
- int i;
-
- video_config.glsl_filter = options().glsl_filter();
-
- video_config.glsl_shader_mamebm_num=0;
-
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- stemp = options().shader_mame(i);
- if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
- {
- video_config.glsl_shader_mamebm[i] = (char *) malloc(strlen(stemp)+1);
- strcpy(video_config.glsl_shader_mamebm[i], stemp);
- video_config.glsl_shader_mamebm_num++;
- } else {
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- }
-
- video_config.glsl_shader_scrn_num=0;
-
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- stemp = options().shader_screen(i);
- if (stemp && strcmp(stemp, OSDOPTVAL_NONE) != 0 && strlen(stemp)>0)
- {
- video_config.glsl_shader_scrn[i] = (char *) malloc(strlen(stemp)+1);
- strcpy(video_config.glsl_shader_scrn[i], stemp);
- video_config.glsl_shader_scrn_num++;
- } else {
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
- } else {
- int i;
- video_config.glsl_filter = 0;
- video_config.glsl_shader_mamebm_num=0;
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- video_config.glsl_shader_mamebm[i] = nullptr;
- }
- video_config.glsl_shader_scrn_num=0;
- for(i=0; i<GLSL_SHADER_MAX; i++)
- {
- video_config.glsl_shader_scrn[i] = nullptr;
- }
- }
-
- #endif /* USE_OPENGL */
-
}
diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp
index b0ab9f2eef0..a8a5b222c37 100644
--- a/src/osd/windows/window.cpp
+++ b/src/osd/windows/window.cpp
@@ -31,14 +31,6 @@
#include "modules/monitor/monitor_common.h"
-#include "modules/render/drawbgfx.h"
-#include "modules/render/drawnone.h"
-#include "modules/render/drawd3d.h"
-#include "modules/render/drawgdi.h"
-#if (USE_OPENGL)
-#include "modules/render/drawogl.h"
-#endif
-
#define NOT_ALREADY_DOWN(x) (x & 0x40000000) == 0
#define SCAN_CODE(x) ((x >> 16) & 0xff)
#define IS_EXTENDED(x) (0x01000000 & x)
@@ -128,73 +120,12 @@ bool windows_osd_interface::window_init()
window_thread = GetCurrentThread();
window_threadid = main_threadid;
- // initialize the renderer
- const int fallbacks[VIDEO_MODE_COUNT] = {
- -1, // NONE -> no fallback
- VIDEO_MODE_NONE, // GDI -> NONE
- VIDEO_MODE_D3D, // BGFX -> D3D
-#if (USE_OPENGL)
- -1, // OPENGL -> no fallback
-#endif
- -1, // No SDL2ACCEL on Windows OSD
-#if (USE_OPENGL)
- VIDEO_MODE_OPENGL, // D3D -> OPENGL
-#else
- VIDEO_MODE_GDI, // D3D -> GDI
-#endif
- -1 // No SOFT on Windows OSD
- };
-
- int current_mode = video_config.mode;
- while (current_mode != VIDEO_MODE_NONE)
- {
- bool error = false;
- switch(current_mode)
- {
- case VIDEO_MODE_NONE:
- error = renderer_none::init(machine());
- break;
- case VIDEO_MODE_GDI:
- error = renderer_gdi::init(machine());
- break;
- case VIDEO_MODE_BGFX:
- error = renderer_bgfx::init(machine());
- break;
-#if (USE_OPENGL)
- case VIDEO_MODE_OPENGL:
- renderer_ogl::init(machine());
- break;
-#endif
- case VIDEO_MODE_SDL2ACCEL:
- fatalerror("SDL2-Accel renderer unavailable on Windows OSD.");
- break;
- case VIDEO_MODE_D3D:
- error = renderer_d3d9::init(machine());
- break;
- case VIDEO_MODE_SOFT:
- fatalerror("SDL1 renderer unavailable on Windows OSD.");
- break;
- default:
- fatalerror("Unknown video mode.");
- break;
- }
- if (error)
- {
- current_mode = fallbacks[current_mode];
- }
- else
- {
- break;
- }
- }
- video_config.mode = current_mode;
-
return true;
}
void windows_osd_interface::update_slider_list()
{
- for (const auto &window : osd_common_t::s_window_list)
+ for (const auto &window : osd_common_t::window_list())
{
// check if any window has dirty sliders
if (window->has_renderer() && window->renderer().sliders_dirty())
@@ -207,14 +138,14 @@ void windows_osd_interface::update_slider_list()
int windows_osd_interface::window_count()
{
- return osd_common_t::s_window_list.size();
+ return osd_common_t::window_list().size();
}
void windows_osd_interface::build_slider_list()
{
m_sliders.clear();
- for (const auto &window : osd_common_t::s_window_list)
+ for (const auto &window : osd_common_t::window_list())
{
if (window->has_renderer())
{
@@ -227,11 +158,9 @@ void windows_osd_interface::build_slider_list()
void windows_osd_interface::add_audio_to_recording(const int16_t *buffer, int samples_this_frame)
{
- auto window = osd_common_t::s_window_list.front(); // We only record on the first window
- if (window != nullptr)
- {
+ auto const &window = osd_common_t::window_list().front(); // We only record on the first window
+ if (window)
window->renderer().add_audio_to_recording(buffer, samples_this_frame);
- }
}
//============================================================
@@ -250,35 +179,11 @@ void windows_osd_interface::window_exit()
// free all the windows
while (!osd_common_t::s_window_list.empty())
{
- auto window = osd_common_t::s_window_list.front();
-
- // Destroy removes it from the list also
+ auto window = std::move(osd_common_t::s_window_list.back());
+ s_window_list.pop_back();
window->destroy();
}
- switch(video_config.mode)
- {
- case VIDEO_MODE_NONE:
- renderer_none::exit();
- break;
- case VIDEO_MODE_GDI:
- renderer_gdi::exit();
- break;
- case VIDEO_MODE_BGFX:
- renderer_bgfx::exit();
- break;
-#if (USE_OPENGL)
- case VIDEO_MODE_OPENGL:
- renderer_ogl::exit();
- break;
-#endif
- case VIDEO_MODE_D3D:
- renderer_d3d9::exit();
- break;
- default:
- break;
- }
-
// kill the UI pause event
if (ui_pause_event)
CloseHandle(ui_pause_event);
@@ -287,10 +192,11 @@ void windows_osd_interface::window_exit()
win_window_info::win_window_info(
running_machine &machine,
+ render_module &renderprovider,
int index,
- std::shared_ptr<osd_monitor_info> monitor,
+ const std::shared_ptr<osd_monitor_info> &monitor,
const osd_window_config *config)
- : osd_window_t(machine, index, std::move(monitor), *config)
+ : osd_window_t(machine, renderprovider, index, std::move(monitor), *config)
, m_init_state(0)
, m_startmaximized(0)
, m_isminimized(0)
@@ -306,6 +212,7 @@ win_window_info::win_window_info(
, m_lastclickx(0)
, m_lastclicky(0)
, m_last_surrogate(0)
+ , m_main(nullptr)
, m_attached_mode(false)
{
m_non_fullscreen_bounds.left = 0;
@@ -396,8 +303,8 @@ static LRESULT CALLBACK winwindow_video_window_proc_ui(HWND wnd, UINT message, W
static bool is_mame_window(HWND hwnd)
{
- for (const auto &window : osd_common_t::s_window_list)
- if (std::static_pointer_cast<win_window_info>(window)->platform_window() == hwnd)
+ for (const auto &window : osd_common_t::window_list())
+ if (dynamic_cast<win_window_info &>(*window).platform_window() == hwnd)
return true;
return false;
@@ -560,10 +467,8 @@ void winwindow_take_snap()
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
- for (const auto &window : osd_common_t::s_window_list)
- {
+ for (const auto &window : osd_common_t::window_list())
window->renderer().save();
- }
}
@@ -578,10 +483,8 @@ void winwindow_toggle_fsfx()
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
- for (const auto &window : osd_common_t::s_window_list)
- {
+ for (const auto &window : osd_common_t::window_list())
window->renderer().toggle_fsfx();
- }
}
@@ -596,10 +499,8 @@ void winwindow_take_video()
assert(GetCurrentThreadId() == main_threadid);
// iterate over windows and request a snap
- for (const auto &window : osd_common_t::s_window_list)
- {
+ for (const auto &window : osd_common_t::window_list())
window->renderer().record();
- }
}
@@ -614,19 +515,27 @@ void winwindow_toggle_full_screen()
assert(GetCurrentThreadId() == main_threadid);
// if we are in debug mode, never go full screen
- for (const auto &window : osd_common_t::s_window_list)
+ for (const auto &window : osd_common_t::window_list())
+ {
if (window->machine().debug_flags & DEBUG_FLAG_OSD_ENABLED)
return;
+ }
// toggle the window mode
video_config.windowed = !video_config.windowed;
// iterate over windows and toggle their fullscreen state
- for (const auto &window : osd_common_t::s_window_list)
- SendMessage(std::static_pointer_cast<win_window_info>(window)->platform_window(), WM_USER_SET_FULLSCREEN, !video_config.windowed, 0);
+ for (const auto &window : osd_common_t::window_list())
+ {
+ SendMessage(
+ dynamic_cast<win_window_info &>(*window).platform_window(),
+ WM_USER_SET_FULLSCREEN,
+ !video_config.windowed,
+ 0);
+ }
// Set the first window as foreground
- SetForegroundWindow(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window());
+ SetForegroundWindow(dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window());
}
@@ -639,9 +548,9 @@ void winwindow_toggle_full_screen()
bool winwindow_has_focus()
{
// see if one of the video windows has focus
- for (const auto &window : osd_common_t::s_window_list)
+ for (const auto &window : osd_common_t::window_list())
{
- switch (std::static_pointer_cast<win_window_info>(window)->focus())
+ switch (dynamic_cast<win_window_info &>(*window).focus())
{
case win_window_focus::NONE:
break;
@@ -682,10 +591,10 @@ void winwindow_update_cursor_state(running_machine &machine)
assert(GetCurrentThreadId() == main_threadid);
// If no windows, just return
- if (osd_common_t::s_window_list.empty())
+ if (osd_common_t::window_list().empty())
return;
- auto &window = static_cast<win_window_info &>(*osd_common_t::s_window_list.front());
+ auto &window = static_cast<win_window_info &>(*osd_common_t::window_list().front());
// if we should hide the mouse cursor, then do it
// rules are:
@@ -720,21 +629,26 @@ void winwindow_update_cursor_state(running_machine &machine)
// (main thread)
//============================================================
-void win_window_info::create(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config *config)
+std::unique_ptr<win_window_info> win_window_info::create(
+ running_machine &machine,
+ render_module &renderprovider,
+ int index,
+ const std::shared_ptr<osd_monitor_info> &monitor,
+ const osd_window_config *config)
{
assert(GetCurrentThreadId() == main_threadid);
// allocate a new window object
- auto window = std::make_shared<win_window_info>(machine, index, monitor, config);
+ auto window = std::make_unique<win_window_info>(machine, renderprovider, index, monitor, config);
// set main window
if (window->index() > 0)
{
- for (const auto &w : osd_common_t::s_window_list)
+ for (const auto &w : osd_common_t::window_list())
{
if (w->index() == 0)
{
- window->set_main_window(std::static_pointer_cast<osd_window>(w));
+ window->set_main_window(dynamic_cast<win_window_info &>(*w));
break;
}
}
@@ -742,12 +656,12 @@ void win_window_info::create(running_machine &machine, int index, std::shared_pt
else
{
// We must be the main window
- window->set_main_window(window);
+ window->set_main_window(*window);
}
// see if we are safe for fullscreen
window->m_fullscreen_safe = TRUE;
- for (const auto &win : osd_common_t::s_window_list)
+ for (const auto &win : osd_common_t::window_list())
if (win->monitor() == monitor.get())
window->m_fullscreen_safe = FALSE;
@@ -767,6 +681,8 @@ void win_window_info::create(running_machine &machine, int index, std::shared_pt
// handle error conditions
if (window->m_init_state == -1)
fatalerror("Unable to complete window creation\n");
+
+ return window;
}
//============================================================
@@ -1016,16 +932,16 @@ int win_window_info::complete_create()
{
// create the window, but don't show it yet
hwnd = win_create_window_ex_utf8(
- fullscreen() ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX,
- "MAME",
- title().c_str(),
- fullscreen() ? FULLSCREEN_STYLE : WINDOW_STYLE,
- monitorbounds.left() + 20, monitorbounds.top() + 20,
- monitorbounds.left() + 100, monitorbounds.top() + 100,
- nullptr,//(osd_common_t::s_window_list != nullptr) ? osd_common_t::s_window_list->m_hwnd : nullptr,
- nullptr,
- GetModuleHandleUni(),
- nullptr);
+ fullscreen() ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX,
+ "MAME",
+ title().c_str(),
+ fullscreen() ? FULLSCREEN_STYLE : WINDOW_STYLE,
+ monitorbounds.left() + 20, monitorbounds.top() + 20,
+ monitorbounds.left() + 100, monitorbounds.top() + 100,
+ nullptr,//(osd_common_t::s_window_list != nullptr) ? osd_common_t::s_window_list->m_hwnd : nullptr,
+ nullptr,
+ GetModuleHandleUni(),
+ nullptr);
}
if (hwnd == nullptr)
@@ -1038,9 +954,9 @@ int win_window_info::complete_create()
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
// skip the positioning stuff for '-video none' or '-attach_window'
- if (video_config.mode == VIDEO_MODE_NONE || attached_mode())
+ if (!renderer_interactive() || attached_mode())
{
- set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
+ renderer_create();
if (renderer().create())
return 1;
return 0;
@@ -1064,7 +980,7 @@ int win_window_info::complete_create()
// show the window
if (!fullscreen() || m_fullscreen_safe)
{
- set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
+ renderer_create();
if (renderer().create())
return 1;
@@ -1301,13 +1217,13 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR
{
if ((wparam == WA_ACTIVE) || (wparam == WA_CLICKACTIVE))
{
- for (const auto &w : osd_common_t::s_window_list)
- ShowWindow(std::static_pointer_cast<win_window_info>(w)->platform_window(), SW_RESTORE);
+ for (const auto &w : osd_common_t::window_list())
+ ShowWindow(dynamic_cast<win_window_info &>(*w).platform_window(), SW_RESTORE);
}
else if ((wparam == WA_INACTIVE) && !is_mame_window(HWND(lparam)))
{
- for (const auto &w : osd_common_t::s_window_list)
- ShowWindow(std::static_pointer_cast<win_window_info>(w)->platform_window(), SW_MINIMIZE);
+ for (const auto &w : osd_common_t::window_list())
+ ShowWindow(dynamic_cast<win_window_info &>(*w).platform_window(), SW_MINIMIZE);
}
}
@@ -1809,17 +1725,19 @@ void win_window_info::set_fullscreen(int fullscreen)
// reset UI to main menu
// FIXME: this cause crash if called when running_machine.m_ui not yet initialised. e.g. when trying to show error/warning messagebox at startup (during auto-switch from full screen to windowed mode).
+ // the menus need to be able to survive a fullscreen toggle anyway
machine().ui().menu_reset();
- // kill off the drawers
+ // kill off the renderer
renderer_reset();
// hide ourself
ShowWindow(platform_window(), SW_HIDE);
- // configure the window if non-fullscreen
if (!fullscreen)
{
+ // configure the window if non-fullscreen
+
// adjust the style
SetWindowLong(platform_window(), GWL_STYLE, WINDOW_STYLE);
SetWindowLong(platform_window(), GWL_EXSTYLE, WINDOW_STYLE_EX);
@@ -1844,10 +1762,10 @@ void win_window_info::set_fullscreen(int fullscreen)
maximize_window();
}
}
-
- // configure the window if fullscreen
else
{
+ // configure the window if fullscreen
+
// save the bounds
GetWindowRect(platform_window(), &m_non_fullscreen_bounds);
@@ -1866,12 +1784,12 @@ void win_window_info::set_fullscreen(int fullscreen)
// show ourself
if (!this->fullscreen() || m_fullscreen_safe)
{
- if (video_config.mode != VIDEO_MODE_NONE)
+ if (renderer_interactive())
ShowWindow(platform_window(), SW_SHOW);
- set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this()));
+ renderer_create();
if (renderer().create())
- exit(1);
+ exit(1); // FIXME: better error handling than just silently exiting on failure
}
// ensure we're still adjusted correctly
@@ -1930,7 +1848,7 @@ bool winwindow_qt_filter(void *message)
if(msg->hwnd) // get the machine associated with this window
ptr = GetWindowLongPtr(msg->hwnd, GWLP_USERDATA);
else // any one will have to do
- ptr = (LONG_PTR)osd_common_t::s_window_list.front().get();
+ ptr = (LONG_PTR)osd_common_t::window_list().front().get();
winwindow_dispatch_message(((win_window_info *)ptr)->machine(), msg);
return true;
diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h
index 3449a8ea1ac..aa56746a820 100644
--- a/src/osd/windows/window.h
+++ b/src/osd/windows/window.h
@@ -54,7 +54,7 @@ enum class win_window_focus
class win_window_info : public osd_window_t<HWND>
{
public:
- win_window_info(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config *config);
+ win_window_info(running_machine &machine, render_module &renderprovider, int index, const std::shared_ptr<osd_monitor_info> &monitor, const osd_window_config *config);
bool attached_mode() const { return m_attached_mode; }
win_window_focus focus() const;
@@ -68,6 +68,9 @@ public:
return osd_dim(client.right - client.left, client.bottom - client.top);
}
+ win_window_info *main_window() const { return m_main; }
+ void set_main_window(win_window_info &main) { m_main = &main; }
+
void capture_pointer() override;
void release_pointer() override;
void show_pointer() override;
@@ -77,7 +80,12 @@ public:
// static
- static void create(running_machine &machine, int index, std::shared_ptr<osd_monitor_info> monitor, const osd_window_config *config);
+ static std::unique_ptr<win_window_info> create(
+ running_machine &machine,
+ render_module &renderprovider,
+ int index,
+ const std::shared_ptr<osd_monitor_info> &monitor,
+ const osd_window_config *config);
// static callbacks
@@ -126,15 +134,10 @@ private:
void adjust_window_position_after_major_change();
void set_fullscreen(int fullscreen);
- static POINT s_saved_cursor_pos;
-
+ win_window_info * m_main;
bool m_attached_mode;
-};
-struct osd_draw_callbacks
-{
- osd_renderer *(*create)(osd_window *window);
- void (*exit)(void);
+ static POINT s_saved_cursor_pos;
};
diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp
index 115853c15d9..6439da96a57 100644
--- a/src/osd/windows/winmain.cpp
+++ b/src/osd/windows/winmain.cpp
@@ -89,7 +89,7 @@ public:
if (channel == OSD_OUTPUT_CHANNEL_ERROR)
{
// if we are in fullscreen mode, go to windowed mode
- if ((video_config.windowed == 0) && !osd_common_t::s_window_list.empty())
+ if ((video_config.windowed == 0) && !osd_common_t::window_list().empty())
winwindow_toggle_full_screen();
auto &state(get_state());
@@ -284,21 +284,6 @@ windows_osd_interface::~windows_osd_interface()
//============================================================
-// video_register
-//============================================================
-
-void windows_osd_interface::video_register()
-{
- video_options_add("gdi", nullptr);
- video_options_add("d3d", nullptr);
-#if USE_OPENGL
- video_options_add("opengl", nullptr);
-#endif
- video_options_add("bgfx", nullptr);
- //video_options_add("auto", nullptr); // making d3d video default one
-}
-
-//============================================================
// init
//============================================================
@@ -352,9 +337,9 @@ void windows_osd_interface::init(running_machine &machine)
osd_common_t::init_subsystems();
// notify listeners of screen configuration
- for (const auto &info : osd_common_t::s_window_list)
+ for (const auto &info : osd_common_t::window_list())
{
- machine.output().set_value(string_format("Orientation(%s)", info->monitor()->devicename()), std::static_pointer_cast<win_window_info>(info)->m_targetorient);
+ machine.output().set_value(string_format("Orientation(%s)", info->monitor()->devicename()), dynamic_cast<win_window_info &>(*info).m_targetorient);
}
// hook up the debugger log
diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h
index 7c4f746a943..b963cf09309 100644
--- a/src/osd/windows/winmain.h
+++ b/src/osd/windows/winmain.h
@@ -67,8 +67,6 @@ public:
// video overridables
virtual void add_audio_to_recording(const int16_t *buffer, int samples_this_frame) override;
- virtual void video_register() override;
-
virtual bool video_init() override;
virtual bool window_init() override;