fix multithread render issues and cleanup the code

This commit is contained in:
2018-08-08 15:59:33 +02:00
parent 91add1b0b3
commit d57d4f3490
2 changed files with 95 additions and 104 deletions

View File

@@ -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:

View File

@@ -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);