Compare commits

..

5 Commits

Author SHA1 Message Date
Attila Uygun 1148e48085 Fix typo 2023-06-26 20:03:22 +02:00
Attila Uygun ce440f2913 Remove OpenGL threaded rendering 2023-06-26 20:03:22 +02:00
Attila Uygun b07ce8514e Do not reset source index when streaming is in progress 2023-06-26 20:03:22 +02:00
Attila Uygun 467e73d3a8 Fix for looping audio 2023-06-26 20:03:15 +02:00
Attila Uygun 1b9faac310 Music should be streamed 2023-06-26 10:25:22 +02:00
16 changed files with 349 additions and 947 deletions

View File

@ -1,7 +1,2 @@
BasedOnStyle: Chromium BasedOnStyle: Chromium
Standard: Cpp11 Standard: Cpp11
MacroBlockBegin: "^\
RENDER_COMMAND_BEGIN$"
MacroBlockEnd: "^\
RENDER_COMMAND_END$"

View File

@ -78,7 +78,6 @@ add_library(kaliber SHARED
../../../src/engine/platform/asset_file.cc ../../../src/engine/platform/asset_file.cc
../../../src/engine/platform/platform_android.cc ../../../src/engine/platform/platform_android.cc
../../../src/engine/renderer/geometry.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_android.cc
../../../src/engine/renderer/opengl/renderer_opengl.cc ../../../src/engine/renderer/opengl/renderer_opengl.cc
../../../src/engine/renderer/renderer_types.cc ../../../src/engine/renderer/renderer_types.cc

View File

@ -111,7 +111,6 @@ ENGINE_SRC := \
$(SRC_ROOT)/engine/platform/asset_file.cc \ $(SRC_ROOT)/engine/platform/asset_file.cc \
$(SRC_ROOT)/engine/platform/platform_linux.cc \ $(SRC_ROOT)/engine/platform/platform_linux.cc \
$(SRC_ROOT)/engine/renderer/geometry.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_linux.cc \
$(SRC_ROOT)/engine/renderer/opengl/renderer_opengl.cc \ $(SRC_ROOT)/engine/renderer/opengl/renderer_opengl.cc \
$(SRC_ROOT)/engine/renderer/renderer_types.cc \ $(SRC_ROOT)/engine/renderer/renderer_types.cc \

View File

@ -54,8 +54,8 @@ bool Demo::PreInitialize() {
"sky_without_nebula.glsl"); "sky_without_nebula.glsl");
Engine::Get().SetShaderSource("sky", "sky.glsl"); Engine::Get().SetShaderSource("sky", "sky.glsl");
Engine::Get().AsyncLoadSound("music", "Game_2_Main.mp3"); Engine::Get().AsyncLoadSound("music", "Game_2_Main.mp3", true);
Engine::Get().AsyncLoadSound("boss_music", "Game_2_Boss.mp3"); Engine::Get().AsyncLoadSound("boss_music", "Game_2_Boss.mp3", true);
if (!enemy_.PreInitialize()) { if (!enemy_.PreInitialize()) {
LOG << "Failed to create the enemy."; LOG << "Failed to create the enemy.";

View File

@ -204,6 +204,7 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
DCHECK(num_samples > 0); DCHECK(num_samples > 0);
for (size_t i = 0; i < num_frames * kChannelCount;) { for (size_t i = 0; i < num_frames * kChannelCount;) {
if (src_index < num_samples) {
// Mix the 1st channel. // Mix the 1st channel.
output_buffer[i++] += src[0][src_index] * amplitude; output_buffer[i++] += src[0][src_index] * amplitude;
@ -229,18 +230,16 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
accumulator += step; accumulator += step;
src_index += accumulator / 100; src_index += accumulator / 100;
accumulator %= 100; accumulator %= 100;
} else {
// Remove, loop or stream if the source data is consumed
if (src_index >= num_samples) {
src_index %= num_samples;
if (audio_bus->EndOfStream()) { if (audio_bus->EndOfStream()) {
marked_for_removal = true; src_index %= num_samples;
marked_for_removal = !(flags & kLoop);
break; break;
} }
if (!it->get()->streaming_in_progress.load( if (!it->get()->streaming_in_progress.load(
std::memory_order_acquire)) { std::memory_order_acquire)) {
src_index %= num_samples;
it->get()->streaming_in_progress.store(true, it->get()->streaming_in_progress.store(true,
std::memory_order_relaxed); std::memory_order_relaxed);

View File

@ -25,8 +25,6 @@ Platform::Platform() {
shared_data_path_ = "./"; shared_data_path_ = "./";
LOG << "Shared data path: " << shared_data_path_.c_str(); LOG << "Shared data path: " << shared_data_path_.c_str();
XInitThreads();
bool res = CreateWindow(800, 1205); bool res = CreateWindow(800, 1205);
CHECK(res) << "Failed to create window."; CHECK(res) << "Failed to create window.";

View File

@ -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

View File

@ -1,139 +0,0 @@
#ifndef ENGINE_RENDERER_OPENGL_RENDER_COMMAND_H
#define ENGINE_RENDERER_OPENGL_RENDER_COMMAND_H
#include <array>
#include <memory>
#include <string>
#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> 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> 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<ShaderSource> 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

File diff suppressed because it is too large Load Diff

View File

@ -6,35 +6,15 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#define THREADED_RENDERING
#ifdef THREADED_RENDERING
#include <condition_variable>
#include <deque>
#include <future>
#include <mutex>
#include <semaphore>
#include <thread>
#endif // THREADED_RENDERING
#include "engine/renderer/opengl/opengl.h" #include "engine/renderer/opengl/opengl.h"
#include "engine/renderer/renderer.h" #include "engine/renderer/renderer.h"
#if defined(__ANDROID__) #if defined(__ANDROID__)
struct ANativeWindow; struct ANativeWindow;
#endif #endif
#ifdef THREADED_RENDERING
namespace base {
class TaskRunner;
}
#endif // THREADED_RENDERING
namespace eng { namespace eng {
struct RenderCommand;
class RendererOpenGL final : public Renderer { class RendererOpenGL final : public Renderer {
public: public:
RendererOpenGL(base::Closure context_lost_cb); RendererOpenGL(base::Closure context_lost_cb);
@ -113,13 +93,9 @@ class RendererOpenGL final : public Renderer {
bool enable_depth_test = false; bool enable_depth_test = false;
}; };
struct TextureOpenGL {
GLuint id = 0;
};
std::unordered_map<uint64_t, GeometryOpenGL> geometries_; std::unordered_map<uint64_t, GeometryOpenGL> geometries_;
std::unordered_map<uint64_t, ShaderOpenGL> shaders_; std::unordered_map<uint64_t, ShaderOpenGL> shaders_;
std::unordered_map<uint64_t, TextureOpenGL> textures_; std::unordered_map<uint64_t, GLuint> textures_;
uint64_t last_resource_id_ = 0; uint64_t last_resource_id_ = 0;
GLuint active_shader_id_ = 0; GLuint active_shader_id_ = 0;
@ -130,23 +106,6 @@ class RendererOpenGL final : public Renderer {
bool is_initialized_ = false; bool is_initialized_ = false;
#ifdef THREADED_RENDERING
// Global commands are independent from frames and guaranteed to be processed.
std::deque<std::unique_ptr<RenderCommand>> global_commands_;
// Draw commands are fame specific and can be discarded if the rendering is
// not throttled.
std::deque<std::unique_ptr<RenderCommand>> 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<base::TaskRunner> main_thread_task_runner_;
#endif // THREADED_RENDERING
// Stats. // Stats.
size_t fps_ = 0; size_t fps_ = 0;
@ -158,43 +117,12 @@ class RendererOpenGL final : public Renderer {
GLXContext glx_context_ = NULL; GLXContext glx_context_ = NULL;
#endif #endif
bool InitInternal();
bool InitCommon(); bool InitCommon();
void ShutdownInternal(); void ShutdownInternal();
void OnDestroy(); void OnDestroy();
void ContextLost(); void ContextLost();
void DestroyAllResources(); void DestroyAllResources();
bool StartRenderThread();
#ifdef THREADED_RENDERING
void RenderThreadMain(std::promise<bool> promise);
#endif // THREADED_RENDERING
void EnqueueCommand(std::unique_ptr<RenderCommand> 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); void BindTexture(GLuint id);
bool SetupVertexLayout(const VertexDescription& vd, bool SetupVertexLayout(const VertexDescription& vd,
GLuint vertex_size, GLuint vertex_size,

View File

@ -12,14 +12,6 @@ bool RendererOpenGL::Initialize(Platform* platform) {
LOG << "Initializing renderer."; LOG << "Initializing renderer.";
window_ = platform->GetWindow(); 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(); ndk_helper::GLContext* gl_context = ndk_helper::GLContext::GetInstance();
if (!gl_context->IsInitialzed()) { if (!gl_context->IsInitialzed()) {
@ -48,21 +40,23 @@ bool RendererOpenGL::InitInternal() {
return InitCommon(); return InitCommon();
} }
void RendererOpenGL::OnDestroy() {
ndk_helper::GLContext::GetInstance()->Invalidate();
}
void RendererOpenGL::ShutdownInternal() { void RendererOpenGL::ShutdownInternal() {
ndk_helper::GLContext::GetInstance()->Suspend(); ndk_helper::GLContext::GetInstance()->Suspend();
} }
void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) { void RendererOpenGL::Present() {
if (EGL_SUCCESS != ndk_helper::GLContext::GetInstance()->Swap()) { if (EGL_SUCCESS != ndk_helper::GLContext::GetInstance()->Swap()) {
ContextLost(); ContextLost();
return; return;
} }
#ifdef THREADED_RENDERING
draw_complete_semaphore_.release();
#endif // THREADED_RENDERING
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
active_shader_id_ = 0; active_shader_id_ = 0;
active_texture_id_ = 0; active_texture_id_ = 0;
fps_++;
} }
} // namespace eng } // namespace eng

View File

@ -16,12 +16,6 @@ bool RendererOpenGL::Initialize(Platform* platform) {
screen_width_ = xwa.width; screen_width_ = xwa.width;
screen_height_ = xwa.height; screen_height_ = xwa.height;
return StartRenderThread();
}
void RendererOpenGL::OnDestroy() {}
bool RendererOpenGL::InitInternal() {
GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER,
None}; None};
XVisualInfo* visual_info = glXChooseVisual(display_, 0, glx_attributes); XVisualInfo* visual_info = glXChooseVisual(display_, 0, glx_attributes);
@ -41,6 +35,8 @@ bool RendererOpenGL::InitInternal() {
return InitCommon(); return InitCommon();
} }
void RendererOpenGL::OnDestroy() {}
void RendererOpenGL::ShutdownInternal() { void RendererOpenGL::ShutdownInternal() {
if (display_ && glx_context_) { if (display_ && glx_context_) {
glXMakeCurrent(display_, None, NULL); glXMakeCurrent(display_, None, NULL);
@ -49,16 +45,12 @@ void RendererOpenGL::ShutdownInternal() {
} }
} }
void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) { void RendererOpenGL::Present() {
if (display_) {
glXSwapBuffers(display_, window_); glXSwapBuffers(display_, window_);
#ifdef THREADED_RENDERING
draw_complete_semaphore_.release();
#endif // THREADED_RENDERING
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
active_shader_id_ = 0; active_shader_id_ = 0;
active_texture_id_ = 0; active_texture_id_ = 0;
} fps_++;
} }
} // namespace eng } // namespace eng

View File

@ -14,7 +14,7 @@ const char kLayoutDelimiter[] = ";/ \t";
namespace eng { namespace eng {
bool ParseVertexDescription(std::string vd_str, VertexDescription& out) { bool ParseVertexDescription(const std::string& vd_str, VertexDescription& out) {
// Parse the description. // Parse the description.
char buffer[32]; char buffer[32];
strcpy(buffer, vd_str.c_str()); strcpy(buffer, vd_str.c_str());

View File

@ -41,7 +41,7 @@ using DataTypeSize = size_t;
using VertexDescription = using VertexDescription =
std::vector<std::tuple<AttribType, DataType, ElementCount, DataTypeSize>>; std::vector<std::tuple<AttribType, DataType, ElementCount, DataTypeSize>>;
bool ParseVertexDescription(std::string vd_str, VertexDescription& out); bool ParseVertexDescription(const std::string& vd_str, VertexDescription& out);
} // namespace eng } // namespace eng

View File

@ -522,8 +522,8 @@ void RendererVulkan::ActivateTexture(uint64_t resource_id) {
if (it == textures_.end()) if (it == textures_.end())
return; return;
// Keep as pengind and bind later in ActivateShader. // Keep as pending and bind later in ActivateShader.
penging_descriptor_sets_[/*TODO*/ 0] = std::get<0>(it->second.desc_set); pending_descriptor_sets_[/*TODO*/ 0] = std::get<0>(it->second.desc_set);
} }
uint64_t RendererVulkan::CreateShader( uint64_t RendererVulkan::CreateShader(
@ -737,8 +737,8 @@ void RendererVulkan::ActivateShader(uint64_t resource_id) {
VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline); VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline);
} }
for (size_t i = 0; i < it->second.desc_set_count; ++i) { for (size_t i = 0; i < it->second.desc_set_count; ++i) {
if (active_descriptor_sets_[i] != penging_descriptor_sets_[i]) { if (active_descriptor_sets_[i] != pending_descriptor_sets_[i]) {
active_descriptor_sets_[i] = penging_descriptor_sets_[i]; active_descriptor_sets_[i] = pending_descriptor_sets_[i];
vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer, vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
it->second.pipeline_layout, 0, 1, it->second.pipeline_layout, 0, 1,
@ -1770,7 +1770,7 @@ bool RendererVulkan::CreatePipelineLayout(
if (active_descriptor_sets_.size() < shader.desc_set_count) { if (active_descriptor_sets_.size() < shader.desc_set_count) {
active_descriptor_sets_.resize(shader.desc_set_count); active_descriptor_sets_.resize(shader.desc_set_count);
penging_descriptor_sets_.resize(shader.desc_set_count); pending_descriptor_sets_.resize(shader.desc_set_count);
} }
// Parse push constants. // Parse push constants.
@ -1977,7 +1977,7 @@ void RendererVulkan::SwapBuffers() {
active_pipeline_ = VK_NULL_HANDLE; active_pipeline_ = VK_NULL_HANDLE;
for (auto& ds : active_descriptor_sets_) for (auto& ds : active_descriptor_sets_)
ds = VK_NULL_HANDLE; ds = VK_NULL_HANDLE;
for (auto& ds : penging_descriptor_sets_) for (auto& ds : pending_descriptor_sets_)
ds = VK_NULL_HANDLE; ds = VK_NULL_HANDLE;
BeginFrame(); BeginFrame();

View File

@ -169,7 +169,7 @@ class RendererVulkan final : public Renderer {
std::vector<std::unique_ptr<DescPool>> desc_pools_; std::vector<std::unique_ptr<DescPool>> desc_pools_;
VkDescriptorSetLayout descriptor_set_layout_ = VK_NULL_HANDLE; VkDescriptorSetLayout descriptor_set_layout_ = VK_NULL_HANDLE;
std::vector<VkDescriptorSet> active_descriptor_sets_; std::vector<VkDescriptorSet> active_descriptor_sets_;
std::vector<VkDescriptorSet> penging_descriptor_sets_; std::vector<VkDescriptorSet> pending_descriptor_sets_;
VkSampler sampler_ = VK_NULL_HANDLE; VkSampler sampler_ = VK_NULL_HANDLE;