decouple windows events and render in a separate thread for better response
This commit is contained in:
@@ -438,7 +438,7 @@
|
|||||||
<Filter>libs\yoga</Filter>
|
<Filter>libs\yoga</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="engine\node_panel_grid.h">
|
<ClInclude Include="engine\node_panel_grid.h">
|
||||||
<Filter>Source Files\ui</Filter>
|
<Filter>Header Files\ui</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ void android_async_lock(struct engine* engine);
|
|||||||
void android_async_swap(struct engine* engine);
|
void android_async_swap(struct engine* engine);
|
||||||
void android_async_unlock(struct engine* engine);
|
void android_async_unlock(struct engine* engine);
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
|
bool async_lock_try();
|
||||||
void async_lock();
|
void async_lock();
|
||||||
void async_swap();
|
void async_swap();
|
||||||
void async_unlock();
|
void async_unlock();
|
||||||
@@ -119,7 +120,7 @@ void App::initLog()
|
|||||||
rec_path = data_path + "\\frames";
|
rec_path = data_path + "\\frames";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LogRemote::I.start();
|
//LogRemote::I.start();
|
||||||
LogRemote::I.file_init();
|
LogRemote::I.file_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
105
engine/main.cpp
105
engine/main.cpp
@@ -23,9 +23,12 @@ std::mutex gl_mutex;
|
|||||||
std::mutex async_mutex;
|
std::mutex async_mutex;
|
||||||
std::thread::id gl_thread;
|
std::thread::id gl_thread;
|
||||||
int gl_count = 0;
|
int gl_count = 0;
|
||||||
|
std::deque<std::packaged_task<void()>> tasklist;
|
||||||
|
|
||||||
#include <WbemCli.h>
|
#include <WbemCli.h>
|
||||||
#include "wacom.h"
|
#include "wacom.h"
|
||||||
|
#include <deque>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
|
//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
|
||||||
std::string GetLastErrorAsString()
|
std::string GetLastErrorAsString()
|
||||||
@@ -68,6 +71,24 @@ void async_lock()
|
|||||||
//assert(ret == true);
|
//assert(ret == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool async_lock_try()
|
||||||
|
{
|
||||||
|
//std::lock_guard<std::mutex> _lock(async_mutex);
|
||||||
|
if (gl_count == 0 || gl_thread != std::this_thread::get_id())
|
||||||
|
{
|
||||||
|
if (!gl_mutex.try_lock())
|
||||||
|
return false;
|
||||||
|
bool ret = wglMakeCurrent(hDC, hRC);
|
||||||
|
if (ret == false)
|
||||||
|
LOG("FAILED wglMakeCurrent: %s", GetLastErrorAsString().c_str());
|
||||||
|
gl_thread = std::this_thread::get_id();
|
||||||
|
//LOG("lock");
|
||||||
|
}
|
||||||
|
gl_count++;
|
||||||
|
//assert(ret == true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void async_swap()
|
void async_swap()
|
||||||
{
|
{
|
||||||
SwapBuffers(hDC);
|
SwapBuffers(hDC);
|
||||||
@@ -401,30 +422,37 @@ int main(int argc, char** argv)
|
|||||||
App::I.redraw = true;
|
App::I.redraw = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
MSG msg;
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
unsigned long t0 = GetTickCount();
|
std::mutex render_mutex;
|
||||||
unsigned long t1;
|
std::condition_variable render_cv;
|
||||||
float one_sec = 0;
|
|
||||||
while (running)
|
std::thread renderer([&] {
|
||||||
{
|
const float target_fps = 10;
|
||||||
// If there any message in the queue process it
|
unsigned long t0 = GetTickCount();
|
||||||
auto present = App::I.animate || App::I.redraw ?
|
unsigned long t1;
|
||||||
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
|
int frames = 0;
|
||||||
|
float one_sec = 0;
|
||||||
running = !(msg.message == WM_QUIT/* || gl.keys[VK_ESCAPE]*/);
|
float render_timer = 0;
|
||||||
if (present)
|
while(running)
|
||||||
{
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
}
|
|
||||||
//else // Otherwise render next frame
|
|
||||||
{
|
{
|
||||||
t1 = GetTickCount();
|
t1 = GetTickCount();
|
||||||
float dt = (float)(t1 - t0) / 1000.0f;
|
float dt = (float)(t1 - t0) / 1000.0f;
|
||||||
if (dt > 1.0f / 60.0f || App::I.redraw)
|
one_sec += dt;
|
||||||
|
render_timer += dt;
|
||||||
|
t0 = t1;
|
||||||
|
|
||||||
|
if (one_sec > 1.f)
|
||||||
{
|
{
|
||||||
t0 = t1;
|
static char title[512];
|
||||||
|
sprintf_s(title, "PanoPainter 0.1.2 alpha - OpenGL 3.1 - %d fps", frames);
|
||||||
|
SetWindowTextA(hWnd, title);
|
||||||
|
one_sec = 0;
|
||||||
|
frames = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (render_timer > 1.0f / target_fps || App::I.redraw)
|
||||||
|
{
|
||||||
|
render_timer = 0;
|
||||||
if (App::I.redraw)
|
if (App::I.redraw)
|
||||||
{
|
{
|
||||||
async_lock();
|
async_lock();
|
||||||
@@ -437,8 +465,39 @@ int main(int argc, char** argv)
|
|||||||
//LOG("swap main");
|
//LOG("swap main");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
frames++;
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> lock(render_mutex);
|
||||||
|
const int framerate = (1.f / target_fps) * 1000;
|
||||||
|
const int diff = framerate - (t1 - t0);
|
||||||
|
render_cv.wait_for(lock, std::chrono::milliseconds(diff));
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MSG msg;
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
while (!tasklist.empty())
|
||||||
|
{
|
||||||
|
tasklist.front()();
|
||||||
|
tasklist.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there any message in the queue process it
|
||||||
|
auto present = App::I.animate || App::I.redraw ?
|
||||||
|
PeekMessage(&msg, 0, 0, 0, PM_REMOVE) : GetMessage(&msg, 0, 0, 0);
|
||||||
|
|
||||||
|
running = !(msg.message == WM_QUIT/* || gl.keys[VK_ESCAPE]*/);
|
||||||
|
if (present)
|
||||||
|
{
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
}
|
||||||
|
render_cv.notify_all();
|
||||||
}
|
}
|
||||||
|
render_cv.notify_all();
|
||||||
|
if (renderer.joinable())
|
||||||
|
renderer.join();
|
||||||
App::I.terminate();
|
App::I.terminate();
|
||||||
// Clean up
|
// Clean up
|
||||||
WacomTablet::I.terminate();
|
WacomTablet::I.terminate();
|
||||||
@@ -509,7 +568,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
async_unlock();
|
async_unlock();
|
||||||
break;
|
break;
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
async_lock();
|
if (!async_lock_try())
|
||||||
|
{
|
||||||
|
tasklist.emplace_back([lp,p=WacomTablet::I.get_pressure()] {
|
||||||
|
App::I.mouse_move((float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), p, kEventSource::Mouse);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
|
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
|
||||||
if (0 && leftDown)
|
if (0 && leftDown)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user