diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp index b7b1bee8f7b..59f9d01badf 100644 --- a/src/osd/sdl/window.cpp +++ b/src/osd/sdl/window.cpp @@ -53,18 +53,6 @@ #define WINDOW_DECORATION_WIDTH (8) // should be more than plenty #define WINDOW_DECORATION_HEIGHT (48) // title bar + bottom drag region -#ifdef MAME_DEBUG -//#define ASSERT_USE(x) do { printf("%x %x\n", (int) SDL_ThreadID(), x); assert_always(SDL_ThreadID() == x, "Wrong Thread"); } while (0) -#define ASSERT_USE(x) do { SDL_threadID _thid = SDL_ThreadID(); assert_always( _thid == x, "Wrong Thread"); } while (0) -#else -#define ASSERT_USE(x) do {} while (0) -//#define ASSERT_USE(x) assert(SDL_ThreadID() == x) -#endif - -#define ASSERT_REDRAW_THREAD() ASSERT_USE(window_threadid) -#define ASSERT_WINDOW_THREAD() ASSERT_USE(window_threadid) -#define ASSERT_MAIN_THREAD() ASSERT_USE(main_threadid) - // minimum window dimension #define MIN_WINDOW_DIM 200 @@ -91,92 +79,14 @@ public: SDL_DisplayMode mode; }; - - -// event handling -static SDL_threadID main_threadid; -static SDL_threadID window_threadid; - // debugger //static int in_background; -class worker_param -{ -public: - worker_param() - : m_window(nullptr), m_list(nullptr), m_resize_new_width(0), m_resize_new_height(0) - { - } - worker_param(std::shared_ptr awindow, render_primitive_list &alist) - : m_window(awindow), m_list(&alist), m_resize_new_width(0), m_resize_new_height(0) - { - } - worker_param(std::shared_ptr awindow, int anew_width, int anew_height) - : m_window(awindow), m_list(nullptr), m_resize_new_width(anew_width), m_resize_new_height(anew_height) - { - } - worker_param(std::shared_ptr awindow) - : m_window(awindow), m_list(nullptr), m_resize_new_width(0), m_resize_new_height(0) - { - } - std::shared_ptr window() const { assert(m_window != nullptr); return m_window; } - render_primitive_list *list() const { return m_list; } - int new_width() const { return m_resize_new_width; } - int new_height() const { return m_resize_new_height; } - // FIXME: only needed for window set-up which returns an error. - void set_window(std::shared_ptr window) { m_window = window; } -private: - std::shared_ptr m_window; - render_primitive_list *m_list; - int m_resize_new_width; - int m_resize_new_height; -}; - //============================================================ // PROTOTYPES //============================================================ -static void sdlwindow_sync(void); - -//============================================================ -// execute_async -//============================================================ - -// The idea of using unique_ptr here is to make sure the caller isn't holding onto a copy -static inline void execute_async(osd_work_callback callback, std::unique_ptr wp) -{ - callback(wp.release(), 0); -} - -static inline void execute_sync(osd_work_callback callback, std::unique_ptr wp) -{ - callback(wp.release(), 0); -} - - -//============================================================ -// execute_async_wait -//============================================================ - -static inline void execute_async_wait(osd_work_callback callback, std::unique_ptr wp) -{ - execute_async(callback, std::move(wp)); - sdlwindow_sync(); -} - - -//============================================================ -// sdlwindow_thread_id -// (window thread) -//============================================================ - -static OSDWORK_CALLBACK(sdlwindow_thread_id) -{ - window_threadid = SDL_ThreadID(); - return nullptr; -} - //============================================================ // window_init @@ -187,13 +97,6 @@ bool sdl_osd_interface::window_init() { osd_printf_verbose("Enter sdlwindow_init\n"); - // get the main thread ID before anything else - main_threadid = SDL_ThreadID(); - - // otherwise, treat the window thread as the main thread - //window_threadid = main_threadid; - sdlwindow_thread_id(nullptr, 0); - // initialize the drawers switch (video_config.mode) @@ -252,16 +155,6 @@ bool sdl_osd_interface::window_init() } -//============================================================ -// sdlwindow_sync -//============================================================ - -static void sdlwindow_sync(void) -{ - // haha, do nothing, losers -} - - void sdl_osd_interface::update_slider_list() { for (auto window : sdl_window_list) @@ -291,20 +184,8 @@ void sdl_osd_interface::build_slider_list() // (main thread) //============================================================ -static OSDWORK_CALLBACK( sdlwindow_exit_wt ) -{ - if (param) - osd_free(param); - return nullptr; -} - - void sdl_osd_interface::window_exit() { - std::unique_ptr wp_dummy(nullptr); - - ASSERT_MAIN_THREAD(); - osd_printf_verbose("Enter sdlwindow_exit\n"); // free all the windows @@ -335,11 +216,7 @@ void sdl_osd_interface::window_exit() default: break; } - - execute_async_wait(&sdlwindow_exit_wt, std::move(wp_dummy)); - osd_printf_verbose("Leave sdlwindow_exit\n"); - } void sdl_window_info::capture_pointer() @@ -370,123 +247,72 @@ void sdl_window_info::show_pointer() //============================================================ // sdlwindow_resize -// (main thread) //============================================================ -OSDWORK_CALLBACK( sdl_window_info::sdlwindow_resize_wt ) -{ - auto wp = std::unique_ptr(static_cast(param)); - auto window = wp->window(); - int width = wp->new_width(); - int height = wp->new_height(); - - ASSERT_WINDOW_THREAD(); - - SDL_SetWindowSize(window->platform_window(), width, height); - window->renderer().notify_changed(); - - return nullptr; -} - void sdl_window_info::resize(INT32 width, INT32 height) { - ASSERT_MAIN_THREAD(); - osd_dim cd = get_size(); if (width != cd.width() || height != cd.height()) { - auto wp = std::make_unique(std::static_pointer_cast(shared_from_this()), width, height); - execute_async_wait(&sdlwindow_resize_wt, std::move(wp)); + SDL_SetWindowSize(platform_window(), width, height); + renderer().notify_changed(); } } //============================================================ // sdlwindow_clear_surface -// (window thread) //============================================================ -OSDWORK_CALLBACK( sdl_window_info::notify_changed_wt ) -{ - auto wp = std::unique_ptr(static_cast(param)); - auto window = wp->window(); - - ASSERT_WINDOW_THREAD(); - - window->renderer().notify_changed(); - return nullptr; -} - void sdl_window_info::notify_changed() { - auto wp = std::make_unique(std::static_pointer_cast(shared_from_this())); - if (SDL_ThreadID() == main_threadid) - { - execute_async_wait(¬ify_changed_wt, std::move(wp)); - } - else - execute_sync(¬ify_changed_wt, std::move(wp)); + renderer().notify_changed(); } //============================================================ // sdlwindow_toggle_full_screen -// (main thread) //============================================================ -OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) +void sdl_window_info::toggle_full_screen() { - auto wp = std::unique_ptr(static_cast(param)); - auto window = wp->window(); - - ASSERT_WINDOW_THREAD(); - // if we are in debug mode, never go full screen - if (window->machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) - return nullptr; + if (machine().debug_flags & DEBUG_FLAG_OSD_ENABLED) + return; // If we are going fullscreen (leaving windowed) remember our windowed size - if (!window->fullscreen()) + if (!fullscreen()) { - window->m_windowed_dim = window->get_size(); + m_windowed_dim = get_size(); } // reset UI to main menu - ui_menu::stack_reset(window->machine()); + ui_menu::stack_reset(machine()); // kill off the drawers - window->renderer_reset(); - window->set_platform_window(nullptr); + renderer_reset(); + set_platform_window(nullptr); bool is_osx = false; #ifdef SDLMAME_MACOSX // FIXME: This is weird behaviour and certainly a bug in SDL is_osx = true; #endif - if (window->fullscreen() && (video_config.switchres || is_osx)) + if (fullscreen() && (video_config.switchres || is_osx)) { - SDL_SetWindowFullscreen(window->platform_window(), 0); // Try to set mode - SDL_SetWindowDisplayMode(window->platform_window(), &window->m_original_mode->mode); // Try to set mode - SDL_SetWindowFullscreen(window->platform_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode + SDL_SetWindowFullscreen(platform_window(), 0); // Try to set mode + SDL_SetWindowDisplayMode(platform_window(), &m_original_mode->mode); // Try to set mode + SDL_SetWindowFullscreen(platform_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode } - SDL_DestroyWindow(window->platform_window()); + SDL_DestroyWindow(platform_window()); - downcast(window->machine().osd()).release_keys(); + downcast(machine().osd()).release_keys(); - window->set_renderer(osd_renderer::make_for_type(video_config.mode, window->shared_from_this())); + set_renderer(osd_renderer::make_for_type(video_config.mode, shared_from_this())); // toggle the window mode - window->set_fullscreen(!window->fullscreen()); + set_fullscreen(!fullscreen()); - complete_create_wt(std::move(wp.release()), 0); - - return nullptr; -} - -void sdl_window_info::toggle_full_screen() -{ - ASSERT_MAIN_THREAD(); - auto wp = std::make_unique(std::static_pointer_cast(shared_from_this())); - execute_async_wait(&sdlwindow_toggle_full_screen_wt, std::move(wp)); + complete_create(); } void sdl_window_info::modify_prescale(int dir) @@ -502,14 +328,11 @@ void sdl_window_info::modify_prescale(int dir) { if (m_fullscreen && video_config.switchres) { - auto wp = std::make_unique(std::static_pointer_cast(shared_from_this())); - execute_async_wait(&sdlwindow_video_window_destroy_wt, std::move(wp)); + complete_destroy(); m_prescale = new_prescale; - wp = std::make_unique(std::static_pointer_cast(shared_from_this())); - execute_async_wait(&complete_create_wt, std::move(wp)); - + complete_create(); } else { @@ -559,16 +382,6 @@ void sdl_window_info::update_cursor_state() #endif } -OSDWORK_CALLBACK( sdl_window_info::update_cursor_state_wt ) -{ - auto wp = std::unique_ptr(static_cast(param)); - auto window = wp->window(); - - window->update_cursor_state(); - - return nullptr; -} - int sdl_window_info::xy_to_render_target(int x, int y, int *xt, int *yt) { return renderer().xy_to_render_target(x, y, xt, yt); @@ -583,8 +396,6 @@ int sdl_window_info::window_init() { int result; - ASSERT_MAIN_THREAD(); - // set the initial maximized state // FIXME: Does not belong here sdl_options &options = downcast(m_machine.options()); @@ -607,9 +418,7 @@ int sdl_window_info::window_init() else sprintf(m_title, "%s: %s [%s] - Screen %d", emulator_info::get_appname(), m_machine.system().description, m_machine.system().name, m_index); - auto wp = std::make_unique(std::static_pointer_cast(shared_from_this())); - - result = *((int *) sdl_window_info::complete_create_wt(wp.release(), 0)); + result = complete_create(); // handle error conditions if (result == 1) @@ -625,44 +434,33 @@ error: //============================================================ // sdlwindow_video_window_destroy -// (main thread) //============================================================ -OSDWORK_CALLBACK( sdl_window_info::sdlwindow_video_window_destroy_wt ) +void sdl_window_info::complete_destroy() { - auto wp = std::unique_ptr(static_cast(param)); - auto window = wp->window(); - - ASSERT_WINDOW_THREAD(); - - if (window->fullscreen() && video_config.switchres) + if (fullscreen() && video_config.switchres) { - SDL_SetWindowFullscreen(window->platform_window(), 0); // Try to set mode - SDL_SetWindowDisplayMode(window->platform_window(), &window->m_original_mode->mode); // Try to set mode - SDL_SetWindowFullscreen(window->platform_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode + SDL_SetWindowFullscreen(platform_window(), 0); // Try to set mode + SDL_SetWindowDisplayMode(platform_window(), &m_original_mode->mode); // Try to set mode + SDL_SetWindowFullscreen(platform_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode } - SDL_DestroyWindow(window->platform_window()); + SDL_DestroyWindow(platform_window()); // release all keys ... - downcast(window->machine().osd()).release_keys(); - - return nullptr; + downcast(machine().osd()).release_keys(); } void sdl_window_info::destroy() { - ASSERT_MAIN_THREAD(); - //osd_event_wait(window->rendered_event, osd_ticks_per_second()*10); // remove us from the list sdl_window_list.remove(std::static_pointer_cast(shared_from_this())); // free the textures etc - auto wp = std::make_unique(std::static_pointer_cast(shared_from_this())); - execute_async_wait(&sdlwindow_video_window_destroy_wt, std::move(wp)); + complete_destroy(); // free the render target, after the textures! - this->machine().render().target_free(m_target); + machine().render().target_free(m_target); } @@ -748,13 +546,11 @@ osd_dim sdl_window_info::pick_best_mode() void sdl_window_info::update() { osd_ticks_t event_wait_ticks; - ASSERT_MAIN_THREAD(); // adjust the cursor state //sdlwindow_update_cursor_state(machine, window); - auto wp = std::make_unique(std::static_pointer_cast(shared_from_this())); - execute_async(&update_cursor_state_wt, std::move(wp)); + update_cursor_state(); // if we're visible and running and not in the middle of a resize, draw if (m_target != nullptr) @@ -786,13 +582,44 @@ void sdl_window_info::update() if (m_rendered_event.wait(event_wait_ticks)) { + const int update = 1; + // ensure the target bounds are up-to-date, and then get the primitives render_primitive_list &primlist = *renderer().get_primitives(); // and redraw now - auto wp = std::make_unique(std::static_pointer_cast(shared_from_this()), primlist); - execute_async(&draw_video_contents_wt, std::move(wp)); + + // Some configurations require events to be polled in the worker thread + downcast< sdl_osd_interface& >(machine().osd()).process_events_buf(); + + // Check whether window has vector screens + + { + const screen_device *screen = screen_device_iterator(machine().root_device()).byindex(m_index); + if ((screen != nullptr) && (screen->screen_type() == SCREEN_TYPE_VECTOR)) + renderer().set_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); + else + renderer().clear_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); + } + + m_primlist = &primlist; + + // if no bitmap, just fill + if (m_primlist == nullptr) + { + } + // otherwise, render with our drawing system + else + { + if( video_config.perftest ) + measure_fps(update); + else + renderer().draw(update); + } + + /* all done, ready for next */ + m_rendered_event.set(); } } } @@ -807,8 +634,6 @@ void sdl_window_info::set_starting_view(int index, const char *defview, const ch { int viewindex; - ASSERT_MAIN_THREAD(); - // choose non-auto over auto if (strcmp(view, "auto") == 0 && strcmp(defview, "auto") != 0) view = defview; @@ -823,38 +648,31 @@ void sdl_window_info::set_starting_view(int index, const char *defview, const ch //============================================================ // complete_create -// (window thread) //============================================================ -OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) +int sdl_window_info::complete_create() { - auto wp = std::unique_ptr(static_cast(param)); - auto window = wp->window(); - osd_dim temp(0,0); - static int result[2] = {0,1}; - - ASSERT_WINDOW_THREAD(); // clear out original mode. Needed on OSX - if (window->fullscreen()) + if (fullscreen()) { // default to the current mode exactly - temp = window->monitor()->position_size().dim(); + temp = monitor()->position_size().dim(); // if we're allowed to switch resolutions, override with something better if (video_config.switchres) - temp = window->pick_best_mode(); + temp = pick_best_mode(); } - else if (window->m_windowed_dim.width() > 0) + else if (m_windowed_dim.width() > 0) { // if we have a remembered size force the new window size to it - temp = window->m_windowed_dim; + temp = m_windowed_dim; } - else if (window->m_startmaximized) - temp = window->get_max_bounds(video_config.keepaspect ); + else if (m_startmaximized) + temp = get_max_bounds(video_config.keepaspect ); else - temp = window->get_min_bounds(video_config.keepaspect ); + temp = get_min_bounds(video_config.keepaspect ); // create the window ..... @@ -865,7 +683,7 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) * */ osd_printf_verbose("Enter sdl_info::create\n"); - if (window->renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL)) + if (renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL)) { SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); @@ -875,10 +693,10 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) * SDL_GL_SetAttribute( SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1 ); * */ - window->m_extra_flags = SDL_WINDOW_OPENGL; + m_extra_flags = SDL_WINDOW_OPENGL; } else - window->m_extra_flags = 0; + m_extra_flags = 0; #ifdef SDLMAME_MACOSX /* FIMXE: On OSX, SDL_WINDOW_FULLSCREEN_DESKTOP seems to be more reliable. @@ -889,7 +707,7 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) // create the SDL window // soft driver also used | SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_MOUSE_FOCUS - window->m_extra_flags |= (window->fullscreen() ? + m_extra_flags |= (fullscreen() ? /*SDL_WINDOW_BORDERLESS |*/ SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE); #if defined(SDLMAME_WIN32) @@ -897,45 +715,45 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) #endif // get monitor work area for centering - osd_rect work = window->monitor()->usuable_position_size(); + osd_rect work = monitor()->usuable_position_size(); // create the SDL window - auto sdlwindow = SDL_CreateWindow(window->m_title, + auto sdlwindow = SDL_CreateWindow(m_title, work.left() + (work.width() - temp.width()) / 2, work.top() + (work.height() - temp.height()) / 2, - temp.width(), temp.height(), window->m_extra_flags); + temp.width(), temp.height(), m_extra_flags); //window().sdl_window() = SDL_CreateWindow(window().m_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, // width, height, m_extra_flags); if (sdlwindow == nullptr ) { - if (window->renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL)) + if (renderer().has_flags(osd_renderer::FLAG_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()); - return (void *) &result[1]; + return 1; } - window->set_platform_window(sdlwindow); + set_platform_window(sdlwindow); - if (window->fullscreen() && video_config.switchres) + if (fullscreen() && video_config.switchres) { SDL_DisplayMode mode; //SDL_GetCurrentDisplayMode(window().monitor()->handle, &mode); - SDL_GetWindowDisplayMode(window->platform_window(), &mode); - window->m_original_mode->mode = mode; + SDL_GetWindowDisplayMode(platform_window(), &mode); + m_original_mode->mode = mode; mode.w = temp.width(); mode.h = temp.height(); - if (window->m_win_config.refresh) - mode.refresh_rate = window->m_win_config.refresh; + if (m_win_config.refresh) + mode.refresh_rate = m_win_config.refresh; - SDL_SetWindowDisplayMode(window->platform_window(), &mode); // Try to set mode + SDL_SetWindowDisplayMode(platform_window(), &mode); // Try to set mode #ifndef SDLMAME_WIN32 /* FIXME: Warp the mouse to 0,0 in case a virtual desktop resolution * is in place after the mode switch - which will most likely be the case * This is a hack to work around a deficiency in SDL2 */ - SDL_WarpMouseInWindow(window->platform_window(), 1, 1); + SDL_WarpMouseInWindow(platform_window(), 1, 1); #endif } else @@ -945,24 +763,24 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) // show window - SDL_ShowWindow(window->platform_window()); + SDL_ShowWindow(platform_window()); //SDL_SetWindowFullscreen(window->sdl_window(), 0); //SDL_SetWindowFullscreen(window->sdl_window(), window->fullscreen()); - SDL_RaiseWindow(window->platform_window()); + SDL_RaiseWindow(platform_window()); #ifdef SDLMAME_WIN32 - if (window->fullscreen()) + if (fullscreen()) SDL_SetWindowGrab(window->platform_window(), SDL_TRUE); #endif // set main window - if (window->m_index > 0) + if (m_index > 0) { for (auto w : sdl_window_list) { if (w->m_index == 0) { - window->set_main_window(std::dynamic_pointer_cast(w)); + set_main_window(std::dynamic_pointer_cast(w)); break; } } @@ -970,23 +788,23 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) else { // We must be the main window - window->set_main_window(window); + set_main_window(shared_from_this()); } // update monitor resolution after mode change to ensure proper pixel aspect - window->monitor()->refresh(); - if (window->fullscreen() && video_config.switchres) - window->monitor()->update_resolution(temp.width(), temp.height()); + monitor()->refresh(); + if (fullscreen() && video_config.switchres) + monitor()->update_resolution(temp.width(), temp.height()); // initialize the drawing backend - if (window->renderer().create()) - return (void *) &result[1]; + if (renderer().create()) + return 1; // Make sure we have a consistent state SDL_ShowCursor(0); SDL_ShowCursor(1); - return (void *) &result[0]; + return 0; } @@ -1037,51 +855,6 @@ void sdl_window_info::measure_fps(int update) } } -OSDWORK_CALLBACK( sdl_window_info::draw_video_contents_wt ) -{ - int update = 1; - auto wp = std::unique_ptr(static_cast(param)); - auto window = wp->window(); - - ASSERT_REDRAW_THREAD(); - - // Some configurations require events to be polled in the worker thread - downcast< sdl_osd_interface& >(window->machine().osd()).process_events_buf(); - - // Check whether window has vector screens - - { -#if 1 - const screen_device *screen = screen_device_iterator(window->machine().root_device()).byindex(window->m_index); - if ((screen != nullptr) && (screen->screen_type() == SCREEN_TYPE_VECTOR)) - window->renderer().set_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); - else - window->renderer().clear_flags(osd_renderer::FLAG_HAS_VECTOR_SCREEN); -#endif - } - - - window->m_primlist = wp->list(); - - // if no bitmap, just fill - if (window->m_primlist == nullptr) - { - } - // otherwise, render with our drawing system - else - { - if( video_config.perftest ) - window->measure_fps(update); - else - window->renderer().draw(update); - } - - /* all done, ready for next */ - window->m_rendered_event.set(); - - return nullptr; -} - int sdl_window_info::wnd_extra_width() { return m_fullscreen ? 0 : WINDOW_DECORATION_WIDTH; diff --git a/src/osd/sdl/window.h b/src/osd/sdl/window.h index 527c587764e..0a99870675f 100644 --- a/src/osd/sdl/window.h +++ b/src/osd/sdl/window.h @@ -89,7 +89,9 @@ private: int m_extra_flags; - static OSDWORK_CALLBACK( complete_create_wt ); + // returns 0 on success, else 1 + int complete_create(); + void complete_destroy(); private: int wnd_extra_width(); @@ -108,15 +110,6 @@ private: osd_monitor_info * m_monitor; int m_fullscreen; - // static callbacks ... - - static OSDWORK_CALLBACK( sdlwindow_resize_wt ); - static OSDWORK_CALLBACK( draw_video_contents_wt ); - static OSDWORK_CALLBACK( sdlwindow_video_window_destroy_wt ); - static OSDWORK_CALLBACK( sdlwindow_toggle_full_screen_wt ); - static OSDWORK_CALLBACK( notify_changed_wt ); - static OSDWORK_CALLBACK( update_cursor_state_wt ); - void measure_fps(int update); };