shithub: cstory

Download patch

ref: 8d92bf200426258db5270163e217d25f73d87528
parent: f8a40318a2a8506d57a6621d76448eb3fa0dd736
author: Clownacy <Clownacy@users.noreply.github.com>
date: Tue Jan 21 11:43:21 EST 2020

Double-buffer the OpenGL VBO

This should reduce stalling when the OpenGL driver is still
processing the buffer when we're about to upload to it.

Hopefully, this is what was making the OpenGL ES 2.0 renderer so much
slower than the SDLTexture renderer on the Raspberry Pi 3B (SDL uses
*8* buffers). Unfortunately, I don't have access to it right now, so
I can't test this.

--- a/src/Backends/Rendering/OpenGL3.cpp
+++ b/src/Backends/Rendering/OpenGL3.cpp
@@ -17,6 +17,8 @@
 
 #include "../../WindowsWrapper.h"
 
+#define TOTAL_VBOS 2
+
 typedef enum RenderMode
 {
 	MODE_BLANK,
@@ -77,7 +79,7 @@
 #ifndef USE_OPENGLES2
 static GLuint vertex_array_id;
 #endif
-static GLuint vertex_buffer_id;
+static GLuint vertex_buffer_ids[TOTAL_VBOS];
 static GLuint framebuffer_id;
 
 static VertexBufferSlot *local_vertex_buffer;
@@ -358,12 +360,17 @@
 
 static void FlushVertexBuffer(void)
 {
-	static unsigned long vertex_buffer_size = 0;
+	static unsigned long vertex_buffer_size[TOTAL_VBOS];
+	static unsigned int current_vertex_buffer = 0;
 
-	if (local_vertex_buffer_size > vertex_buffer_size)
+	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_ids[current_vertex_buffer]);
+	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, vertex_coordinate));
+	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texture_coordinate));
+
+	if (local_vertex_buffer_size > vertex_buffer_size[current_vertex_buffer])
 	{
-		vertex_buffer_size = local_vertex_buffer_size;
-		glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size * sizeof(VertexBufferSlot), local_vertex_buffer, GL_STREAM_DRAW);
+		vertex_buffer_size[current_vertex_buffer] = local_vertex_buffer_size;
+		glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size[current_vertex_buffer] * sizeof(VertexBufferSlot), local_vertex_buffer, GL_STREAM_DRAW);
 	}
 	else
 	{
@@ -370,6 +377,9 @@
 		glBufferSubData(GL_ARRAY_BUFFER, 0, current_vertex_buffer_slot * sizeof(VertexBufferSlot), local_vertex_buffer);
 	}
 
+	if (++current_vertex_buffer >= TOTAL_VBOS)
+		current_vertex_buffer = 0;
+
 	if (last_render_mode == MODE_DRAW_GLYPH_LCD)
 	{
 		// Here we're going to draw with per-component alpha.
@@ -453,14 +463,11 @@
 					glBindVertexArray(vertex_array_id);
 				#endif
 
-					// Set up Vertex Buffer Object
-					glGenBuffers(1, &vertex_buffer_id);
-					glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id);
+					// Set up Vertex Buffer Objects
+					glGenBuffers(TOTAL_VBOS, vertex_buffer_ids);
 
 					// Set up the vertex attributes
 					glEnableVertexAttribArray(1);
-					glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, vertex_coordinate));
-					glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, texture_coordinate));
 
 					// Set up our shaders
 					program_texture = CompileShader(vertex_shader_texture, fragment_shader_texture);
@@ -524,7 +531,7 @@
 					if (program_texture != 0)
 						glDeleteProgram(program_texture);
 
-					glDeleteBuffers(1, &vertex_buffer_id);
+					glDeleteBuffers(TOTAL_VBOS, vertex_buffer_ids);
 				#ifndef USE_OPENGLES2
 					glDeleteVertexArrays(1, &vertex_array_id);
 				#endif
@@ -550,7 +557,7 @@
 	glDeleteProgram(program_colour_fill);
 	glDeleteProgram(program_texture_colour_key);
 	glDeleteProgram(program_texture);
-	glDeleteBuffers(1, &vertex_buffer_id);
+	glDeleteBuffers(TOTAL_VBOS, vertex_buffer_ids);
 #ifndef USE_OPENGLES2
 	glDeleteVertexArrays(1, &vertex_array_id);
 #endif
--