diff --git a/engine.vcxproj.filters b/engine.vcxproj.filters index 9d7a3ca..b681c9b 100644 --- a/engine.vcxproj.filters +++ b/engine.vcxproj.filters @@ -438,7 +438,7 @@ libs\yoga - Source Files\ui + Header Files\ui diff --git a/engine/app.cpp b/engine/app.cpp index 9a83d3a..08b579c 100644 --- a/engine/app.cpp +++ b/engine/app.cpp @@ -14,6 +14,7 @@ void android_async_lock(struct engine* engine); void android_async_swap(struct engine* engine); void android_async_unlock(struct engine* engine); #elif _WIN32 +bool async_lock_try(); void async_lock(); void async_swap(); void async_unlock(); @@ -119,7 +120,7 @@ void App::initLog() rec_path = data_path + "\\frames"; #endif - LogRemote::I.start(); + //LogRemote::I.start(); LogRemote::I.file_init(); } diff --git a/engine/main.cpp b/engine/main.cpp index 5a1c992..dbfb2b6 100644 --- a/engine/main.cpp +++ b/engine/main.cpp @@ -23,9 +23,12 @@ std::mutex gl_mutex; std::mutex async_mutex; std::thread::id gl_thread; int gl_count = 0; +std::deque> tasklist; #include #include "wacom.h" +#include +#include //Returns the last Win32 error, in string format. Returns an empty string if there is no error. std::string GetLastErrorAsString() @@ -68,6 +71,24 @@ void async_lock() //assert(ret == true); } +bool async_lock_try() +{ + //std::lock_guard _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() { SwapBuffers(hDC); @@ -401,30 +422,37 @@ int main(int argc, char** argv) App::I.redraw = true; }); - MSG msg; bool running = true; - unsigned long t0 = GetTickCount(); - unsigned long t1; - float one_sec = 0; - while (running) - { - // 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); - } - //else // Otherwise render next frame + std::mutex render_mutex; + std::condition_variable render_cv; + + std::thread renderer([&] { + const float target_fps = 10; + unsigned long t0 = GetTickCount(); + unsigned long t1; + int frames = 0; + float one_sec = 0; + float render_timer = 0; + while(running) { t1 = GetTickCount(); 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) { async_lock(); @@ -437,8 +465,39 @@ int main(int argc, char** argv) //LOG("swap main"); } } + frames++; + + std::unique_lock 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(); // Clean up WacomTablet::I.terminate(); @@ -509,7 +568,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) async_unlock(); break; 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 if (0 && leftDown) {