diff --git a/include/frontend.hpp b/include/frontend.hpp index 1555709..ed86051 100755 --- a/include/frontend.hpp +++ b/include/frontend.hpp @@ -52,7 +52,7 @@ class WindowScreen { public: ScreenInfo m_info; - WindowScreen(ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, AudioData* audio_data, ExtraButtonShortcuts* extra_button_shortcuts); + WindowScreen(ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, AudioData* audio_data, ExtraButtonShortcuts* extra_button_shortcuts, ConsumerMutex *draw_lock); ~WindowScreen(); void build(); @@ -188,6 +188,7 @@ private: TextRectangle* notification; ConsumerMutex display_lock; + ConsumerMutex *draw_lock; bool done_display; VideoOutputData *saved_buf; ScreenInfo loaded_info; diff --git a/source/WindowScreen.cpp b/source/WindowScreen.cpp index 7443827..fb891c3 100755 --- a/source/WindowScreen.cpp +++ b/source/WindowScreen.cpp @@ -25,7 +25,8 @@ static bool loaded_shaders = false; static int n_shader_refs = 0; static sf::Shader *base_shader; -WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, AudioData* audio_data, ExtraButtonShortcuts* extra_button_shortcuts) { +WindowScreen::WindowScreen(ScreenType stype, CaptureStatus* capture_status, DisplayData* display_data, AudioData* audio_data, ExtraButtonShortcuts* extra_button_shortcuts, ConsumerMutex *draw_lock) { + this->draw_lock = draw_lock; this->m_stype = stype; insert_basic_crops(this->possible_crops, this->m_stype, false, false); insert_basic_crops(this->possible_crops_ds, this->m_stype, true, false); @@ -139,8 +140,10 @@ void WindowScreen::display_call(bool is_main_thread) { this->prepare_screen_rendering(); if(this->m_win.isOpen()) { if(this->main_thread_owns_window != is_main_thread) { + this->draw_lock->lock(); this->m_win.setActive(true); this->main_thread_owns_window = is_main_thread; + this->draw_lock->unlock(); } this->window_render_call(); } @@ -158,21 +161,29 @@ void WindowScreen::display_thread() { this->display_call(false); } } - if(!this->main_thread_owns_window) + if(!this->main_thread_owns_window) { + this->draw_lock->lock(); this->m_win.setActive(false); + this->draw_lock->unlock(); + } this->done_display = true; } void WindowScreen::end() { - if(this->main_thread_owns_window) + if(this->main_thread_owns_window) { + this->draw_lock->lock(); this->m_win.setActive(false); + this->draw_lock->unlock(); + } this->display_lock.unlock(); } void WindowScreen::after_thread_join() { if(this->m_win.isOpen()) { + this->draw_lock->lock(); this->m_win.setActive(true); this->m_win.close(); + this->draw_lock->unlock(); } } @@ -261,10 +272,11 @@ void WindowScreen::reset_operations(ScreenOperations &operations) { void WindowScreen::free_ownership_of_window(bool is_main_thread) { if(is_main_thread == this->main_thread_owns_window) { - if(this->scheduled_work_on_window) - this->m_win.setActive(false); - else if(is_main_thread == this->loaded_info.async) + if((this->scheduled_work_on_window) || (is_main_thread == this->loaded_info.async)) { + this->draw_lock->lock(); this->m_win.setActive(false); + this->draw_lock->unlock(); + } } } @@ -359,15 +371,18 @@ bool WindowScreen::window_needs_work() { void WindowScreen::window_factory(bool is_main_thread) { if(this->loaded_operations.call_close) { + this->draw_lock->lock(); this->m_win.setActive(true); this->main_thread_owns_window = is_main_thread; this->m_win.close(); while(!events_queue.empty()) events_queue.pop(); + this->draw_lock->unlock(); this->loaded_operations.call_close = false; this->loaded_operations.call_create = false; } if(this->loaded_operations.call_create) { + this->draw_lock->lock(); this->m_win.setActive(true); this->main_thread_owns_window = is_main_thread; bool previously_open = this->m_win.isOpen(); @@ -394,13 +409,16 @@ void WindowScreen::window_factory(bool is_main_thread) { this->m_win.setPosition(prev_pos); this->last_window_creation_time = std::chrono::high_resolution_clock::now(); this->update_screen_settings(); + this->draw_lock->unlock(); this->loaded_operations.call_create = false; } if(this->m_win.isOpen()) { this->setWinSize(is_main_thread); } if((is_main_thread == this->main_thread_owns_window) && (this->main_thread_owns_window == this->loaded_info.async)) { + this->draw_lock->lock(); this->m_win.setActive(false); + this->draw_lock->unlock(); } this->update_connection(); this->is_window_factory_done = true; @@ -431,10 +449,12 @@ void WindowScreen::update_texture() { void WindowScreen::pre_texture_conversion_processing() { if(this->loaded_menu == CONNECT_MENU_TYPE) return; - //Place preprocessing window-specific effects here if(!this->capture_status->connected) return; + this->draw_lock->lock(); + //Place preprocessing window-specific effects here this->update_texture(); + this->draw_lock->unlock(); } void WindowScreen::post_texture_conversion_processing(out_rect_data &rect_data, const sf::RectangleShape &in_rect, bool actually_draw, bool is_top, bool is_debug) { @@ -470,6 +490,7 @@ void WindowScreen::window_bg_processing() { } void WindowScreen::display_data_to_window(bool actually_draw, bool is_debug) { + this->draw_lock->lock(); this->post_texture_conversion_processing(this->m_out_rect_top, this->m_in_rect_top, actually_draw, true, is_debug); this->post_texture_conversion_processing(this->m_out_rect_bot, this->m_in_rect_bot, actually_draw, false, is_debug); @@ -495,6 +516,7 @@ void WindowScreen::display_data_to_window(bool actually_draw, bool is_debug) { this->execute_menu_draws(); this->notification->draw(this->m_win); this->m_win.display(); + this->draw_lock->unlock(); } void WindowScreen::window_render_call() { @@ -1071,8 +1093,10 @@ void WindowScreen::setWinSize(bool is_main_thread) { int win_width = this->m_win.getSize().x; int win_height = this->m_win.getSize().y; if((win_width != width) || (win_height != height)) { + this->draw_lock->lock(); this->m_win.setActive(true); this->main_thread_owns_window = is_main_thread; this->m_win.setSize(sf::Vector2u(width, height)); + this->draw_lock->unlock(); } } diff --git a/source/cc3dsfs.cpp b/source/cc3dsfs.cpp index 936d826..faa07ef 100755 --- a/source/cc3dsfs.cpp +++ b/source/cc3dsfs.cpp @@ -284,6 +284,7 @@ static int mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data, int num_elements_fps_array = 0; int curr_out, prev_out = NUM_CONCURRENT_DATA_BUFFERS - 1; FrontendData frontend_data; + ConsumerMutex draw_lock; reset_display_data(&frontend_data.display_data); frontend_data.display_data.mono_app_mode = mono_app; frontend_data.reload = true; @@ -298,9 +299,10 @@ static int mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data, out_buf = new VideoOutputData; memset(out_buf, 0, sizeof(VideoOutputData)); - WindowScreen *top_screen = new WindowScreen(ScreenType::TOP, &capture_data->status, &frontend_data.display_data, audio_data, &extra_button_shortcuts); - WindowScreen *bot_screen = new WindowScreen(ScreenType::BOTTOM, &capture_data->status, &frontend_data.display_data, audio_data, &extra_button_shortcuts); - WindowScreen *joint_screen = new WindowScreen(ScreenType::JOINT, &capture_data->status, &frontend_data.display_data, audio_data, &extra_button_shortcuts); + draw_lock.unlock(); + WindowScreen *top_screen = new WindowScreen(ScreenType::TOP, &capture_data->status, &frontend_data.display_data, audio_data, &extra_button_shortcuts, &draw_lock); + WindowScreen *bot_screen = new WindowScreen(ScreenType::BOTTOM, &capture_data->status, &frontend_data.display_data, audio_data, &extra_button_shortcuts, &draw_lock); + WindowScreen *joint_screen = new WindowScreen(ScreenType::JOINT, &capture_data->status, &frontend_data.display_data, audio_data, &extra_button_shortcuts, &draw_lock); frontend_data.top_screen = top_screen; frontend_data.bot_screen = bot_screen; frontend_data.joint_screen = joint_screen;