From ce440f291342f97114b5b568d61afd87c4897e18 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Mon, 26 Jun 2023 14:46:06 +0200 Subject: [PATCH] Remove OpenGL threaded rendering --- .clang-format | 5 - build/android/app/CMakeLists.txt | 1 - build/linux/Makefile | 1 - src/engine/platform/platform_linux.cc | 2 - src/engine/renderer/opengl/render_command.cc | 36 - src/engine/renderer/opengl/render_command.h | 139 --- src/engine/renderer/opengl/renderer_opengl.cc | 917 ++++++------------ src/engine/renderer/opengl/renderer_opengl.h | 74 +- .../opengl/renderer_opengl_android.cc | 18 +- .../renderer/opengl/renderer_opengl_linux.cc | 24 +- src/engine/renderer/renderer_types.cc | 2 +- src/engine/renderer/renderer_types.h | 2 +- 12 files changed, 312 insertions(+), 909 deletions(-) delete mode 100644 src/engine/renderer/opengl/render_command.cc delete mode 100644 src/engine/renderer/opengl/render_command.h diff --git a/.clang-format b/.clang-format index e59a580..b17a52a 100644 --- a/.clang-format +++ b/.clang-format @@ -1,7 +1,2 @@ BasedOnStyle: Chromium Standard: Cpp11 - -MacroBlockBegin: "^\ -RENDER_COMMAND_BEGIN$" -MacroBlockEnd: "^\ -RENDER_COMMAND_END$" diff --git a/build/android/app/CMakeLists.txt b/build/android/app/CMakeLists.txt index d2b3dab..5a795ea 100644 --- a/build/android/app/CMakeLists.txt +++ b/build/android/app/CMakeLists.txt @@ -78,7 +78,6 @@ add_library(kaliber SHARED ../../../src/engine/platform/asset_file.cc ../../../src/engine/platform/platform_android.cc ../../../src/engine/renderer/geometry.cc - ../../../src/engine/renderer/opengl/render_command.cc ../../../src/engine/renderer/opengl/renderer_opengl_android.cc ../../../src/engine/renderer/opengl/renderer_opengl.cc ../../../src/engine/renderer/renderer_types.cc diff --git a/build/linux/Makefile b/build/linux/Makefile index 330e846..4201ea1 100644 --- a/build/linux/Makefile +++ b/build/linux/Makefile @@ -111,7 +111,6 @@ ENGINE_SRC := \ $(SRC_ROOT)/engine/platform/asset_file.cc \ $(SRC_ROOT)/engine/platform/platform_linux.cc \ $(SRC_ROOT)/engine/renderer/geometry.cc \ - $(SRC_ROOT)/engine/renderer/opengl/render_command.cc \ $(SRC_ROOT)/engine/renderer/opengl/renderer_opengl_linux.cc \ $(SRC_ROOT)/engine/renderer/opengl/renderer_opengl.cc \ $(SRC_ROOT)/engine/renderer/renderer_types.cc \ diff --git a/src/engine/platform/platform_linux.cc b/src/engine/platform/platform_linux.cc index 6d04399..d911257 100644 --- a/src/engine/platform/platform_linux.cc +++ b/src/engine/platform/platform_linux.cc @@ -25,8 +25,6 @@ Platform::Platform() { shared_data_path_ = "./"; LOG << "Shared data path: " << shared_data_path_.c_str(); - XInitThreads(); - bool res = CreateWindow(800, 1205); CHECK(res) << "Failed to create window."; diff --git a/src/engine/renderer/opengl/render_command.cc b/src/engine/renderer/opengl/render_command.cc deleted file mode 100644 index 14ad0e0..0000000 --- a/src/engine/renderer/opengl/render_command.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include "engine/renderer/opengl/render_command.h" - -#include "engine/asset/image.h" -#include "engine/asset/mesh.h" -#include "engine/asset/shader_source.h" - -#ifdef _DEBUG -#define RENDER_COMMAND_IMPL(NAME, GLOBAL) \ - NAME::NAME() : RenderCommand(CMD_ID, GLOBAL, #NAME) {} -#else -#define RENDER_COMMAND_IMPL(NAME, GLOBAL) \ - NAME::NAME() : RenderCommand(CMD_ID, GLOBAL) {} -#endif - -namespace eng { - -RENDER_COMMAND_IMPL(CmdPresent, false); -RENDER_COMMAND_IMPL(CmdInvalidateAllResources, true); -RENDER_COMMAND_IMPL(CmdCreateTexture, true); -RENDER_COMMAND_IMPL(CmdUpdateTexture, true); -RENDER_COMMAND_IMPL(CmdDestoryTexture, true); -RENDER_COMMAND_IMPL(CmdActivateTexture, false); -RENDER_COMMAND_IMPL(CmdCreateGeometry, true); -RENDER_COMMAND_IMPL(CmdDestroyGeometry, true); -RENDER_COMMAND_IMPL(CmdDrawGeometry, false); -RENDER_COMMAND_IMPL(CmdCreateShader, true); -RENDER_COMMAND_IMPL(CmdDestroyShader, true); -RENDER_COMMAND_IMPL(CmdActivateShader, false); -RENDER_COMMAND_IMPL(CmdSetUniformVec2, false); -RENDER_COMMAND_IMPL(CmdSetUniformVec3, false); -RENDER_COMMAND_IMPL(CmdSetUniformVec4, false); -RENDER_COMMAND_IMPL(CmdSetUniformMat4, false); -RENDER_COMMAND_IMPL(CmdSetUniformInt, false); -RENDER_COMMAND_IMPL(CmdSetUniformFloat, false); - -} // namespace eng diff --git a/src/engine/renderer/opengl/render_command.h b/src/engine/renderer/opengl/render_command.h deleted file mode 100644 index 13a76e7..0000000 --- a/src/engine/renderer/opengl/render_command.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef ENGINE_RENDERER_OPENGL_RENDER_COMMAND_H -#define ENGINE_RENDERER_OPENGL_RENDER_COMMAND_H - -#include -#include -#include - -#include "base/hash.h" -#include "base/vecmath.h" -#include "engine/renderer/renderer_types.h" - -namespace eng { - -class Image; -class ShaderSource; -class Mesh; - -#define RENDER_COMMAND_BEGIN(NAME) \ - struct NAME : RenderCommand { \ - static constexpr CommandId CMD_ID = base::Hash(#NAME); \ - NAME(); -#define RENDER_COMMAND_END \ - } \ - ; - -struct RenderCommand { - using CommandId = size_t; - static constexpr CommandId INVALID_CMD_ID = 0; - -#ifdef _DEBUG - RenderCommand(CommandId id, bool g, const char* name) - : cmd_id(id), global(g), cmd_name(name) {} -#else - RenderCommand(CommandId id, bool g) : cmd_id(id), global(g) {} -#endif - - virtual ~RenderCommand() = default; - - const CommandId cmd_id = INVALID_CMD_ID; - - // Global render commands are guaranteed to be processed. Others commands are - // frame specific and can be discared by the renderer if not throttled. - const bool global = false; - -#ifdef _DEBUG - std::string cmd_name; -#endif -}; - -RENDER_COMMAND_BEGIN(CmdPresent) -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdInvalidateAllResources) -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdCreateTexture) - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdUpdateTexture) - std::unique_ptr image; - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdDestoryTexture) - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdActivateTexture) - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdCreateGeometry) - std::unique_ptr mesh; - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdDestroyGeometry) - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdDrawGeometry) - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdCreateShader) - std::unique_ptr source; - VertexDescription vertex_description; - uint64_t resource_id; - bool enable_depth_test; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdDestroyShader) - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdActivateShader) - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdSetUniformVec2) - std::string name; - base::Vector2f v; - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdSetUniformVec3) - std::string name; - base::Vector3f v; - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdSetUniformVec4) - std::string name; - base::Vector4f v; - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdSetUniformMat4) - std::string name; - base::Matrix4f m; - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdSetUniformInt) - std::string name; - int i; - uint64_t resource_id; -RENDER_COMMAND_END - -RENDER_COMMAND_BEGIN(CmdSetUniformFloat) - std::string name; - float f; - uint64_t resource_id; -RENDER_COMMAND_END - -} // namespace eng - -#endif // ENGINE_RENDERER_OPENGL_RENDER_COMMAND_H diff --git a/src/engine/renderer/opengl/renderer_opengl.cc b/src/engine/renderer/opengl/renderer_opengl.cc index 75e42b9..721d29a 100644 --- a/src/engine/renderer/opengl/renderer_opengl.cc +++ b/src/engine/renderer/opengl/renderer_opengl.cc @@ -1,6 +1,3 @@ -// © 2021 Attila Uygun -// Licensed under the MIT license. - #include "engine/renderer/opengl/renderer_opengl.h" #include @@ -10,14 +7,10 @@ #include "base/log.h" #include "base/vecmath.h" -#ifdef THREADED_RENDERING -#include "base/task_runner.h" -#endif // THREADED_RENDERING #include "engine/asset/image.h" #include "engine/asset/mesh.h" #include "engine/asset/shader_source.h" #include "engine/renderer/geometry.h" -#include "engine/renderer/opengl/render_command.h" #include "engine/renderer/shader.h" #include "engine/renderer/texture.h" @@ -39,14 +32,8 @@ const std::string kAttributeNames[eng::kAttribType_Max] = { namespace eng { -#ifdef THREADED_RENDERING -RendererOpenGL::RendererOpenGL(base::Closure context_lost_cb) - : Renderer(context_lost_cb), - main_thread_task_runner_(TaskRunner::GetThreadLocalTaskRunner()) {} -#else RendererOpenGL::RendererOpenGL(base::Closure context_lost_cb) : Renderer(context_lost_cb) {} -#endif // THREADED_RENDERING RendererOpenGL::~RendererOpenGL() { Shutdown(); @@ -54,70 +41,219 @@ RendererOpenGL::~RendererOpenGL() { } void RendererOpenGL::Shutdown() { - is_initialized_ = false; - -#ifdef THREADED_RENDERING - if (terminate_render_thread_) - return; - LOG << "Shutting down renderer."; - { - std::unique_lock scoped_lock(mutex_); - terminate_render_thread_ = true; - } - cv_.notify_one(); - LOG << "Terminating render thread"; - render_thread_.join(); -#else + is_initialized_ = false; ShutdownInternal(); -#endif // THREADED_RENDERING } uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr mesh) { - auto cmd = std::make_unique(); - cmd->mesh = std::move(mesh); - cmd->resource_id = ++last_resource_id_; - EnqueueCommand(std::move(cmd)); - return last_resource_id_; + // Verify that we have a valid layout and get the total byte size per vertex. + GLuint vertex_size = mesh->GetVertexSize(); + if (!vertex_size) { + LOG << "Invalid vertex layout"; + return 0; + } + + // Make sure the vertex format is understood and the attribute pointers are + // set up. + std::vector vertex_layout; + if (!SetupVertexLayout(mesh->vertex_description(), vertex_size, + vertex_array_objects_, vertex_layout)) { + LOG << "Invalid vertex layout"; + return 0; + } + + GLuint vertex_array_id = 0; + if (vertex_array_objects_) { + glGenVertexArrays(1, &vertex_array_id); + glBindVertexArray(vertex_array_id); + } + + // Create the vertex buffer and upload the data. + GLuint vertex_buffer_id = 0; + glGenBuffers(1, &vertex_buffer_id); + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id); + glBufferData(GL_ARRAY_BUFFER, mesh->num_vertices() * vertex_size, + mesh->GetVertices(), GL_STATIC_DRAW); + + // Create the index buffer and upload the data. + GLuint index_buffer_id = 0; + if (mesh->GetIndices()) { + glGenBuffers(1, &index_buffer_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + mesh->num_indices() * mesh->GetIndexSize(), mesh->GetIndices(), + GL_STATIC_DRAW); + } + + if (vertex_array_id) { + // De-activate the buffer again and we're done. + glBindVertexArray(0); + } else { + // De-activate the individual buffers. + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } + + uint64_t resource_id = ++last_resource_id_; + geometries_[resource_id] = {(GLsizei)mesh->num_vertices(), + (GLsizei)mesh->num_indices(), + kGlPrimitive[mesh->primitive()], + kGlDataType[mesh->index_description()], + vertex_layout, + vertex_size, + vertex_array_id, + vertex_buffer_id, + index_buffer_id}; + return resource_id; } void RendererOpenGL::DestroyGeometry(uint64_t resource_id) { - auto cmd = std::make_unique(); - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = geometries_.find(resource_id); + if (it == geometries_.end()) + return; + + if (it->second.index_buffer_id) + glDeleteBuffers(1, &(it->second.index_buffer_id)); + if (it->second.vertex_buffer_id) + glDeleteBuffers(1, &(it->second.vertex_buffer_id)); + if (it->second.vertex_array_id) + glDeleteVertexArrays(1, &(it->second.vertex_array_id)); + + geometries_.erase(it); } void RendererOpenGL::Draw(uint64_t resource_id) { - auto cmd = std::make_unique(); - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = geometries_.find(resource_id); + if (it == geometries_.end()) + return; + + // Set up the vertex data. + if (it->second.vertex_array_id) + glBindVertexArray(it->second.vertex_array_id); + else { + glBindBuffer(GL_ARRAY_BUFFER, it->second.vertex_buffer_id); + for (GLuint attribute_index = 0; + attribute_index < (GLuint)it->second.vertex_layout.size(); + ++attribute_index) { + GeometryOpenGL::Element& e = it->second.vertex_layout[attribute_index]; + glEnableVertexAttribArray(attribute_index); + glVertexAttribPointer(attribute_index, e.num_elements, e.type, GL_FALSE, + it->second.vertex_size, + (const GLvoid*)e.vertex_offset); + } + + if (it->second.num_indices > 0) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id); + } + + // Draw the primitive. + if (it->second.num_indices > 0) + glDrawElements(it->second.primitive, it->second.num_indices, + it->second.index_type, NULL); + else + glDrawArrays(it->second.primitive, 0, it->second.num_vertices); + + // Clean up states. + if (it->second.vertex_array_id) + glBindVertexArray(0); + else { + for (GLuint attribute_index = 0; + attribute_index < (GLuint)it->second.vertex_layout.size(); + ++attribute_index) + glDisableVertexAttribArray(attribute_index); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } } uint64_t RendererOpenGL::CreateTexture() { - auto cmd = std::make_unique(); - cmd->resource_id = ++last_resource_id_; - EnqueueCommand(std::move(cmd)); - return last_resource_id_; + GLuint gl_id = 0; + glGenTextures(1, &gl_id); + + BindTexture(gl_id); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + uint64_t resource_id = ++last_resource_id_; + textures_[resource_id] = gl_id; + return resource_id; } void RendererOpenGL::UpdateTexture(uint64_t resource_id, std::unique_ptr image) { - auto cmd = std::make_unique(); - cmd->image = std::move(image); - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = textures_.find(resource_id); + if (it == textures_.end()) + return; + + BindTexture(it->second); + if (image->IsCompressed()) { + GLenum format = 0; + switch (image->GetFormat()) { + case Image::kDXT1: + format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + break; + case Image::kDXT5: + format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + case Image::kETC1: + format = GL_ETC1_RGB8_OES; + break; +#if defined(__ANDROID__) + case Image::kATC: + format = GL_ATC_RGB_AMD; + break; + case Image::kATCIA: + format = GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD; + break; +#endif + default: + NOTREACHED << "- Unhandled texure format: " << image->GetFormat(); + } + + glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, image->GetWidth(), + image->GetHeight(), 0, image->GetSize(), + image->GetBuffer()); + + // On some devices the first glCompressedTexImage2D call after context-lost + // returns GL_INVALID_VALUE for some reason. + GLenum err = glGetError(); + if (err == GL_INVALID_VALUE) { + glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, image->GetWidth(), + image->GetHeight(), 0, image->GetSize(), + image->GetBuffer()); + err = glGetError(); + } + + if (err != GL_NO_ERROR) + LOG << "GL ERROR after glCompressedTexImage2D: " << (int)err; + } else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->GetWidth(), + image->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, + image->GetBuffer()); + } } void RendererOpenGL::DestroyTexture(uint64_t resource_id) { - auto cmd = std::make_unique(); - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = textures_.find(resource_id); + if (it == textures_.end()) + return; + + glDeleteTextures(1, &(it->second)); + textures_.erase(it); } void RendererOpenGL::ActivateTexture(uint64_t resource_id) { - auto cmd = std::make_unique(); - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = textures_.find(resource_id); + if (it == textures_.end()) { + return; + } + + BindTexture(it->second); } uint64_t RendererOpenGL::CreateShader( @@ -125,112 +261,150 @@ uint64_t RendererOpenGL::CreateShader( const VertexDescription& vertex_description, Primitive primitive, bool enable_depth_test) { - auto cmd = std::make_unique(); - cmd->source = std::move(source); - cmd->vertex_description = vertex_description; - cmd->resource_id = ++last_resource_id_; - cmd->enable_depth_test = enable_depth_test; - EnqueueCommand(std::move(cmd)); - return last_resource_id_; + GLuint vertex_shader = + CreateShader(source->GetVertexSource(), GL_VERTEX_SHADER); + if (!vertex_shader) + return 0; + + GLuint fragment_shader = + CreateShader(source->GetFragmentSource(), GL_FRAGMENT_SHADER); + if (!fragment_shader) + return 0; + + GLuint id = glCreateProgram(); + if (id) { + glAttachShader(id, vertex_shader); + glAttachShader(id, fragment_shader); + if (!BindAttributeLocation(id, vertex_description)) { + glDeleteProgram(id); + return 0; + } + + glLinkProgram(id); + GLint linkStatus = GL_FALSE; + glGetProgramiv(id, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint length = 0; + glGetProgramiv(id, GL_INFO_LOG_LENGTH, &length); + if (length > 0) { + char* buffer = (char*)malloc(length); + if (buffer) { + glGetProgramInfoLog(id, length, NULL, buffer); + LOG << "Could not link program:\n" << buffer; + free(buffer); + } + } + glDeleteProgram(id); + return 0; + } + } + + uint64_t resource_id = ++last_resource_id_; + shaders_[resource_id] = {id, {}, enable_depth_test}; + return resource_id; } void RendererOpenGL::DestroyShader(uint64_t resource_id) { - auto cmd = std::make_unique(); - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + glDeleteProgram(it->second.id); + shaders_.erase(it); } void RendererOpenGL::ActivateShader(uint64_t resource_id) { - auto cmd = std::make_unique(); - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + if (it->second.id != active_shader_id_) { + glUseProgram(it->second.id); + active_shader_id_ = it->second.id; + if (it->second.enable_depth_test) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + } } void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector2f& val) { - auto cmd = std::make_unique(); - cmd->name = name; - cmd->v = val; - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + if (index >= 0) + glUniform2fv(index, 1, val.GetData()); } void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector3f& val) { - auto cmd = std::make_unique(); - cmd->name = name; - cmd->v = val; - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + if (index >= 0) + glUniform3fv(index, 1, val.GetData()); } void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector4f& val) { - auto cmd = std::make_unique(); - cmd->name = name; - cmd->v = val; - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + if (index >= 0) + glUniform4fv(index, 1, val.GetData()); } void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, const base::Matrix4f& val) { - auto cmd = std::make_unique(); - cmd->name = name; - cmd->m = val; - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + if (index >= 0) + glUniformMatrix4fv(index, 1, GL_FALSE, val.GetData()); } void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, float val) { - auto cmd = std::make_unique(); - cmd->name = name; - cmd->f = val; - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + if (index >= 0) + glUniform1f(index, val); } void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, int val) { - auto cmd = std::make_unique(); - cmd->name = name; - cmd->i = val; - cmd->resource_id = resource_id; - EnqueueCommand(std::move(cmd)); -} + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; -void RendererOpenGL::Present() { - EnqueueCommand(std::make_unique()); -#ifdef THREADED_RENDERING - draw_complete_semaphore_.acquire(); -#endif // THREADED_RENDERING - fps_++; + GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + if (index >= 0) + glUniform1i(index, val); } void RendererOpenGL::ContextLost() { LOG << "Context lost."; -#ifdef THREADED_RENDERING - { - std::unique_lock scoped_lock(mutex_); - global_commands_.clear(); - draw_commands_[0].clear(); - draw_commands_[1].clear(); - } - - DestroyAllResources(); - main_thread_task_runner_->PostTask(HERE, context_lost_cb_); -#else DestroyAllResources(); context_lost_cb_(); -#endif // THREADED_RENDERING } size_t RendererOpenGL::GetAndResetFPS() { @@ -325,527 +499,26 @@ void RendererOpenGL::DestroyAllResources() { std::vector resource_ids; for (auto& r : geometries_) resource_ids.push_back(r.first); - for (auto& r : resource_ids) { - auto cmd = std::make_unique(); - cmd->resource_id = r; - ProcessCommand(cmd.get()); - } + for (auto& r : resource_ids) + DestroyGeometry(r); resource_ids.clear(); for (auto& r : shaders_) resource_ids.push_back(r.first); - for (auto& r : resource_ids) { - auto cmd = std::make_unique(); - cmd->resource_id = r; - ProcessCommand(cmd.get()); - } + for (auto& r : resource_ids) + DestroyShader(r); resource_ids.clear(); for (auto& r : textures_) resource_ids.push_back(r.first); - for (auto& r : resource_ids) { - auto cmd = std::make_unique(); - cmd->resource_id = r; - ProcessCommand(cmd.get()); - } + for (auto& r : resource_ids) + DestroyTexture(r); DCHECK(geometries_.size() == 0); DCHECK(shaders_.size() == 0); DCHECK(textures_.size() == 0); } -bool RendererOpenGL::StartRenderThread() { -#ifdef THREADED_RENDERING - LOG << "Starting render thread."; - - global_commands_.clear(); - draw_commands_[0].clear(); - draw_commands_[1].clear(); - terminate_render_thread_ = false; - - std::promise promise; - std::future future = promise.get_future(); - render_thread_ = - std::thread(&RendererOpenGL::RenderThreadMain, this, std::move(promise)); - future.wait(); - return future.get(); -#else - LOG << "Single threaded rendering."; - return InitInternal(); -#endif // THREADED_RENDERING -} - -#ifdef THREADED_RENDERING - -void RendererOpenGL::RenderThreadMain(std::promise promise) { - promise.set_value(InitInternal()); - - std::deque> cq[2]; - for (;;) { - { - std::unique_lock scoped_lock(mutex_); - cv_.wait(scoped_lock, [&]() -> bool { - return !global_commands_.empty() || !draw_commands_[0].empty() || - terminate_render_thread_; - }); - if (terminate_render_thread_) { - ShutdownInternal(); - return; - } - cq[0].swap(global_commands_); - cq[1].swap(draw_commands_[0]); - } - -#if 0 - LOG << "qlobal queue size: " << (int)cq[0].size(); - LOG << "draw queue size: " << (int)cq[1].size(); -#endif - - for (int i = 0; i < 2; ++i) { - while (!cq[i].empty()) { - ProcessCommand(cq[i].front().get()); - cq[i].pop_front(); - } - } - } -} - -#endif // THREADED_RENDERING - -void RendererOpenGL::EnqueueCommand(std::unique_ptr cmd) { -#ifdef THREADED_RENDERING - if (cmd->global) { - { - std::unique_lock scoped_lock(mutex_); - global_commands_.push_back(std::move(cmd)); - } - cv_.notify_one(); - return; - } - - bool new_frame = cmd->cmd_id == CmdPresent::CMD_ID; - draw_commands_[1].push_back(std::move(cmd)); - if (new_frame) { - { - std::unique_lock scoped_lock(mutex_); - draw_commands_[0].swap(draw_commands_[1]); - } - cv_.notify_one(); - draw_commands_[1].clear(); - } -#else - ProcessCommand(cmd.get()); -#endif // THREADED_RENDERING -} - -void RendererOpenGL::ProcessCommand(RenderCommand* cmd) { -#if 0 - LOG << "Processing command: " << cmd->cmd_name.c_str(); -#endif - - switch (cmd->cmd_id) { - case CmdPresent::CMD_ID: - HandleCmdPresent(cmd); - break; - case CmdCreateTexture::CMD_ID: - HandleCmdCreateTexture(cmd); - break; - case CmdUpdateTexture::CMD_ID: - HandleCmdUpdateTexture(cmd); - break; - case CmdDestoryTexture::CMD_ID: - HandleCmdDestoryTexture(cmd); - break; - case CmdActivateTexture::CMD_ID: - HandleCmdActivateTexture(cmd); - break; - case CmdCreateGeometry::CMD_ID: - HandleCmdCreateGeometry(cmd); - break; - case CmdDestroyGeometry::CMD_ID: - HandleCmdDestroyGeometry(cmd); - break; - case CmdDrawGeometry::CMD_ID: - HandleCmdDrawGeometry(cmd); - break; - case CmdCreateShader::CMD_ID: - HandleCmdCreateShader(cmd); - break; - case CmdDestroyShader::CMD_ID: - HandleCmdDestroyShader(cmd); - break; - case CmdActivateShader::CMD_ID: - HandleCmdActivateShader(cmd); - break; - case CmdSetUniformVec2::CMD_ID: - HandleCmdSetUniformVec2(cmd); - break; - case CmdSetUniformVec3::CMD_ID: - HandleCmdSetUniformVec3(cmd); - break; - case CmdSetUniformVec4::CMD_ID: - HandleCmdSetUniformVec4(cmd); - break; - case CmdSetUniformMat4::CMD_ID: - HandleCmdSetUniformMat4(cmd); - break; - case CmdSetUniformFloat::CMD_ID: - HandleCmdSetUniformFloat(cmd); - break; - case CmdSetUniformInt::CMD_ID: - HandleCmdSetUniformInt(cmd); - break; - default: - NOTREACHED << "- Unknown render command: " << cmd->cmd_id; - } -} - -void RendererOpenGL::HandleCmdCreateTexture(RenderCommand* cmd) { - auto* c = static_cast(cmd); - - GLuint gl_id = 0; - glGenTextures(1, &gl_id); - - BindTexture(gl_id); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - textures_.insert({c->resource_id, {gl_id}}); -} - -void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = textures_.find(c->resource_id); - if (it == textures_.end()) - return; - - BindTexture(it->second.id); - if (c->image->IsCompressed()) { - GLenum format = 0; - switch (c->image->GetFormat()) { - case Image::kDXT1: - format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - break; - case Image::kDXT5: - format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - case Image::kETC1: - format = GL_ETC1_RGB8_OES; - break; -#if defined(__ANDROID__) - case Image::kATC: - format = GL_ATC_RGB_AMD; - break; - case Image::kATCIA: - format = GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD; - break; -#endif - default: - NOTREACHED << "- Unhandled texure format: " << c->image->GetFormat(); - } - - glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, c->image->GetWidth(), - c->image->GetHeight(), 0, c->image->GetSize(), - c->image->GetBuffer()); - - // On some devices the first glCompressedTexImage2D call after context-lost - // returns GL_INVALID_VALUE for some reason. - GLenum err = glGetError(); - if (err == GL_INVALID_VALUE) { - glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, c->image->GetWidth(), - c->image->GetHeight(), 0, c->image->GetSize(), - c->image->GetBuffer()); - err = glGetError(); - } - - if (err != GL_NO_ERROR) - LOG << "GL ERROR after glCompressedTexImage2D: " << (int)err; - } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, c->image->GetWidth(), - c->image->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, - c->image->GetBuffer()); - } -} - -void RendererOpenGL::HandleCmdDestoryTexture(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = textures_.find(c->resource_id); - if (it == textures_.end()) - return; - - glDeleteTextures(1, &(it->second.id)); - textures_.erase(it); -} - -void RendererOpenGL::HandleCmdActivateTexture(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = textures_.find(c->resource_id); - if (it == textures_.end()) { - return; - } - - BindTexture(it->second.id); -} - -void RendererOpenGL::HandleCmdCreateGeometry(RenderCommand* cmd) { - auto* c = static_cast(cmd); - - // Verify that we have a valid layout and get the total byte size per vertex. - GLuint vertex_size = c->mesh->GetVertexSize(); - if (!vertex_size) { - LOG << "Invalid vertex layout"; - return; - } - - GLuint vertex_array_id = 0; - if (vertex_array_objects_) { - glGenVertexArrays(1, &vertex_array_id); - glBindVertexArray(vertex_array_id); - } - - // Create the vertex buffer and upload the data. - GLuint vertex_buffer_id = 0; - glGenBuffers(1, &vertex_buffer_id); - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id); - glBufferData(GL_ARRAY_BUFFER, c->mesh->num_vertices() * vertex_size, - c->mesh->GetVertices(), GL_STATIC_DRAW); - - // Make sure the vertex format is understood and the attribute pointers are - // set up. - std::vector vertex_layout; - if (!SetupVertexLayout(c->mesh->vertex_description(), vertex_size, - vertex_array_objects_, vertex_layout)) - return; - - // Create the index buffer and upload the data. - GLuint index_buffer_id = 0; - if (c->mesh->GetIndices()) { - glGenBuffers(1, &index_buffer_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - c->mesh->num_indices() * c->mesh->GetIndexSize(), - c->mesh->GetIndices(), GL_STATIC_DRAW); - } - - if (vertex_array_id) { - // De-activate the buffer again and we're done. - glBindVertexArray(0); - } else { - // De-activate the individual buffers. - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - - geometries_[c->resource_id] = {(GLsizei)c->mesh->num_vertices(), - (GLsizei)c->mesh->num_indices(), - kGlPrimitive[c->mesh->primitive()], - kGlDataType[c->mesh->index_description()], - vertex_layout, - vertex_size, - vertex_array_id, - vertex_buffer_id, - index_buffer_id}; -} - -void RendererOpenGL::HandleCmdDestroyGeometry(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = geometries_.find(c->resource_id); - if (it == geometries_.end()) - return; - - if (it->second.index_buffer_id) - glDeleteBuffers(1, &(it->second.index_buffer_id)); - if (it->second.vertex_buffer_id) - glDeleteBuffers(1, &(it->second.vertex_buffer_id)); - if (it->second.vertex_array_id) - glDeleteVertexArrays(1, &(it->second.vertex_array_id)); - - geometries_.erase(it); -} - -void RendererOpenGL::HandleCmdDrawGeometry(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = geometries_.find(c->resource_id); - if (it == geometries_.end()) - return; - - // Set up the vertex data. - if (it->second.vertex_array_id) - glBindVertexArray(it->second.vertex_array_id); - else { - glBindBuffer(GL_ARRAY_BUFFER, it->second.vertex_buffer_id); - for (GLuint attribute_index = 0; - attribute_index < (GLuint)it->second.vertex_layout.size(); - ++attribute_index) { - GeometryOpenGL::Element& e = it->second.vertex_layout[attribute_index]; - glEnableVertexAttribArray(attribute_index); - glVertexAttribPointer(attribute_index, e.num_elements, e.type, GL_FALSE, - it->second.vertex_size, - (const GLvoid*)e.vertex_offset); - } - - if (it->second.num_indices > 0) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id); - } - - // Draw the primitive. - if (it->second.num_indices > 0) - glDrawElements(it->second.primitive, it->second.num_indices, - it->second.index_type, NULL); - else - glDrawArrays(it->second.primitive, 0, it->second.num_vertices); - - // Clean up states. - if (it->second.vertex_array_id) - glBindVertexArray(0); - else { - for (GLuint attribute_index = 0; - attribute_index < (GLuint)it->second.vertex_layout.size(); - ++attribute_index) - glDisableVertexAttribArray(attribute_index); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } -} - -void RendererOpenGL::HandleCmdCreateShader(RenderCommand* cmd) { - auto* c = static_cast(cmd); - - GLuint vertex_shader = - CreateShader(c->source->GetVertexSource(), GL_VERTEX_SHADER); - if (!vertex_shader) - return; - - GLuint fragment_shader = - CreateShader(c->source->GetFragmentSource(), GL_FRAGMENT_SHADER); - if (!fragment_shader) - return; - - GLuint id = glCreateProgram(); - if (id) { - glAttachShader(id, vertex_shader); - glAttachShader(id, fragment_shader); - if (!BindAttributeLocation(id, c->vertex_description)) - return; - - glLinkProgram(id); - GLint linkStatus = GL_FALSE; - glGetProgramiv(id, GL_LINK_STATUS, &linkStatus); - if (linkStatus != GL_TRUE) { - GLint length = 0; - glGetProgramiv(id, GL_INFO_LOG_LENGTH, &length); - if (length > 0) { - char* buffer = (char*)malloc(length); - if (buffer) { - glGetProgramInfoLog(id, length, NULL, buffer); - LOG << "Could not link program:\n" << buffer; - free(buffer); - } - } - glDeleteProgram(id); - return; - } - } - - shaders_[c->resource_id] = {id, {}, c->enable_depth_test}; -} - -void RendererOpenGL::HandleCmdDestroyShader(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = shaders_.find(c->resource_id); - if (it == shaders_.end()) - return; - - glDeleteProgram(it->second.id); - shaders_.erase(it); -} - -void RendererOpenGL::HandleCmdActivateShader(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = shaders_.find(c->resource_id); - if (it == shaders_.end()) - return; - - if (it->second.id != active_shader_id_) { - glUseProgram(it->second.id); - active_shader_id_ = it->second.id; - if (it->second.enable_depth_test) - glEnable(GL_DEPTH_TEST); - else - glDisable(GL_DEPTH_TEST); - } -} - -void RendererOpenGL::HandleCmdSetUniformVec2(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = shaders_.find(c->resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); - if (index >= 0) - glUniform2fv(index, 1, c->v.GetData()); -} - -void RendererOpenGL::HandleCmdSetUniformVec3(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = shaders_.find(c->resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); - if (index >= 0) - glUniform3fv(index, 1, c->v.GetData()); -} - -void RendererOpenGL::HandleCmdSetUniformVec4(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = shaders_.find(c->resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); - if (index >= 0) - glUniform4fv(index, 1, c->v.GetData()); -} - -void RendererOpenGL::HandleCmdSetUniformMat4(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = shaders_.find(c->resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); - if (index >= 0) - glUniformMatrix4fv(index, 1, GL_FALSE, c->m.GetData()); -} - -void RendererOpenGL::HandleCmdSetUniformFloat(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = shaders_.find(c->resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); - if (index >= 0) - glUniform1f(index, c->f); -} - -void RendererOpenGL::HandleCmdSetUniformInt(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto it = shaders_.find(c->resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); - if (index >= 0) - glUniform1i(index, c->i); -} - void RendererOpenGL::BindTexture(GLuint id) { if (id != active_texture_id_) { glBindTexture(GL_TEXTURE_2D, id); diff --git a/src/engine/renderer/opengl/renderer_opengl.h b/src/engine/renderer/opengl/renderer_opengl.h index 71ab414..a2e04d2 100644 --- a/src/engine/renderer/opengl/renderer_opengl.h +++ b/src/engine/renderer/opengl/renderer_opengl.h @@ -6,35 +6,15 @@ #include #include -#define THREADED_RENDERING - -#ifdef THREADED_RENDERING -#include -#include -#include -#include -#include -#include -#endif // THREADED_RENDERING - #include "engine/renderer/opengl/opengl.h" - #include "engine/renderer/renderer.h" #if defined(__ANDROID__) struct ANativeWindow; #endif -#ifdef THREADED_RENDERING -namespace base { -class TaskRunner; -} -#endif // THREADED_RENDERING - namespace eng { -struct RenderCommand; - class RendererOpenGL final : public Renderer { public: RendererOpenGL(base::Closure context_lost_cb); @@ -113,13 +93,9 @@ class RendererOpenGL final : public Renderer { bool enable_depth_test = false; }; - struct TextureOpenGL { - GLuint id = 0; - }; - std::unordered_map geometries_; std::unordered_map shaders_; - std::unordered_map textures_; + std::unordered_map textures_; uint64_t last_resource_id_ = 0; GLuint active_shader_id_ = 0; @@ -130,23 +106,6 @@ class RendererOpenGL final : public Renderer { bool is_initialized_ = false; -#ifdef THREADED_RENDERING - // Global commands are independent from frames and guaranteed to be processed. - std::deque> global_commands_; - // Draw commands are fame specific and can be discarded if the rendering is - // not throttled. - std::deque> draw_commands_[2]; - - std::condition_variable cv_; - std::mutex mutex_; - std::thread render_thread_; - bool terminate_render_thread_ = false; - - std::counting_semaphore<> draw_complete_semaphore_{0}; - - std::shared_ptr main_thread_task_runner_; -#endif // THREADED_RENDERING - // Stats. size_t fps_ = 0; @@ -158,43 +117,12 @@ class RendererOpenGL final : public Renderer { GLXContext glx_context_ = NULL; #endif - bool InitInternal(); bool InitCommon(); void ShutdownInternal(); - void OnDestroy(); - void ContextLost(); - void DestroyAllResources(); - bool StartRenderThread(); - -#ifdef THREADED_RENDERING - void RenderThreadMain(std::promise promise); -#endif // THREADED_RENDERING - - void EnqueueCommand(std::unique_ptr cmd); - void ProcessCommand(RenderCommand* cmd); - - void HandleCmdPresent(RenderCommand* cmd); - void HandleCmdCreateTexture(RenderCommand* cmd); - void HandleCmdUpdateTexture(RenderCommand* cmd); - void HandleCmdDestoryTexture(RenderCommand* cmd); - void HandleCmdActivateTexture(RenderCommand* cmd); - void HandleCmdCreateGeometry(RenderCommand* cmd); - void HandleCmdDestroyGeometry(RenderCommand* cmd); - void HandleCmdDrawGeometry(RenderCommand* cmd); - void HandleCmdCreateShader(RenderCommand* cmd); - void HandleCmdDestroyShader(RenderCommand* cmd); - void HandleCmdActivateShader(RenderCommand* cmd); - void HandleCmdSetUniformVec2(RenderCommand* cmd); - void HandleCmdSetUniformVec3(RenderCommand* cmd); - void HandleCmdSetUniformVec4(RenderCommand* cmd); - void HandleCmdSetUniformMat4(RenderCommand* cmd); - void HandleCmdSetUniformFloat(RenderCommand* cmd); - void HandleCmdSetUniformInt(RenderCommand* cmd); - void BindTexture(GLuint id); bool SetupVertexLayout(const VertexDescription& vd, GLuint vertex_size, diff --git a/src/engine/renderer/opengl/renderer_opengl_android.cc b/src/engine/renderer/opengl/renderer_opengl_android.cc index e8db219..82ae164 100644 --- a/src/engine/renderer/opengl/renderer_opengl_android.cc +++ b/src/engine/renderer/opengl/renderer_opengl_android.cc @@ -12,14 +12,6 @@ bool RendererOpenGL::Initialize(Platform* platform) { LOG << "Initializing renderer."; window_ = platform->GetWindow(); - return StartRenderThread(); -} - -void RendererOpenGL::OnDestroy() { - ndk_helper::GLContext::GetInstance()->Invalidate(); -} - -bool RendererOpenGL::InitInternal() { ndk_helper::GLContext* gl_context = ndk_helper::GLContext::GetInstance(); if (!gl_context->IsInitialzed()) { @@ -48,21 +40,23 @@ bool RendererOpenGL::InitInternal() { return InitCommon(); } +void RendererOpenGL::OnDestroy() { + ndk_helper::GLContext::GetInstance()->Invalidate(); +} + void RendererOpenGL::ShutdownInternal() { ndk_helper::GLContext::GetInstance()->Suspend(); } -void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) { +void RendererOpenGL::Present() { if (EGL_SUCCESS != ndk_helper::GLContext::GetInstance()->Swap()) { ContextLost(); return; } -#ifdef THREADED_RENDERING - draw_complete_semaphore_.release(); -#endif // THREADED_RENDERING glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); active_shader_id_ = 0; active_texture_id_ = 0; + fps_++; } } // namespace eng diff --git a/src/engine/renderer/opengl/renderer_opengl_linux.cc b/src/engine/renderer/opengl/renderer_opengl_linux.cc index 9d5cd00..39b6176 100644 --- a/src/engine/renderer/opengl/renderer_opengl_linux.cc +++ b/src/engine/renderer/opengl/renderer_opengl_linux.cc @@ -16,12 +16,6 @@ bool RendererOpenGL::Initialize(Platform* platform) { screen_width_ = xwa.width; screen_height_ = xwa.height; - return StartRenderThread(); -} - -void RendererOpenGL::OnDestroy() {} - -bool RendererOpenGL::InitInternal() { GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None}; XVisualInfo* visual_info = glXChooseVisual(display_, 0, glx_attributes); @@ -41,6 +35,8 @@ bool RendererOpenGL::InitInternal() { return InitCommon(); } +void RendererOpenGL::OnDestroy() {} + void RendererOpenGL::ShutdownInternal() { if (display_ && glx_context_) { glXMakeCurrent(display_, None, NULL); @@ -49,16 +45,12 @@ void RendererOpenGL::ShutdownInternal() { } } -void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) { - if (display_) { - glXSwapBuffers(display_, window_); -#ifdef THREADED_RENDERING - draw_complete_semaphore_.release(); -#endif // THREADED_RENDERING - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - active_shader_id_ = 0; - active_texture_id_ = 0; - } +void RendererOpenGL::Present() { + glXSwapBuffers(display_, window_); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + active_shader_id_ = 0; + active_texture_id_ = 0; + fps_++; } } // namespace eng diff --git a/src/engine/renderer/renderer_types.cc b/src/engine/renderer/renderer_types.cc index 42b2f02..1f5449d 100644 --- a/src/engine/renderer/renderer_types.cc +++ b/src/engine/renderer/renderer_types.cc @@ -14,7 +14,7 @@ const char kLayoutDelimiter[] = ";/ \t"; namespace eng { -bool ParseVertexDescription(std::string vd_str, VertexDescription& out) { +bool ParseVertexDescription(const std::string& vd_str, VertexDescription& out) { // Parse the description. char buffer[32]; strcpy(buffer, vd_str.c_str()); diff --git a/src/engine/renderer/renderer_types.h b/src/engine/renderer/renderer_types.h index 6354cf6..056075a 100644 --- a/src/engine/renderer/renderer_types.h +++ b/src/engine/renderer/renderer_types.h @@ -41,7 +41,7 @@ using DataTypeSize = size_t; using VertexDescription = std::vector>; -bool ParseVertexDescription(std::string vd_str, VertexDescription& out); +bool ParseVertexDescription(const std::string& vd_str, VertexDescription& out); } // namespace eng