restore multithreading on iOS and use DisplayLink to decouple rendering from the main loop

This commit is contained in:
2019-03-01 15:16:05 +01:00
parent 8cd02787b3
commit 27f4cb3ba8
4 changed files with 69 additions and 81 deletions

View File

@@ -21,6 +21,7 @@
> >
{ {
@public GameView* glview; @public GameView* glview;
@public CADisplayLink *displayLink;
} }
- (void)display_file:(std::string)filename; - (void)display_file:(std::string)filename;
- (void)reset_touch; - (void)reset_touch;
@@ -32,4 +33,6 @@
- (void)unregisterForKeyboardNotifications; - (void)unregisterForKeyboardNotifications;
- (void)crash; - (void)crash;
- (void)share_file:(NSString*)file_path; - (void)share_file:(NSString*)file_path;
- (void)tick;
- (void)render_loop;
@end @end

View File

@@ -14,6 +14,8 @@
std::deque<std::packaged_task<void()>> tasklist; std::deque<std::packaged_task<void()>> tasklist;
std::mutex task_mutex; std::mutex task_mutex;
std::mutex render_mutex;
std::condition_variable render_cv;
@interface GameImagePicker : UIImagePickerController @interface GameImagePicker : UIImagePickerController
{ {
@@ -432,13 +434,14 @@ std::set<UITouch*> ignored_touch;
return YES; return YES;
} }
- (void)setupGL -(void)tick
{ {
[self async_lock]; //std::lock_guard<std::mutex> lock(render_mutex);
App::I.init(); render_cv.notify_one();
[self async_unlock]; }
std::thread([self]{ -(void)render_loop
{
while (true) while (true)
{ {
static auto time = std::chrono::steady_clock::now(); static auto time = std::chrono::steady_clock::now();
@@ -450,7 +453,7 @@ std::set<UITouch*> ignored_touch;
elapsed += dt.count(); elapsed += dt.count();
min_fps_timer += dt.count(); min_fps_timer += dt.count();
if (min_fps_timer > 0.1) if (min_fps_timer > 0.5)
{ {
App::I.redraw = true; App::I.redraw = true;
min_fps_timer = 0; min_fps_timer = 0;
@@ -465,15 +468,16 @@ std::set<UITouch*> ignored_touch;
App::I.tick(dt.count()); App::I.tick(dt.count());
[self async_lock];
if (!(App::I.redraw || App::I.animate || !working_list.empty())) if (!(App::I.redraw || App::I.animate || !working_list.empty()))
{ {
//[self.context presentRenderbuffer:GL_FRAMEBUFFER]; //[self.context presentRenderbuffer:GL_FRAMEBUFFER];
[self async_unlock]; //[self async_unlock];
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::unique_lock<std::mutex> lock(render_mutex);
render_cv.wait(lock);
continue; continue;
} }
[self async_lock];
while (!working_list.empty()) while (!working_list.empty())
{ {
working_list.front()(); working_list.front()();
@@ -486,7 +490,21 @@ std::set<UITouch*> ignored_touch;
[self->glview display]; [self->glview display];
elapsed = 0; elapsed = 0;
} }
}
- (void)setupGL
{
[self async_lock];
App::I.init();
[self async_unlock];
std::thread([self]{
[self render_loop];
}).detach(); }).detach();
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick)];
displayLink.frameInterval = 4;
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
} }
- (void)tearDownGL - (void)tearDownGL

View File

@@ -1176,10 +1176,6 @@ void Canvas::clear_context()
void Canvas::import_equirectangular(std::string file_path) void Canvas::import_equirectangular(std::string file_path)
{ {
#if __IOS__
import_equirectangular_thread(file_path);
return;
#endif
std::thread t(&Canvas::import_equirectangular_thread, this, file_path); std::thread t(&Canvas::import_equirectangular_thread, this, file_path);
t.detach(); t.detach();
} }
@@ -1253,12 +1249,6 @@ void Canvas::export_equirectangular(std::string file_path, std::function<void()>
{ {
if (App::I.check_license()) if (App::I.check_license())
{ {
#if __IOS__
export_equirectangular_thread(file_path);
if (on_complete)
on_complete();
return;
#endif
std::thread t([=] { std::thread t([=] {
export_equirectangular_thread(file_path); export_equirectangular_thread(file_path);
if (on_complete) if (on_complete)
@@ -1563,12 +1553,6 @@ void Canvas::export_layers(std::string file_name, std::function<void()> on_compl
{ {
if (App::I.check_license()) if (App::I.check_license())
{ {
#if __IOS__
export_layers_thread(file_name);
if (on_complete)
on_complete();
return;
#endif
std::thread t([=] { std::thread t([=] {
export_layers_thread(file_name); export_layers_thread(file_name);
if (on_complete) if (on_complete)
@@ -1824,12 +1808,6 @@ void Canvas::project_save(std::function<void(bool)> on_complete)
{ {
if (App::I.check_license()) if (App::I.check_license())
{ {
#if __IOS__
bool ret = project_save_thread(App::I.doc_path);
if (on_complete)
on_complete(ret);
return;
#endif
std::thread t([=] { std::thread t([=] {
bool ret = project_save_thread(App::I.doc_path); bool ret = project_save_thread(App::I.doc_path);
if (on_complete) if (on_complete)
@@ -1844,12 +1822,6 @@ void Canvas::project_save(std::string file_path, std::function<void(bool)> on_co
LOG("saving %s", file_path.c_str()); LOG("saving %s", file_path.c_str());
if (App::I.check_license()) if (App::I.check_license())
{ {
#if __IOS__
bool ret = project_save_thread(file_path);
if (on_complete)
on_complete(ret);
return;
#endif
std::thread t([=] { std::thread t([=] {
bool ret = project_save_thread(file_path); bool ret = project_save_thread(file_path);
if (on_complete) if (on_complete)
@@ -2046,12 +2018,6 @@ bool Canvas::project_save_thread(std::string file_path)
void Canvas::project_open(std::string file_path, std::function<void(bool)> on_complete) void Canvas::project_open(std::string file_path, std::function<void(bool)> on_complete)
{ {
#if __IOS__
bool ret = project_open_thread(file_path);
if (on_complete)
on_complete(ret);
return;
#endif
std::thread t([=] { std::thread t([=] {
bool result = project_open_thread(file_path); bool result = project_open_thread(file_path);
if (on_complete) if (on_complete)

View File

@@ -492,6 +492,7 @@ void NodeStrokePreview::draw_stroke()
gl.save(); gl.save();
node->draw_stroke_immediate(); node->draw_stroke_immediate();
gl.restore(); gl.restore();
node->app_redraw();
node->async_end(); node->async_end();
std::this_thread::sleep_for(std::chrono::milliseconds(30)); std::this_thread::sleep_for(std::chrono::milliseconds(30));
} }