move render thread to App class and add ui thread with ui tasks queue
This commit is contained in:
120
src/app.cpp
120
src/app.cpp
@@ -1019,3 +1019,123 @@ void App::rec_loop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void App::render_thread_main()
|
||||||
|
{
|
||||||
|
uint32_t count = 0;
|
||||||
|
render_thread_id = std::this_thread::get_id();
|
||||||
|
render_running = true;
|
||||||
|
while (render_running)
|
||||||
|
{
|
||||||
|
std::deque<std::packaged_task<void()>> working_list;
|
||||||
|
|
||||||
|
// move the task list locally to free the queue for other threads
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(render_task_mutex);
|
||||||
|
render_cv.wait(lock, [this] { return render_tasklist.empty() && render_running ? false : true; });
|
||||||
|
working_list = std::move(render_tasklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the tasks
|
||||||
|
if (!working_list.empty())
|
||||||
|
{
|
||||||
|
async_lock();
|
||||||
|
while (!working_list.empty())
|
||||||
|
{
|
||||||
|
//LOG("render task %d", count);
|
||||||
|
count++;
|
||||||
|
working_list.front()();
|
||||||
|
working_list.pop_front();
|
||||||
|
}
|
||||||
|
async_unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::ui_thread_main()
|
||||||
|
{
|
||||||
|
uint32_t count = 0;
|
||||||
|
ui_thread_id = std::this_thread::get_id();
|
||||||
|
ui_running = true;
|
||||||
|
auto t_start = std::chrono::high_resolution_clock::now();
|
||||||
|
float t_frame = 0;
|
||||||
|
float t_fps_counter = 0;
|
||||||
|
int rendered_frames = 0;
|
||||||
|
while (ui_running)
|
||||||
|
{
|
||||||
|
std::deque<std::packaged_task<void()>> working_list;
|
||||||
|
|
||||||
|
// move the task list locally to free the queue for other threads
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(ui_task_mutex);
|
||||||
|
ui_cv.wait(lock, [this] { return ui_tasklist.empty() && ui_running ? false : true; });
|
||||||
|
working_list = std::move(ui_tasklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the tasks
|
||||||
|
if (!working_list.empty())
|
||||||
|
{
|
||||||
|
while (!working_list.empty())
|
||||||
|
{
|
||||||
|
//LOG("ui task %d", count);
|
||||||
|
count++;
|
||||||
|
working_list.front()();
|
||||||
|
working_list.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto t_now = std::chrono::high_resolution_clock::now();
|
||||||
|
float dt = std::chrono::duration<float>(t_now - t_start).count();
|
||||||
|
|
||||||
|
// increment timers
|
||||||
|
t_frame += dt;
|
||||||
|
t_fps_counter += dt;
|
||||||
|
|
||||||
|
if (t_fps_counter > 1.f)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tick(dt);
|
||||||
|
|
||||||
|
if (redraw)
|
||||||
|
{
|
||||||
|
update(t_frame);
|
||||||
|
render_task([this, t_frame]
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
clear();
|
||||||
|
draw(t_frame);
|
||||||
|
async_swap();
|
||||||
|
});
|
||||||
|
t_frame = 0;
|
||||||
|
rendered_frames++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::render_thread_start()
|
||||||
|
{
|
||||||
|
render_thread = std::thread(&App::render_thread_main, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::render_thread_stop()
|
||||||
|
{
|
||||||
|
render_running = false;
|
||||||
|
render_cv.notify_all();
|
||||||
|
if (render_thread.joinable())
|
||||||
|
render_thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::ui_thread_start()
|
||||||
|
{
|
||||||
|
ui_thread = std::thread(&App::ui_thread_main, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::ui_thread_stop()
|
||||||
|
{
|
||||||
|
ui_running = false;
|
||||||
|
ui_cv.notify_all();
|
||||||
|
if (ui_thread.joinable())
|
||||||
|
ui_thread.join();
|
||||||
|
}
|
||||||
|
|||||||
95
src/app.h
95
src/app.h
@@ -251,11 +251,23 @@ public:
|
|||||||
|
|
||||||
void cmd_convert(std::string pano_path, std::string out_path);
|
void cmd_convert(std::string pano_path, std::string out_path);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// RENDER THREAD
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::deque<std::packaged_task<void()>> render_tasklist;
|
||||||
|
std::mutex render_task_mutex;
|
||||||
|
std::condition_variable render_cv;
|
||||||
|
std::thread render_thread;
|
||||||
|
std::thread::id render_thread_id;
|
||||||
|
bool render_running = false;
|
||||||
|
void render_thread_main();
|
||||||
|
void render_thread_start();
|
||||||
|
void render_thread_stop();
|
||||||
|
|
||||||
bool is_render_thread()
|
bool is_render_thread()
|
||||||
{
|
{
|
||||||
extern std::thread::id render_thread_id;
|
return std::this_thread::get_id() == render_thread_id;
|
||||||
extern std::thread::id gl_thread;
|
|
||||||
return std::this_thread::get_id() == render_thread_id || std::this_thread::get_id() == gl_thread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't capture a reference to this ptr as the object may be destroyed
|
// don't capture a reference to this ptr as the object may be destroyed
|
||||||
@@ -264,9 +276,6 @@ public:
|
|||||||
std::future<R> render_task_async(T task)
|
std::future<R> render_task_async(T task)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern std::deque<std::packaged_task<R()>> render_tasklist;
|
|
||||||
extern std::mutex render_task_mutex;
|
|
||||||
extern std::condition_variable render_cv;
|
|
||||||
std::packaged_task<R()> pt(task);
|
std::packaged_task<R()> pt(task);
|
||||||
std::future<R> f = pt.get_future();
|
std::future<R> f = pt.get_future();
|
||||||
if (is_render_thread())
|
if (is_render_thread())
|
||||||
@@ -289,9 +298,6 @@ public:
|
|||||||
R render_task(T task)
|
R render_task(T task)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern std::deque<std::packaged_task<R()>> render_tasklist;
|
|
||||||
extern std::mutex render_task_mutex;
|
|
||||||
extern std::condition_variable render_cv;
|
|
||||||
std::packaged_task<R()> pt(task);
|
std::packaged_task<R()> pt(task);
|
||||||
std::future<R> f = pt.get_future();
|
std::future<R> f = pt.get_future();
|
||||||
if (is_render_thread())
|
if (is_render_thread())
|
||||||
@@ -306,7 +312,7 @@ public:
|
|||||||
}
|
}
|
||||||
render_cv.notify_all();
|
render_cv.notify_all();
|
||||||
}
|
}
|
||||||
return f.get();
|
return render_running ? f.get() : R();
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,4 +321,73 @@ public:
|
|||||||
render_task([] {});
|
render_task([] {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// UI THREAD
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::deque<std::packaged_task<void()>> ui_tasklist;
|
||||||
|
std::mutex ui_task_mutex;
|
||||||
|
std::condition_variable ui_cv;
|
||||||
|
std::thread ui_thread;
|
||||||
|
std::thread::id ui_thread_id;
|
||||||
|
bool ui_running = false;
|
||||||
|
void ui_thread_main();
|
||||||
|
void ui_thread_start();
|
||||||
|
void ui_thread_stop();
|
||||||
|
|
||||||
|
bool is_ui_thread()
|
||||||
|
{
|
||||||
|
return std::this_thread::get_id() == ui_thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't capture a reference to this ptr as the object may be destroyed
|
||||||
|
// by the time the task is executed
|
||||||
|
template<typename T, typename R = std::result_of<T()>::type>
|
||||||
|
std::future<R> ui_task_async(T task)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::packaged_task<R()> pt(task);
|
||||||
|
std::future<R> f = pt.get_future();
|
||||||
|
if (is_ui_thread())
|
||||||
|
{
|
||||||
|
pt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(ui_task_mutex);
|
||||||
|
ui_tasklist.push_back(std::move(pt));
|
||||||
|
}
|
||||||
|
ui_cv.notify_all();
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
#endif // _WIN32
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename R = std::result_of<T()>::type>
|
||||||
|
R ui_task(T task)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::packaged_task<R()> pt(task);
|
||||||
|
std::future<R> f = pt.get_future();
|
||||||
|
if (is_ui_thread())
|
||||||
|
{
|
||||||
|
pt();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(ui_task_mutex);
|
||||||
|
ui_tasklist.push_back(std::move(pt));
|
||||||
|
}
|
||||||
|
ui_cv.notify_all();
|
||||||
|
}
|
||||||
|
return ui_running ? f.get() : R();
|
||||||
|
#endif // _WIN32
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_sync()
|
||||||
|
{
|
||||||
|
ui_task([] {});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
bool win32_vr_start();
|
bool win32_vr_start();
|
||||||
void win32_vr_stop();
|
void win32_vr_stop();
|
||||||
void win32_render_thread_notify();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool trigger_down = false;
|
bool trigger_down = false;
|
||||||
@@ -86,9 +85,6 @@ void App::vr_update(float dt)
|
|||||||
mouse_move(controller_cursor.x, controller_cursor.y, 1.f, kEventSource::Mouse, false);
|
mouse_move(controller_cursor.x, controller_cursor.y, 1.f, kEventSource::Mouse, false);
|
||||||
async_end();
|
async_end();
|
||||||
ui_inside = true;
|
ui_inside = true;
|
||||||
#ifdef _WIN32
|
|
||||||
win32_render_thread_notify();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,17 +118,11 @@ void App::vr_analog(const VRController& c, VRController::kButton b, VRController
|
|||||||
{
|
{
|
||||||
mouse_down(0, controller_cursor.x, controller_cursor.y, 1.f, kEventSource::Mouse, false);
|
mouse_down(0, controller_cursor.x, controller_cursor.y, 1.f, kEventSource::Mouse, false);
|
||||||
ui_capture = true;
|
ui_capture = true;
|
||||||
#ifdef _WIN32
|
|
||||||
win32_render_thread_notify();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mouse_up(0, controller_cursor.x, controller_cursor.y, kEventSource::Mouse, false);
|
mouse_up(0, controller_cursor.x, controller_cursor.y, kEventSource::Mouse, false);
|
||||||
ui_capture = false;
|
ui_capture = false;
|
||||||
#ifdef _WIN32
|
|
||||||
win32_render_thread_notify();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
async_end();
|
async_end();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2845,8 +2845,6 @@ void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, con
|
|||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
draw_merge();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2940,8 +2938,6 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
|
|||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
draw_merge();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ void ActionStroke::undo()
|
|||||||
LOG("undo invalid box size (%d, %d)", (int)box_sz.x, (int)box_sz.y);
|
LOG("undo invalid box size (%d, %d)", (int)box_sz.x, (int)box_sz.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_canvas->draw_merge();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ActionStroke::memory()
|
size_t ActionStroke::memory()
|
||||||
|
|||||||
201
src/main.cpp
201
src/main.cpp
@@ -33,23 +33,11 @@ std::thread::id gl_thread;
|
|||||||
std::map<kKey, int> vkey_map;
|
std::map<kKey, int> vkey_map;
|
||||||
|
|
||||||
std::thread hmd_renderer;
|
std::thread hmd_renderer;
|
||||||
std::thread ui_renderer;
|
|
||||||
int vr_frames = 0;
|
int vr_frames = 0;
|
||||||
int running = -1;
|
int running = -1;
|
||||||
int vr_running = 0;
|
int vr_running = 0;
|
||||||
std::mutex ui_render_mutex;
|
|
||||||
std::condition_variable ui_render_cv;
|
|
||||||
|
|
||||||
std::deque<std::packaged_task<void()>> render_tasklist;
|
|
||||||
std::mutex render_task_mutex;
|
|
||||||
std::condition_variable render_cv;
|
|
||||||
std::thread render_thread;
|
|
||||||
std::thread::id render_thread_id;
|
|
||||||
bool render_running = false;
|
|
||||||
|
|
||||||
int gl_count = 0;
|
int gl_count = 0;
|
||||||
std::deque<std::packaged_task<void()>> tasklist;
|
|
||||||
std::mutex task_mutex;
|
|
||||||
std::deque<std::packaged_task<void()>> main_tasklist;
|
std::deque<std::packaged_task<void()>> main_tasklist;
|
||||||
std::mutex main_task_mutex;
|
std::mutex main_task_mutex;
|
||||||
float timer_stylus = 0;
|
float timer_stylus = 0;
|
||||||
@@ -119,63 +107,6 @@ void destroy_window()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_render_thread()
|
|
||||||
{
|
|
||||||
extern std::thread::id render_thread_id;
|
|
||||||
extern std::thread::id gl_thread;
|
|
||||||
return std::this_thread::get_id() == render_thread_id || std::this_thread::get_id() == gl_thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename R = std::result_of<T()>::type>
|
|
||||||
std::future<R> render_task_async(T task)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
extern std::deque<std::packaged_task<R()>> render_tasklist;
|
|
||||||
extern std::mutex render_task_mutex;
|
|
||||||
extern std::condition_variable render_cv;
|
|
||||||
std::packaged_task<R()> pt(task);
|
|
||||||
std::future<R> f = pt.get_future();
|
|
||||||
if (is_render_thread())
|
|
||||||
{
|
|
||||||
pt();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(render_task_mutex);
|
|
||||||
render_tasklist.push_back(std::move(pt));
|
|
||||||
}
|
|
||||||
render_cv.notify_all();
|
|
||||||
}
|
|
||||||
return f;
|
|
||||||
#endif // _WIN32
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename R = std::result_of<T()>::type>
|
|
||||||
R render_task(T task)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
extern std::deque<std::packaged_task<R()>> render_tasklist;
|
|
||||||
extern std::mutex render_task_mutex;
|
|
||||||
extern std::condition_variable render_cv;
|
|
||||||
std::packaged_task<R()> pt(task);
|
|
||||||
std::future<R> f = pt.get_future();
|
|
||||||
if (is_render_thread())
|
|
||||||
{
|
|
||||||
pt();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(render_task_mutex);
|
|
||||||
render_tasklist.push_back(std::move(pt));
|
|
||||||
}
|
|
||||||
render_cv.notify_all();
|
|
||||||
}
|
|
||||||
return f.get();
|
|
||||||
#endif // _WIN32
|
|
||||||
}
|
|
||||||
|
|
||||||
void async_lock()
|
void async_lock()
|
||||||
{
|
{
|
||||||
//std::lock_guard<std::mutex> _lock(async_mutex);
|
//std::lock_guard<std::mutex> _lock(async_mutex);
|
||||||
@@ -228,11 +159,6 @@ void async_unlock()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void win32_render_thread_notify()
|
|
||||||
{
|
|
||||||
ui_render_cv.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void win32_show_cursor(bool visible)
|
void win32_show_cursor(bool visible)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(main_task_mutex);
|
std::lock_guard<std::mutex> lock(main_task_mutex);
|
||||||
@@ -781,46 +707,6 @@ BOOL UnadjustWindowRectEx(LPRECT prc, DWORD dwStyle, BOOL fMenu, DWORD dwExStyle
|
|||||||
return fRc;
|
return fRc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_thread_main()
|
|
||||||
{
|
|
||||||
uint32_t count = 0;
|
|
||||||
render_thread_id = std::this_thread::get_id();
|
|
||||||
render_running = true;
|
|
||||||
while (render_running == 1)
|
|
||||||
{
|
|
||||||
std::deque<std::packaged_task<void()>> working_list;
|
|
||||||
|
|
||||||
// move the task list locally to free the queue for other threads
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(render_task_mutex);
|
|
||||||
render_cv.wait(lock, [] { return render_tasklist.empty() && render_running ? false : true; });
|
|
||||||
working_list = std::move(render_tasklist);
|
|
||||||
}
|
|
||||||
|
|
||||||
//{
|
|
||||||
// std::lock_guard<std::mutex> lock(task_mutex);
|
|
||||||
// working_list.insert(working_list.end(),
|
|
||||||
// std::make_move_iterator(tasklist.begin()),
|
|
||||||
// std::make_move_iterator(tasklist.end()));
|
|
||||||
// tasklist.clear();
|
|
||||||
//}
|
|
||||||
|
|
||||||
// execute the tasks
|
|
||||||
if (!working_list.empty())
|
|
||||||
{
|
|
||||||
async_lock();
|
|
||||||
while (!working_list.empty())
|
|
||||||
{
|
|
||||||
LOG("render task %d", count);
|
|
||||||
count++;
|
|
||||||
working_list.front()();
|
|
||||||
working_list.pop_front();
|
|
||||||
}
|
|
||||||
async_unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
WNDCLASS wc;
|
WNDCLASS wc;
|
||||||
@@ -1015,7 +901,8 @@ int main(int argc, char** argv)
|
|||||||
wglMakeCurrent(NULL, NULL);
|
wglMakeCurrent(NULL, NULL);
|
||||||
|
|
||||||
running = 1;
|
running = 1;
|
||||||
render_thread = std::thread(render_thread_main);
|
App::I.render_thread_start();
|
||||||
|
App::I.ui_thread_start();
|
||||||
|
|
||||||
LOG("init app");
|
LOG("init app");
|
||||||
App::I.init();
|
App::I.init();
|
||||||
@@ -1034,6 +921,17 @@ int main(int argc, char** argv)
|
|||||||
SendMessage(hWnd, WM_SETICON, ICON_SMALL,
|
SendMessage(hWnd, WM_SETICON, ICON_SMALL,
|
||||||
(LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1)));
|
(LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1)));
|
||||||
|
|
||||||
|
{
|
||||||
|
WINDOWPLACEMENT wp;
|
||||||
|
GetWindowPlacement(hWnd, &wp);
|
||||||
|
wp.showCmd = show_cmd;
|
||||||
|
SetWindowPlacement(hWnd, &wp);
|
||||||
|
//GetClientRect(hWnd, &clientRect);
|
||||||
|
//App::I.width = clientRect.right - clientRect.left;
|
||||||
|
//App::I.height = clientRect.bottom - clientRect.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
ui_renderer = std::thread([&] {
|
ui_renderer = std::thread([&] {
|
||||||
BT_SetTerminate();
|
BT_SetTerminate();
|
||||||
LOG("start render thread");
|
LOG("start render thread");
|
||||||
@@ -1041,7 +939,6 @@ int main(int argc, char** argv)
|
|||||||
const float target_tick_rate = 10;
|
const float target_tick_rate = 10;
|
||||||
unsigned long t0 = GetTickCount64();
|
unsigned long t0 = GetTickCount64();
|
||||||
unsigned long t1;
|
unsigned long t1;
|
||||||
bool first_frame = true;
|
|
||||||
int frames = 0;
|
int frames = 0;
|
||||||
float one_sec = 0;
|
float one_sec = 0;
|
||||||
float render_timer = 0;
|
float render_timer = 0;
|
||||||
@@ -1094,18 +991,6 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_frame)
|
|
||||||
{
|
|
||||||
first_frame = false;
|
|
||||||
WINDOWPLACEMENT wp;
|
|
||||||
GetWindowPlacement(hWnd, &wp);
|
|
||||||
wp.showCmd = show_cmd;
|
|
||||||
SetWindowPlacement(hWnd, &wp);
|
|
||||||
// GetClientRect(hWnd, &clientRect);
|
|
||||||
// App::I.width = clientRect.right - clientRect.left;
|
|
||||||
// App::I.height = clientRect.bottom - clientRect.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
App::I.tick(dt);
|
App::I.tick(dt);
|
||||||
|
|
||||||
std::unique_lock<std::mutex> lock(ui_render_mutex);
|
std::unique_lock<std::mutex> lock(ui_render_mutex);
|
||||||
@@ -1134,7 +1019,7 @@ int main(int argc, char** argv)
|
|||||||
if (App::I.redraw)
|
if (App::I.redraw)
|
||||||
{
|
{
|
||||||
App::I.update(frame_timer);
|
App::I.update(frame_timer);
|
||||||
render_task([frame_timer]
|
App::I.render_task([frame_timer]
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
App::I.clear();
|
App::I.clear();
|
||||||
@@ -1151,9 +1036,8 @@ int main(int argc, char** argv)
|
|||||||
//std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
//std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||||||
t0 = t1;
|
t0 = t1;
|
||||||
}
|
}
|
||||||
LOG("renderer terminated");
|
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
SetTimer(hWnd, 1, 500, NULL);
|
SetTimer(hWnd, 1, 500, NULL);
|
||||||
|
|
||||||
if (start_in_vr)
|
if (start_in_vr)
|
||||||
@@ -1202,12 +1086,11 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tasklist.empty())
|
// if (!tasklist.empty())
|
||||||
ui_render_cv.notify_all();
|
// ui_render_cv.notify_all();
|
||||||
}
|
}
|
||||||
// Clean up
|
// Clean up
|
||||||
WacomTablet::I.terminate();
|
WacomTablet::I.terminate();
|
||||||
render_cv.notify_all();
|
|
||||||
|
|
||||||
UnregisterClass(className, hInst);
|
UnregisterClass(className, hInst);
|
||||||
LogRemote::I.stop();
|
LogRemote::I.stop();
|
||||||
@@ -1227,16 +1110,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
{
|
{
|
||||||
case WM_USER_CLOSE:
|
case WM_USER_CLOSE:
|
||||||
running = 0;
|
running = 0;
|
||||||
ui_render_cv.notify_all();
|
|
||||||
if (ui_renderer.joinable())
|
|
||||||
ui_renderer.join();
|
|
||||||
if (hmd_renderer.joinable())
|
if (hmd_renderer.joinable())
|
||||||
hmd_renderer.join();
|
hmd_renderer.join();
|
||||||
|
App::I.ui_thread_stop();
|
||||||
|
App::I.render_thread_stop();
|
||||||
App::I.terminate();
|
App::I.terminate();
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
render_running = false;
|
|
||||||
if (render_thread.joinable())
|
|
||||||
render_thread.join();
|
|
||||||
return 0;
|
return 0;
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
App::I.redraw = true;
|
App::I.redraw = true;
|
||||||
@@ -1246,8 +1125,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
break;
|
break;
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([] {
|
||||||
tasklist.emplace_back([=] {
|
|
||||||
if (App::I.request_close())
|
if (App::I.request_close())
|
||||||
{
|
{
|
||||||
destroy_window();
|
destroy_window();
|
||||||
@@ -1262,8 +1140,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
auto h = (float)HIWORD(lp);
|
auto h = (float)HIWORD(lp);
|
||||||
if (h != 0 && running == 1)
|
if (h != 0 && running == 1)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([=]
|
||||||
tasklist.emplace_back([=]
|
|
||||||
{
|
{
|
||||||
App::I.resize(w, h);
|
App::I.resize(w, h);
|
||||||
App::I.redraw = true;
|
App::I.redraw = true;
|
||||||
@@ -1273,8 +1150,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
}
|
}
|
||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([=] {
|
||||||
tasklist.emplace_back([=] {
|
|
||||||
int active = GET_WM_ACTIVATE_STATE(wp, lp);
|
int active = GET_WM_ACTIVATE_STATE(wp, lp);
|
||||||
WacomTablet::I.set_focus(active);
|
WacomTablet::I.set_focus(active);
|
||||||
static BYTE keys[256];
|
static BYTE keys[256];
|
||||||
@@ -1298,8 +1174,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
}
|
}
|
||||||
// case WM_TOUCH:
|
// case WM_TOUCH:
|
||||||
// {
|
// {
|
||||||
// std::lock_guard<std::mutex> lock(task_mutex);
|
// App::I.ui_task_async([=] {
|
||||||
// tasklist.emplace_back([=] {
|
|
||||||
// //LOG("touch");
|
// //LOG("touch");
|
||||||
// });
|
// });
|
||||||
// break;
|
// break;
|
||||||
@@ -1308,8 +1183,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
{
|
{
|
||||||
App::I.set_stylus();
|
App::I.set_stylus();
|
||||||
timer_stylus = 0;
|
timer_stylus = 0;
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([=] {
|
||||||
tasklist.emplace_back([=] {
|
|
||||||
WacomTablet::I.handle_message(hWnd, msg, wp, lp);
|
WacomTablet::I.handle_message(hWnd, msg, wp, lp);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -1319,8 +1193,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
if ((lp >> 30 & 1) == 0 && // ignore repeated
|
if ((lp >> 30 & 1) == 0 && // ignore repeated
|
||||||
!(wp == VK_TAB && App::I.keys[(int)kKey::KeyAlt])) // ignore alt+tab
|
!(wp == VK_TAB && App::I.keys[(int)kKey::KeyAlt])) // ignore alt+tab
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([wp] {
|
||||||
tasklist.emplace_back([wp] {
|
|
||||||
App::I.key_down(convert_key((int)wp));
|
App::I.key_down(convert_key((int)wp));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1329,16 +1202,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
if (!(wp == VK_TAB && App::I.keys[(int)kKey::KeyAlt])) // ignore alt+tab
|
if (!(wp == VK_TAB && App::I.keys[(int)kKey::KeyAlt])) // ignore alt+tab
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([wp] {
|
||||||
tasklist.emplace_back([wp] {
|
|
||||||
App::I.key_up(convert_key((int)wp));
|
App::I.key_up(convert_key((int)wp));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([wp]{
|
||||||
tasklist.emplace_back([wp]{
|
|
||||||
App::I.key_char((int)wp);
|
App::I.key_char((int)wp);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1362,8 +1233,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
||||||
|
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([pt, extra, p = WacomTablet::I.get_pressure()]{
|
||||||
tasklist.emplace_back([pt, extra, p = WacomTablet::I.get_pressure()]{
|
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
@@ -1382,9 +1252,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WM_LBUTTONDOWN:
|
case WM_LBUTTONDOWN:
|
||||||
{
|
{
|
||||||
SetCapture(hWnd);
|
SetCapture(hWnd);
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
tasklist.emplace_back([pt, extra, hWnd, p = WacomTablet::I.get_pressure()]{
|
App::I.ui_task_async([pt, extra, hWnd, p = WacomTablet::I.get_pressure()]{
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
@@ -1403,9 +1272,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WM_LBUTTONUP:
|
case WM_LBUTTONUP:
|
||||||
{
|
{
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
tasklist.emplace_back([pt, extra] {
|
App::I.ui_task_async([pt, extra] {
|
||||||
WacomTablet::I.reset_pressure();
|
WacomTablet::I.reset_pressure();
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
@@ -1425,9 +1293,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WM_RBUTTONDOWN:
|
case WM_RBUTTONDOWN:
|
||||||
{
|
{
|
||||||
SetCapture(hWnd);
|
SetCapture(hWnd);
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
tasklist.emplace_back([pt, extra, hWnd] {
|
App::I.ui_task_async([pt, extra, hWnd] {
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
@@ -1446,9 +1313,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
case WM_RBUTTONUP:
|
case WM_RBUTTONUP:
|
||||||
{
|
{
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
|
||||||
auto pt = lastPoint;
|
auto pt = lastPoint;
|
||||||
tasklist.emplace_back([pt, extra] {
|
App::I.ui_task_async([pt, extra] {
|
||||||
kEventSource pointer_source;
|
kEventSource pointer_source;
|
||||||
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
if (WacomTablet::I.m_ink_pen || WacomTablet::I.m_ink_touch)
|
||||||
{
|
{
|
||||||
@@ -1471,8 +1337,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
pt.y = GET_Y_LPARAM(lp);
|
pt.y = GET_Y_LPARAM(lp);
|
||||||
ScreenToClient(hWnd, &pt);
|
ScreenToClient(hWnd, &pt);
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(task_mutex);
|
App::I.ui_task_async([pt, wp] {
|
||||||
tasklist.emplace_back([pt, wp] {
|
|
||||||
App::I.mouse_scroll((float)pt.x, (float)pt.y,
|
App::I.mouse_scroll((float)pt.x, (float)pt.y,
|
||||||
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user