fix multithread render issues and cleanup the code
This commit is contained in:
197
engine/main.cpp
197
engine/main.cpp
@@ -8,10 +8,17 @@
|
||||
#include "keymap.h"
|
||||
#include "../resource.h"
|
||||
|
||||
#include <WbemCli.h>
|
||||
#include "wacom.h"
|
||||
#include <deque>
|
||||
#include <chrono>
|
||||
|
||||
#pragma comment (lib, "opengl32.lib")
|
||||
#pragma comment (lib, "glew32.lib")
|
||||
#pragma comment(lib, "wbemuuid.lib")
|
||||
|
||||
#define WM_USER_CLOSE (WM_USER + 1)
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);
|
||||
HINSTANCE hInst;
|
||||
HWND hWnd;
|
||||
@@ -24,11 +31,7 @@ std::mutex async_mutex;
|
||||
std::thread::id gl_thread;
|
||||
int gl_count = 0;
|
||||
std::deque<std::packaged_task<void()>> tasklist;
|
||||
|
||||
#include <WbemCli.h>
|
||||
#include "wacom.h"
|
||||
#include <deque>
|
||||
#include <chrono>
|
||||
std::mutex task_mutex;
|
||||
|
||||
//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
|
||||
std::string GetLastErrorAsString()
|
||||
@@ -52,7 +55,7 @@ std::string GetLastErrorAsString()
|
||||
|
||||
void destroy_window()
|
||||
{
|
||||
DestroyWindow(hWnd);
|
||||
SendMessage(hWnd, WM_USER_CLOSE, 0, 0);
|
||||
}
|
||||
|
||||
void async_lock()
|
||||
@@ -427,6 +430,7 @@ int main(int argc, char** argv)
|
||||
std::condition_variable render_cv;
|
||||
|
||||
std::thread renderer([&] {
|
||||
BT_SetTerminate();
|
||||
const float target_fps = 10;
|
||||
unsigned long t0 = GetTickCount();
|
||||
unsigned long t1;
|
||||
@@ -450,6 +454,24 @@ int main(int argc, char** argv)
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
{
|
||||
std::deque<std::packaged_task<void()>> working_list;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
working_list = std::move(tasklist);
|
||||
}
|
||||
|
||||
async_lock();
|
||||
while (!working_list.empty())
|
||||
{
|
||||
|
||||
working_list.front()();
|
||||
working_list.pop_front();
|
||||
}
|
||||
async_unlock();
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(render_mutex);
|
||||
if (render_timer > 1.0f / target_fps || App::I.redraw)
|
||||
{
|
||||
render_timer = 0;
|
||||
@@ -467,7 +489,6 @@ int main(int argc, char** argv)
|
||||
}
|
||||
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));
|
||||
@@ -477,12 +498,6 @@ int main(int argc, char** argv)
|
||||
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);
|
||||
@@ -493,7 +508,9 @@ int main(int argc, char** argv)
|
||||
DispatchMessage(&msg);
|
||||
TranslateMessage(&msg);
|
||||
}
|
||||
render_cv.notify_all();
|
||||
|
||||
if (!tasklist.empty())
|
||||
render_cv.notify_all();
|
||||
}
|
||||
render_cv.notify_all();
|
||||
if (renderer.joinable())
|
||||
@@ -501,7 +518,7 @@ int main(int argc, char** argv)
|
||||
App::I.terminate();
|
||||
// Clean up
|
||||
WacomTablet::I.terminate();
|
||||
DestroyWindow(hWnd);
|
||||
//DestroyWindow(hWnd);
|
||||
UnregisterClass(className, hInst);
|
||||
LogRemote::I.stop();
|
||||
}
|
||||
@@ -513,6 +530,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
static POINT lastPoint;
|
||||
switch (msg)
|
||||
{
|
||||
case WM_USER_CLOSE:
|
||||
DestroyWindow(hWnd);
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_PAINT:
|
||||
App::I.redraw = true;
|
||||
break;
|
||||
@@ -522,7 +543,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
case WM_CLOSE:
|
||||
if (App::I.request_close())
|
||||
PostQuitMessage(0);
|
||||
else return true;
|
||||
else
|
||||
return true;
|
||||
break;
|
||||
case WM_SIZE:
|
||||
{
|
||||
@@ -550,112 +572,76 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
break;
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
async_lock();
|
||||
keys[wp] = true;
|
||||
App::I.key_down(convert_key((int)wp));
|
||||
async_unlock();
|
||||
break;
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
async_lock();
|
||||
keys[wp] = false;
|
||||
App::I.key_up(convert_key((int)wp));
|
||||
async_unlock();
|
||||
break;
|
||||
case WM_CHAR:
|
||||
async_lock();
|
||||
App::I.key_char((int)wp);
|
||||
async_unlock();
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
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);
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([wp] {
|
||||
App::I.key_down(convert_key((int)wp));
|
||||
});
|
||||
break;
|
||||
}
|
||||
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
|
||||
if (0 && leftDown)
|
||||
break;
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
POINT pt = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
||||
// See discussion for why this code is wrong
|
||||
ClientToScreen(hWnd, &pt);
|
||||
MOUSEMOVEPOINT mmpt = { pt.x & 0x0000FFFF, pt.y & 0x0000FFFF, GetMessageTime() };
|
||||
MOUSEMOVEPOINT rgmmpt[64];
|
||||
int cmmpt = GetMouseMovePointsEx(sizeof(mmpt), &mmpt,
|
||||
rgmmpt, 64, GMMP_USE_DISPLAY_POINTS);
|
||||
|
||||
if (cmmpt == -1 || cmmpt == 64)
|
||||
{
|
||||
App::I.mouse_move((float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), WacomTablet::I.get_pressure(), kEventSource::Mouse);
|
||||
lastPoint = pt;
|
||||
lastTime = GetMessageTime();
|
||||
break;
|
||||
}
|
||||
|
||||
POINT ptLastScreen = lastPoint;
|
||||
ClientToScreen(hWnd, &ptLastScreen);
|
||||
int i;
|
||||
for (i = 0; i < cmmpt; i++)
|
||||
{
|
||||
if (rgmmpt[i].x > 32767) rgmmpt[i].x -= 65536;
|
||||
if (rgmmpt[i].y > 32767) rgmmpt[i].y -= 65536;
|
||||
LOG("x %4d y %4d", rgmmpt[i].x, rgmmpt[i].y);
|
||||
|
||||
if (rgmmpt[i].time < lastTime) break;
|
||||
if (rgmmpt[i].time == lastTime &&
|
||||
rgmmpt[i].x == ptLastScreen.x &&
|
||||
rgmmpt[i].y == ptLastScreen.y) break;
|
||||
}
|
||||
while (--i >= 0)
|
||||
{
|
||||
POINT ptClient = { rgmmpt[i].x, rgmmpt[i].y };
|
||||
ScreenToClient(hWnd, &ptClient);
|
||||
if (ptClient.x != lastPoint.x || ptClient.y != lastPoint.y)
|
||||
{
|
||||
lastPoint = ptClient;
|
||||
App::I.mouse_move((float)ptClient.x, (float)ptClient.y, WacomTablet::I.get_pressure(), kEventSource::Mouse);
|
||||
}
|
||||
}
|
||||
lastTime = GetMessageTime();
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([wp] {
|
||||
App::I.key_up(convert_key((int)wp));
|
||||
});
|
||||
}
|
||||
else
|
||||
break;
|
||||
case WM_CHAR:
|
||||
{
|
||||
App::I.mouse_move((float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), WacomTablet::I.get_pressure(), kEventSource::Mouse);
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([wp]{
|
||||
App::I.key_char((int)wp);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
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);
|
||||
});
|
||||
}
|
||||
async_unlock();
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
|
||||
async_lock();
|
||||
leftDown = true;
|
||||
SetCapture(hWnd);
|
||||
lastTime = GetMessageTime();
|
||||
lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
|
||||
App::I.mouse_down(0, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), WacomTablet::I.get_pressure(), kEventSource::Mouse);
|
||||
async_unlock();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([lp, p = WacomTablet::I.get_pressure()]{
|
||||
App::I.mouse_down(0, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), p, kEventSource::Mouse);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
async_lock();
|
||||
WacomTablet::I.reset_pressure();
|
||||
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
|
||||
App::I.mouse_up(0, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), kEventSource::Mouse);
|
||||
ReleaseCapture();
|
||||
leftDown = false;
|
||||
async_unlock();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([lp]{
|
||||
App::I.mouse_up(0, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), kEventSource::Mouse);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
async_lock();
|
||||
App::I.mouse_down(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), 1.f, kEventSource::Mouse);
|
||||
SetCapture(hWnd);
|
||||
async_unlock();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([lp]{
|
||||
App::I.mouse_down(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), 1.f, kEventSource::Mouse);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case WM_RBUTTONUP:
|
||||
async_lock();
|
||||
App::I.mouse_up(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), kEventSource::Mouse);
|
||||
ReleaseCapture();
|
||||
async_unlock();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([lp]{
|
||||
App::I.mouse_up(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), kEventSource::Mouse);
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
{
|
||||
@@ -664,8 +650,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
pt.x = GET_X_LPARAM(lp);
|
||||
pt.y = GET_Y_LPARAM(lp);
|
||||
ScreenToClient(hWnd, &pt);
|
||||
App::I.mouse_scroll((float)pt.x, (float)pt.y,
|
||||
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
tasklist.emplace_back([pt, wp] {
|
||||
App::I.mouse_scroll((float)pt.x, (float)pt.y,
|
||||
(float)GET_WHEEL_DELTA_WPARAM(wp) / (float)WHEEL_DELTA);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_POINTERUPDATE:
|
||||
|
||||
@@ -20,7 +20,7 @@ void NodeImageTexture::draw()
|
||||
{
|
||||
using namespace ui;
|
||||
tex.bind();
|
||||
auto& sampler = tex.has_mips ? NodeImage::m_sampler : NodeImage::m_sampler_mips;
|
||||
auto& sampler = tex.has_mips ? NodeImage::m_sampler_mips : NodeImage::m_sampler;
|
||||
sampler.bind(0);
|
||||
glEnable(GL_BLEND);
|
||||
ui::ShaderManager::use(kShader::Texture);
|
||||
|
||||
Reference in New Issue
Block a user