move render thread to App class and add ui thread with ui tasks queue

This commit is contained in:
2019-07-09 01:07:13 +02:00
parent f7ead8e157
commit cb6744be44
6 changed files with 239 additions and 194 deletions

View File

@@ -33,23 +33,11 @@ std::thread::id gl_thread;
std::map<kKey, int> vkey_map;
std::thread hmd_renderer;
std::thread ui_renderer;
int vr_frames = 0;
int running = -1;
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;
std::deque<std::packaged_task<void()>> tasklist;
std::mutex task_mutex;
std::deque<std::packaged_task<void()>> main_tasklist;
std::mutex main_task_mutex;
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()
{
//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)
{
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;
}
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)
{
WNDCLASS wc;
@@ -1015,7 +901,8 @@ int main(int argc, char** argv)
wglMakeCurrent(NULL, NULL);
running = 1;
render_thread = std::thread(render_thread_main);
App::I.render_thread_start();
App::I.ui_thread_start();
LOG("init app");
App::I.init();
@@ -1034,6 +921,17 @@ int main(int argc, char** argv)
SendMessage(hWnd, WM_SETICON, ICON_SMALL,
(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([&] {
BT_SetTerminate();
LOG("start render thread");
@@ -1041,7 +939,6 @@ int main(int argc, char** argv)
const float target_tick_rate = 10;
unsigned long t0 = GetTickCount64();
unsigned long t1;
bool first_frame = true;
int frames = 0;
float one_sec = 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);
std::unique_lock<std::mutex> lock(ui_render_mutex);
@@ -1134,7 +1019,7 @@ int main(int argc, char** argv)
if (App::I.redraw)
{
App::I.update(frame_timer);
render_task([frame_timer]
App::I.render_task([frame_timer]
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
App::I.clear();
@@ -1151,9 +1036,8 @@ int main(int argc, char** argv)
//std::this_thread::sleep_for(std::chrono::milliseconds(30));
t0 = t1;
}
LOG("renderer terminated");
});
*/
SetTimer(hWnd, 1, 500, NULL);
if (start_in_vr)
@@ -1202,12 +1086,11 @@ int main(int argc, char** argv)
}
}
if (!tasklist.empty())
ui_render_cv.notify_all();
// if (!tasklist.empty())
// ui_render_cv.notify_all();
}
// Clean up
WacomTablet::I.terminate();
render_cv.notify_all();
UnregisterClass(className, hInst);
LogRemote::I.stop();
@@ -1227,16 +1110,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
case WM_USER_CLOSE:
running = 0;
ui_render_cv.notify_all();
if (ui_renderer.joinable())
ui_renderer.join();
if (hmd_renderer.joinable())
hmd_renderer.join();
App::I.ui_thread_stop();
App::I.render_thread_stop();
App::I.terminate();
PostQuitMessage(0);
render_running = false;
if (render_thread.joinable())
render_thread.join();
return 0;
case WM_PAINT:
App::I.redraw = true;
@@ -1246,8 +1125,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
break;
case WM_CLOSE:
{
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([=] {
App::I.ui_task_async([] {
if (App::I.request_close())
{
destroy_window();
@@ -1262,8 +1140,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
auto h = (float)HIWORD(lp);
if (h != 0 && running == 1)
{
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([=]
App::I.ui_task_async([=]
{
App::I.resize(w, h);
App::I.redraw = true;
@@ -1273,8 +1150,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
}
case WM_ACTIVATE:
{
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([=] {
App::I.ui_task_async([=] {
int active = GET_WM_ACTIVATE_STATE(wp, lp);
WacomTablet::I.set_focus(active);
static BYTE keys[256];
@@ -1298,8 +1174,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
}
// case WM_TOUCH:
// {
// std::lock_guard<std::mutex> lock(task_mutex);
// tasklist.emplace_back([=] {
// App::I.ui_task_async([=] {
// //LOG("touch");
// });
// break;
@@ -1308,8 +1183,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
App::I.set_stylus();
timer_stylus = 0;
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([=] {
App::I.ui_task_async([=] {
WacomTablet::I.handle_message(hWnd, msg, wp, lp);
});
break;
@@ -1319,8 +1193,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
if ((lp >> 30 & 1) == 0 && // ignore repeated
!(wp == VK_TAB && App::I.keys[(int)kKey::KeyAlt])) // ignore alt+tab
{
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([wp] {
App::I.ui_task_async([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:
if (!(wp == VK_TAB && App::I.keys[(int)kKey::KeyAlt])) // ignore alt+tab
{
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([wp] {
App::I.ui_task_async([wp] {
App::I.key_up(convert_key((int)wp));
});
}
break;
case WM_CHAR:
{
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([wp]{
App::I.ui_task_async([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) };
auto pt = lastPoint;
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([pt, extra, p = WacomTablet::I.get_pressure()]{
App::I.ui_task_async([pt, extra, p = WacomTablet::I.get_pressure()]{
kEventSource pointer_source;
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:
{
SetCapture(hWnd);
std::lock_guard<std::mutex> lock(task_mutex);
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;
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:
{
ReleaseCapture();
std::lock_guard<std::mutex> lock(task_mutex);
auto pt = lastPoint;
tasklist.emplace_back([pt, extra] {
App::I.ui_task_async([pt, extra] {
WacomTablet::I.reset_pressure();
kEventSource pointer_source;
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:
{
SetCapture(hWnd);
std::lock_guard<std::mutex> lock(task_mutex);
auto pt = lastPoint;
tasklist.emplace_back([pt, extra, hWnd] {
App::I.ui_task_async([pt, extra, hWnd] {
kEventSource pointer_source;
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:
{
ReleaseCapture();
std::lock_guard<std::mutex> lock(task_mutex);
auto pt = lastPoint;
tasklist.emplace_back([pt, extra] {
App::I.ui_task_async([pt, extra] {
kEventSource pointer_source;
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);
ScreenToClient(hWnd, &pt);
{
std::lock_guard<std::mutex> lock(task_mutex);
tasklist.emplace_back([pt, wp] {
App::I.ui_task_async([pt, wp] {
App::I.mouse_scroll((float)pt.x, (float)pt.y,
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
});