restore multithreading on iOS and use DisplayLink to decouple rendering from the main loop
This commit is contained in:
@@ -14,6 +14,8 @@
|
||||
|
||||
std::deque<std::packaged_task<void()>> tasklist;
|
||||
std::mutex task_mutex;
|
||||
std::mutex render_mutex;
|
||||
std::condition_variable render_cv;
|
||||
|
||||
@interface GameImagePicker : UIImagePickerController
|
||||
{
|
||||
@@ -432,6 +434,64 @@ std::set<UITouch*> ignored_touch;
|
||||
return YES;
|
||||
}
|
||||
|
||||
-(void)tick
|
||||
{
|
||||
//std::lock_guard<std::mutex> lock(render_mutex);
|
||||
render_cv.notify_one();
|
||||
}
|
||||
|
||||
-(void)render_loop
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
static auto time = std::chrono::steady_clock::now();
|
||||
static double elapsed = 0;
|
||||
static double min_fps_timer = 0;
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto dt = std::chrono::duration<float>(now - time);
|
||||
time = now;
|
||||
elapsed += dt.count();
|
||||
min_fps_timer += dt.count();
|
||||
|
||||
if (min_fps_timer > 0.5)
|
||||
{
|
||||
App::I.redraw = true;
|
||||
min_fps_timer = 0;
|
||||
}
|
||||
|
||||
std::deque<std::packaged_task<void()>> working_list;
|
||||
if (!tasklist.empty())
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
working_list = std::move(tasklist);
|
||||
}
|
||||
|
||||
App::I.tick(dt.count());
|
||||
|
||||
if (!(App::I.redraw || App::I.animate || !working_list.empty()))
|
||||
{
|
||||
//[self.context presentRenderbuffer:GL_FRAMEBUFFER];
|
||||
//[self async_unlock];
|
||||
std::unique_lock<std::mutex> lock(render_mutex);
|
||||
render_cv.wait(lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
[self async_lock];
|
||||
while (!working_list.empty())
|
||||
{
|
||||
working_list.front()();
|
||||
working_list.pop_front();
|
||||
}
|
||||
App::I.clear();
|
||||
App::I.update(elapsed);
|
||||
[self.context presentRenderbuffer:GL_FRAMEBUFFER];
|
||||
[self async_unlock];
|
||||
[self->glview display];
|
||||
elapsed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupGL
|
||||
{
|
||||
[self async_lock];
|
||||
@@ -439,54 +499,12 @@ std::set<UITouch*> ignored_touch;
|
||||
[self async_unlock];
|
||||
|
||||
std::thread([self]{
|
||||
while (true)
|
||||
{
|
||||
static auto time = std::chrono::steady_clock::now();
|
||||
static double elapsed = 0;
|
||||
static double min_fps_timer = 0;
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
auto dt = std::chrono::duration<float>(now - time);
|
||||
time = now;
|
||||
elapsed += dt.count();
|
||||
min_fps_timer += dt.count();
|
||||
|
||||
if (min_fps_timer > 0.1)
|
||||
{
|
||||
App::I.redraw = true;
|
||||
min_fps_timer = 0;
|
||||
}
|
||||
|
||||
std::deque<std::packaged_task<void()>> working_list;
|
||||
if (!tasklist.empty())
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(task_mutex);
|
||||
working_list = std::move(tasklist);
|
||||
}
|
||||
|
||||
App::I.tick(dt.count());
|
||||
|
||||
[self async_lock];
|
||||
if (!(App::I.redraw || App::I.animate || !working_list.empty()))
|
||||
{
|
||||
//[self.context presentRenderbuffer:GL_FRAMEBUFFER];
|
||||
[self async_unlock];
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
while (!working_list.empty())
|
||||
{
|
||||
working_list.front()();
|
||||
working_list.pop_front();
|
||||
}
|
||||
App::I.clear();
|
||||
App::I.update(elapsed);
|
||||
[self.context presentRenderbuffer:GL_FRAMEBUFFER];
|
||||
[self async_unlock];
|
||||
[self->glview display];
|
||||
elapsed = 0;
|
||||
}
|
||||
[self render_loop];
|
||||
}).detach();
|
||||
|
||||
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick)];
|
||||
displayLink.frameInterval = 4;
|
||||
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
|
||||
}
|
||||
|
||||
- (void)tearDownGL
|
||||
|
||||
Reference in New Issue
Block a user