From 3aa79fc1a32f505f71c88e58023d728a225353e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= <pedrojrulez@gmail.com>
Date: Mon, 30 Oct 2017 21:33:36 +0100
Subject: [PATCH] Add ability to opt-out buffer swapping in `VS::draw()`

---
 drivers/gles3/rasterizer_gles3.cpp       | 7 +++++--
 drivers/gles3/rasterizer_gles3.h         | 2 +-
 servers/visual/rasterizer.h              | 2 +-
 servers/visual/visual_server_raster.cpp  | 4 ++--
 servers/visual/visual_server_raster.h    | 2 +-
 servers/visual/visual_server_wrap_mt.cpp | 4 ++--
 servers/visual/visual_server_wrap_mt.h   | 2 +-
 servers/visual_server.cpp                | 4 ++--
 servers/visual_server.h                  | 2 +-
 9 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index ee61481a869..b34aec089d1 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -352,7 +352,7 @@ void RasterizerGLES3::blit_render_target_to_screen(RID p_render_target, const Re
 	canvas->canvas_end();
 }
 
-void RasterizerGLES3::end_frame() {
+void RasterizerGLES3::end_frame(bool p_swap_buffers) {
 
 #if 0
 	canvas->canvas_begin();
@@ -384,7 +384,10 @@ void RasterizerGLES3::end_frame() {
 
 	canvas->draw_generic_textured_rect(Rect2(0,0,15,15),Rect2(0,0,1,1));
 #endif
-	OS::get_singleton()->swap_buffers();
+	if (p_swap_buffers)
+		OS::get_singleton()->swap_buffers();
+	else
+		glFinish();
 
 	/*	print_line("objects: "+itos(storage->info.render_object_count));
 	print_line("material chages: "+itos(storage->info.render_material_switch_count));
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index 4bfec09bf32..c27af7d0191 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -59,7 +59,7 @@ public:
 	virtual void restore_render_target();
 	virtual void clear_render_target(const Color &p_color);
 	virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0);
-	virtual void end_frame();
+	virtual void end_frame(bool p_swap_buffers);
 	virtual void finalize();
 
 	static void make_current();
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 21d059c48e3..2499551607f 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -1027,7 +1027,7 @@ public:
 	virtual void restore_render_target() = 0;
 	virtual void clear_render_target(const Color &p_color) = 0;
 	virtual void blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen = 0) = 0;
-	virtual void end_frame() = 0;
+	virtual void end_frame(bool p_swap_buffers) = 0;
 	virtual void finalize() = 0;
 
 	virtual ~Rasterizer() {}
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 9432d3fdd91..6b527b5cd10 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -92,7 +92,7 @@ void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const Str
 	frame_drawn_callbacks.push_back(fdc);
 }
 
-void VisualServerRaster::draw() {
+void VisualServerRaster::draw(bool p_swap_buffers) {
 
 	changes = 0;
 
@@ -103,7 +103,7 @@ void VisualServerRaster::draw() {
 	VSG::viewport->draw_viewports();
 	VSG::scene->render_probes();
 	_draw_margins();
-	VSG::rasterizer->end_frame();
+	VSG::rasterizer->end_frame(p_swap_buffers);
 
 	while (frame_drawn_callbacks.front()) {
 
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 75514859194..56400d6a19f 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -625,7 +625,7 @@ public:
 
 	virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata);
 
-	virtual void draw();
+	virtual void draw(bool p_swap_buffers);
 	virtual void sync();
 	virtual bool has_changed() const;
 	virtual void init();
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index a9bfef7ef31..03c68ab4543 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -89,7 +89,7 @@ void VisualServerWrapMT::sync() {
 	}
 }
 
-void VisualServerWrapMT::draw() {
+void VisualServerWrapMT::draw(bool p_swap_buffers) {
 
 	if (create_thread) {
 
@@ -97,7 +97,7 @@ void VisualServerWrapMT::draw() {
 		command_queue.push(this, &VisualServerWrapMT::thread_draw);
 	} else {
 
-		visual_server->draw();
+		visual_server->draw(p_swap_buffers);
 	}
 }
 
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 417e8de833a..1e8071af610 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -542,7 +542,7 @@ public:
 
 	virtual void init();
 	virtual void finish();
-	virtual void draw();
+	virtual void draw(bool p_swap_buffers);
 	virtual void sync();
 	FUNC0RC(bool, has_changed)
 
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 10f350d6671..f745785efd8 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1481,7 +1481,7 @@ Array VisualServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surfa
 void VisualServer::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("force_sync"), &VisualServer::sync);
-	ClassDB::bind_method(D_METHOD("force_draw"), &VisualServer::draw);
+	ClassDB::bind_method(D_METHOD("force_draw"), &VisualServer::draw, DEFVAL(true));
 
 	ClassDB::bind_method(D_METHOD("texture_create"), &VisualServer::texture_create);
 	ClassDB::bind_method(D_METHOD("texture_create_from_image", "image", "flags"), &VisualServer::texture_create_from_image, DEFVAL(TEXTURE_FLAGS_DEFAULT));
@@ -1658,7 +1658,7 @@ void VisualServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("free", "rid"), &VisualServer::free);
 
 	ClassDB::bind_method(D_METHOD("request_frame_drawn_callback", "where", "method", "userdata"), &VisualServer::request_frame_drawn_callback);
-	ClassDB::bind_method(D_METHOD("draw"), &VisualServer::draw);
+	ClassDB::bind_method(D_METHOD("draw"), &VisualServer::draw, DEFVAL(true));
 	ClassDB::bind_method(D_METHOD("sync"), &VisualServer::sync);
 	ClassDB::bind_method(D_METHOD("has_changed"), &VisualServer::has_changed);
 	ClassDB::bind_method(D_METHOD("init"), &VisualServer::init);
diff --git a/servers/visual_server.h b/servers/visual_server.h
index c4b15830095..9df389999aa 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -909,7 +909,7 @@ public:
 
 	/* EVENT QUEUING */
 
-	virtual void draw() = 0;
+	virtual void draw(bool p_swap_buffers = true) = 0;
 	virtual void sync() = 0;
 	virtual bool has_changed() const = 0;
 	virtual void init() = 0;