From 9278a0d8f9f385b900df2269e7fa9b2e425d0173 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Thu, 3 Jul 2025 18:30:32 +0800 Subject: [PATCH 01/27] renderer: initialize the webgpu backend to support drawcall record and exec --- src/renderer/command_encoder.hpp | 254 +++++++++++++++++++++++++++ src/renderer/content_renderer.cpp | 4 +- src/renderer/content_renderer.hpp | 2 +- src/renderer/gles/context_app.cpp | 87 ++++++++- src/renderer/gles/context_app.hpp | 19 +- src/renderer/render_api.cpp | 8 +- src/renderer/render_api_opengles.cpp | 75 +++----- 7 files changed, 387 insertions(+), 62 deletions(-) create mode 100644 src/renderer/command_encoder.hpp diff --git a/src/renderer/command_encoder.hpp b/src/renderer/command_encoder.hpp new file mode 100644 index 000000000..f970c364d --- /dev/null +++ b/src/renderer/command_encoder.hpp @@ -0,0 +1,254 @@ +#pragma once + +#include +#include + +namespace renderer +{ + class GPUHandle + { + public: + virtual ~GPUHandle() = default; + + public: + std::string label = ""; + }; + + class GPUCommandEncoder + { + }; + + class GPUBuffer : public GPUHandle + { + }; + + enum class GPUTextureFormat + { + // 8-bit formats + kR8UNORM, + kR8SNORM, + kR8UINT, + kR8SINT, + + // 16-bit formats + kR16UNORM, + kR16SNORM, + kR16UINT, + kR16SINT, + kR16FLOAT, + kRG8UNORM, + kRG8SNORM, + kRG8UINT, + kRG8SINT, + + // 32-bit formats + kR32UINT, + kR32SINT, + kR32FLOAT, + kRG16UNORM, + kRG16SNORM, + kRG16UINT, + kRG16SINT, + kRG16FLOAT, + kRGBA8UNORM, + kRGBA8UNORM_SRGB, + kRGBA8SNORM, + kRGBA8UINT, + kRGBA8SINT, + kBGRA8UNORM, + kBGRA8UNORM_SRGB, + + // Packed 32-bit formats + kRGB9E5UFLOAT, + kRGB10A2UINT, + kRGB10A2UNORM, + kRG11B10UFLOAT, + + // 64-bit formats + kRG32UINT, + kRG32SINT, + kRG32FLOAT, + kRGBA16UNORM, + kRGBA16SNORM, + kRGBA16UINT, + kRGBA16SINT, + kRGBA16FLOAT, + + // 128-bit formats + kRGBA32UINT, + kRGBA32SINT, + kRGBA32FLOAT, + + // Depth/stencil formats + kSTENCIL8, + kDEPTH16UNORM, + kDEPTH24PLUS, + kDEPTH24PLUS_STENCIL8, + kDEPTH32FLOAT, + kDEPTH32FLOAT_STENCIL8, + + // BC compressed formats + kBC1_RGBA_UNORM, + kBC1_RGBA_UNORM_SRGB, + kBC2_RGBA_UNORM, + kBC2_RGBA_UNORM_SRGB, + kBC3_RGBA_UNORM, + kBC3_RGBA_UNORM_SRGB, + kBC4_R_UNORM, + kBC4_R_SNORM, + kBC5_RG_UNORM, + kBC5_RG_SNORM, + kBC6H_RGB_UFLOAT, + kBC6H_RGB_FLOAT, + kBC7_RGBA_UNORM, + kBC7_RGBA_UNORM_SRGB, + + // ETC2 compressed formats + kETC2_RGB8UNORM, + kETC2_RGB8UNORM_SRGB, + kETC2_RGB8A1UNORM, + kETC2_RGB8A1UNORM_SRGB, + kETC2_RGBA8UNORM, + kETC2_RGBA8UNORM_SRGB, + kEAC_R11UNORM, + kEAC_R11SNORM, + kEAC_RG11UNORM, + kEAC_RG11SNORM, + + // ASTC compressed formats + kASTC_4x4_UNORM, + kASTC_4x4_UNORM_SRGB, + kASTC_5x4_UNORM, + kASTC_5x4_UNORM_SRGB, + kASTC_5x5_UNORM, + kASTC_5x5_UNORM_SRGB, + kASTC_6x5_UNORM, + kASTC_6x5_UNORM_SRGB, + kASTC_6x6_UNORM, + kASTC_6x6_UNORM_SRGB, + kASTC_8x5_UNORM, + kASTC_8x5_UNORM_SRGB, + kASTC_8x6_UNORM, + kASTC_8x6_UNORM_SRGB, + kASTC_8x8_UNORM, + kASTC_8x8_UNORM_SRGB, + kASTC_10x5_UNORM, + kASTC_10x5_UNORM_SRGB, + kASTC_10x6_UNORM, + kASTC_10x6_UNORM_SRGB, + kASTC_10x8_UNORM, + kASTC_10x8_UNORM_SRGB, + kASTC_10x10_UNORM, + kASTC_10x10_UNORM_SRGB, + kASTC_12x10_UNORM, + kASTC_12x10_UNORM_SRGB, + kASTC_12x12_UNORM, + kASTC_12x12_UNORM_SRGB + }; + + enum class GPUTextureDimension + { + kTexture1D, + kTexture2D, + kTexture3D, + }; + + class GPUTexture : public GPUHandle + { + public: + private: + uint32_t width_; + uint32_t height_; + uint32_t depth_or_array_layers_; + GPUTextureDimension dimension_; + GPUTextureFormat format_; + uint32_t mip_level_count_; + uint32_t sample_count_; + }; + + class GPUTextureView : public GPUHandle + { + private: + std::weak_ptr texture_; + }; + + class GPURenderPassDescriptor + { + public: + enum LoadOp + { + Load, + Clear, + }; + enum StoreOp + { + Store, + Discard, + }; + + class ColorAttachment + { + public: + float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + LoadOp loadOp; + StoreOp storeOp; + std::optional resolveTarget; + GPUTextureView view; + }; + + class DepthStencilAttachment + { + public: + float depthClearValue = 1.0f; + std::optional depthReadOnly; + std::optional depthLoadOp; + std::optional depthStoreOp; + float stencilClearValue = 0.0f; + std::optional stencilReadOnly; + std::optional stencilLoadOp; + std::optional stencilStoreOp; + GPUTextureView view; + }; + + public: + std::optional label; + std::optional maxDrawCount; + std::vector colorAttachments; + std::optional depthStencilAttachment; + }; + + class GPUBindGroupLayout : public GPUHandle + { + }; + + class GPURenderPipelineDescriptor + { + public: + std::optional label; + }; + + class GPURenderPipeline : public GPUHandle + { + public: + GPUBindGroupLayout &getBindGroupLayout(size_t index) + { + if (index < bind_group_layouts_.size()) + return bind_group_layouts_[index]; + throw std::out_of_range("Bind group layout index out of range"); + } + + private: + std::vector bind_group_layouts_; + }; + + class GPURenderPassEncoder : public GPUHandle + { + private: + float viewport_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height + float scissor_rect_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height + std::optional index_buffer_; + std::optional vertex_buffer_; + std::optional render_pipeline_; + std::optional stencil_reference_value_; + }; +} diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index 7a563e684..8cefcaa2f 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -330,9 +330,9 @@ namespace renderer return; auto idStrBase = GetContentRendererId(getContent(), contextId); - glContext = make_unique(idStrBase); + glContext = make_unique(idStrBase, shared_from_this()); glContext->initializeContext(constellation->renderer->glHostContext); - glContextForBackup = make_unique(idStrBase + "~backup"); + glContextForBackup = make_unique(idStrBase + "~backup", shared_from_this()); isGraphicsContextsInitialized = true; } diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index c2d5e1765..3f1ee573b 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -41,7 +41,7 @@ namespace renderer TrContentRenderer *contentRenderer; }; - class TrContentRenderer final + class TrContentRenderer final : public std::enable_shared_from_this { friend class TrContentRuntime; friend class TrBackupGLContextScope; diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index 2cff36726..1b225e97a 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -1,8 +1,14 @@ +#include +#include + #include "./context_app.hpp" #include "./context_host.hpp" -ContextGLApp::ContextGLApp(string name) +using namespace std; + +ContextGLApp::ContextGLApp(string name, shared_ptr content_renderer) : ContextGLStorage(name) + , m_ContentRenderer(content_renderer) , m_GLObjectManager(make_unique(name)) { /** @@ -55,6 +61,7 @@ ContextGLApp::ContextGLApp(string name) ContextGLApp::ContextGLApp(string name, ContextGLApp *from) : ContextGLStorage(name, from) + , m_ContentRenderer(from->m_ContentRenderer) , m_CurrentDefaultRenderTarget(from->m_CurrentDefaultRenderTarget) , m_GLObjectManager(from->m_GLObjectManager) { @@ -283,6 +290,51 @@ void ContextGLApp::RecordSamplerOnDeleted(GLuint sampler) m_Samplers.erase(sampler); } +GLuint ContextGLApp::createProgram(uint32_t id) +{ + GLuint program = ObjectManagerRef().CreateProgram(id); + RecordProgramOnCreated(program); + return program; +} + +void ContextGLApp::deleteProgram(uint32_t id, GLuint &program) +{ + program = ObjectManagerRef().FindProgram(id); + ObjectManagerRef().DeleteProgram(id); + + /** + * Reset the program in both "AppGlobal" and "XRFrame" when we receiving a delete program command to avoid the + * context using the deleted program. + */ + resetProgram(program); + RecordProgramOnDeleted(program); +} + +void ContextGLApp::useProgram(uint32_t id, GLuint &program) +{ + program = ObjectManagerRef().FindProgram(id); + glUseProgram(program); + onProgramChanged(program); +} + +void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) +{ + if (shouleExecuteDrawOnCurrent(count)) + { + glDrawArrays(mode, first, count); + onAfterDraw(count); + } +} + +void ContextGLApp::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) +{ + if (shouleExecuteDrawOnCurrent(count)) + { + glDrawElements(mode, count, type, indices); + onAfterDraw(count); + } +} + void ContextGLApp::MarkAsDirty() { m_Dirty = true; @@ -357,3 +409,36 @@ bool ContextGLApp::IsChanged(ContextGLApp *other) // No changes return false; } + +renderer::TrContentRenderer &ContextGLApp::contentRendererChecked() const +{ + auto contentRenderer = m_ContentRenderer.lock(); + assert(contentRenderer != nullptr && "Content renderer must not be null"); + return *contentRenderer; +} + +bool ContextGLApp::shouleExecuteDrawOnCurrent(GLsizei count) +{ + assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); + if (!m_FramebufferId.has_value() || m_FramebufferId.value() == 0) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, "Skip this draw: the framebuffer is not set."); + return false; + } + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, "Skip this draw: the framebuffer is not complete."); + return false; + } + if (m_FramebufferId.value() != m_CurrentDefaultRenderTarget) + { + // TODO(yorkie): should record the GPU command buffer and draw parameters + return false; + } + return true; +} + +void ContextGLApp::onAfterDraw(int drawCount) +{ + contentRendererChecked().increaseDrawCallsCount(drawCount); +} diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index 2c54a7d06..f0f8dab10 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -3,17 +3,16 @@ #include #include #include +#include #include "./context_storage.hpp" #include "./framebuffer.hpp" -typedef GLuint HostFramebufferIdentifier; - class ContextGLHost; class ContextGLApp : public ContextGLStorage { public: - ContextGLApp(std::string name); + ContextGLApp(std::string name, std::shared_ptr); ContextGLApp(std::string name, ContextGLApp *from); public: @@ -51,19 +50,33 @@ class ContextGLApp : public ContextGLStorage void RecordSamplerOnCreated(GLuint sampler); void RecordSamplerOnDeleted(GLuint sampler); +public: // GLES Implementations + GLuint createProgram(uint32_t id); + void deleteProgram(uint32_t id, GLuint &program); + void useProgram(uint32_t id, GLuint &program); + + void drawArrays(GLenum mode, GLint first, GLsizei count); + void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); + public: void MarkAsDirty(); bool IsDirty(); bool IsChanged(ContextGLApp *other); public: + renderer::TrContentRenderer &contentRendererChecked() const; gles::GLObjectManager &ObjectManagerRef() { return *m_GLObjectManager; } +private: + [[nodiscard]] bool shouleExecuteDrawOnCurrent(GLsizei count); + void onAfterDraw(int drawCount); + private: bool m_Dirty = false; + std::weak_ptr m_ContentRenderer; GLuint m_CurrentDefaultRenderTarget; std::shared_ptr m_GLObjectManager; diff --git a/src/renderer/render_api.cpp b/src/renderer/render_api.cpp index 5e029f7a6..2c5fa6e1e 100644 --- a/src/renderer/render_api.cpp +++ b/src/renderer/render_api.cpp @@ -105,13 +105,13 @@ RenderAPI *CreateRenderAPI(UnityGfxRenderer apiType) #if SUPPORT_OPENGL_UNIFIED if (apiType == kUnityGfxRendererOpenGLCore || apiType == kUnityGfxRendererOpenGLES20 || apiType == kUnityGfxRendererOpenGLES30) { - extern RenderAPI *CreateRenderAPI_OpenGLCoreES(RHIBackendType type); + extern RenderAPI *CreateRenderAPI_OpenGL(RHIBackendType type); if (apiType == kUnityGfxRendererOpenGLCore) - return CreateRenderAPI_OpenGLCoreES(RHIBackendType::OpenGLCore); + return CreateRenderAPI_OpenGL(RHIBackendType::OpenGLCore); else if (apiType == kUnityGfxRendererOpenGLES20) - return CreateRenderAPI_OpenGLCoreES(RHIBackendType::OpenGLESv2); + return CreateRenderAPI_OpenGL(RHIBackendType::OpenGLESv2); else - return CreateRenderAPI_OpenGLCoreES(RHIBackendType::OpenGLESv3); + return CreateRenderAPI_OpenGL(RHIBackendType::OpenGLESv3); } #endif // if SUPPORT_OPENGL_UNIFIED diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index c4b938c1f..90128cf75 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -48,14 +48,14 @@ void getline(const string &input, string &line, size_t &pos, char delim = '\n') } } -class RenderAPI_OpenGLCoreES : public RenderAPI +class RenderAPI_OpenGL : public RenderAPI { private: bool m_DebugEnabled = true; public: - RenderAPI_OpenGLCoreES(RHIBackendType backendType); - ~RenderAPI_OpenGLCoreES() + RenderAPI_OpenGL(RHIBackendType backendType); + ~RenderAPI_OpenGL() { } void ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces) override; @@ -67,11 +67,10 @@ class RenderAPI_OpenGLCoreES : public RenderAPI public: // Execute command buffer bool ExecuteCommandBuffer(); - bool ExecuteCommandBuffer( - vector &commandBuffers, - renderer::TrContentRenderer *content, - xr::DeviceFrame *deviceFrame, - bool isDefaultQueue) override; + bool ExecuteCommandBuffer(vector &commandBuffers, + renderer::TrContentRenderer *content, + xr::DeviceFrame *deviceFrame, + bool isDefaultQueue) override; private: /** @@ -405,9 +404,7 @@ class RenderAPI_OpenGLCoreES : public RenderAPI renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto glContext = reqContentRenderer->getOpenGLContext(); - GLuint program = glContext->ObjectManagerRef().CreateProgram(req->clientId); - reqContentRenderer->getOpenGLContext()->RecordProgramOnCreated(program); + GLuint program = reqContentRenderer->getOpenGLContext()->createProgram(req->clientId); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::CreateProgram(%d) => %d", options.isDefaultQueue, req->clientId, program); } @@ -415,17 +412,8 @@ class RenderAPI_OpenGLCoreES : public RenderAPI renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto glContext = reqContentRenderer->getOpenGLContext(); - auto program = glContext->ObjectManagerRef().FindProgram(req->clientId); - glContext->ObjectManagerRef().DeleteProgram(req->clientId); - - /** - * Reset the program in both "AppGlobal" and "XRFrame" when we receiving a delete program command to avoid the - * context using the deleted program. - */ - auto appGlContext = reqContentRenderer->getOpenGLContext(); - appGlContext->resetProgram(program); - appGlContext->RecordProgramOnDeleted(program); + GLuint program; + reqContentRenderer->getOpenGLContext()->deleteProgram(req->clientId, program); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::DeleteProgram(%d)", options.isDefaultQueue, program); } @@ -544,11 +532,8 @@ class RenderAPI_OpenGLCoreES : public RenderAPI renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto glContext = reqContentRenderer->getOpenGLContext(); - auto program = glContext->ObjectManagerRef().FindProgram(req->clientId); - glUseProgram(program); - reqContentRenderer->getOpenGLContext()->onProgramChanged(program); - + GLuint program; + reqContentRenderer->getOpenGLContext()->useProgram(req->clientId, program); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::UseProgram(%d)", options.isDefaultQueue, program); } @@ -1778,9 +1763,7 @@ class RenderAPI_OpenGLCoreES : public RenderAPI auto first = req->first; auto count = req->count; - assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); - glDrawArrays(mode, first, count); - reqContentRenderer->increaseDrawCallsCount(count); + reqContentRenderer->getOpenGLContext()->drawArrays(mode, first, count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DumpDrawCallInfo(DEBUG_TAG, "DrawArrays", options.isDefaultQueue, mode, count, 0, nullptr); } @@ -1791,16 +1774,7 @@ class RenderAPI_OpenGLCoreES : public RenderAPI auto type = req->indicesType; auto indices = reinterpret_cast(req->indicesOffset); - assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); - - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - { - DEBUG(LOG_TAG_ERROR, "Skip this drawElements(): the framebuffer is not complete."); - return; - } - glDrawElements(mode, count, type, indices); - reqContentRenderer->increaseDrawCallsCount(count); - + reqContentRenderer->getOpenGLContext()->drawElements(mode, count, type, indices); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DumpDrawCallInfo(DEBUG_TAG, "DrawElements", options.isDefaultQueue, mode, count, type, indices); } @@ -1809,7 +1783,6 @@ class RenderAPI_OpenGLCoreES : public RenderAPI auto n = req->n; auto buffers = req->bufs; glDrawBuffers(n, (const GLenum *)buffers); - reqContentRenderer->increaseDrawCallsCount(n); if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es2/glDrawBuffers") != GL_NO_ERROR || options.printsCall)) { DEBUG(DEBUG_TAG, "[%d] GL::DrawBuffers()", options.isDefaultQueue); @@ -2211,18 +2184,18 @@ class RenderAPI_OpenGLCoreES : public RenderAPI } }; -RenderAPI *CreateRenderAPI_OpenGLCoreES(RHIBackendType apiType) +RenderAPI *CreateRenderAPI_OpenGL(RHIBackendType apiType) { - return new RenderAPI_OpenGLCoreES(apiType); + return new RenderAPI_OpenGL(apiType); } -RenderAPI_OpenGLCoreES::RenderAPI_OpenGLCoreES(RHIBackendType type) +RenderAPI_OpenGL::RenderAPI_OpenGL(RHIBackendType type) { backendType = type; OnCreated(); } -void RenderAPI_OpenGLCoreES::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces) +void RenderAPI_OpenGL::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces) { switch (type) { @@ -2236,17 +2209,17 @@ void RenderAPI_OpenGLCoreES::ProcessDeviceEvent(UnityGfxDeviceEventType type, IU } } -bool RenderAPI_OpenGLCoreES::SupportsWebGL2() +bool RenderAPI_OpenGL::SupportsWebGL2() { return backendType == RHIBackendType::OpenGLESv3; } -int RenderAPI_OpenGLCoreES::GetDrawingBufferWidth() +int RenderAPI_OpenGL::GetDrawingBufferWidth() { return GetRenderer()->getOpenGLContext()->viewport().width(); } -int RenderAPI_OpenGLCoreES::GetDrawingBufferHeight() +int RenderAPI_OpenGL::GetDrawingBufferHeight() { return GetRenderer()->getOpenGLContext()->viewport().height(); } @@ -2311,7 +2284,7 @@ static void KHR_CustomDebugCallback(GLenum source, GLenum type, GLuint id, GLenu } #endif -void RenderAPI_OpenGLCoreES::EnableGraphicsDebugLog(bool _apiOnly) +void RenderAPI_OpenGL::EnableGraphicsDebugLog(bool _apiOnly) { #ifdef ANDROID // Open KHR_debug extension @@ -2323,7 +2296,7 @@ void RenderAPI_OpenGLCoreES::EnableGraphicsDebugLog(bool _apiOnly) #endif } -void RenderAPI_OpenGLCoreES::DisableGraphicsDebugLog() +void RenderAPI_OpenGL::DisableGraphicsDebugLog() { #ifdef ANDROID if (backendType == RHIBackendType::OpenGLESv3) @@ -2334,7 +2307,7 @@ void RenderAPI_OpenGLCoreES::DisableGraphicsDebugLog() #endif } -bool RenderAPI_OpenGLCoreES::ExecuteCommandBuffer( +bool RenderAPI_OpenGL::ExecuteCommandBuffer( vector &commandBuffers, renderer::TrContentRenderer *contentRenderer, xr::DeviceFrame *deviceFrame, From eec383b593860bfc7dcadd1ed0a6001e954303bf Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 4 Jul 2025 14:01:34 +0800 Subject: [PATCH 02/27] move gpu classes to common which can be shared in client and server-side --- .vscode/settings.json | 3 +- src/common/command_buffers/gpu/gpu_base.hpp | 40 +++++++ .../command_buffers/gpu/gpu_bind_group.hpp | 67 +++++++++++ src/common/command_buffers/gpu/gpu_buffer.hpp | 12 ++ .../gpu/gpu_command_buffer.hpp | 12 ++ .../gpu/gpu_command_encoder.hpp | 18 +++ src/common/command_buffers/gpu/gpu_device.hpp | 36 ++++++ .../command_buffers/gpu/gpu_pipeline.hpp | 37 ++++++ .../gpu/gpu_renderpass_encoder.hpp | 67 +++++++++++ .../command_buffers/gpu/gpu_texture.hpp} | 108 +----------------- .../command_buffers/gpu/gpu_texture_view.hpp | 24 ++++ 11 files changed, 317 insertions(+), 107 deletions(-) create mode 100644 src/common/command_buffers/gpu/gpu_base.hpp create mode 100644 src/common/command_buffers/gpu/gpu_bind_group.hpp create mode 100644 src/common/command_buffers/gpu/gpu_buffer.hpp create mode 100644 src/common/command_buffers/gpu/gpu_command_buffer.hpp create mode 100644 src/common/command_buffers/gpu/gpu_command_encoder.hpp create mode 100644 src/common/command_buffers/gpu/gpu_device.hpp create mode 100644 src/common/command_buffers/gpu/gpu_pipeline.hpp create mode 100644 src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp rename src/{renderer/command_encoder.hpp => common/command_buffers/gpu/gpu_texture.hpp} (54%) create mode 100644 src/common/command_buffers/gpu/gpu_texture_view.hpp diff --git a/.vscode/settings.json b/.vscode/settings.json index d4a96a0d9..c301e8e83 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -97,7 +97,8 @@ "memory_resource": "cpp", "__availability": "cpp", "span": "cpp", - "execution": "cpp" + "execution": "cpp", + "cassert": "cpp" }, "cmake.buildDirectory": "${workspaceFolder}/build/targets/darwin", "C_Cpp.default.cppStandard": "c++17", diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp new file mode 100644 index 000000000..42b9adc48 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +namespace commandbuffers +{ + enum class GPUShaderStage + { + kVertex, + kFragment, + kCompute, + }; + + enum class GPUBufferType + { + kReadOnlyStorage, + kStorage, + kUniform, + }; + + enum class GPUStorageAccess + { + kReadOnly, + kReadWrite, + kWriteOnly, + }; + + enum class GPUSamplerType + { + kComparison, + kFiltering, + kNonFiltering, + }; + + class GPUHandle + { + public: + std::string label = ""; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_bind_group.hpp b/src/common/command_buffers/gpu/gpu_bind_group.hpp new file mode 100644 index 000000000..aa14ce744 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_bind_group.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include +#include +#include + +#include "./gpu_base.hpp" +#include "./gpu_texture.hpp" + +namespace commandbuffers +{ + class GPUBindGroupLayout : public GPUHandle + { + public: + class BufferLayout + { + public: + GPUBufferType type; + bool hasDynamicOffset = false; + uint32_t minBindingSize = 0; // in bytes + }; + + class TextureLayout + { + public: + bool multisampled = false; + }; + + class StorageTextureLayout + { + public: + GPUStorageAccess access; + GPUTextureFormat format; + std::optional viewDimension; + }; + + class ExternalTextureLayout + { + }; + + class SamplerLayout + { + public: + GPUSamplerType type; + }; + + using ResourceLayout = std::variant; + class Entry + { + public: + uint32_t binding; + GPUShaderStage visibility; + ResourceLayout layout; + }; + + private: + std::vector entries_; + }; + + class GPUBindGroup : public GPUHandle + { + }; +} diff --git a/src/common/command_buffers/gpu/gpu_buffer.hpp b/src/common/command_buffers/gpu/gpu_buffer.hpp new file mode 100644 index 000000000..e969351f4 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_buffer.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "./gpu_base.hpp" + +namespace commandbuffers +{ + class GPUBuffer : public GPUHandle + { + public: + ~GPUBuffer() = default; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.hpp b/src/common/command_buffers/gpu/gpu_command_buffer.hpp new file mode 100644 index 000000000..2594bda3d --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_command_buffer.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "./gpu_base.hpp" + +namespace commandbuffers +{ + class GPUCommandBuffer : public GPUHandle + { + public: + virtual ~GPUCommandBuffer() = default; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp new file mode 100644 index 000000000..bbab5541d --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "./gpu_base.hpp" +#include "./gpu_command_buffer.hpp" +#include "./gpu_renderpass_encoder.hpp" + +namespace commandbuffers +{ + class GPUCommandEncoder : public GPUHandle + { + public: + virtual ~GPUCommandEncoder() = default; + + public: + virtual GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor &) = 0; + virtual GPUCommandBuffer finish(std::optional label = std::nullopt) = 0; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp new file mode 100644 index 000000000..b4bae229a --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +#include "./gpu_base.hpp" +#include "./gpu_command_buffer.hpp" + +namespace commandbuffers +{ + class GPUQueue : public GPUHandle + { + public: + virtual ~GPUQueue() = default; + + public: + virtual void submit(const std::vector &) = 0; + }; + + class GPUDevice : public GPUHandle + { + public: + virtual ~GPUDevice() = default; + + public: + GPUQueue &queueRef() + { + assert(queue_ != nullptr); + return *queue_; + } + + private: + std::unique_ptr queue_; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_pipeline.hpp b/src/common/command_buffers/gpu/gpu_pipeline.hpp new file mode 100644 index 000000000..7a2113626 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_pipeline.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include + +#include "./gpu_base.hpp" +#include "./gpu_bind_group.hpp" + +namespace commandbuffers +{ + class GPUPipelineLayout : public GPUHandle + { + private: + std::vector bind_group_layouts_; + }; + + class GPURenderPipelineDescriptor + { + public: + std::optional label; + }; + + class GPURenderPipeline : public GPUHandle + { + public: + GPUBindGroupLayout &getBindGroupLayout(size_t index) + { + if (index < bind_group_layouts_.size()) + return bind_group_layouts_[index]; + throw std::out_of_range("Bind group layout index out of range"); + } + + private: + std::vector bind_group_layouts_; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp new file mode 100644 index 000000000..79695eada --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include + +#include "./gpu_base.hpp" +#include "./gpu_buffer.hpp" +#include "./gpu_pipeline.hpp" +#include "./gpu_texture_view.hpp" + +namespace commandbuffers +{ + class GPURenderPassDescriptor + { + public: + enum LoadOp + { + Load, + Clear, + }; + enum StoreOp + { + Store, + Discard, + }; + + class ColorAttachment + { + public: + float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + LoadOp loadOp; + StoreOp storeOp; + std::optional resolveTarget; + GPUTextureView view; + }; + + class DepthStencilAttachment + { + public: + float depthClearValue = 1.0f; + std::optional depthReadOnly; + std::optional depthLoadOp; + std::optional depthStoreOp; + float stencilClearValue = 0.0f; + std::optional stencilReadOnly; + std::optional stencilLoadOp; + std::optional stencilStoreOp; + GPUTextureView view; + }; + + public: + std::optional label; + std::optional maxDrawCount; + std::vector colorAttachments; + std::optional depthStencilAttachment; + }; + + class GPURenderPassEncoder : public GPUHandle + { + private: + float viewport_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height + float scissor_rect_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height + std::optional index_buffer_; + std::optional vertex_buffer_; + std::optional render_pipeline_; + std::optional stencil_reference_value_; + }; +} diff --git a/src/renderer/command_encoder.hpp b/src/common/command_buffers/gpu/gpu_texture.hpp similarity index 54% rename from src/renderer/command_encoder.hpp rename to src/common/command_buffers/gpu/gpu_texture.hpp index f970c364d..7a30052cd 100644 --- a/src/renderer/command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_texture.hpp @@ -1,27 +1,9 @@ #pragma once -#include -#include +#include "./gpu_base.hpp" -namespace renderer +namespace commandbuffers { - class GPUHandle - { - public: - virtual ~GPUHandle() = default; - - public: - std::string label = ""; - }; - - class GPUCommandEncoder - { - }; - - class GPUBuffer : public GPUHandle - { - }; - enum class GPUTextureFormat { // 8-bit formats @@ -165,90 +147,4 @@ namespace renderer uint32_t mip_level_count_; uint32_t sample_count_; }; - - class GPUTextureView : public GPUHandle - { - private: - std::weak_ptr texture_; - }; - - class GPURenderPassDescriptor - { - public: - enum LoadOp - { - Load, - Clear, - }; - enum StoreOp - { - Store, - Discard, - }; - - class ColorAttachment - { - public: - float clearColor[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - LoadOp loadOp; - StoreOp storeOp; - std::optional resolveTarget; - GPUTextureView view; - }; - - class DepthStencilAttachment - { - public: - float depthClearValue = 1.0f; - std::optional depthReadOnly; - std::optional depthLoadOp; - std::optional depthStoreOp; - float stencilClearValue = 0.0f; - std::optional stencilReadOnly; - std::optional stencilLoadOp; - std::optional stencilStoreOp; - GPUTextureView view; - }; - - public: - std::optional label; - std::optional maxDrawCount; - std::vector colorAttachments; - std::optional depthStencilAttachment; - }; - - class GPUBindGroupLayout : public GPUHandle - { - }; - - class GPURenderPipelineDescriptor - { - public: - std::optional label; - }; - - class GPURenderPipeline : public GPUHandle - { - public: - GPUBindGroupLayout &getBindGroupLayout(size_t index) - { - if (index < bind_group_layouts_.size()) - return bind_group_layouts_[index]; - throw std::out_of_range("Bind group layout index out of range"); - } - - private: - std::vector bind_group_layouts_; - }; - - class GPURenderPassEncoder : public GPUHandle - { - private: - float viewport_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height - float scissor_rect_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height - std::optional index_buffer_; - std::optional vertex_buffer_; - std::optional render_pipeline_; - std::optional stencil_reference_value_; - }; } diff --git a/src/common/command_buffers/gpu/gpu_texture_view.hpp b/src/common/command_buffers/gpu/gpu_texture_view.hpp new file mode 100644 index 000000000..557402b71 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_texture_view.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "./gpu_texture.hpp" + +namespace commandbuffers +{ + class GPUTextureView : public GPUHandle + { + public: + const GPUTexture &textureRef() const + { + auto texture = texture_.lock(); + if (!texture) + throw std::runtime_error("GPUTextureView: Texture has been destroyed."); + return *texture; + } + + private: + std::weak_ptr texture_; + }; +} From 9dff10c7fbdfa587e426b073d598e5fce86377a2 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 4 Jul 2025 15:32:41 +0800 Subject: [PATCH 03/27] update --- .../command_buffers/gpu/gpu_adapter.hpp | 69 +++++++++++++++++ src/common/command_buffers/gpu/gpu_device.hpp | 25 ++++++- src/examples/desktop_opengl.cpp | 4 +- src/renderer/content_renderer.hpp | 2 + src/renderer/gles/context_app.cpp | 3 + src/renderer/render_api.cpp | 74 ++++++++++++------- src/renderer/render_api.hpp | 72 +++++++++--------- src/renderer/render_api_metal.mm | 19 +++-- src/renderer/render_api_opengles.cpp | 33 +++++---- src/renderer/renderer.cpp | 42 +++++------ src/renderer/renderer.hpp | 8 +- src/runtime/unity_entry.cpp | 7 +- 12 files changed, 237 insertions(+), 121 deletions(-) create mode 100644 src/common/command_buffers/gpu/gpu_adapter.hpp diff --git a/src/common/command_buffers/gpu/gpu_adapter.hpp b/src/common/command_buffers/gpu/gpu_adapter.hpp new file mode 100644 index 000000000..f34e799b6 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_adapter.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include +#include + +#include "./gpu_base.hpp" + +namespace commandbuffers +{ + class GPUAdapterInfo + { + public: + std::string architecture = ""; + std::string description = ""; + std::string device = ""; + std::string vendor = ""; + uint32_t subgroupMaxSize; + uint32_t subgroupMinSize; + }; + + class GPUSupportedFeatures : public std::unordered_set + { + public: + GPUSupportedFeatures() + { + // TODO(yorkie): add required features + } + }; + + class GPUSupportedLimits : public std::unordered_map + { + public: + GPUSupportedLimits() + { + insert({"maxTextureDimension1D", 8192}); + insert({"maxTextureDimension2D", 8192}); + insert({"maxTextureDimension3D", 2048}); + insert({"maxTextureArrayLayers", 256}); + insert({"maxBindGroups", 4}); + insert({"maxBindGroupEntries", 640}); + } + + public: + uint32_t maxTextureDimension1D() const + { + return at("maxTextureDimension1D"); + } + uint32_t maxTextureDimension2D() const + { + return at("maxTextureDimension2D"); + } + uint32_t maxTextureDimension3D() const + { + return at("maxTextureDimension3D"); + } + uint32_t maxTextureArrayLayers() const + { + return at("maxTextureArrayLayers"); + } + uint32_t maxBindGroups() const + { + return at("maxBindGroups"); + } + uint32_t maxBindGroupEntries() const + { + return at("maxBindGroupEntries"); + } + }; +} diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index b4bae229a..0906515eb 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -5,6 +5,7 @@ #include #include "./gpu_base.hpp" +#include "./gpu_adapter.hpp" #include "./gpu_command_buffer.hpp" namespace commandbuffers @@ -18,19 +19,41 @@ namespace commandbuffers virtual void submit(const std::vector &) = 0; }; + /** + * The `GPUDevice` interface represents a logical GPU device. + * + * In usually, at client-side WebGPU implementation, it implements the `GPUDevice` interface to send + * `GPUCommandBuffer` to the renderer. And at server-side's renderer, it implements the same `GPUDevice` interface to + * execute the `GPUCommandBuffer` on the corresponding graphics API (e.g. OpenGL, Vulkan, etc.) via RHI. + */ class GPUDevice : public GPUHandle { public: virtual ~GPUDevice() = default; public: + const GPUAdapterInfo &adapterInfo() const + { + return adapter_info_; + } + const GPUSupportedFeatures &features() const + { + return features_; + } + const GPUSupportedLimits &limits() const + { + return limits_; + } GPUQueue &queueRef() { assert(queue_ != nullptr); return *queue_; } - private: + protected: + GPUAdapterInfo adapter_info_; + GPUSupportedFeatures features_; + GPUSupportedLimits limits_; std::unique_ptr queue_; }; } diff --git a/src/examples/desktop_opengl.cpp b/src/examples/desktop_opengl.cpp index b198cc1d7..f05342e68 100644 --- a/src/examples/desktop_opengl.cpp +++ b/src/examples/desktop_opengl.cpp @@ -53,8 +53,8 @@ namespace jsar::example : TrEmbedder() { auto renderer = constellation->renderer; - auto api = RenderAPI::Create(kUnityGfxRendererOpenGLCore, constellation.get()); - renderer->setApi(api); + auto rhi = RHIFactory::CreateRHI(kUnityGfxRendererOpenGLCore, constellation.get()); + renderer->setRHI(rhi); renderer->useDoubleWideFramebuffer = true; // Check the environment variable to enable tracing diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index 3f1ee573b..faaf3fa9f 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -157,6 +158,7 @@ namespace renderer private: std::weak_ptr content; TrConstellation *constellation = nullptr; + // TODO(yorkie): Remove this when gpu device is ready, because WebGPU is context-less. std::unique_ptr glContext; std::unique_ptr glContextForBackup; bool isGraphicsContextsInitialized = false; diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index 1b225e97a..5d3ed24e0 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -88,6 +88,9 @@ GLuint ContextGLApp::currentDefaultRenderTarget() const void ContextGLApp::onFrameWillStart(ContextGLHost *host_context) { m_CurrentDefaultRenderTarget = host_context->currentFramebufferId(); + if (!m_FramebufferId.has_value()) + m_FramebufferId = m_CurrentDefaultRenderTarget; + glBindFramebuffer(GL_FRAMEBUFFER, m_CurrentDefaultRenderTarget); glClear(GL_STENCIL_BUFFER_BIT); diff --git a/src/renderer/render_api.cpp b/src/renderer/render_api.cpp index 2c5fa6e1e..c38fde991 100644 --- a/src/renderer/render_api.cpp +++ b/src/renderer/render_api.cpp @@ -9,42 +9,24 @@ using namespace std; -RenderAPI *RenderAPI::s_instance = nullptr; -RenderAPI *RenderAPI::Create(UnityGfxRenderer apiType, TrConstellation *constellation) -{ - assert(s_instance == nullptr); - s_instance = CreateRenderAPI(apiType); - if (s_instance != nullptr) - { - s_instance->constellation = constellation; - s_instance->renderer = weak_ptr(constellation->renderer); - return s_instance; - } - else - { - DEBUG(LOG_TAG_ERROR, "Failed to create renderer for %04x", apiType); - return nullptr; - } -} - -void RenderAPI::AddCommandBuffer(commandbuffers::TrCommandBufferBase *commandBuffer) +void TrRenderHardwareInterface::AddCommandBuffer(commandbuffers::TrCommandBufferBase *commandBuffer) { unique_lock lock(m_CommandBuffersMutex); m_CommandBuffers.push_back(commandBuffer); } -size_t RenderAPI::GetCommandBuffersCount() +size_t TrRenderHardwareInterface::GetCommandBuffersCount() { unique_lock lock(m_CommandBuffersMutex); return m_CommandBuffers.size(); } -void RenderAPI::OnCreated() +void TrRenderHardwareInterface::OnCreated() { m_Analytics = new analytics::Analytics(); } -bool RenderAPI::OnFrameStarted() +bool TrRenderHardwareInterface::OnFrameStarted() { auto now = std::chrono::high_resolution_clock::now(); if (m_IsFirstFrame) @@ -66,7 +48,7 @@ bool RenderAPI::OnFrameStarted() } #define MAX_DURATION_OF_FRAME 50 * 1000 // 50ms -bool RenderAPI::CheckGpuBusyStatus() +bool TrRenderHardwareInterface::CheckGpuBusyStatus() { auto duration = m_DeltaTimeDuration.count(); if (duration > MAX_DURATION_OF_FRAME) @@ -84,7 +66,7 @@ bool RenderAPI::CheckGpuBusyStatus() return m_IsGpuBusy; } -RenderAPI *CreateRenderAPI(UnityGfxRenderer apiType) +TrRenderHardwareInterface *CreateRHI_Impl(UnityGfxRenderer apiType) { #if SUPPORT_D3D11 if (apiType == kUnityGfxRendererD3D11) @@ -105,13 +87,13 @@ RenderAPI *CreateRenderAPI(UnityGfxRenderer apiType) #if SUPPORT_OPENGL_UNIFIED if (apiType == kUnityGfxRendererOpenGLCore || apiType == kUnityGfxRendererOpenGLES20 || apiType == kUnityGfxRendererOpenGLES30) { - extern RenderAPI *CreateRenderAPI_OpenGL(RHIBackendType type); + extern TrRenderHardwareInterface *CreateRHI_OpenGL(RHIBackendType type); if (apiType == kUnityGfxRendererOpenGLCore) - return CreateRenderAPI_OpenGL(RHIBackendType::OpenGLCore); + return CreateRHI_OpenGL(RHIBackendType::OpenGLCore); else if (apiType == kUnityGfxRendererOpenGLES20) - return CreateRenderAPI_OpenGL(RHIBackendType::OpenGLESv2); + return CreateRHI_OpenGL(RHIBackendType::OpenGLESv2); else - return CreateRenderAPI_OpenGL(RHIBackendType::OpenGLESv3); + return CreateRHI_OpenGL(RHIBackendType::OpenGLESv3); } #endif // if SUPPORT_OPENGL_UNIFIED @@ -135,3 +117,39 @@ RenderAPI *CreateRenderAPI(UnityGfxRenderer apiType) // Unknown or unsupported graphics API return NULL; } + + +TrRenderHardwareInterface *RHIFactory::CreateRHI(UnityGfxRenderer renderer_type, TrConstellation *constellation) +{ + assert(Instance_ == nullptr && "RHIFactory::CreateRHI should only be called once."); + + Instance_ = CreateRHI_Impl(renderer_type); + if (Instance_ != nullptr) + { + Instance_->constellation = constellation; + Instance_->renderer = constellation->renderer; + return Instance_; + } + else + { + DEBUG(LOG_TAG_ERROR, "Failed to create renderer for %04x", renderer_type); + return nullptr; + } +} + +TrRenderHardwareInterface *RHIFactory::Get() +{ + return Instance_; +} + +TrRenderHardwareInterface *RHIFactory::GetChecked() +{ + assert(Instance_ != nullptr && "RHIFactory::GetChecked should only be called after CreateRHI."); + return Instance_; +} + +TrRenderHardwareInterface &RHIFactory::GetRef() +{ + assert(Instance_ != nullptr && "RHIFactory::GetRef should only be called after CreateRHI."); + return *Instance_; +} diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index dbee7d091..ead16a3d8 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -4,15 +4,16 @@ #include #include #include -#include -#include "analytics/analytics.hpp" -#include "common/debug.hpp" +#include +#include +#include #include "common/classes.hpp" -#include "common/command_buffers/base.hpp" -#include "common/command_buffers/command_buffers.hpp" -#include "common/command_buffers/webgl_constants.hpp" -#include "xr/device.hpp" +#include +#include +#include +#include +#include #define TR_RENDERAPI_TAG "TR_RAPI" // Transmute Render API @@ -54,14 +55,15 @@ enum class RHIBackendType OpenGLESv3, VULKAN, Metal, - // Direct3D 11 + // Direct3D D3D11, - // Direct3D 12 D3D12, }; +class RHIFactory; + /** - * Rendering Hardware Interface. + * Transmute Rendering Hardware Interface. * * This virtual class is used to define the platform-independent high-level graphics APIs. It is used to abstract the * platform-specific graphics APIs, such as OpenGL, OpenGL ES, Metal, D3D11, D3D12, etc. @@ -72,38 +74,17 @@ enum class RHIBackendType * |-------------------|-----------| * | OpenGL | Yes | * | OpenGL ES | Yes | + * | Vulkan | No | * | Metal | No | * | D3D11 | No | * | D3D12 | No | */ -class RenderAPI +class TrRenderHardwareInterface { -private: - static RenderAPI *s_instance; + friend class RHIFactory; public: - /** - * @returns the singleton instance of the current RHI. - */ - static inline RenderAPI *Get() - { - return s_instance; - } - - /** - * Creates the RHI instance. - * - * @param apiType the type of the RHI, such as: OpenGL, OpenGL ES, Metal, D3D11, D3D12, etc. - * @param constellation the constellation instance. - * @returns the created RHI instance. - */ - static RenderAPI *Create(UnityGfxRenderer apiType, TrConstellation *constellation); - -public: - virtual ~RenderAPI() - { - s_instance = nullptr; - } + virtual ~TrRenderHardwareInterface() = default; /** * Process general event like initialization, shutdown, device loss/reset etc. @@ -320,6 +301,11 @@ class RenderAPI */ bool m_PrintsContext = false; + /** + * The GPU device instance. + */ + std::unique_ptr gpuDevice = nullptr; + /** * The default command buffer queue. */ @@ -357,5 +343,17 @@ class RenderAPI std::weak_ptr renderer; }; -// Create a graphics API implementation instance for the given API type. -RenderAPI *CreateRenderAPI(UnityGfxRenderer apiType); +// Alias for the RHI type. +using RHI = TrRenderHardwareInterface; + +class RHIFactory +{ +private: + static inline RHI *Instance_ = nullptr; + +public: + static RHI *CreateRHI(UnityGfxRenderer, TrConstellation *); + static RHI *Get(); + static RHI *GetChecked(); + static RHI &GetRef(); +}; diff --git a/src/renderer/render_api_metal.mm b/src/renderer/render_api_metal.mm index 6b56ede95..b8a090a82 100644 --- a/src/renderer/render_api_metal.mm +++ b/src/renderer/render_api_metal.mm @@ -75,10 +75,10 @@ - (instancetype)initWithSize:(int)size metalDevice:(id)metalDevice { } @end -class RenderAPI_Metal : public RenderAPI { +class RHI_Metal : public TrRenderHardwareInterface { public: - RenderAPI_Metal(); - ~RenderAPI_Metal() {} + RHI_Metal(); + ~RHI_Metal() {} void ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces); @@ -129,18 +129,16 @@ bool ExecuteCommandBuffer( id m_Pipeline; }; -RenderAPI *CreateRenderAPI_Metal() { return new RenderAPI_Metal(); } - static Class MTLVertexDescriptorClass; static Class MTLRenderPipelineDescriptorClass; static Class MTLDepthStencilDescriptorClass; // const int kVertexSize = 12 + 4; -RenderAPI_Metal::RenderAPI_Metal() { +RHI_Metal::RHI_Metal() { m_VertexDescriptor = [MTLVertexDescriptorClass vertexDescriptor]; } -id RenderAPI_Metal::CreateCommandEncoder() { +id RHI_Metal::CreateCommandEncoder() { if (m_CurrentCommandEncoder != nil) { return m_CurrentCommandEncoder; } @@ -160,7 +158,7 @@ bool ExecuteCommandBuffer( return m_CurrentCommandEncoder; } -void RenderAPI_Metal::ProcessDeviceEvent(UnityGfxDeviceEventType type, +void RHI_Metal::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces) { if (type == kUnityGfxDeviceEventInitialize) { m_UnityLog = interfaces->Get(); @@ -175,4 +173,9 @@ bool ExecuteCommandBuffer( } } +TrRenderHardwareInterface *CreateRHI_Metal() +{ + return new RHI_Metal(); +} + #endif // #if SUPPORT_METAL diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 90128cf75..567200553 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -48,16 +48,17 @@ void getline(const string &input, string &line, size_t &pos, char delim = '\n') } } -class RenderAPI_OpenGL : public RenderAPI +class RHI_OpenGL : public TrRenderHardwareInterface { private: bool m_DebugEnabled = true; public: - RenderAPI_OpenGL(RHIBackendType backendType); - ~RenderAPI_OpenGL() + RHI_OpenGL(RHIBackendType backendType); + ~RHI_OpenGL() { } + void ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces) override; bool SupportsWebGL2() override; int GetDrawingBufferWidth() override; @@ -2184,18 +2185,13 @@ class RenderAPI_OpenGL : public RenderAPI } }; -RenderAPI *CreateRenderAPI_OpenGL(RHIBackendType apiType) -{ - return new RenderAPI_OpenGL(apiType); -} - -RenderAPI_OpenGL::RenderAPI_OpenGL(RHIBackendType type) +RHI_OpenGL::RHI_OpenGL(RHIBackendType type) { backendType = type; OnCreated(); } -void RenderAPI_OpenGL::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces) +void RHI_OpenGL::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces) { switch (type) { @@ -2209,17 +2205,17 @@ void RenderAPI_OpenGL::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityIn } } -bool RenderAPI_OpenGL::SupportsWebGL2() +bool RHI_OpenGL::SupportsWebGL2() { return backendType == RHIBackendType::OpenGLESv3; } -int RenderAPI_OpenGL::GetDrawingBufferWidth() +int RHI_OpenGL::GetDrawingBufferWidth() { return GetRenderer()->getOpenGLContext()->viewport().width(); } -int RenderAPI_OpenGL::GetDrawingBufferHeight() +int RHI_OpenGL::GetDrawingBufferHeight() { return GetRenderer()->getOpenGLContext()->viewport().height(); } @@ -2284,7 +2280,7 @@ static void KHR_CustomDebugCallback(GLenum source, GLenum type, GLuint id, GLenu } #endif -void RenderAPI_OpenGL::EnableGraphicsDebugLog(bool _apiOnly) +void RHI_OpenGL::EnableGraphicsDebugLog(bool _apiOnly) { #ifdef ANDROID // Open KHR_debug extension @@ -2296,7 +2292,7 @@ void RenderAPI_OpenGL::EnableGraphicsDebugLog(bool _apiOnly) #endif } -void RenderAPI_OpenGL::DisableGraphicsDebugLog() +void RHI_OpenGL::DisableGraphicsDebugLog() { #ifdef ANDROID if (backendType == RHIBackendType::OpenGLESv3) @@ -2307,7 +2303,7 @@ void RenderAPI_OpenGL::DisableGraphicsDebugLog() #endif } -bool RenderAPI_OpenGL::ExecuteCommandBuffer( +bool RHI_OpenGL::ExecuteCommandBuffer( vector &commandBuffers, renderer::TrContentRenderer *contentRenderer, xr::DeviceFrame *deviceFrame, @@ -2522,4 +2518,9 @@ bool RenderAPI_OpenGL::ExecuteCommandBuffer( return contentGlContext->IsChanged(&contextBaseState); } +TrRenderHardwareInterface *CreateRHI_OpenGL(RHIBackendType apiType) +{ + return new RHI_OpenGL(apiType); +} + #endif // #if SUPPORT_OPENGL_UNIFIED diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 5fc7a07bd..545b56abc 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -14,14 +14,14 @@ namespace renderer TrRenderer::TrRenderer(TrConstellation *constellation) : constellation(constellation) - , api(nullptr) + , rhi(nullptr) , commandBufferChanServer(std::make_unique("commandBufferChan")) { } TrRenderer::~TrRenderer() { - api = nullptr; + rhi = nullptr; constellation = nullptr; // TODO: use unique_ptr for `glHostContext`. @@ -39,7 +39,7 @@ namespace renderer void TrRenderer::initialize() { - if (api == nullptr) + if (rhi == nullptr) [[unlikely]] return; glHostContext = new ContextGLHost(); @@ -49,7 +49,7 @@ namespace renderer void TrRenderer::onOpaquesRenderPass(analytics::PerformanceCounter &perfCounter) { - if (api == nullptr) [[unlikely]] + if (rhi == nullptr) [[unlikely]] return; // Skip if api is not ready. tickingTimepoint = std::chrono::high_resolution_clock::now(); @@ -97,7 +97,7 @@ namespace renderer void TrRenderer::onTransparentsRenderPass(analytics::PerformanceCounter &perfCounter) { - if (api == nullptr) [[unlikely]] + if (rhi == nullptr) [[unlikely]] return; // Skip if api is not ready. } @@ -111,31 +111,29 @@ namespace renderer // TODO } - void TrRenderer::setApi(RenderAPI *api) + void TrRenderer::setRHI(TrRenderHardwareInterface *rhi) { - if (api != nullptr) + if (rhi != nullptr) { - api->EnableAppGlobalLog(); - api->EnableXRFrameLog(); - this->api = api; + rhi->EnableAppGlobalLog(); + rhi->EnableXRFrameLog(); + this->rhi = rhi; } } - RenderAPI *TrRenderer::getApi() + TrRenderHardwareInterface *TrRenderer::getRHI() { - return api; + return rhi; } bool TrRenderer::addContentRenderer(std::shared_ptr content, uint8_t contextId) { - if (TR_UNLIKELY(api == nullptr)) + if (rhi == nullptr) [[unlikely]] return false; // Remove the existing content renderer if it has been added again. - if (TR_UNLIKELY(removeContentRenderer(content->id, contextId))) - { + if (removeContentRenderer(content->id, contextId)) [[unlikely]] DEBUG(LOG_TAG_ERROR, "Detected the ContentRenderer(%d, %d) has been added multiple times, so it will be replaced.", content->id, static_cast(contextId)); - } // Create a new content renderer and add it to the renderer. { @@ -269,17 +267,17 @@ namespace renderer void TrRenderer::setDrawingViewport(TrViewport viewport) { - api->SetDrawingViewport(viewport); + rhi->SetDrawingViewport(viewport); } void TrRenderer::setRecommendedFov(float fov) { - api->SetFieldOfView(fov); + rhi->SetFieldOfView(fov); } void TrRenderer::setTime(float time) { - api->SetTime(time); + rhi->SetTime(time); } /** @@ -327,17 +325,17 @@ namespace renderer if (xrDevice->isRenderedAsMultipass()) { xr::MultiPassFrame deviceFrame(xrDevice, 0); - return api->ExecuteCommandBuffer(commandBuffers, contentRenderer, &deviceFrame, true); + return rhi->ExecuteCommandBuffer(commandBuffers, contentRenderer, &deviceFrame, true); } else { xr::SinglePassFrame deviceFrame(xrDevice, 0); - return api->ExecuteCommandBuffer(commandBuffers, contentRenderer, &deviceFrame, true); + return rhi->ExecuteCommandBuffer(commandBuffers, contentRenderer, &deviceFrame, true); } } else { - return api->ExecuteCommandBuffer(commandBuffers, contentRenderer, nullptr, true); + return rhi->ExecuteCommandBuffer(commandBuffers, contentRenderer, nullptr, true); } } diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index 3c43c62be..fc3a88fb5 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -24,7 +24,7 @@ using namespace commandbuffers; using namespace frame_request; using namespace collision; -class RenderAPI; +class TrRenderHardwareInterface; namespace renderer { @@ -136,8 +136,8 @@ namespace renderer { commandBufferChanServer->removeClient(client); } - void setApi(RenderAPI *api); - RenderAPI *getApi(); + void setRHI(TrRenderHardwareInterface *); + TrRenderHardwareInterface *getRHI(); /** * @returns The host graphics context. */ @@ -232,7 +232,7 @@ namespace renderer uint32_t clientDefaultFrameRate = 45; private: - RenderAPI *api = nullptr; + TrRenderHardwareInterface *rhi = nullptr; TrConstellation *constellation = nullptr; ContextGLHost *glHostContext = nullptr; ContentRenderersList contentRenderers; diff --git a/src/runtime/unity_entry.cpp b/src/runtime/unity_entry.cpp index 61233eacf..0e93aa443 100644 --- a/src/runtime/unity_entry.cpp +++ b/src/runtime/unity_entry.cpp @@ -62,7 +62,8 @@ class UnityEmbedder final : public TrEmbedder deviceType = graphics->GetRenderer(); // set the backend api to the renderer. - auto api = RenderAPI::Create(deviceType, constellation.get()); + RHI* rhi = RHIFactory::CreateRHI(deviceType, constellation.get()); + assert(rhi != nullptr && "Failed to create RHI for Unity embedder."); /** * Check if the graphics debug log should be enabled by the property `jsar.renderer.graphics.debug`. @@ -72,10 +73,10 @@ class UnityEmbedder final : public TrEmbedder if (__system_property_get("jsar.renderer.graphics.debug", enableGraphicsDebugLogStr) >= 0) { if (strcmp(enableGraphicsDebugLogStr, "yes") == 0) - api->EnableGraphicsDebugLog(true); + rhi->EnableGraphicsDebugLog(true); } #endif - constellation->renderer->setApi(api); + constellation->renderer->setRHI(rhi); } void unload() From d044badbe006b3428eacfcd9b3718b3e5d2d021d Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Fri, 4 Jul 2025 19:45:02 +0800 Subject: [PATCH 04/27] update --- .../command_buffers/gpu/gpu_adapter.hpp | 22 ++++++ src/common/command_buffers/gpu/gpu_base.hpp | 8 ++- .../gpu/gpu_command_encoder.hpp | 2 + src/common/command_buffers/gpu/gpu_device.hpp | 3 + .../gpu/gpu_renderpass_encoder.hpp | 50 ++++++++++++- src/examples/desktop_opengl.cpp | 29 ++++---- src/renderer/content_renderer.cpp | 30 +++++++- src/renderer/content_renderer.hpp | 19 +++-- src/renderer/gles/context_app.cpp | 14 ++++ src/renderer/gles/context_app.hpp | 2 + src/renderer/gles/gpu_command_buffer_impl.hpp | 10 +++ .../gles/gpu_command_encoder_impl.cpp | 33 +++++++++ .../gles/gpu_command_encoder_impl.hpp | 25 +++++++ src/renderer/gles/gpu_device_impl.cpp | 71 +++++++++++++++++++ src/renderer/gles/gpu_device_impl.hpp | 23 ++++++ .../gles/gpu_renderpass_encoder_impl.hpp | 12 ++++ src/renderer/render_api.cpp | 10 +++ src/renderer/render_api.hpp | 6 ++ src/renderer/render_api_opengles.cpp | 3 + src/renderer/renderer.cpp | 58 ++++++++++----- src/renderer/renderer.hpp | 7 +- src/runtime/constellation.cpp | 4 ++ 22 files changed, 397 insertions(+), 44 deletions(-) create mode 100644 src/renderer/gles/gpu_command_buffer_impl.hpp create mode 100644 src/renderer/gles/gpu_command_encoder_impl.cpp create mode 100644 src/renderer/gles/gpu_command_encoder_impl.hpp create mode 100644 src/renderer/gles/gpu_device_impl.cpp create mode 100644 src/renderer/gles/gpu_device_impl.hpp create mode 100644 src/renderer/gles/gpu_renderpass_encoder_impl.hpp diff --git a/src/common/command_buffers/gpu/gpu_adapter.hpp b/src/common/command_buffers/gpu/gpu_adapter.hpp index f34e799b6..8e37a08e7 100644 --- a/src/common/command_buffers/gpu/gpu_adapter.hpp +++ b/src/common/command_buffers/gpu/gpu_adapter.hpp @@ -2,6 +2,8 @@ #include #include +#include +#include #include "./gpu_base.hpp" @@ -16,6 +18,26 @@ namespace commandbuffers std::string vendor = ""; uint32_t subgroupMaxSize; uint32_t subgroupMinSize; + + public: + friend std::ostream &operator<<(std::ostream &os, const GPUAdapterInfo &info) + { + os << "GPUAdapterInfo {" << std::endl + << " architecture: " << info.architecture << std::endl + << " description: " << info.description << std::endl + << " device: " << info.device << std::endl + << " vendor: " << info.vendor << std::endl + << " subgroupMaxSize: " << info.subgroupMaxSize << std::endl + << " subgroupMinSize: " << info.subgroupMinSize << std::endl + << "}"; + return os; + } + std::string toString() const + { + std::stringstream ss; + ss << *this; + return ss.str(); + } }; class GPUSupportedFeatures : public std::unordered_set diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index 42b9adc48..a9ae7f6a0 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -35,6 +35,12 @@ namespace commandbuffers class GPUHandle { public: - std::string label = ""; + GPUHandle(std::string label = "") + : label(std::move(label)) + { + } + + public: + const std::string label = ""; }; } diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index bbab5541d..4852b0ab3 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -8,6 +8,8 @@ namespace commandbuffers { class GPUCommandEncoder : public GPUHandle { + using GPUHandle::GPUHandle; + public: virtual ~GPUCommandEncoder() = default; diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index 0906515eb..832e41491 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -7,6 +7,7 @@ #include "./gpu_base.hpp" #include "./gpu_adapter.hpp" #include "./gpu_command_buffer.hpp" +#include "./gpu_command_encoder.hpp" namespace commandbuffers { @@ -50,6 +51,8 @@ namespace commandbuffers return *queue_; } + virtual std::unique_ptr createCommandEncoder(std::optional label) = 0; + protected: GPUAdapterInfo adapter_info_; GPUSupportedFeatures features_; diff --git a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp index 79695eada..a82d15073 100644 --- a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "./gpu_base.hpp" #include "./gpu_buffer.hpp" @@ -56,12 +57,59 @@ namespace commandbuffers class GPURenderPassEncoder : public GPUHandle { - private: + using GPUHandle::GPUHandle; + + struct Draw + { + uint32_t vertex_count; + uint32_t instance_count; + uint32_t first_vertex; + uint32_t first_instance; + }; + struct IndexedDraw + { + uint32_t index_count; + uint32_t instance_count; + uint32_t first_index; + int32_t base_vertex; + uint32_t first_instance; + }; + using DrawCommand = std::variant; + + public: + virtual ~GPURenderPassEncoder() = default; + + public: + void draw(uint32_t vertex_count, + uint32_t instance_count = 1, + uint32_t first_vertex = 0, + uint32_t first_instance = 0) + { + if (!ended_) [[likely]] + draw_commands_.emplace_back(Draw{vertex_count, instance_count, first_vertex, first_instance}); + } + void drawIndexed(uint32_t index_count, + uint32_t instance_count = 1, + uint32_t first_index = 0, + int32_t base_vertex = 0, + uint32_t first_instance = 0) + { + if (!ended_) [[likely]] + draw_commands_.emplace_back(IndexedDraw{index_count, instance_count, first_index, base_vertex, first_instance}); + } + void end() + { + ended_ = true; + } + + protected: + bool ended_ = false; float viewport_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height float scissor_rect_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height std::optional index_buffer_; std::optional vertex_buffer_; std::optional render_pipeline_; std::optional stencil_reference_value_; + std::vector draw_commands_; }; } diff --git a/src/examples/desktop_opengl.cpp b/src/examples/desktop_opengl.cpp index f05342e68..f77304d2e 100644 --- a/src/examples/desktop_opengl.cpp +++ b/src/examples/desktop_opengl.cpp @@ -204,6 +204,19 @@ namespace jsar::example if (windowCtx_->isTerminated()) return false; + // Make the context available before starting the embedder + glfwMakeContextCurrent(windowCtx_->window); + glfwSwapInterval(1); + { + // Get environment variables for OpenGL context + const char *str = getenv("JSAR_DISABLE_MULTISAMPLE"); + if (str != NULL && strcmp(str, "1") == 0) + multisampleEnabled = false; + + // Initialize OpenGL context + prepareRenderTarget(samples); + } + embedder_ = std::make_unique(); assert(embedder_ != nullptr); @@ -229,22 +242,6 @@ namespace jsar::example } } - // Make the context available before starting the embedder - glfwMakeContextCurrent(windowCtx_->window); - glfwSwapInterval(1); - { - auto version = glGetString(GL_VERSION); - fprintf(stdout, "OpenGL version: %s\n", version); - - // Get environment variables for OpenGL context - const char *str = getenv("JSAR_DISABLE_MULTISAMPLE"); - if (str != NULL && strcmp(str, "1") == 0) - multisampleEnabled = false; - - // Initialize OpenGL context - prepareRenderTarget(samples); - } - if (!embedder_->start()) { fprintf(stderr, "Failed to start the embedder\n"); diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index 8cefcaa2f..3abb6d94e 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -3,7 +3,9 @@ #include #include #include + #include "./content_renderer.hpp" +#include "./render_api.hpp" namespace renderer { @@ -103,12 +105,12 @@ namespace renderer return contentRef->sendCommandBufferResponse(res); } - ContextGLApp *TrContentRenderer::getOpenGLContext() + ContextGLApp *TrContentRenderer::getOpenGLContext() const { return usingBackupContext ? glContextForBackup.get() : glContext.get(); } - pid_t TrContentRenderer::getContentPid() + pid_t TrContentRenderer::getContentPid() const { auto contentRef = getContent(); return contentRef == nullptr @@ -116,6 +118,13 @@ namespace renderer : contentRef->pid.load(); } + TrRenderer &TrContentRenderer::getRendererRef() const + { + assert(constellation != nullptr && constellation->renderer != nullptr && + "The constellation or renderer is not initialized."); + return *constellation->renderer; + } + // The `req` argument is a pointer to `TrCommandBufferBase` in the heap, it will be stored in the corresponding queues // such as `defaultCommandBufferRequests` or `stereoFramesList`, otherwise it will be deleted in this function. void TrContentRenderer::onCommandBufferRequestReceived(TrCommandBufferBase *req) @@ -215,7 +224,7 @@ namespace renderer } } - void TrContentRenderer::onHostFrame(chrono::time_point time) + void TrContentRenderer::onOpaquesRenderPass(chrono::time_point time) { // Check and initialize the graphics contexts on host frame. initializeGraphicsContextsOnce(); @@ -302,6 +311,21 @@ namespace renderer onEndFrame(); } + void TrContentRenderer::onTransparentsRenderPass(chrono::time_point time) + { + // TODO(yorkie): implement the transparents render pass. + } + + void TrContentRenderer::onRenderTexturesRenderPass() + { + if (commandBuffersOnRenderTexture.size() > 0) + { + std::vector commandbuffers = commandBuffersOnRenderTexture; + commandBuffersOnRenderTexture.clear(); + constellation->renderer->getRHI()->SubmitGPUCommandBuffer(commandbuffers); + } + } + void TrContentRenderer::onStartFrame() { frameStartTime = chrono::system_clock::now(); diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index faaf3fa9f..3cfb6f8f7 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,9 @@ using namespace commandbuffers; namespace renderer { + class TrRenderer; class TrContentRenderer; + /** * A scope class for backup GL context, using this class will automatically restore the gl context after the scope: * @@ -78,12 +81,13 @@ namespace renderer public: bool sendCommandBufferResponse(TrCommandBufferResponse &res); - ContextGLApp *getOpenGLContext(); - inline shared_ptr getContent() + ContextGLApp *getOpenGLContext() const; + inline shared_ptr getContent() const { return content.lock(); } - pid_t getContentPid(); + pid_t getContentPid() const; + TrRenderer &getRendererRef() const; public: /** @@ -127,7 +131,10 @@ namespace renderer * @param req The command buffer request to be handled. */ void onCommandBufferRequestReceived(TrCommandBufferBase *req); - void onHostFrame(chrono::time_point time); + void onOpaquesRenderPass(chrono::time_point time); + void onTransparentsRenderPass(chrono::time_point time); + void onRenderTexturesRenderPass(); + void onStartFrame(); void onEndFrame(); @@ -167,10 +174,14 @@ namespace renderer private: // command buffers & rendering frames std::shared_mutex commandBufferRequestsMutex; + // TODO(yorkie): use `GPUCommandBuffer` later. std::vector defaultCommandBufferRequests; std::atomic isDefaultCommandQueuePending = false; std::atomic defaultCommandQueueSkipTimes = 0; + // The recorded command buffers which render to other render textures, such as shadow maps, reflection maps, etc. + std::vector commandBuffersOnRenderTexture; + std::vector stereoFramesList; std::unique_ptr stereoFrameForBackup = nullptr; /** diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index 5d3ed24e0..837950436 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include "./context_app.hpp" #include "./context_host.hpp" @@ -103,7 +105,17 @@ void ContextGLApp::onFrameEnded(ContextGLHost *host_context) void ContextGLApp::onProgramChanged(int program) { + auto rhi = contentRendererChecked().getRendererRef().getRHI(); + assert(rhi != nullptr && "RHI must not be null"); + m_ProgramId = program; + + auto command_encoder = rhi->CreateCommandEncoder(); + if (gles::GPUCommandEncoderImpl *impl = dynamic_cast(command_encoder.get())) + { + command_encoder.release(); + m_CurrentCommandEncoder = unique_ptr(impl); + } } void ContextGLApp::onArrayBufferChanged(int vao) @@ -322,6 +334,7 @@ void ContextGLApp::useProgram(uint32_t id, GLuint &program) void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) { + m_CurrentCommandEncoder->getOrStartRecordingRenderPass().draw(count, 1, first, 0); if (shouleExecuteDrawOnCurrent(count)) { glDrawArrays(mode, first, count); @@ -331,6 +344,7 @@ void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) void ContextGLApp::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) { + m_CurrentCommandEncoder->getOrStartRecordingRenderPass().drawIndexed(count, 1, 0, 0, 0); if (shouleExecuteDrawOnCurrent(count)) { glDrawElements(mode, count, type, indices); diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index f0f8dab10..466043a8f 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -7,6 +7,7 @@ #include "./context_storage.hpp" #include "./framebuffer.hpp" +#include "./gpu_command_encoder_impl.hpp" class ContextGLHost; class ContextGLApp : public ContextGLStorage @@ -78,6 +79,7 @@ class ContextGLApp : public ContextGLStorage bool m_Dirty = false; std::weak_ptr m_ContentRenderer; GLuint m_CurrentDefaultRenderTarget; + std::unique_ptr m_CurrentCommandEncoder = nullptr; std::shared_ptr m_GLObjectManager; OpenGLNamesStorage m_Programs; diff --git a/src/renderer/gles/gpu_command_buffer_impl.hpp b/src/renderer/gles/gpu_command_buffer_impl.hpp new file mode 100644 index 000000000..d0f2dbac8 --- /dev/null +++ b/src/renderer/gles/gpu_command_buffer_impl.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace gles +{ + class GPUCommandBufferImpl : public commandbuffers::GPUCommandBuffer + { + }; +} diff --git a/src/renderer/gles/gpu_command_encoder_impl.cpp b/src/renderer/gles/gpu_command_encoder_impl.cpp new file mode 100644 index 000000000..b465f0002 --- /dev/null +++ b/src/renderer/gles/gpu_command_encoder_impl.cpp @@ -0,0 +1,33 @@ +#include "./common.hpp" +#include "./gpu_command_encoder_impl.hpp" +#include "./gpu_command_buffer_impl.hpp" +#include "./gpu_renderpass_encoder_impl.hpp" + +namespace gles +{ + using namespace std; + using namespace commandbuffers; + + GPURenderPassEncoder GPUCommandEncoderImpl::beginRenderPass(GPURenderPassDescriptor &) + { + throw runtime_error("beginRenderPass not implemented in gles::GPUCommandEncoderImpl"); + } + + GPUCommandBuffer GPUCommandEncoderImpl::finish(optional label) + { + return GPUCommandBufferImpl(); + } + + GPURenderPassEncoder &GPUCommandEncoderImpl::getOrStartRecordingRenderPass() + { + if (recording_renderpass_encoder_ != nullptr) + { + return *recording_renderpass_encoder_; + } + else + { + recording_renderpass_encoder_ = make_unique(); + return *recording_renderpass_encoder_; + } + } +} diff --git a/src/renderer/gles/gpu_command_encoder_impl.hpp b/src/renderer/gles/gpu_command_encoder_impl.hpp new file mode 100644 index 000000000..0a945256e --- /dev/null +++ b/src/renderer/gles/gpu_command_encoder_impl.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include + +namespace gles +{ + class GPUCommandEncoderImpl : public commandbuffers::GPUCommandEncoder + { + friend class GPUDeviceImpl; + using commandbuffers::GPUCommandEncoder::GPUCommandEncoder; + + public: + commandbuffers::GPURenderPassEncoder beginRenderPass(commandbuffers::GPURenderPassDescriptor &) override; + commandbuffers::GPUCommandBuffer finish(std::optional label = std::nullopt) override; + + public: + commandbuffers::GPURenderPassEncoder &getOrStartRecordingRenderPass(); + + private: + std::unique_ptr recording_renderpass_encoder_ = nullptr; + }; +} diff --git a/src/renderer/gles/gpu_device_impl.cpp b/src/renderer/gles/gpu_device_impl.cpp new file mode 100644 index 000000000..4bc60a05a --- /dev/null +++ b/src/renderer/gles/gpu_device_impl.cpp @@ -0,0 +1,71 @@ +#include +#include +#include + +#include "./common.hpp" +#include "./gpu_device_impl.hpp" +#include "./gpu_command_encoder_impl.hpp" + +namespace gles +{ + using namespace std; + using namespace commandbuffers; + + GPUQueueImpl::GPUQueueImpl() + : GPUQueue() + { + // Initialize the queue if needed. + // For GLES, this might not require any specific initialization. + } + + void GPUQueueImpl::submit(const std::vector &command_buffers) + { + cout << "Submitting GPU command buffers to the queue: " << command_buffers.size() << endl; + } + + GPUDeviceImpl::GPUDeviceImpl() + : GPUDevice() + { + queue_ = make_unique(); + + auto get_gl_string = [](GLenum name) -> string + { + const char *str = (const char *)glGetString(name); + return str == nullptr ? "" : string(str); + }; + + // Initialize adapter_info_, features_, and limits_ with appropriate values. + adapter_info_.architecture = ""; + adapter_info_.vendor = get_gl_string(GL_VENDOR); + adapter_info_.device = get_gl_string(GL_RENDERER); + { + stringstream description_ss; + description_ss << adapter_info_.vendor << " " + << adapter_info_.device << " " + << get_gl_string(GL_VERSION) << " " + << "GLSL(" << get_gl_string(GL_SHADING_LANGUAGE_VERSION) << ") "; + + description_ss << "Extensions("; + GLint extensions_len; + glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_len); + for (int i = 0; i < extensions_len; i++) + { + const GLubyte *s = glGetStringi(GL_EXTENSIONS, i); + if (s != nullptr) + { + description_ss << string((const char *)s); + if (i < extensions_len - 1) + description_ss << ", "; + } + } + description_ss << ")"; + adapter_info_.description = description_ss.str(); + } + DEBUG(LOG_TAG_RENDERER, "GPU Device Info: %s", adapter_info_.toString().c_str()); + } + + unique_ptr GPUDeviceImpl::createCommandEncoder(optional label) + { + return unique_ptr(new GPUCommandEncoderImpl(label.value_or(""))); + } +} diff --git a/src/renderer/gles/gpu_device_impl.hpp b/src/renderer/gles/gpu_device_impl.hpp new file mode 100644 index 000000000..feadfc7a8 --- /dev/null +++ b/src/renderer/gles/gpu_device_impl.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +namespace gles +{ + class GPUQueueImpl : public commandbuffers::GPUQueue + { + public: + GPUQueueImpl(); + void submit(const std::vector &) override; + }; + + class GPUDeviceImpl : public commandbuffers::GPUDevice + { + public: + GPUDeviceImpl(); + + public: + std::unique_ptr createCommandEncoder(std::optional label) override; + }; +} diff --git a/src/renderer/gles/gpu_renderpass_encoder_impl.hpp b/src/renderer/gles/gpu_renderpass_encoder_impl.hpp new file mode 100644 index 000000000..6f90f4b00 --- /dev/null +++ b/src/renderer/gles/gpu_renderpass_encoder_impl.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +namespace gles +{ + class GPURenderPassEncoderImpl : public commandbuffers::GPURenderPassEncoder + { + using commandbuffers::GPURenderPassEncoder::GPURenderPassEncoder; + }; +} diff --git a/src/renderer/render_api.cpp b/src/renderer/render_api.cpp index c38fde991..d56bdfc38 100644 --- a/src/renderer/render_api.cpp +++ b/src/renderer/render_api.cpp @@ -9,6 +9,16 @@ using namespace std; +void TrRenderHardwareInterface::SubmitGPUCommandBuffer(std::vector &commandBuffers) +{ + gpuDevice->queueRef().submit(commandBuffers); +} + +unique_ptr TrRenderHardwareInterface::CreateCommandEncoder() +{ + return gpuDevice->createCommandEncoder(""); +} + void TrRenderHardwareInterface::AddCommandBuffer(commandbuffers::TrCommandBufferBase *commandBuffer) { unique_lock lock(m_CommandBuffersMutex); diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index ead16a3d8..bd15c8644 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -137,6 +137,12 @@ class TrRenderHardwareInterface */ virtual void DisableGraphicsDebugLog() = 0; + /** + * Submit a GPUCommandBuffer list to the GPU device for execution. + */ + void SubmitGPUCommandBuffer(std::vector &); + std::unique_ptr CreateCommandEncoder(); + /** * Adds a command buffer to the command buffer queue. * diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 567200553..4b56a40dc 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -10,6 +10,7 @@ #include "gles/common.hpp" #include "gles/context_storage.hpp" #include "gles/object_manager.hpp" +#include "gles/gpu_device_impl.hpp" #include "math/matrix.hpp" #include "runtime/content.hpp" @@ -2188,6 +2189,8 @@ class RHI_OpenGL : public TrRenderHardwareInterface RHI_OpenGL::RHI_OpenGL(RHIBackendType type) { backendType = type; + gpuDevice = unique_ptr(new gles::GPUDeviceImpl()); + OnCreated(); } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 545b56abc..f7e4b2885 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -47,6 +47,31 @@ namespace renderer startWatchers(); } + void TrRenderer::shutdown() + { + stopWatchers(); + } + + void TrRenderer::setLogFilter(string filterExpr) + { + // TODO + } + + void TrRenderer::setRHI(TrRenderHardwareInterface *rhi) + { + if (rhi != nullptr) + { + rhi->EnableAppGlobalLog(); + rhi->EnableXRFrameLog(); + this->rhi = rhi; + } + } + + TrRenderHardwareInterface *TrRenderer::getRHI() + { + return rhi; + } + void TrRenderer::onOpaquesRenderPass(analytics::PerformanceCounter &perfCounter) { if (rhi == nullptr) [[unlikely]] @@ -82,7 +107,7 @@ namespace renderer */ continue; } - contentRenderer->onHostFrame(tickingTimepoint); + contentRenderer->onOpaquesRenderPass(tickingTimepoint); totalDrawCalls += contentRenderer->drawCallsPerFrame; totalDrawCallsCount += contentRenderer->drawCallsCountPerFrame; } @@ -101,29 +126,28 @@ namespace renderer return; // Skip if api is not ready. } - void TrRenderer::shutdown() + void TrRenderer::onBeforeRendering() { - stopWatchers(); + if (rhi == nullptr) [[unlikely]] + return; // Skip if api is not ready. } - void TrRenderer::setLogFilter(string filterExpr) + void TrRenderer::onAfterRendering() { - // TODO - } + if (rhi == nullptr) [[unlikely]] + return; // Skip if api is not ready. - void TrRenderer::setRHI(TrRenderHardwareInterface *rhi) - { - if (rhi != nullptr) + glHostContext->recordFromHost(); { - rhi->EnableAppGlobalLog(); - rhi->EnableXRFrameLog(); - this->rhi = rhi; + for (auto contentRenderer : contentRenderers) + { + auto content = contentRenderer->getContent(); + if (content == nullptr || content->disableRendering) [[unlikely]] + continue; + contentRenderer->onRenderTexturesRenderPass(); + } } - } - - TrRenderHardwareInterface *TrRenderer::getRHI() - { - return rhi; + glHostContext->restore(); } bool TrRenderer::addContentRenderer(std::shared_ptr content, uint8_t contextId) diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index fc3a88fb5..64bbdda43 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -67,8 +67,6 @@ namespace renderer public: void initialize(); - void onOpaquesRenderPass(analytics::PerformanceCounter &); - void onTransparentsRenderPass(analytics::PerformanceCounter &); void shutdown(); void setLogFilter(string filterExpr); /** @@ -146,6 +144,11 @@ namespace renderer return glHostContext; } + void onOpaquesRenderPass(analytics::PerformanceCounter &); + void onTransparentsRenderPass(analytics::PerformanceCounter &); + void onBeforeRendering(); + void onAfterRendering(); + public: // API for content renderer /** * Create a new content renderer and add it to the renderer. diff --git a/src/runtime/constellation.cpp b/src/runtime/constellation.cpp index 7917dab69..4a063c1ac 100644 --- a/src/runtime/constellation.cpp +++ b/src/runtime/constellation.cpp @@ -97,6 +97,9 @@ void TrConstellation::onBeforeRendering(analytics::PerformanceCounter &perfCount contentManager->tickOnFrame(); perfCounter.record("finishContentManager"); + + renderer->onBeforeRendering(); + perfCounter.record("finishRenderer"); } void TrConstellation::onOpaquesRenderPass(analytics::PerformanceCounter &perfCounter) @@ -129,6 +132,7 @@ void TrConstellation::onAfterRendering() if (initialized == false || disableTicking) [[unlikely]] return; + renderer->onAfterRendering(); #ifdef TR_ENABLE_INSPECTOR inspector->tick(); #endif From 22d3c532e82a3c02653dcfe0dc1c9f4128b2f2b0 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Mon, 7 Jul 2025 21:45:42 +0800 Subject: [PATCH 05/27] update --- src/common/command_buffers/gpu/gpu_base.hpp | 13 + .../gpu/gpu_command_buffer.hpp | 235 ++++++++++++++++++ .../gpu/gpu_command_encoder.hpp | 9 +- src/common/command_buffers/gpu/gpu_device.hpp | 2 +- .../gpu/gpu_pass_encoder_base.hpp | 48 ++++ .../command_buffers/gpu/gpu_pipeline.hpp | 2 + .../gpu/gpu_renderpass_encoder.hpp | 89 ++++--- src/examples/desktop_opengl.cpp | 25 +- src/renderer/content_renderer.cpp | 8 +- src/renderer/content_renderer.hpp | 5 +- src/renderer/gles/context_app.cpp | 61 ++++- src/renderer/gles/context_app.hpp | 10 +- src/renderer/gles/gpu_command_buffer_impl.cpp | 85 +++++++ src/renderer/gles/gpu_command_buffer_impl.hpp | 21 ++ .../gles/gpu_command_encoder_impl.cpp | 41 ++- .../gles/gpu_command_encoder_impl.hpp | 7 +- src/renderer/gles/gpu_device_impl.cpp | 5 +- src/renderer/gles/gpu_device_impl.hpp | 2 +- src/renderer/gles/gpu_pipeline_impl.hpp | 21 ++ .../gles/gpu_renderpass_encoder_impl.cpp | 24 ++ .../gles/gpu_renderpass_encoder_impl.hpp | 15 +- src/renderer/render_api.cpp | 2 +- src/renderer/render_api.hpp | 2 +- src/renderer/render_api_opengles.cpp | 14 +- 24 files changed, 650 insertions(+), 96 deletions(-) create mode 100644 src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp create mode 100644 src/renderer/gles/gpu_command_buffer_impl.cpp create mode 100644 src/renderer/gles/gpu_pipeline_impl.hpp create mode 100644 src/renderer/gles/gpu_renderpass_encoder_impl.cpp diff --git a/src/common/command_buffers/gpu/gpu_base.hpp b/src/common/command_buffers/gpu/gpu_base.hpp index a9ae7f6a0..9ed377959 100644 --- a/src/common/command_buffers/gpu/gpu_base.hpp +++ b/src/common/command_buffers/gpu/gpu_base.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace commandbuffers { @@ -18,6 +19,12 @@ namespace commandbuffers kUniform, }; + enum class GPUIndexFormat + { + kUint16, + kUint32, + }; + enum class GPUStorageAccess { kReadOnly, @@ -32,15 +39,21 @@ namespace commandbuffers kNonFiltering, }; + typedef uint32_t GPUIdentifier; class GPUHandle { + private: + static inline TrIdGeneratorBase Ids = TrIdGeneratorBase(0); + public: GPUHandle(std::string label = "") : label(std::move(label)) + , id(Ids.get()) { } public: const std::string label = ""; + const GPUIdentifier id; }; } diff --git a/src/common/command_buffers/gpu/gpu_command_buffer.hpp b/src/common/command_buffers/gpu/gpu_command_buffer.hpp index 2594bda3d..fd3d0a280 100644 --- a/src/common/command_buffers/gpu/gpu_command_buffer.hpp +++ b/src/common/command_buffers/gpu/gpu_command_buffer.hpp @@ -1,12 +1,247 @@ #pragma once +#include +#include + #include "./gpu_base.hpp" +#include "./gpu_buffer.hpp" +#include "./gpu_pipeline.hpp" namespace commandbuffers { + class GPUCommand + { + public: + enum GPUCommandType : uint8_t + { + kDraw = 0, + kDrawIndexed, + kDrawIndirect, + kDrawIndexedIndirect, + kSetViewport, + kSetScissor, + kSetRenderPipeline, + kSetIndexBuffer, + kSetVertexBuffer, + kSetBindGroup, + kSetBlendConstant, + kSetStencilReference, + }; + + public: + const GPUCommandType type; + + GPUCommand(GPUCommandType type) + : type(type) + { + } + virtual ~GPUCommand() = default; + }; + + class GPUDrawCommand : public GPUCommand + { + public: + const uint32_t vertexCount; + const uint32_t instanceCount; + const uint32_t firstVertex; + const uint32_t firstInstance; + + GPUDrawCommand(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) + : GPUCommand(kDraw) + , vertexCount(vertex_count) + , instanceCount(instance_count) + , firstVertex(first_vertex) + , firstInstance(first_instance) + { + } + }; + + class GPUDrawIndexedCommand : public GPUCommand + { + public: + const uint32_t indexCount; + const uint32_t instanceCount; + const uint32_t firstIndex; + const int32_t baseVertex; + const uint32_t firstInstance; + + GPUDrawIndexedCommand(uint32_t index_count, + uint32_t instance_count, + uint32_t first_index, + int32_t base_vertex, + uint32_t first_instance) + : GPUCommand(kDrawIndexed) + , indexCount(index_count) + , instanceCount(instance_count) + , firstIndex(first_index) + , baseVertex(base_vertex) + , firstInstance(first_instance) + { + } + }; + + class GPUSetViewportCommand : public GPUCommand + { + public: + const float x; + const float y; + const float width; + const float height; + const float minDepth; + const float maxDepth; + + GPUSetViewportCommand(float x, float y, float width, float height, float min_depth, float max_depth) + : GPUCommand(kSetViewport) + , x(x) + , y(y) + , width(width) + , height(height) + , minDepth(min_depth) + , maxDepth(max_depth) + { + } + }; + + class GPUSetScissorCommand : public GPUCommand + { + public: + const float x; + const float y; + const float width; + const float height; + + GPUSetScissorCommand(float x, float y, float width, float height) + : GPUCommand(kSetScissor) + , x(x) + , y(y) + , width(width) + , height(height) + { + } + }; + + class GPUSetRenderPipelineCommand : public GPUCommand + { + public: + const GPUIdentifier pipelineId; + + GPUSetRenderPipelineCommand(const GPURenderPipeline &pipeline) + : GPUCommand(kSetRenderPipeline) + , pipelineId(pipeline.id) + { + } + }; + + class GPUSetIndexBufferCommand : public GPUCommand + { + public: + const GPUIdentifier bufferId; + const GPUIndexFormat indexFormat; + const uint32_t offset; + const uint32_t size; + + GPUSetIndexBufferCommand(const GPUBuffer &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size) + : GPUCommand(kSetIndexBuffer) + , bufferId(buffer.id) + , indexFormat(index_format) + , offset(offset) + , size(size) + { + } + }; + + class GPUSetVertexBufferCommand : public GPUCommand + { + public: + const uint32_t slot; + const GPUIdentifier bufferId; + const uint32_t offset; + const uint32_t size; + + GPUSetVertexBufferCommand(const uint32_t slot, const GPUBuffer &buffer, uint64_t offset, uint32_t size) + : GPUCommand(kSetVertexBuffer) + , slot(slot) + , bufferId(buffer.id) + , offset(offset) + , size(size) + { + } + }; + + class GPUSetBindGroupCommand : public GPUCommand + { + public: + const GPUIdentifier bindGroupId; + const uint32_t index; + + GPUSetBindGroupCommand(const GPUBindGroup &bindGroup, uint32_t index) + : GPUCommand(kSetBindGroup) + , bindGroupId(bindGroup.id) + , index(index) + { + } + }; + + class GPUSetBlendConstantCommand : public GPUCommand + { + public: + const float r; + const float g; + const float b; + const float a; + + GPUSetBlendConstantCommand(float r, float g, float b, float a) + : GPUCommand(kSetBlendConstant) + , r(r) + , g(g) + , b(b) + , a(a) + { + } + }; + + class GPUSetStencilReferenceCommand : public GPUCommand + { + public: + const uint32_t reference; + + GPUSetStencilReferenceCommand(uint32_t reference) + : GPUCommand(kSetStencilReference) + , reference(reference) + { + } + }; + class GPUCommandBuffer : public GPUHandle { + friend class GPUComputePassEncoder; + friend class GPURenderPassEncoder; + public: + GPUCommandBuffer(std::optional label) + : GPUHandle(label.value_or("GPUCommandBuffer")) + , commands_() + { + } + GPUCommandBuffer(std::optional label, const GPUCommandBuffer &source) + : GPUHandle(label.value_or("GPUCommandBuffer")) + , commands_(source.commands_) + { + } virtual ~GPUCommandBuffer() = default; + + public: + virtual void execute() = 0; + + private: + template + void addCommand(Args &&...args) + { + auto command = std::make_shared(std::forward(args)...); + commands_.push_back(command); + } + + protected: + std::vector> commands_; }; } diff --git a/src/common/command_buffers/gpu/gpu_command_encoder.hpp b/src/common/command_buffers/gpu/gpu_command_encoder.hpp index 4852b0ab3..78e1971d0 100644 --- a/src/common/command_buffers/gpu/gpu_command_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_command_encoder.hpp @@ -1,7 +1,10 @@ #pragma once +#include + #include "./gpu_base.hpp" #include "./gpu_command_buffer.hpp" +#include "./gpu_pass_encoder_base.hpp" #include "./gpu_renderpass_encoder.hpp" namespace commandbuffers @@ -14,7 +17,11 @@ namespace commandbuffers virtual ~GPUCommandEncoder() = default; public: + // TODO(yorkie): begineComputePass virtual GPURenderPassEncoder beginRenderPass(GPURenderPassDescriptor &) = 0; - virtual GPUCommandBuffer finish(std::optional label = std::nullopt) = 0; + virtual std::unique_ptr finish(std::optional label = std::nullopt) const = 0; + + protected: + std::shared_ptr current_pass_encoder_; }; } diff --git a/src/common/command_buffers/gpu/gpu_device.hpp b/src/common/command_buffers/gpu/gpu_device.hpp index 832e41491..991888ce7 100644 --- a/src/common/command_buffers/gpu/gpu_device.hpp +++ b/src/common/command_buffers/gpu/gpu_device.hpp @@ -17,7 +17,7 @@ namespace commandbuffers virtual ~GPUQueue() = default; public: - virtual void submit(const std::vector &) = 0; + virtual void submit(const std::vector> &) = 0; }; /** diff --git a/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp b/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp new file mode 100644 index 000000000..7e7ec9715 --- /dev/null +++ b/src/common/command_buffers/gpu/gpu_pass_encoder_base.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include "./gpu_command_buffer.hpp" + +namespace commandbuffers +{ + class GPUPassEncoderBase + { + public: + GPUPassEncoderBase() + : ended_(false) + { + } + virtual ~GPUPassEncoderBase() = default; + + public: + virtual bool isComputePassEncoder() const + { + return false; + } + virtual bool isRenderPassEncoder() const + { + return false; + } + + virtual void begin() + { + ended_ = false; + assert(command_buffer_ != nullptr && "Command buffer must be initialized before beginning pass encoder."); + } + virtual void end() + { + ended_ = true; + } + + const GPUCommandBuffer &commandBuffer() const + { + assert(command_buffer_ != nullptr && "Command buffer is not initialized."); + return *command_buffer_; + } + + protected: + std::unique_ptr command_buffer_; + bool ended_ = false; + }; +} diff --git a/src/common/command_buffers/gpu/gpu_pipeline.hpp b/src/common/command_buffers/gpu/gpu_pipeline.hpp index 7a2113626..a6bcdc46c 100644 --- a/src/common/command_buffers/gpu/gpu_pipeline.hpp +++ b/src/common/command_buffers/gpu/gpu_pipeline.hpp @@ -23,6 +23,8 @@ namespace commandbuffers class GPURenderPipeline : public GPUHandle { + using GPUHandle::GPUHandle; + public: GPUBindGroupLayout &getBindGroupLayout(size_t index) { diff --git a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp index a82d15073..04305f4c6 100644 --- a/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp +++ b/src/common/command_buffers/gpu/gpu_renderpass_encoder.hpp @@ -4,7 +4,9 @@ #include #include "./gpu_base.hpp" +#include "./gpu_pass_encoder_base.hpp" #include "./gpu_buffer.hpp" +#include "./gpu_command_buffer.hpp" #include "./gpu_pipeline.hpp" #include "./gpu_texture_view.hpp" @@ -55,38 +57,32 @@ namespace commandbuffers std::optional depthStencilAttachment; }; - class GPURenderPassEncoder : public GPUHandle + class GPURenderPassEncoder : public GPUPassEncoderBase, + public GPUHandle { - using GPUHandle::GPUHandle; - - struct Draw - { - uint32_t vertex_count; - uint32_t instance_count; - uint32_t first_vertex; - uint32_t first_instance; - }; - struct IndexedDraw + public: + GPURenderPassEncoder(std::string label) + : GPUPassEncoderBase() + , GPUHandle(label) { - uint32_t index_count; - uint32_t instance_count; - uint32_t first_index; - int32_t base_vertex; - uint32_t first_instance; - }; - using DrawCommand = std::variant; + } public: - virtual ~GPURenderPassEncoder() = default; + bool isRenderPassEncoder() const override + { + return true; + } - public: void draw(uint32_t vertex_count, uint32_t instance_count = 1, uint32_t first_vertex = 0, uint32_t first_instance = 0) { if (!ended_) [[likely]] - draw_commands_.emplace_back(Draw{vertex_count, instance_count, first_vertex, first_instance}); + command_buffer_->addCommand(vertex_count, + instance_count, + first_vertex, + first_instance); } void drawIndexed(uint32_t index_count, uint32_t instance_count = 1, @@ -95,21 +91,46 @@ namespace commandbuffers uint32_t first_instance = 0) { if (!ended_) [[likely]] - draw_commands_.emplace_back(IndexedDraw{index_count, instance_count, first_index, base_vertex, first_instance}); + command_buffer_->addCommand(index_count, + instance_count, + first_index, + base_vertex, + first_instance); } - void end() + void setViewport(float x, float y, float width, float height, float min_depth = 0.0f, float max_depth = 1.0f) { - ended_ = true; + if (!ended_) [[likely]] + command_buffer_->addCommand(x, y, width, height, min_depth, max_depth); + } + void setScissorRect(float x, float y, float width, float height) + { + if (!ended_) [[likely]] + command_buffer_->addCommand(x, y, width, height); + } + void setPipeline(const GPURenderPipeline &pipeline) + { + if (!ended_) [[likely]] + command_buffer_->addCommand(pipeline); + } + void setIndexBuffer(const GPUBuffer &buffer, GPUIndexFormat index_format, uint32_t offset, uint32_t size) + { + if (!ended_) [[likely]] + command_buffer_->addCommand(buffer, index_format, offset, size); + } + void setVertexBuffer(uint32_t slot, const GPUBuffer &buffer, uint32_t offset = 0, uint32_t size = 0) + { + if (!ended_) [[likely]] + command_buffer_->addCommand(slot, buffer, offset, size); + } + void setBlendConstant(float r, float g, float b, float a) + { + if (!ended_) [[likely]] + command_buffer_->addCommand(r, g, b, a); + } + void setStencilReference(uint32_t ref) + { + if (!ended_) [[likely]] + command_buffer_->addCommand(ref); } - - protected: - bool ended_ = false; - float viewport_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height - float scissor_rect_[4] = {0.0f, 0.0f, 1.0f, 1.0f}; // x, y, width, height - std::optional index_buffer_; - std::optional vertex_buffer_; - std::optional render_pipeline_; - std::optional stencil_reference_value_; - std::vector draw_commands_; }; } diff --git a/src/examples/desktop_opengl.cpp b/src/examples/desktop_opengl.cpp index f77304d2e..3457323d4 100644 --- a/src/examples/desktop_opengl.cpp +++ b/src/examples/desktop_opengl.cpp @@ -455,17 +455,20 @@ namespace jsar::example GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved_fbo_); - glBlitFramebuffer(0, - 0, - drawingViewport.width(), - drawingViewport.height(), - 0, - 0, - drawingViewport.width(), - drawingViewport.height(), - GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, - GL_NEAREST); + if (multisampleEnabled) + { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved_fbo_); + glBlitFramebuffer(0, + 0, + drawingViewport.width(), + drawingViewport.height(), + 0, + 0, + drawingViewport.width(), + drawingViewport.height(), + GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, + GL_NEAREST); + } // Unbind the framebuffers before swapping buffersAdd commentMore actions glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index 3abb6d94e..6deeca819 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -125,6 +125,12 @@ namespace renderer return *constellation->renderer; } + void TrContentRenderer::scheduleGPUCommandBufferOnRenderTexture(std::shared_ptr commandbuffer) + { + // TODO(yorkie): use a lock? + commandBuffersOnRenderTexture.push_back(commandbuffer); + } + // The `req` argument is a pointer to `TrCommandBufferBase` in the heap, it will be stored in the corresponding queues // such as `defaultCommandBufferRequests` or `stereoFramesList`, otherwise it will be deleted in this function. void TrContentRenderer::onCommandBufferRequestReceived(TrCommandBufferBase *req) @@ -320,7 +326,7 @@ namespace renderer { if (commandBuffersOnRenderTexture.size() > 0) { - std::vector commandbuffers = commandBuffersOnRenderTexture; + vector> commandbuffers = commandBuffersOnRenderTexture; commandBuffersOnRenderTexture.clear(); constellation->renderer->getRHI()->SubmitGPUCommandBuffer(commandbuffers); } diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index 3cfb6f8f7..cf7c6aa11 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -124,6 +124,9 @@ namespace renderer drawCallsCountPerFrame += count; } + // Schedule a GPU command buffer to be executed in the post stage for render textures. + void scheduleGPUCommandBufferOnRenderTexture(std::shared_ptr); + private: // private lifecycle /** * The callback function to handle the command buffer request received. @@ -180,7 +183,7 @@ namespace renderer std::atomic defaultCommandQueueSkipTimes = 0; // The recorded command buffers which render to other render textures, such as shadow maps, reflection maps, etc. - std::vector commandBuffersOnRenderTexture; + std::vector> commandBuffersOnRenderTexture; std::vector stereoFramesList; std::unique_ptr stereoFrameForBackup = nullptr; diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index 837950436..410a468f7 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -5,6 +5,8 @@ #include "./context_app.hpp" #include "./context_host.hpp" +#include "./gpu_command_buffer_impl.hpp" +#include "./gpu_pipeline_impl.hpp" using namespace std; @@ -65,6 +67,7 @@ ContextGLApp::ContextGLApp(string name, ContextGLApp *from) : ContextGLStorage(name, from) , m_ContentRenderer(from->m_ContentRenderer) , m_CurrentDefaultRenderTarget(from->m_CurrentDefaultRenderTarget) + , m_CurrentCommandEncoder(from->m_CurrentCommandEncoder) , m_GLObjectManager(from->m_GLObjectManager) { m_Programs = OpenGLNamesStorage(&from->m_Programs); @@ -95,6 +98,7 @@ void ContextGLApp::onFrameWillStart(ContextGLHost *host_context) glBindFramebuffer(GL_FRAMEBUFFER, m_CurrentDefaultRenderTarget); glClear(GL_STENCIL_BUFFER_BIT); + updateCurrentCommandEncoder(); ContextGLStorage::restore(); } @@ -105,17 +109,8 @@ void ContextGLApp::onFrameEnded(ContextGLHost *host_context) void ContextGLApp::onProgramChanged(int program) { - auto rhi = contentRendererChecked().getRendererRef().getRHI(); - assert(rhi != nullptr && "RHI must not be null"); - m_ProgramId = program; - - auto command_encoder = rhi->CreateCommandEncoder(); - if (gles::GPUCommandEncoderImpl *impl = dynamic_cast(command_encoder.get())) - { - command_encoder.release(); - m_CurrentCommandEncoder = unique_ptr(impl); - } + m_CurrentCommandEncoder->getOrStartRecordingRenderPass().setPipeline(gles::GPURenderPipelineImpl(program)); } void ContextGLApp::onArrayBufferChanged(int vao) @@ -130,7 +125,19 @@ void ContextGLApp::onElementBufferChanged(int ebo) void ContextGLApp::onFramebufferChanged(int fbo) { - m_FramebufferId = fbo; + if (!m_FramebufferId.has_value() || m_FramebufferId != fbo) + { + // TODO(yorkie): support scheduling GPU command buffer to transparent objects. + if (m_CurrentCommandEncoder != nullptr && + !m_CurrentCommandEncoder->isRenderPassWith(m_CurrentDefaultRenderTarget)) + { + auto commandbuffer = m_CurrentCommandEncoder->finish(); + if (commandbuffer != nullptr) [[likely]] + contentRendererChecked().scheduleGPUCommandBufferOnRenderTexture(move(commandbuffer)); + } + m_FramebufferId = fbo; + updateCurrentCommandEncoder(); + } } void ContextGLApp::onRenderbufferChanged(int rbo) @@ -332,6 +339,20 @@ void ContextGLApp::useProgram(uint32_t id, GLuint &program) onProgramChanged(program); } +void ContextGLApp::bindFramebuffer(GLenum target, uint32_t id, GLuint &framebuffer) +{ + /** + * TODO(yorkie): Now we use 0 or -1 to indicate the default render target, should we use enum instead? + */ + if (id == 0 || id == -1) + framebuffer = currentDefaultRenderTarget(); + else + framebuffer = ObjectManagerRef().FindFramebuffer(id); + + glBindFramebuffer(target, framebuffer); + onFramebufferChanged(framebuffer); +} + void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) { m_CurrentCommandEncoder->getOrStartRecordingRenderPass().draw(count, 1, first, 0); @@ -434,6 +455,20 @@ renderer::TrContentRenderer &ContextGLApp::contentRendererChecked() const return *contentRenderer; } +void ContextGLApp::updateCurrentCommandEncoder() +{ + auto rhi = contentRendererChecked().getRendererRef().getRHI(); + assert(rhi != nullptr && "RHI must not be null"); + + auto command_encoder = rhi->CreateCommandEncoder(); + if (gles::GPUCommandEncoderImpl *impl = dynamic_cast(command_encoder.get())) + { + command_encoder.release(); + m_CurrentCommandEncoder = unique_ptr(impl); + } + assert(m_CurrentCommandEncoder != nullptr && "Current command encoder must not be null"); +} + bool ContextGLApp::shouleExecuteDrawOnCurrent(GLsizei count) { assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); @@ -455,7 +490,7 @@ bool ContextGLApp::shouleExecuteDrawOnCurrent(GLsizei count) return true; } -void ContextGLApp::onAfterDraw(int drawCount) +void ContextGLApp::onAfterDraw(int draw_count) { - contentRendererChecked().increaseDrawCallsCount(drawCount); + contentRendererChecked().increaseDrawCallsCount(draw_count); } diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index 466043a8f..e673b1390 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -56,6 +56,10 @@ class ContextGLApp : public ContextGLStorage void deleteProgram(uint32_t id, GLuint &program); void useProgram(uint32_t id, GLuint &program); + // Framebuffer functions + void bindFramebuffer(GLenum target, uint32_t id, GLuint &framebuffer); + + // Draw functions void drawArrays(GLenum mode, GLint first, GLsizei count); void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); @@ -72,14 +76,18 @@ class ContextGLApp : public ContextGLStorage } private: + // This updates the current `GPUCommandEncoder` to be used for recording commands. + void updateCurrentCommandEncoder(); + [[nodiscard]] bool shouleExecuteDrawOnCurrent(GLsizei count); void onAfterDraw(int drawCount); private: bool m_Dirty = false; std::weak_ptr m_ContentRenderer; + GLuint m_CurrentDefaultRenderTarget; - std::unique_ptr m_CurrentCommandEncoder = nullptr; + std::shared_ptr m_CurrentCommandEncoder = nullptr; std::shared_ptr m_GLObjectManager; OpenGLNamesStorage m_Programs; diff --git a/src/renderer/gles/gpu_command_buffer_impl.cpp b/src/renderer/gles/gpu_command_buffer_impl.cpp new file mode 100644 index 000000000..2a9692e3d --- /dev/null +++ b/src/renderer/gles/gpu_command_buffer_impl.cpp @@ -0,0 +1,85 @@ +#include "./common.hpp" +#include "./framebuffer.hpp" +#include "./gpu_command_buffer_impl.hpp" + +namespace gles +{ + using namespace std; + using namespace commandbuffers; + + GPUCommandBufferImpl::GPUCommandBufferImpl(optional label) + : GPUCommandBuffer(move(label)) + , framebuffer_(0) + { + } + + GPUCommandBufferImpl::GPUCommandBufferImpl(optional label, const GPURenderPassEncoderImpl &renderpass_encoder) + : GPUCommandBuffer(move(label), renderpass_encoder.commandBuffer()) + , framebuffer_(renderpass_encoder.framebuffer_) + { + assert(framebuffer_ > 0 && "Framebuffer must be bound before creating GPUCommandBufferImpl"); + } + + void GPUCommandBufferImpl::execute() + { + GLFramebuffer framebuffer(framebuffer_, false); + GLFramebufferScope framebuffer_scope(GL_FRAMEBUFFER, framebuffer); + + // TODO(yorkie): execute the commands in the command buffer. + for (const auto &command : commands_) + { + switch (command->type) + { + case GPUCommand::kDraw: + onDraw(*dynamic_pointer_cast(command)); + break; + case GPUCommand::kDrawIndexed: + onDraw(*dynamic_pointer_cast(command)); + break; + case GPUCommand::kSetViewport: + setViewport(*dynamic_pointer_cast(command)); + break; + case GPUCommand::kSetScissor: + setScissorRect(*dynamic_pointer_cast(command)); + break; + default: + break; + } + } + } + + void GPUCommandBufferImpl::onDraw(const commandbuffers::GPUDrawCommand &command) + { + if (command.instanceCount > 1) + glDrawArraysInstanced(GL_TRIANGLES, command.firstVertex, command.vertexCount, command.instanceCount); + else + glDrawArrays(GL_TRIANGLES, command.firstVertex, command.vertexCount); + } + + void GPUCommandBufferImpl::onDraw(const commandbuffers::GPUDrawIndexedCommand &command) + { + if (command.instanceCount > 1) + glDrawElementsInstanced( + GL_TRIANGLES, + command.indexCount, + GL_UNSIGNED_BYTE, + nullptr, + command.instanceCount); + else + glDrawElements( + GL_TRIANGLES, + command.indexCount, + GL_UNSIGNED_BYTE, + nullptr); + } + + void GPUCommandBufferImpl::setViewport(const commandbuffers::GPUSetViewportCommand &command) + { + glViewport(command.x, command.y, command.width, command.height); + } + + void GPUCommandBufferImpl::setScissorRect(const commandbuffers::GPUSetScissorCommand &command) + { + glScissor(command.x, command.y, command.width, command.height); + } +} diff --git a/src/renderer/gles/gpu_command_buffer_impl.hpp b/src/renderer/gles/gpu_command_buffer_impl.hpp index d0f2dbac8..5a147498b 100644 --- a/src/renderer/gles/gpu_command_buffer_impl.hpp +++ b/src/renderer/gles/gpu_command_buffer_impl.hpp @@ -1,10 +1,31 @@ #pragma once +#include +#include +#include #include +#include "./common.hpp" +#include "./gpu_renderpass_encoder_impl.hpp" + namespace gles { class GPUCommandBufferImpl : public commandbuffers::GPUCommandBuffer { + public: + GPUCommandBufferImpl(std::optional label); + GPUCommandBufferImpl(std::optional label, const GPURenderPassEncoderImpl &); + + public: + void execute() override; + + private: + void onDraw(const commandbuffers::GPUDrawCommand &); + void onDraw(const commandbuffers::GPUDrawIndexedCommand &); + void setViewport(const commandbuffers::GPUSetViewportCommand &); + void setScissorRect(const commandbuffers::GPUSetScissorCommand &); + + private: + GLuint framebuffer_; }; } diff --git a/src/renderer/gles/gpu_command_encoder_impl.cpp b/src/renderer/gles/gpu_command_encoder_impl.cpp index b465f0002..fac46a6e4 100644 --- a/src/renderer/gles/gpu_command_encoder_impl.cpp +++ b/src/renderer/gles/gpu_command_encoder_impl.cpp @@ -10,24 +10,45 @@ namespace gles GPURenderPassEncoder GPUCommandEncoderImpl::beginRenderPass(GPURenderPassDescriptor &) { - throw runtime_error("beginRenderPass not implemented in gles::GPUCommandEncoderImpl"); + assert(false && "beginRenderPass not implemented in gles::GPUCommandEncoderImpl"); } - GPUCommandBuffer GPUCommandEncoderImpl::finish(optional label) + std::unique_ptr GPUCommandEncoderImpl::finish(std::optional label) const { - return GPUCommandBufferImpl(); - } + if (current_pass_encoder_ == nullptr) + return nullptr; - GPURenderPassEncoder &GPUCommandEncoderImpl::getOrStartRecordingRenderPass() - { - if (recording_renderpass_encoder_ != nullptr) + if (current_pass_encoder_->isRenderPassEncoder()) { - return *recording_renderpass_encoder_; + const auto &renderpass_encoder = dynamic_cast(*current_pass_encoder_); + return unique_ptr(new GPUCommandBufferImpl(label, renderpass_encoder)); } else { - recording_renderpass_encoder_ = make_unique(); - return *recording_renderpass_encoder_; + return nullptr; + } + } + + GPURenderPassEncoder &GPUCommandEncoderImpl::getOrStartRecordingRenderPass() + { + if (current_pass_encoder_ == nullptr || !current_pass_encoder_->isRenderPassEncoder()) + { + unique_ptr renderpass_encoder = make_unique(); + renderpass_encoder->begin(); + current_pass_encoder_ = move(renderpass_encoder); } + + auto renderpass_encoder = dynamic_pointer_cast(current_pass_encoder_); + assert(renderpass_encoder != nullptr && "Current pass encoder must be a GPURenderPassEncoderImpl"); + return *renderpass_encoder; + } + + bool GPUCommandEncoderImpl::isRenderPassWith(GLuint target_framebuffer) const + { + if (current_pass_encoder_ == nullptr || !current_pass_encoder_->isRenderPassEncoder()) + return false; + + const auto &renderpass_encoder = dynamic_cast(*current_pass_encoder_); + return renderpass_encoder.targetFramebuffer() == target_framebuffer; } } diff --git a/src/renderer/gles/gpu_command_encoder_impl.hpp b/src/renderer/gles/gpu_command_encoder_impl.hpp index 0a945256e..188883daa 100644 --- a/src/renderer/gles/gpu_command_encoder_impl.hpp +++ b/src/renderer/gles/gpu_command_encoder_impl.hpp @@ -4,6 +4,7 @@ #include #include #include +#include "./gpu_command_buffer_impl.hpp" namespace gles { @@ -14,12 +15,10 @@ namespace gles public: commandbuffers::GPURenderPassEncoder beginRenderPass(commandbuffers::GPURenderPassDescriptor &) override; - commandbuffers::GPUCommandBuffer finish(std::optional label = std::nullopt) override; + std::unique_ptr finish(std::optional label = std::nullopt) const override; public: commandbuffers::GPURenderPassEncoder &getOrStartRecordingRenderPass(); - - private: - std::unique_ptr recording_renderpass_encoder_ = nullptr; + bool isRenderPassWith(GLuint target_framebuffer) const; }; } diff --git a/src/renderer/gles/gpu_device_impl.cpp b/src/renderer/gles/gpu_device_impl.cpp index 4bc60a05a..e453a664d 100644 --- a/src/renderer/gles/gpu_device_impl.cpp +++ b/src/renderer/gles/gpu_device_impl.cpp @@ -18,9 +18,10 @@ namespace gles // For GLES, this might not require any specific initialization. } - void GPUQueueImpl::submit(const std::vector &command_buffers) + void GPUQueueImpl::submit(const vector> &command_buffers) { - cout << "Submitting GPU command buffers to the queue: " << command_buffers.size() << endl; + for (const auto &command_buffer : command_buffers) + command_buffer->execute(); } GPUDeviceImpl::GPUDeviceImpl() diff --git a/src/renderer/gles/gpu_device_impl.hpp b/src/renderer/gles/gpu_device_impl.hpp index feadfc7a8..81d1317e7 100644 --- a/src/renderer/gles/gpu_device_impl.hpp +++ b/src/renderer/gles/gpu_device_impl.hpp @@ -9,7 +9,7 @@ namespace gles { public: GPUQueueImpl(); - void submit(const std::vector &) override; + void submit(const std::vector> &) override; }; class GPUDeviceImpl : public commandbuffers::GPUDevice diff --git a/src/renderer/gles/gpu_pipeline_impl.hpp b/src/renderer/gles/gpu_pipeline_impl.hpp new file mode 100644 index 000000000..51001b5a8 --- /dev/null +++ b/src/renderer/gles/gpu_pipeline_impl.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include + +namespace gles +{ + class GPURenderPipelineImpl : public commandbuffers::GPURenderPipeline + { + public: + GPURenderPipelineImpl(GLuint program) + : commandbuffers::GPURenderPipeline("GPURenderPipeline") + , program_(program) + { + } + + private: + GLuint program_; + }; +} diff --git a/src/renderer/gles/gpu_renderpass_encoder_impl.cpp b/src/renderer/gles/gpu_renderpass_encoder_impl.cpp new file mode 100644 index 000000000..6885cc5e3 --- /dev/null +++ b/src/renderer/gles/gpu_renderpass_encoder_impl.cpp @@ -0,0 +1,24 @@ +#include "./common.hpp" +#include "./gpu_command_buffer_impl.hpp" +#include "./gpu_renderpass_encoder_impl.hpp" + +namespace gles +{ + using namespace std; + using namespace commandbuffers; + + GPURenderPassEncoderImpl::GPURenderPassEncoderImpl(std::string label) + : commandbuffers::GPURenderPassEncoder(label) + , framebuffer_(0) + { + } + + void GPURenderPassEncoderImpl::begin() + { + glGetIntegerv(GL_FRAMEBUFFER_BINDING, reinterpret_cast(&framebuffer_)); + assert(framebuffer_ > 0 && "Framebuffer must be bound before beginning render pass"); + command_buffer_ = make_unique(label); + + GPURenderPassEncoder::begin(); + } +} diff --git a/src/renderer/gles/gpu_renderpass_encoder_impl.hpp b/src/renderer/gles/gpu_renderpass_encoder_impl.hpp index 6f90f4b00..edba7a185 100644 --- a/src/renderer/gles/gpu_renderpass_encoder_impl.hpp +++ b/src/renderer/gles/gpu_renderpass_encoder_impl.hpp @@ -2,11 +2,24 @@ #include #include +#include "./common.hpp" namespace gles { class GPURenderPassEncoderImpl : public commandbuffers::GPURenderPassEncoder { - using commandbuffers::GPURenderPassEncoder::GPURenderPassEncoder; + friend class GPUCommandBufferImpl; + + public: + GPURenderPassEncoderImpl(std::string label = "GPURenderPassEncoder"); + + void begin() override; + GLuint targetFramebuffer() const + { + return framebuffer_; + } + + private: + GLuint framebuffer_; }; } diff --git a/src/renderer/render_api.cpp b/src/renderer/render_api.cpp index d56bdfc38..25754890f 100644 --- a/src/renderer/render_api.cpp +++ b/src/renderer/render_api.cpp @@ -9,7 +9,7 @@ using namespace std; -void TrRenderHardwareInterface::SubmitGPUCommandBuffer(std::vector &commandBuffers) +void TrRenderHardwareInterface::SubmitGPUCommandBuffer(vector> &commandBuffers) { gpuDevice->queueRef().submit(commandBuffers); } diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index bd15c8644..97a8df131 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -140,7 +140,7 @@ class TrRenderHardwareInterface /** * Submit a GPUCommandBuffer list to the GPU device for execution. */ - void SubmitGPUCommandBuffer(std::vector &); + void SubmitGPUCommandBuffer(std::vector> &); std::unique_ptr CreateCommandEncoder(); /** diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 4b56a40dc..cdb504289 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -921,20 +921,8 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); - auto target = req->target; GLuint framebuffer; - - /** - * TODO(yorkie): Now we use 0 or -1 to indicate the default render target, should we use enum instead? - */ - if (req->framebuffer == 0 || req->framebuffer == -1) - framebuffer = reqContentRenderer->getOpenGLContext()->currentDefaultRenderTarget(); - else - framebuffer = glObjectManager.FindFramebuffer(req->framebuffer); - - glBindFramebuffer(target, framebuffer); - reqContentRenderer->getOpenGLContext()->onFramebufferChanged(framebuffer); + reqContentRenderer->getOpenGLContext()->bindFramebuffer(req->target, req->framebuffer, framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::BindFramebuffer(%d)", options.isDefaultQueue, framebuffer); } From 347c3484530909a94966511de8e76034125b126d Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 8 Jul 2025 23:12:41 +0800 Subject: [PATCH 06/27] update --- src/common/command_buffers/base.hpp | 30 +- src/common/command_buffers/details/buffer.hpp | 157 +++++ src/common/command_buffers/details/clear.hpp | 23 + .../command_buffers/details/draw_calls.hpp | 53 +- .../details/get_extensions.hpp | 11 +- .../command_buffers/details/metrics.hpp | 5 + .../command_buffers/details/program.hpp | 67 ++- .../command_buffers/details/properties.hpp | 39 +- .../command_buffers/details/sampler.hpp | 56 ++ src/common/command_buffers/details/shader.hpp | 78 ++- src/common/command_buffers/details/states.hpp | 154 ++++- .../command_buffers/details/texture.hpp | 132 ++++- .../command_buffers/details/uniforms.hpp | 154 +++-- .../command_buffers/details/vertex_array.hpp | 25 + .../command_buffers/details/vertex_attrib.hpp | 37 ++ .../details/webgl_context_init.hpp | 49 +- src/common/command_buffers/details/xr.hpp | 18 + src/common/frame_request/types.hpp | 16 +- src/common/ipc_message.hpp | 4 +- src/common/xr/types.hpp | 2 +- src/renderer/content_renderer.cpp | 71 ++- src/renderer/content_renderer.hpp | 32 +- src/renderer/gles/context_app.cpp | 52 +- src/renderer/gles/context_app.hpp | 12 +- src/renderer/render_api.hpp | 42 +- src/renderer/render_api_metal.mm | 7 +- src/renderer/render_api_opengles.cpp | 540 ++++++++++++------ src/renderer/renderer.cpp | 26 +- src/renderer/renderer.hpp | 21 +- src/runtime/content.cpp | 5 +- src/runtime/unity_entry.cpp | 2 +- tests/command_buffers_base.cpp | 8 + 32 files changed, 1506 insertions(+), 422 deletions(-) diff --git a/src/common/command_buffers/base.hpp b/src/common/command_buffers/base.hpp index cba693938..ca350846f 100644 --- a/src/common/command_buffers/base.hpp +++ b/src/common/command_buffers/base.hpp @@ -55,6 +55,13 @@ namespace commandbuffers : TrIpcSerializableBase(type, size) { } + TrCommandBufferBase(const TrCommandBufferBase& that) + : TrIpcSerializableBase(that.type, that.size) + , id(that.id) + , contextId(that.contextId) + , renderingInfo(that.renderingInfo) + { + } public: /** @@ -87,11 +94,9 @@ namespace commandbuffers : TrCommandBufferBase(type, size) { } - TrCommandBufferRequest(TrCommandBufferRequest &that) - : TrCommandBufferBase(that.type, that.size) + TrCommandBufferRequest(const TrCommandBufferRequest &that, bool clone = false) + : TrCommandBufferBase(that) { - contextId = that.contextId; - renderingInfo = that.renderingInfo; } }; @@ -104,11 +109,10 @@ namespace commandbuffers { contextId = req->contextId; } - TrCommandBufferResponse(TrCommandBufferResponse &that) - : TrCommandBufferBase(that.type, that.size) + TrCommandBufferResponse(const TrCommandBufferResponse &that, bool clone = false) + : TrCommandBufferBase(that) , requestId(that.requestId) { - contextId = that.contextId; } public: @@ -130,8 +134,8 @@ namespace commandbuffers : TrCommandBufferRequest(Type, sizeof(Derived)) { } - TrCommandBufferSimpleRequest(TrCommandBufferSimpleRequest &that) - : TrCommandBufferRequest(that) + TrCommandBufferSimpleRequest(const TrCommandBufferSimpleRequest &that, bool clone = false) + : TrCommandBufferRequest(that, clone) { } ~TrCommandBufferSimpleRequest() = default; @@ -153,13 +157,13 @@ namespace commandbuffers class TrCommandBufferSimpleResponse : public TrCommandBufferResponse { public: - TrCommandBufferSimpleResponse(TrCommandBufferSimpleResponse &that) - : TrCommandBufferResponse(that) - { - } TrCommandBufferSimpleResponse(CommandBufferType type, TrCommandBufferRequest *req) : TrCommandBufferResponse(type, sizeof(Derived), req) { } + TrCommandBufferSimpleResponse(const TrCommandBufferSimpleResponse &that, bool clone = false) + : TrCommandBufferResponse(that, clone) + { + } }; } diff --git a/src/common/command_buffers/details/buffer.hpp b/src/common/command_buffers/details/buffer.hpp index b5a92ee1d..3c334d74b 100644 --- a/src/common/command_buffers/details/buffer.hpp +++ b/src/common/command_buffers/details/buffer.hpp @@ -15,6 +15,11 @@ namespace commandbuffers , clientId(clientId) { } + CreateBufferCommandBufferRequest(const CreateBufferCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -30,6 +35,11 @@ namespace commandbuffers , buffer(buffer) { } + DeleteBufferCommandBufferRequest(const DeleteBufferCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , buffer(that.buffer) + { + } public: uint32_t buffer; @@ -46,6 +56,12 @@ namespace commandbuffers , buffer(buffer) { } + BindBufferCommandBufferRequest(const BindBufferCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , buffer(that.buffer) + { + } public: uint32_t target; @@ -74,6 +90,20 @@ namespace commandbuffers memcpy(data, srcData, srcSize); } } + BufferDataCommandBufferRequest(const BufferDataCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , dataSize(0) + , data(nullptr) + , usage(that.usage) + { + if (clone == true && that.data != nullptr) + { + dataSize = that.dataSize; + data = malloc(dataSize); + memcpy(data, that.data, dataSize); + } + } ~BufferDataCommandBufferRequest() { if (data != nullptr) @@ -120,6 +150,20 @@ namespace commandbuffers if (data != nullptr) memcpy(data, srcData, srcSize); } + BufferSubDataCommandBufferRequest(const BufferSubDataCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , offset(that.offset) + , dataSize(0) + , data(nullptr) + { + if (clone == true && that.data != nullptr) + { + dataSize = that.dataSize; + data = malloc(dataSize); + memcpy(data, that.data, dataSize); + } + } ~BufferSubDataCommandBufferRequest() { if (data != nullptr) @@ -162,6 +206,11 @@ namespace commandbuffers , clientId(clientId) { } + CreateFramebufferCommandBufferRequest(const CreateFramebufferCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -178,6 +227,11 @@ namespace commandbuffers , framebuffer(framebuffer) { } + DeleteFramebufferCommandBufferRequest(const DeleteFramebufferCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , framebuffer(that.framebuffer) + { + } public: uint32_t framebuffer; @@ -194,6 +248,12 @@ namespace commandbuffers , framebuffer(framebuffer) { } + BindFramebufferCommandBufferRequest(const BindFramebufferCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , framebuffer(that.framebuffer) + { + } public: uint32_t target; @@ -214,6 +274,15 @@ namespace commandbuffers , renderbuffer(renderbuffer) { } + FramebufferRenderbufferCommandBufferRequest(const FramebufferRenderbufferCommandBufferRequest &that, + bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , attachment(that.attachment) + , renderbufferTarget(that.renderbufferTarget) + , renderbuffer(that.renderbuffer) + { + } public: uint32_t target; @@ -237,6 +306,15 @@ namespace commandbuffers , level(level) { } + FramebufferTexture2DCommandBufferRequest(const FramebufferTexture2DCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , attachment(that.attachment) + , textarget(that.textarget) + , texture(that.texture) + , level(that.level) + { + } public: uint32_t target; @@ -257,6 +335,11 @@ namespace commandbuffers , target(target) { } + CheckFramebufferStatusCommandBufferRequest(const CheckFramebufferStatusCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + { + } public: uint32_t target; @@ -272,6 +355,11 @@ namespace commandbuffers , status(status) { } + CheckFramebufferStatusCommandBufferResponse(const CheckFramebufferStatusCommandBufferResponse &that, bool clone) + : TrCommandBufferSimpleResponse(that, clone) + , status(that.status) + { + } public: uint32_t status; @@ -288,6 +376,11 @@ namespace commandbuffers , clientId(clientId) { } + CreateRenderbufferCommandBufferRequest(const CreateRenderbufferCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -304,6 +397,11 @@ namespace commandbuffers , renderbuffer(renderbuffer) { } + DeleteRenderbufferCommandBufferRequest(const DeleteRenderbufferCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , renderbuffer(that.renderbuffer) + { + } public: uint32_t renderbuffer; @@ -321,6 +419,12 @@ namespace commandbuffers , renderbuffer(renderbuffer) { } + BindRenderbufferCommandBufferRequest(const BindRenderbufferCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , renderbuffer(that.renderbuffer) + { + } public: uint32_t target; @@ -341,6 +445,14 @@ namespace commandbuffers , height(height) { } + RenderbufferStorageCommandBufferRequest(const RenderbufferStorageCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , internalformat(that.internalformat) + , width(that.width) + , height(that.height) + { + } public: uint32_t target; @@ -360,6 +472,11 @@ namespace commandbuffers , mode(mode) { } + ReadBufferCommandBufferRequest(const ReadBufferCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + { + } public: uint32_t mode; @@ -378,6 +495,13 @@ namespace commandbuffers , buffer(buffer) { } + BindBufferBaseCommandBufferRequest(const BindBufferBaseCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , index(that.index) + , buffer(that.buffer) + { + } public: uint32_t target; @@ -400,6 +524,15 @@ namespace commandbuffers , bufferSize(size) { } + BindBufferRangeCommandBufferRequest(const BindBufferRangeCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , index(that.index) + , buffer(that.buffer) + , offset(that.offset) + , bufferSize(that.size) + { + } public: uint32_t target; @@ -438,6 +571,20 @@ namespace commandbuffers , filter(filter) { } + BlitFramebufferCommandBufferRequest(const BlitFramebufferCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , srcX0(that.srcX0) + , srcY0(that.srcY0) + , srcX1(that.srcX1) + , srcY1(that.srcY1) + , dstX0(that.dstX0) + , dstY0(that.dstY0) + , dstX1(that.dstX1) + , dstY1(that.dstY1) + , mask(that.mask) + , filter(that.filter) + { + } public: uint32_t srcX0; @@ -471,6 +618,16 @@ namespace commandbuffers , height(height) { } + RenderbufferStorageMultisampleCommandBufferRequest(const RenderbufferStorageMultisampleCommandBufferRequest &that, + bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , samples(that.samples) + , internalformat(that.internalformat) + , width(that.width) + , height(that.height) + { + } public: uint32_t target; diff --git a/src/common/command_buffers/details/clear.hpp b/src/common/command_buffers/details/clear.hpp index 078027363..9bb56cd32 100644 --- a/src/common/command_buffers/details/clear.hpp +++ b/src/common/command_buffers/details/clear.hpp @@ -15,6 +15,11 @@ namespace commandbuffers , mask(mask) { } + ClearCommandBufferRequest(const ClearCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mask(that.mask) + { + } public: int mask; @@ -34,6 +39,14 @@ namespace commandbuffers , a(a) { } + ClearColorCommandBufferRequest(const ClearColorCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , r(that.r) + , g(that.g) + , b(that.b) + , a(that.a) + { + } public: float r; @@ -53,6 +66,11 @@ namespace commandbuffers , depth(depth) { } + ClearDepthCommandBufferRequest(const ClearDepthCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , depth(that.depth) + { + } public: float depth; @@ -69,6 +87,11 @@ namespace commandbuffers , stencil(stencil) { } + ClearStencilCommandBufferRequest(const ClearStencilCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , stencil(that.stencil) + { + } public: int stencil; diff --git a/src/common/command_buffers/details/draw_calls.hpp b/src/common/command_buffers/details/draw_calls.hpp index 2b6efb7c9..7595b15ae 100644 --- a/src/common/command_buffers/details/draw_calls.hpp +++ b/src/common/command_buffers/details/draw_calls.hpp @@ -17,6 +17,13 @@ namespace commandbuffers , count(count) { } + DrawArraysCommandBufferRequest(const DrawArraysCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + , first(that.first) + , count(that.count) + { + } public: int mode; @@ -38,6 +45,14 @@ namespace commandbuffers , instanceCount(instanceCount) { } + DrawArraysInstancedCommandBufferRequest(const DrawArraysInstancedCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + , first(that.first) + , count(that.count) + , instanceCount(that.instanceCount) + { + } public: int mode; @@ -60,6 +75,14 @@ namespace commandbuffers , indicesOffset(offset) { } + DrawElementsCommandBufferRequest(const DrawElementsCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + , count(that.count) + , indicesType(that.indicesType) + , indicesOffset(that.indicesOffset) + { + } public: int mode; @@ -83,6 +106,15 @@ namespace commandbuffers , instanceCount(instanceCount) { } + DrawElementsInstancedCommandBufferRequest(const DrawElementsInstancedCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + , count(that.count) + , indicesType(that.indicesType) + , indicesOffset(that.indicesOffset) + , instanceCount(that.instanceCount) + { + } public: int mode; @@ -95,6 +127,8 @@ namespace commandbuffers class DrawBuffersCommandBufferRequest final : public TrCommandBufferSimpleRequest { + using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; + public: DrawBuffersCommandBufferRequest() = delete; DrawBuffersCommandBufferRequest(size_t n, const uint32_t *bufs) @@ -104,6 +138,14 @@ namespace commandbuffers for (size_t i = 0; i < n; i++) this->bufs[i] = bufs[i]; } + DrawBuffersCommandBufferRequest(const DrawBuffersCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , n(that.n) + , bufs() + { + for (size_t i = 0; i < that.n; i++) + this->bufs[i] = that.bufs[i]; + } public: size_t n; @@ -114,7 +156,6 @@ namespace commandbuffers : public TrCommandBufferSimpleRequest { - public: DrawRangeElementsCommandBufferRequest() = delete; DrawRangeElementsCommandBufferRequest(int mode, int start, int end, int count, int type, int offset) @@ -127,6 +168,16 @@ namespace commandbuffers , indicesOffset(offset) { } + DrawRangeElementsCommandBufferRequest(const DrawRangeElementsCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + , start(that.start) + , end(that.end) + , count(that.count) + , indicesType(that.indicesType) + , indicesOffset(that.indicesOffset) + { + } public: int mode; diff --git a/src/common/command_buffers/details/get_extensions.hpp b/src/common/command_buffers/details/get_extensions.hpp index 79c3fa422..4b7646131 100644 --- a/src/common/command_buffers/details/get_extensions.hpp +++ b/src/common/command_buffers/details/get_extensions.hpp @@ -9,7 +9,6 @@ namespace commandbuffers : public TrCommandBufferSimpleRequest { - public: using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; }; @@ -17,14 +16,16 @@ namespace commandbuffers : public TrCommandBufferSimpleResponse { public: - GetExtensionsCommandBufferResponse(GetExtensionsCommandBufferResponse &that) - : TrCommandBufferSimpleResponse(that) - { - } GetExtensionsCommandBufferResponse(GetExtensionsCommandBufferRequest *req) : TrCommandBufferSimpleResponse(COMMAND_BUFFER_GET_EXTENSIONS_RES, req) { } + GetExtensionsCommandBufferResponse(const GetExtensionsCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + { + if (clone) + extensions = that.extensions; + } public: TrCommandBufferMessage *serialize() override diff --git a/src/common/command_buffers/details/metrics.hpp b/src/common/command_buffers/details/metrics.hpp index 95ce2dd5f..e66cc05d2 100644 --- a/src/common/command_buffers/details/metrics.hpp +++ b/src/common/command_buffers/details/metrics.hpp @@ -22,6 +22,11 @@ namespace commandbuffers , category(category) { } + PaintingMetricsCommandBufferRequest(const PaintingMetricsCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , category(that.category) + { + } public: inline std::string toString() diff --git a/src/common/command_buffers/details/program.hpp b/src/common/command_buffers/details/program.hpp index 43964b900..7e8b150ba 100644 --- a/src/common/command_buffers/details/program.hpp +++ b/src/common/command_buffers/details/program.hpp @@ -16,6 +16,11 @@ namespace commandbuffers , clientId(clientId) { } + CreateProgramCommandBufferRequest(const CreateProgramCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -32,6 +37,11 @@ namespace commandbuffers , clientId(clientId) { } + DeleteProgramCommandBufferRequest(const DeleteProgramCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -48,6 +58,11 @@ namespace commandbuffers , clientId(clientId) { } + LinkProgramCommandBufferRequest(const LinkProgramCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -138,6 +153,19 @@ namespace commandbuffers , success(success) { } + LinkProgramCommandBufferResponse(const LinkProgramCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , success(that.success) + { + if (clone) + { + activeAttribs = that.activeAttribs; + activeUniforms = that.activeUniforms; + attribLocations = that.attribLocations; + uniformLocations = that.uniformLocations; + uniformBlocks = that.uniformBlocks; + } + } public: TrCommandBufferMessage *serialize() override @@ -315,6 +343,11 @@ namespace commandbuffers , clientId(clientId) { } + UseProgramCommandBufferRequest(const UseProgramCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -333,8 +366,8 @@ namespace commandbuffers , attribName(name) { } - BindAttribLocationCommandBufferRequest(BindAttribLocationCommandBufferRequest &that) - : TrCommandBufferSimpleRequest(that) + BindAttribLocationCommandBufferRequest(const BindAttribLocationCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) , program(that.program) , attribIndex(that.attribIndex) { @@ -370,6 +403,12 @@ namespace commandbuffers , pname(pname) { } + GetProgramParamCommandBufferRequest(const GetProgramParamCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + , pname(that.pname) + { + } public: uint32_t clientId; @@ -380,16 +419,16 @@ namespace commandbuffers : public TrCommandBufferSimpleResponse { public: - GetProgramParamCommandBufferResponse(GetProgramParamCommandBufferResponse &that) - : TrCommandBufferSimpleResponse(that) - , value(that.value) - { - } GetProgramParamCommandBufferResponse(GetProgramParamCommandBufferRequest *req, int value) : TrCommandBufferSimpleResponse(COMMAND_BUFFER_GET_PROGRAM_PARAM_RES, req) , value(value) { } + GetProgramParamCommandBufferResponse(const GetProgramParamCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , value(that.value) + { + } public: int value; @@ -406,6 +445,11 @@ namespace commandbuffers , clientId(clientId) { } + GetProgramInfoLogCommandBufferRequest(const GetProgramInfoLogCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -420,6 +464,13 @@ namespace commandbuffers , infoLog(infoLog) { } + GetProgramInfoLogCommandBufferResponse(const GetProgramInfoLogCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , infoLog() + { + if (clone) + infoLog = that.infoLog; + } public: TrCommandBufferMessage *serialize() override @@ -434,6 +485,6 @@ namespace commandbuffers } public: - string infoLog; + std::string infoLog; }; } diff --git a/src/common/command_buffers/details/properties.hpp b/src/common/command_buffers/details/properties.hpp index 504a442d0..854ed4466 100644 --- a/src/common/command_buffers/details/properties.hpp +++ b/src/common/command_buffers/details/properties.hpp @@ -15,6 +15,11 @@ namespace commandbuffers , pname(pname) { } + GetParameterCommandBufferRequest(const Derived &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , pname(that.pname) + { + } public: int pname; @@ -30,6 +35,11 @@ namespace commandbuffers , value(value) { } + GetParameterCommandBufferResponse(const Derived &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , value(that.value) + { + } public: ValueType value; @@ -39,7 +49,6 @@ namespace commandbuffers : public GetParameterCommandBufferRequest { - public: using GetParameterCommandBufferRequest::GetParameterCommandBufferRequest; }; @@ -49,7 +58,6 @@ namespace commandbuffers bool, COMMAND_BUFFER_GET_BOOLEANV_RES> { - public: using GetParameterCommandBufferResponse::GetParameterCommandBufferResponse; }; @@ -57,7 +65,6 @@ namespace commandbuffers : public GetParameterCommandBufferRequest { - public: using GetParameterCommandBufferRequest::GetParameterCommandBufferRequest; }; @@ -67,7 +74,6 @@ namespace commandbuffers int, COMMAND_BUFFER_GET_INTEGERV_RES> { - public: using GetParameterCommandBufferResponse::GetParameterCommandBufferResponse; }; @@ -75,7 +81,6 @@ namespace commandbuffers : public GetParameterCommandBufferRequest { - public: using GetParameterCommandBufferRequest::GetParameterCommandBufferRequest; }; @@ -85,7 +90,6 @@ namespace commandbuffers float, COMMAND_BUFFER_GET_FLOATV_RES> { - public: using GetParameterCommandBufferResponse::GetParameterCommandBufferResponse; }; @@ -93,7 +97,6 @@ namespace commandbuffers : public GetParameterCommandBufferRequest { - public: using GetParameterCommandBufferRequest::GetParameterCommandBufferRequest; }; @@ -103,7 +106,6 @@ namespace commandbuffers std::string, COMMAND_BUFFER_GET_STRING_RES> { - public: using GetParameterCommandBufferResponse::GetParameterCommandBufferResponse; public: @@ -137,6 +139,13 @@ namespace commandbuffers , precisiontype(precisiontype) { } + GetShaderPrecisionFormatCommandBufferRequest(const GetShaderPrecisionFormatCommandBufferRequest &that, + bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , shadertype(that.shadertype) + , precisiontype(that.precisiontype) + { + } public: int shadertype; @@ -158,6 +167,14 @@ namespace commandbuffers , precision(precision) { } + GetShaderPrecisionFormatCommandBufferResponse(const GetShaderPrecisionFormatCommandBufferResponse &that, + bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , rangeMin(that.rangeMin) + , rangeMax(that.rangeMax) + , precision(that.precision) + { + } public: int rangeMin; @@ -168,7 +185,6 @@ namespace commandbuffers class GetErrorCommandBufferRequest final : public TrCommandBufferSimpleRequest { - public: using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; }; @@ -182,6 +198,11 @@ namespace commandbuffers , error(error) { } + GetErrorCommandBufferResponse(const GetErrorCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , error(that.error) + { + } public: int error; diff --git a/src/common/command_buffers/details/sampler.hpp b/src/common/command_buffers/details/sampler.hpp index ef9010e3c..d1610c5b0 100644 --- a/src/common/command_buffers/details/sampler.hpp +++ b/src/common/command_buffers/details/sampler.hpp @@ -16,6 +16,11 @@ namespace commandbuffers , clientId(clientId) { } + CreateSamplerCommandBufferRequest(const CreateSamplerCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -32,6 +37,11 @@ namespace commandbuffers , sampler(sampler) { } + DeleteSamplerCommandBufferRequest(const DeleteSamplerCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , sampler(that.sampler) + { + } public: uint32_t sampler; @@ -49,6 +59,12 @@ namespace commandbuffers , sampler(sampler) { } + BindSamplerCommandBufferRequest(const BindSamplerCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , unit(that.unit) + , sampler(that.sampler) + { + } public: uint32_t unit; @@ -68,6 +84,13 @@ namespace commandbuffers , param(param) { } + SamplerParameteriCommandBufferRequest(const SamplerParameteriCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , sampler(that.sampler) + , pname(that.pname) + , param(that.param) + { + } public: uint32_t sampler; @@ -88,6 +111,13 @@ namespace commandbuffers , param(param) { } + SamplerParameterfCommandBufferRequest(const SamplerParameterfCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , sampler(that.sampler) + , pname(that.pname) + , param(that.param) + { + } public: uint32_t sampler; @@ -107,6 +137,12 @@ namespace commandbuffers , pname(pname) { } + GetSamplerParameterCommandBufferRequest(const GetSamplerParameterCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , sampler(that.sampler) + , pname(that.pname) + { + } public: uint32_t sampler; @@ -122,6 +158,16 @@ namespace commandbuffers , value(value) { } + GetSamplerParameterCommandBufferResponse(GetSamplerParameterCommandBufferRequest *req, float value) + : TrCommandBufferSimpleResponse(COMMAND_BUFFER_GET_SAMPLER_PARAMETER_RES, req) + , value(value) + { + } + GetSamplerParameterCommandBufferResponse(const GetSamplerParameterCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , value(that.value) + { + } public: int32_t value; @@ -138,6 +184,11 @@ namespace commandbuffers , sampler(sampler) { } + IsSamplerCommandBufferRequest(const IsSamplerCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , sampler(that.sampler) + { + } public: uint32_t sampler; @@ -152,6 +203,11 @@ namespace commandbuffers , value(value) { } + IsSamplerCommandBufferResponse(const IsSamplerCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , value(that.value) + { + } public: bool value; diff --git a/src/common/command_buffers/details/shader.hpp b/src/common/command_buffers/details/shader.hpp index 38f8a3bd6..1580e0e34 100644 --- a/src/common/command_buffers/details/shader.hpp +++ b/src/common/command_buffers/details/shader.hpp @@ -17,6 +17,12 @@ namespace commandbuffers , shader(shader) { } + AttachShaderCommandBufferRequest(const AttachShaderCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , program(that.program) + , shader(that.shader) + { + } public: uint32_t program; @@ -35,6 +41,12 @@ namespace commandbuffers , shader(shader) { } + DetachShaderCommandBufferRequest(const DetachShaderCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , program(that.program) + , shader(that.shader) + { + } public: uint32_t program; @@ -53,6 +65,12 @@ namespace commandbuffers , shaderType(type) { } + CreateShaderCommandBufferRequest(const CreateShaderCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + , shaderType(that.shaderType) + { + } public: uint32_t clientId; @@ -70,6 +88,11 @@ namespace commandbuffers , shader(shader) { } + DeleteShaderCommandBufferRequest(const DeleteShaderCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , shader(that.shader) + { + } public: uint32_t shader; @@ -85,6 +108,11 @@ namespace commandbuffers , shader(shader) { } + CompileShaderCommandBufferRequest(const CompileShaderCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , shader(that.shader) + { + } public: uint32_t shader; @@ -103,6 +131,19 @@ namespace commandbuffers sourceStr = reinterpret_cast(malloc(sourceSize)); memcpy(sourceStr, source.c_str(), sourceSize); } + ShaderSourceCommandBufferRequest(const ShaderSourceCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that) + , shader(that.shader) + , sourceStr(nullptr) + , sourceSize(0) + { + if (clone == true && that.sourceStr != nullptr) + { + sourceSize = that.sourceSize; + sourceStr = reinterpret_cast(malloc(sourceSize)); + memcpy(sourceStr, that.sourceStr, sourceSize); + } + } ~ShaderSourceCommandBufferRequest() { if (sourceStr != nullptr) @@ -150,6 +191,11 @@ namespace commandbuffers , shader(shader) { } + GetShaderSourceCommandBufferRequest(const GetShaderSourceCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , shader(that.shader) + { + } public: uint32_t shader; @@ -164,6 +210,13 @@ namespace commandbuffers : TrCommandBufferSimpleResponse(COMMAND_BUFFER_GET_SHADER_SOURCE_RES, req) { } + GetShaderSourceCommandBufferResponse(const GetShaderSourceCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , source("") + { + if (clone) + source = that.source; + } public: TrCommandBufferMessage *serialize() override @@ -178,7 +231,7 @@ namespace commandbuffers } public: - string source; + std::string source; }; class GetShaderParamCommandBufferRequest final @@ -193,6 +246,12 @@ namespace commandbuffers , pname(pname) { } + GetShaderParamCommandBufferRequest(const GetShaderParamCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , shader(that.shader) + , pname(that.pname) + { + } public: uint32_t shader; @@ -208,6 +267,11 @@ namespace commandbuffers , value(value) { } + GetShaderParamCommandBufferResponse(const GetShaderParamCommandBufferResponse &that, bool clone) + : TrCommandBufferSimpleResponse(that, clone) + , value(that.value) + { + } public: int32_t value; @@ -224,6 +288,11 @@ namespace commandbuffers , shader(shader) { } + GetShaderInfoLogCommandBufferRequest(const GetShaderInfoLogCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , shader(that.shader) + { + } public: uint32_t shader; @@ -239,6 +308,13 @@ namespace commandbuffers , infoLog(log) { } + GetShaderInfoLogCommandBufferResponse(const GetShaderInfoLogCommandBufferResponse &that, bool clone) + : TrCommandBufferSimpleResponse(that, clone) + , infoLog("") + { + if (clone) + infoLog = that.infoLog; + } public: TrCommandBufferMessage *serialize() override diff --git a/src/common/command_buffers/details/states.hpp b/src/common/command_buffers/details/states.hpp index f762b5a61..5f45ee8f5 100644 --- a/src/common/command_buffers/details/states.hpp +++ b/src/common/command_buffers/details/states.hpp @@ -19,6 +19,14 @@ namespace commandbuffers , height(height) { } + SetViewportCommandBufferRequest(const SetViewportCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , x(that.x) + , y(that.y) + , width(that.width) + , height(that.height) + { + } public: int x; @@ -41,6 +49,14 @@ namespace commandbuffers , height(height) { } + SetScissorCommandBufferRequest(const SetScissorCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , x(that.x) + , y(that.y) + , width(that.width) + , height(that.height) + { + } public: int x; @@ -60,6 +76,12 @@ namespace commandbuffers , mode(mode) { } + HintCommandBufferRequest(const HintCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , mode(that.mode) + { + } public: int target; @@ -76,6 +98,11 @@ namespace commandbuffers , width(width) { } + LineWidthCommandBufferRequest(const LineWidthCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , width(that.width) + { + } public: float width; @@ -92,6 +119,12 @@ namespace commandbuffers , param(param) { } + PixelStoreiCommandBufferRequest(const PixelStoreiCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , pname(that.pname) + , param(that.param) + { + } public: int pname; @@ -109,6 +142,12 @@ namespace commandbuffers , units(units) { } + PolygonOffsetCommandBufferRequest(const PolygonOffsetCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , factor(that.factor) + , units(that.units) + { + } public: float factor; @@ -125,6 +164,11 @@ namespace commandbuffers , flag(flag) { } + DepthMaskCommandBufferRequest(const DepthMaskCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , flag(that.flag) + { + } public: bool flag; @@ -140,6 +184,11 @@ namespace commandbuffers , func(func) { } + DepthFuncCommandBufferRequest(const DepthFuncCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , func(that.func) + { + } public: int func; @@ -156,6 +205,12 @@ namespace commandbuffers , f(f) { } + DepthRangeCommandBufferRequest(const DepthRangeCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , n(that.n) + , f(that.f) + { + } public: float n; @@ -174,6 +229,13 @@ namespace commandbuffers , mask(mask) { } + StencilFuncCommandBufferRequest(const StencilFuncCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , func(that.func) + , ref(that.ref) + , mask(that.mask) + { + } public: int func; @@ -195,6 +257,14 @@ namespace commandbuffers , mask(mask) { } + StencilFuncSeparateCommandBufferRequest(const StencilFuncSeparateCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , face(that.face) + , func(that.func) + , ref(that.ref) + , mask(that.mask) + { + } public: int face; @@ -214,6 +284,11 @@ namespace commandbuffers , mask(mask) { } + StencilMaskCommandBufferRequest(const StencilMaskCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mask(that.mask) + { + } public: int mask; @@ -231,6 +306,12 @@ namespace commandbuffers , mask(mask) { } + StencilMaskSeparateCommandBufferRequest(const StencilMaskSeparateCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , face(that.face) + , mask(that.mask) + { + } public: int face; @@ -249,6 +330,13 @@ namespace commandbuffers , zpass(zpass) { } + StencilOpCommandBufferRequest(const StencilOpCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , fail(that.fail) + , zfail(that.zfail) + , zpass(that.zpass) + { + } public: int fail; @@ -270,6 +358,14 @@ namespace commandbuffers , zpass(zpass) { } + StencilOpSeparateCommandBufferRequest(const StencilOpSeparateCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , face(that.face) + , fail(that.fail) + , zfail(that.zfail) + , zpass(that.zpass) + { + } public: int face; @@ -291,6 +387,14 @@ namespace commandbuffers , alpha(alpha) { } + BlendColorCommandBufferRequest(const BlendColorCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , red(that.red) + , green(that.green) + , blue(that.blue) + , alpha(that.alpha) + { + } public: float red; @@ -309,6 +413,11 @@ namespace commandbuffers , mode(mode) { } + BlendEquationCommandBufferRequest(const BlendEquationCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + { + } public: int mode; @@ -326,6 +435,12 @@ namespace commandbuffers , modeAlpha(modeAlpha) { } + BlendEquationSeparateCommandBufferRequest(const BlendEquationSeparateCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , modeRGB(that.modeRGB) + , modeAlpha(that.modeAlpha) + { + } public: int modeRGB; @@ -343,6 +458,12 @@ namespace commandbuffers , dfactor(dfactor) { } + BlendFuncCommandBufferRequest(const BlendFuncCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , sfactor(that.sfactor) + , dfactor(that.dfactor) + { + } public: int sfactor; @@ -363,6 +484,14 @@ namespace commandbuffers , dstAlpha(dstAlpha) { } + BlendFuncSeparateCommandBufferRequest(const BlendFuncSeparateCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , srcRGB(that.srcRGB) + , dstRGB(that.dstRGB) + , srcAlpha(that.srcAlpha) + , dstAlpha(that.dstAlpha) + { + } public: int srcRGB; @@ -385,6 +514,14 @@ namespace commandbuffers , alpha(alpha) { } + ColorMaskCommandBufferRequest(const ColorMaskCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , red(that.red) + , green(that.green) + , blue(that.blue) + , alpha(that.alpha) + { + } public: bool red; @@ -403,6 +540,11 @@ namespace commandbuffers , mode(mode) { } + CullFaceCommandBufferRequest(const CullFaceCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + { + } public: int mode; @@ -418,6 +560,11 @@ namespace commandbuffers , mode(mode) { } + FrontFaceCommandBufferRequest(const FrontFaceCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , mode(that.mode) + { + } public: int mode; @@ -434,6 +581,11 @@ namespace commandbuffers , cap(cap) { } + CapabilityCommandBufferRequest(const CapabilityCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , cap(that.cap) + { + } public: int cap; @@ -442,14 +594,12 @@ namespace commandbuffers class EnableCommandBufferRequest final : public CapabilityCommandBufferRequest { - public: using CapabilityCommandBufferRequest::CapabilityCommandBufferRequest; }; class DisableCommandBufferRequest final : public CapabilityCommandBufferRequest { - public: using CapabilityCommandBufferRequest::CapabilityCommandBufferRequest; }; } diff --git a/src/common/command_buffers/details/texture.hpp b/src/common/command_buffers/details/texture.hpp index cf97a8b9d..b0e9a3518 100644 --- a/src/common/command_buffers/details/texture.hpp +++ b/src/common/command_buffers/details/texture.hpp @@ -15,6 +15,11 @@ namespace commandbuffers , clientId(clientId) { } + CreateTextureCommandBufferRequest(const CreateTextureCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + { + } public: int clientId; @@ -30,6 +35,11 @@ namespace commandbuffers , texture(texture) { } + DeleteTextureCommandBufferRequest(const DeleteTextureCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , texture(that.texture) + { + } public: int texture; @@ -46,6 +56,12 @@ namespace commandbuffers , texture(texture) { } + BindTextureCommandBufferRequest(const BindTextureCommandBufferRequest &that, bool clone) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , texture(that.texture) + { + } public: int target; @@ -60,13 +76,17 @@ namespace commandbuffers : TrCommandBufferRequest(type, sizeof(T)) { } - TextureImageNDCommandBufferRequest(TextureImageNDCommandBufferRequest &that) - : TrCommandBufferRequest(that) + TextureImageNDCommandBufferRequest(const TextureImageNDCommandBufferRequest &that, bool clone = false) + : TrCommandBufferRequest(that, clone) , target(that.target) , level(that.level) , format(that.format) , pixelType(that.pixelType) { + if (clone) + { + // TODO(yorkie): implement the clone + } } virtual ~TextureImageNDCommandBufferRequest() { @@ -201,6 +221,11 @@ namespace commandbuffers this->target = target; this->level = level; } + TextureImage2DCommandBufferRequest(const TextureImage2DCommandBufferRequest &that, bool clone = false) + : TextureImageNDCommandBufferRequest(that, clone) + , internalformat(that.internalformat) + { + } public: size_t computePixelsByteLength() override @@ -230,10 +255,20 @@ namespace commandbuffers : TextureImageNDCommandBufferRequest(COMMAND_BUFFER_TEXTURE_SUB_IMAGE_2D_REQ) , xoffset(xoffset) , yoffset(yoffset) + , width(0) + , height(0) { this->target = target; this->level = level; } + TextureSubImage2DCommandBufferRequest(const TextureSubImage2DCommandBufferRequest &that, bool clone = false) + : TextureImageNDCommandBufferRequest(that, clone) + , xoffset(that.xoffset) + , yoffset(that.yoffset) + , width(that.width) + , height(that.height) + { + } public: size_t computePixelsByteLength() override @@ -252,9 +287,6 @@ namespace commandbuffers : public TrCommandBufferSimpleRequest { - public: - using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; - public: CopyTextureImage2DCommandBufferRequest( uint32_t target, @@ -276,6 +308,18 @@ namespace commandbuffers , border(border) { } + CopyTextureImage2DCommandBufferRequest(const CopyTextureImage2DCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , level(that.level) + , internalFormat(that.internalFormat) + , x(that.x) + , y(that.y) + , width(that.width) + , height(that.height) + , border(that.border) + { + } public: int target; @@ -292,9 +336,6 @@ namespace commandbuffers : public TrCommandBufferSimpleRequest { - public: - using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; - public: CopyTextureSubImage2DCommandBufferRequest( uint32_t target, @@ -316,6 +357,18 @@ namespace commandbuffers , height(height) { } + CopyTextureSubImage2DCommandBufferRequest(const CopyTextureSubImage2DCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , level(that.level) + , xoffset(that.xoffset) + , yoffset(that.yoffset) + , x(that.x) + , y(that.y) + , width(that.width) + , height(that.height) + { + } public: int target; @@ -341,6 +394,13 @@ namespace commandbuffers , param(param) { } + TextureParameteriCommandBufferRequest(const TextureParameteriCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , pname(that.pname) + , param(that.param) + { + } public: int target; @@ -361,6 +421,13 @@ namespace commandbuffers , param(param) { } + TextureParameterfCommandBufferRequest(const TextureParameterfCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , pname(that.pname) + , param(that.param) + { + } public: int target; @@ -381,6 +448,11 @@ namespace commandbuffers if (activeUnit < WEBGL_TEXTURE0 || activeUnit > WEBGL_TEXTURE31) activeUnit = WEBGL_TEXTURE0; } + ActiveTextureCommandBufferRequest(const ActiveTextureCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , activeUnit(that.activeUnit) + { + } public: uint32_t activeUnit; @@ -397,6 +469,11 @@ namespace commandbuffers , target(target) { } + GenerateMipmapCommandBufferRequest(const GenerateMipmapCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + { + } public: int target; @@ -410,6 +487,15 @@ namespace commandbuffers : TextureImageNDCommandBufferRequest(COMMAND_BUFFER_TEXTURE_IMAGE_3D_REQ) { } + TextureImage3DCommandBufferRequest(const TextureImage3DCommandBufferRequest &that, bool clone = false) + : TextureImageNDCommandBufferRequest(that, clone) + , internalformat(that.internalformat) + , width(that.width) + , height(that.height) + , depth(that.depth) + , border(that.border) + { + } public: size_t computePixelsByteLength() override @@ -433,6 +519,16 @@ namespace commandbuffers : TextureImageNDCommandBufferRequest(COMMAND_BUFFER_TEXTURE_SUB_IMAGE_3D_REQ) { } + TextureSubImage3DCommandBufferRequest(const TextureSubImage3DCommandBufferRequest &that, bool clone = false) + : TextureImageNDCommandBufferRequest(that, clone) + , xoffset(that.xoffset) + , yoffset(that.yoffset) + , zoffset(that.zoffset) + , width(that.width) + , height(that.height) + , depth(that.depth) + { + } public: size_t computePixelsByteLength() override @@ -461,6 +557,13 @@ namespace commandbuffers , internalformat(internalformat) { } + TextureStorageNDCommandBufferRequest(const TextureStorageNDCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , target(that.target) + , levels(that.levels) + , internalformat(that.internalformat) + { + } public: int target; @@ -480,6 +583,12 @@ namespace commandbuffers , height(height) { } + TextureStorage2DCommandBufferRequest(const TextureStorage2DCommandBufferRequest &that, bool clone = false) + : TextureStorageNDCommandBufferRequest(that, clone) + , width(that.width) + , height(that.height) + { + } public: int width; @@ -499,6 +608,13 @@ namespace commandbuffers , depth(depth) { } + TextureStorage3DCommandBufferRequest(const TextureStorage3DCommandBufferRequest &that, bool clone = false) + : TextureStorageNDCommandBufferRequest(that, clone) + , width(that.width) + , height(that.height) + , depth(that.depth) + { + } public: int width; diff --git a/src/common/command_buffers/details/uniforms.hpp b/src/common/command_buffers/details/uniforms.hpp index 6e259d7dc..c103ea986 100644 --- a/src/common/command_buffers/details/uniforms.hpp +++ b/src/common/command_buffers/details/uniforms.hpp @@ -53,6 +53,13 @@ namespace commandbuffers , uniformBlockBinding(uniformBlockBinding) { } + UniformBlockBindingCommandBufferRequest(const UniformBlockBindingCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , program(that.program) + , uniformBlockIndex(that.uniformBlockIndex) + , uniformBlockBinding(that.uniformBlockBinding) + { + } public: uint32_t program; @@ -70,6 +77,12 @@ namespace commandbuffers , v0(v0) { } + Uniform1fCommandBufferRequest(const Uniform1fCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , location(that.location) + , v0(that.v0) + { + } public: uint32_t location; @@ -87,10 +100,13 @@ namespace commandbuffers , values(values) { } - Uniform1fvCommandBufferRequest(Uniform1fvCommandBufferRequest &that) - : TrCommandBufferSimpleRequest(that) + Uniform1fvCommandBufferRequest(const Uniform1fvCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) , location(that.location) + , values() { + if (clone) + values = that.values; } public: @@ -124,6 +140,12 @@ namespace commandbuffers , v0(v0) { } + Uniform1iCommandBufferRequest(const Uniform1iCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , location(that.location) + , v0(that.v0) + { + } public: uint32_t location; @@ -141,10 +163,13 @@ namespace commandbuffers , values(values) { } - Uniform1ivCommandBufferRequest(Uniform1ivCommandBufferRequest &that) - : TrCommandBufferSimpleRequest(that) + Uniform1ivCommandBufferRequest(const Uniform1ivCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) , location(that.location) + , values() { + if (clone) + values = that.values; } public: @@ -179,6 +204,13 @@ namespace commandbuffers , v1(v1) { } + Uniform2fCommandBufferRequest(const Uniform2fCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , location(that.location) + , v0(that.v0) + , v1(that.v1) + { + } public: uint32_t location; @@ -197,10 +229,13 @@ namespace commandbuffers , values(values) { } - Uniform2fvCommandBufferRequest(Uniform2fvCommandBufferRequest &that) - : TrCommandBufferSimpleRequest(that) + Uniform2fvCommandBufferRequest(const Uniform2fvCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) , location(that.location) + , values() { + if (clone) + values = that.values; } public: @@ -235,6 +270,13 @@ namespace commandbuffers , v1(v1) { } + Uniform2iCommandBufferRequest(const Uniform2iCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , location(that.location) + , v0(that.v0) + , v1(that.v1) + { + } public: uint32_t location; @@ -253,10 +295,13 @@ namespace commandbuffers , values(values) { } - Uniform2ivCommandBufferRequest(Uniform2ivCommandBufferRequest &that) - : TrCommandBufferSimpleRequest(that) + Uniform2ivCommandBufferRequest(const Uniform2ivCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) , location(that.location) + , values() { + if (clone) + values = that.values; } public: @@ -292,6 +337,14 @@ namespace commandbuffers , v2(v2) { } + Uniform3fCommandBufferRequest(const Uniform3fCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , location(that.location) + , v0(that.v0) + , v1(that.v1) + , v2(that.v2) + { + } public: uint32_t location; @@ -311,10 +364,13 @@ namespace commandbuffers , values(values) { } - Uniform3fvCommandBufferRequest(Uniform3fvCommandBufferRequest &that) - : TrCommandBufferSimpleRequest(that) + Uniform3fvCommandBufferRequest(const Uniform3fvCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) , location(that.location) + , values() { + if (clone) + values = that.values; } public: @@ -350,6 +406,14 @@ namespace commandbuffers , v2(v2) { } + Uniform3iCommandBufferRequest(const Uniform3iCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , location(that.location) + , v0(that.v0) + , v1(that.v1) + , v2(that.v2) + { + } public: uint32_t location; @@ -369,10 +433,13 @@ namespace commandbuffers , values(values) { } - Uniform3ivCommandBufferRequest(Uniform3ivCommandBufferRequest &that) + Uniform3ivCommandBufferRequest(const Uniform3ivCommandBufferRequest &that, bool clone = false) : TrCommandBufferSimpleRequest(that) , location(that.location) + , values() { + if (clone) + values = that.values; } public: @@ -408,6 +475,15 @@ namespace commandbuffers , v3(v3) { } + Uniform4xCommandBufferRequest(const Uniform4xCommandBufferRequest &that, bool clone = false) + : TrCommandBufferRequest(that, clone) + , location(that.location) + , v0(that.v0) + , v1(that.v1) + , v2(that.v2) + , v3(that.v3) + { + } public: TrCommandBufferMessage *serialize() override final @@ -431,17 +507,20 @@ namespace commandbuffers class Uniform4xvCommandBufferRequest : public TrCommandBufferRequest { public: - Uniform4xvCommandBufferRequest(Uniform4xvCommandBufferRequest &that) - : TrCommandBufferRequest(that) - , location(that.location) - { - } Uniform4xvCommandBufferRequest(CommandBufferType type, uint32_t location, const std::vector &values) : TrCommandBufferRequest(type, sizeof(Tb)) , location(location) , values(values) { } + Uniform4xvCommandBufferRequest(const Uniform4xvCommandBufferRequest &that, bool clone = false) + : TrCommandBufferRequest(that, clone) + , location(that.location) + , values() + { + if (clone) + values = that.values; + } public: TrCommandBufferMessage *serialize() override final @@ -466,6 +545,8 @@ namespace commandbuffers class Uniform4fCommandBufferRequest final : public Uniform4xCommandBufferRequest { + using Uniform4xCommandBufferRequest::Uniform4xCommandBufferRequest; + public: Uniform4fCommandBufferRequest(uint32_t location, float v0, float v1, float v2, float v3) : Uniform4xCommandBufferRequest(COMMAND_BUFFER_UNIFORM4F_REQ, location, v0, v1, v2, v3) @@ -476,8 +557,9 @@ namespace commandbuffers class Uniform4fvCommandBufferRequest final : public Uniform4xvCommandBufferRequest { - public: using Uniform4xvCommandBufferRequest::Uniform4xvCommandBufferRequest; + + public: Uniform4fvCommandBufferRequest(uint32_t location, const std::vector &values) : Uniform4xvCommandBufferRequest(COMMAND_BUFFER_UNIFORM4FV_REQ, location, values) { @@ -487,6 +569,8 @@ namespace commandbuffers class Uniform4iCommandBufferRequest final : public Uniform4xCommandBufferRequest { + using Uniform4xCommandBufferRequest::Uniform4xCommandBufferRequest; + public: Uniform4iCommandBufferRequest(uint32_t location, int v0, int v1, int v2, int v3) : Uniform4xCommandBufferRequest(COMMAND_BUFFER_UNIFORM4I_REQ, location, v0, v1, v2, v3) @@ -497,7 +581,6 @@ namespace commandbuffers class Uniform4ivCommandBufferRequest final : public Uniform4xvCommandBufferRequest { - public: using Uniform4xvCommandBufferRequest::Uniform4xvCommandBufferRequest; public: @@ -511,19 +594,22 @@ namespace commandbuffers class UniformMatrixNfvCommandBufferRequest : public TrCommandBufferRequest { public: - UniformMatrixNfvCommandBufferRequest(UniformMatrixNfvCommandBufferRequest &that) - : TrCommandBufferRequest(that) - , location(that.location) - , transpose(that.transpose) - , computationGraph4values(that.computationGraph4values) - { - } UniformMatrixNfvCommandBufferRequest(CommandBufferType type, uint32_t location, bool transpose) : TrCommandBufferRequest(type, sizeof(T)) , location(location) , transpose(transpose) { } + UniformMatrixNfvCommandBufferRequest(const UniformMatrixNfvCommandBufferRequest &that, bool clone = false) + : TrCommandBufferRequest(that, clone) + , location(that.location) + , transpose(that.transpose) + , values() + , computationGraph4values(that.computationGraph4values) + { + if (clone) + values = that.values; + } public: size_t count() const @@ -563,11 +649,9 @@ namespace commandbuffers class UniformMatrix2fvCommandBufferRequest final : public UniformMatrixNfvCommandBufferRequest { + using UniformMatrixNfvCommandBufferRequest::UniformMatrixNfvCommandBufferRequest; + public: - UniformMatrix2fvCommandBufferRequest(UniformMatrix2fvCommandBufferRequest &that) - : UniformMatrixNfvCommandBufferRequest(that) - { - } UniformMatrix2fvCommandBufferRequest(uint32_t location, bool transpose, const std::vector &values) : UniformMatrixNfvCommandBufferRequest(COMMAND_BUFFER_UNIFORM_MATRIX2FV_REQ, location, transpose) { @@ -578,11 +662,9 @@ namespace commandbuffers class UniformMatrix3fvCommandBufferRequest final : public UniformMatrixNfvCommandBufferRequest { + using UniformMatrixNfvCommandBufferRequest::UniformMatrixNfvCommandBufferRequest; + public: - UniformMatrix3fvCommandBufferRequest(UniformMatrix3fvCommandBufferRequest &that) - : UniformMatrixNfvCommandBufferRequest(that) - { - } UniformMatrix3fvCommandBufferRequest(uint32_t location, bool transpose, const std::vector &values) : UniformMatrixNfvCommandBufferRequest(COMMAND_BUFFER_UNIFORM_MATRIX3FV_REQ, location, transpose) { @@ -593,11 +675,9 @@ namespace commandbuffers class UniformMatrix4fvCommandBufferRequest final : public UniformMatrixNfvCommandBufferRequest { + using UniformMatrixNfvCommandBufferRequest::UniformMatrixNfvCommandBufferRequest; + public: - UniformMatrix4fvCommandBufferRequest(UniformMatrix4fvCommandBufferRequest &that) - : UniformMatrixNfvCommandBufferRequest(that) - { - } UniformMatrix4fvCommandBufferRequest(uint32_t location, bool transpose) : UniformMatrixNfvCommandBufferRequest(COMMAND_BUFFER_UNIFORM_MATRIX4FV_REQ, location, transpose) { diff --git a/src/common/command_buffers/details/vertex_array.hpp b/src/common/command_buffers/details/vertex_array.hpp index c718b0666..0be8b6aac 100644 --- a/src/common/command_buffers/details/vertex_array.hpp +++ b/src/common/command_buffers/details/vertex_array.hpp @@ -16,6 +16,11 @@ namespace commandbuffers , clientId(clientId) { } + CreateVertexArrayCommandBufferRequest(const CreateVertexArrayCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , clientId(that.clientId) + { + } public: uint32_t clientId; @@ -32,6 +37,11 @@ namespace commandbuffers , vertexArray(vertexArray) { } + DeleteVertexArrayCommandBufferRequest(const DeleteVertexArrayCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , vertexArray(that.vertexArray) + { + } public: uint32_t vertexArray; @@ -48,6 +58,11 @@ namespace commandbuffers , vertexArray(vertexArray) { } + BindVertexArrayCommandBufferRequest(const BindVertexArrayCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , vertexArray(that.vertexArray) + { + } public: uint32_t vertexArray; @@ -64,6 +79,11 @@ namespace commandbuffers , vertexArray(vertexArray) { } + IsVertexArrayCommandBufferRequest(const IsVertexArrayCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , vertexArray(that.vertexArray) + { + } public: uint32_t vertexArray; @@ -77,6 +97,11 @@ namespace commandbuffers , value(value) { } + IsVertexArrayCommandBufferResponse(const IsVertexArrayCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , value(that.value) + { + } ~IsVertexArrayCommandBufferResponse() { } diff --git a/src/common/command_buffers/details/vertex_attrib.hpp b/src/common/command_buffers/details/vertex_attrib.hpp index f4b1d3249..1dc05da7b 100644 --- a/src/common/command_buffers/details/vertex_attrib.hpp +++ b/src/common/command_buffers/details/vertex_attrib.hpp @@ -16,6 +16,12 @@ namespace commandbuffers , index(index) { } + EnableVertexAttribArrayCommandBufferRequest(const EnableVertexAttribArrayCommandBufferRequest &that, + bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , index(that.index) + { + } public: uint32_t index; @@ -32,6 +38,12 @@ namespace commandbuffers , index(index) { } + DisableVertexAttribArrayCommandBufferRequest(const DisableVertexAttribArrayCommandBufferRequest &that, + bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , index(that.index) + { + } public: uint32_t index; @@ -52,6 +64,16 @@ namespace commandbuffers , offset(offset) { } + VertexAttribPointerCommandBufferRequest(const VertexAttribPointerCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , index(that.index) + , conponentSize(that.conponentSize) + , componentType(that.componentType) + , normalized(that.normalized) + , stride(that.stride) + , offset(that.offset) + { + } public: uint32_t index; @@ -76,6 +98,15 @@ namespace commandbuffers , offset(offset) { } + VertexAttribIPointerCommandBufferRequest(const VertexAttribIPointerCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , index(that.index) + , componentSize(that.componentSize) + , componentType(that.componentType) + , stride(that.stride) + , offset(that.offset) + { + } public: uint32_t index; @@ -96,6 +127,12 @@ namespace commandbuffers , divisor(divisor) { } + VertexAttribDivisorCommandBufferRequest(const VertexAttribDivisorCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , index(that.index) + , divisor(that.divisor) + { + } public: uint32_t index; diff --git a/src/common/command_buffers/details/webgl_context_init.hpp b/src/common/command_buffers/details/webgl_context_init.hpp index 5d52eed69..1e2f0fb02 100644 --- a/src/common/command_buffers/details/webgl_context_init.hpp +++ b/src/common/command_buffers/details/webgl_context_init.hpp @@ -9,14 +9,12 @@ namespace commandbuffers class CreateWebGLContextRequest final : public TrCommandBufferSimpleRequest { - public: using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; }; class RemoveWebGLContextRequest final : public TrCommandBufferSimpleRequest { - public: using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; }; @@ -24,7 +22,6 @@ namespace commandbuffers : public TrCommandBufferSimpleRequest { - public: using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; }; @@ -36,8 +33,8 @@ namespace commandbuffers : TrCommandBufferSimpleResponse(COMMAND_BUFFER_WEBGL_CONTEXT_INIT_RES, req) { } - WebGL1ContextInitCommandBufferResponse(WebGL1ContextInitCommandBufferResponse &that) - : TrCommandBufferSimpleResponse(that) + WebGL1ContextInitCommandBufferResponse(const WebGL1ContextInitCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) , drawingViewport(that.drawingViewport) , maxCombinedTextureImageUnits(that.maxCombinedTextureImageUnits) , maxCubeMapTextureSize(that.maxCubeMapTextureSize) @@ -50,6 +47,12 @@ namespace commandbuffers , maxVertexTextureImageUnits(that.maxVertexTextureImageUnits) , maxVertexUniformVectors(that.maxVertexUniformVectors) { + if (clone) + { + vendor = that.vendor; + version = that.version; + renderer = that.renderer; + } } ~WebGL1ContextInitCommandBufferResponse() { @@ -92,7 +95,6 @@ namespace commandbuffers : public TrCommandBufferSimpleRequest { - public: using TrCommandBufferSimpleRequest::TrCommandBufferSimpleRequest; }; @@ -104,6 +106,41 @@ namespace commandbuffers : TrCommandBufferSimpleResponse(COMMAND_BUFFER_WEBGL2_CONTEXT_INIT_RES, req) { } + WebGL2ContextInitCommandBufferResponse(const WebGL2ContextInitCommandBufferResponse &that, bool clone = false) + : TrCommandBufferSimpleResponse(that, clone) + , max3DTextureSize(that.max3DTextureSize) + , maxArrayTextureLayers(that.maxArrayTextureLayers) + , maxColorAttachments(that.maxColorAttachments) + , maxCombinedUniformBlocks(that.maxCombinedUniformBlocks) + , maxDrawBuffers(that.maxDrawBuffers) + , maxElementsIndices(that.maxElementsIndices) + , maxElementsVertices(that.maxElementsVertices) + , maxFragmentInputComponents(that.maxFragmentInputComponents) + , maxFragmentUniformBlocks(that.maxFragmentUniformBlocks) + , maxFragmentUniformComponents(that.maxFragmentUniformComponents) + , maxProgramTexelOffset(that.maxProgramTexelOffset) + , maxSamples(that.maxSamples) + , maxTransformFeedbackInterleavedComponents(that.maxTransformFeedbackInterleavedComponents) + , maxTransformFeedbackSeparateAttributes(that.maxTransformFeedbackSeparateAttributes) + , maxTransformFeedbackSeparateComponents(that.maxTransformFeedbackSeparateComponents) + , maxUniformBufferBindings(that.maxUniformBufferBindings) + , maxVaryingComponents(that.maxVaryingComponents) + , maxVertexOutputComponents(that.maxVertexOutputComponents) + , maxVertexUniformBlocks(that.maxVertexUniformBlocks) + , maxVertexUniformComponents(that.maxVertexUniformComponents) + , minProgramTexelOffset(that.minProgramTexelOffset) + , maxClientWaitTimeout(that.maxClientWaitTimeout) + , maxCombinedFragmentUniformComponents(that.maxCombinedFragmentUniformComponents) + , maxCombinedVertexUniformComponents(that.maxCombinedVertexUniformComponents) + , maxElementIndex(that.maxElementIndex) + , maxServerWaitTimeout(that.maxServerWaitTimeout) + , maxUniformBlockSize(that.maxUniformBlockSize) + , maxTextureLODBias(that.maxTextureLODBias) + // Extensions + , OVR_maxViews(that.OVR_maxViews) + , maxTextureMaxAnisotropy(that.maxTextureMaxAnisotropy) + { + } ~WebGL2ContextInitCommandBufferResponse() { } diff --git a/src/common/command_buffers/details/xr.hpp b/src/common/command_buffers/details/xr.hpp index e4f310133..8246a0a96 100644 --- a/src/common/command_buffers/details/xr.hpp +++ b/src/common/command_buffers/details/xr.hpp @@ -16,6 +16,12 @@ namespace commandbuffers , viewIndex(viewIndex) { } + XRFrameStartCommandBufferRequest(const XRFrameStartCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , stereoId(that.stereoId) + , viewIndex(that.viewIndex) + { + } public: int stereoId; @@ -37,6 +43,12 @@ namespace commandbuffers , viewIndex(viewIndex) { } + XRFrameFlushCommandBufferRequest(const XRFrameFlushCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , stereoId(that.stereoId) + , viewIndex(that.viewIndex) + { + } public: int stereoId; @@ -54,6 +66,12 @@ namespace commandbuffers , viewIndex(viewIndex) { } + XRFrameEndCommandBufferRequest(const XRFrameEndCommandBufferRequest &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , stereoId(that.stereoId) + , viewIndex(that.viewIndex) + { + } public: int stereoId; diff --git a/src/common/frame_request/types.hpp b/src/common/frame_request/types.hpp index 636dcb167..1ff0a9168 100644 --- a/src/common/frame_request/types.hpp +++ b/src/common/frame_request/types.hpp @@ -105,15 +105,15 @@ namespace frame_request class TrFrameRequestSimple : public TrFrameRequestBase { public: - TrFrameRequestSimple(TrFrameRequestSimple &that) - : TrFrameRequestBase(that.type, that.size) - , time(that.time) - { - } TrFrameRequestSimple(TrFrameRequestType type) : TrFrameRequestBase(type, sizeof(T)) { } + TrFrameRequestSimple(const TrFrameRequestSimple &that, bool clone = false) + : TrFrameRequestBase(that.type, that.size) + , time(that.time) + { + } public: void resetTime() @@ -128,11 +128,9 @@ namespace frame_request class TrAnimationFrameRequest : public TrFrameRequestSimple { + using TrFrameRequestSimple::TrFrameRequestSimple; + public: - TrAnimationFrameRequest(TrAnimationFrameRequest &that) - : TrFrameRequestSimple(that) - { - } TrAnimationFrameRequest() : TrFrameRequestSimple(TrFrameRequestType::AnimationFrame) { diff --git a/src/common/ipc_message.hpp b/src/common/ipc_message.hpp index 53811112a..750e4023c 100644 --- a/src/common/ipc_message.hpp +++ b/src/common/ipc_message.hpp @@ -327,8 +327,8 @@ namespace ipc T *createInstanceFromBase() { assert(base != nullptr); - T *baseRef = reinterpret_cast(base); - return new T(*baseRef); + const T *baseRef = reinterpret_cast(base); + return new T(*baseRef, false /** clone: false */); } /** diff --git a/src/common/xr/types.hpp b/src/common/xr/types.hpp index 23c9749fb..5bead777c 100644 --- a/src/common/xr/types.hpp +++ b/src/common/xr/types.hpp @@ -37,7 +37,7 @@ namespace xr , viewIndex(-1) { } - TrXRFrameRenderingInfo(TrXRFrameRenderingInfo &that) + TrXRFrameRenderingInfo(const TrXRFrameRenderingInfo &that) : sessionId(that.sessionId) , stereoId(that.stereoId) , viewIndex(that.viewIndex) diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index 6deeca819..ab02e7dfd 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -125,12 +125,6 @@ namespace renderer return *constellation->renderer; } - void TrContentRenderer::scheduleGPUCommandBufferOnRenderTexture(std::shared_ptr commandbuffer) - { - // TODO(yorkie): use a lock? - commandBuffersOnRenderTexture.push_back(commandbuffer); - } - // The `req` argument is a pointer to `TrCommandBufferBase` in the heap, it will be stored in the corresponding queues // such as `defaultCommandBufferRequests` or `stereoFramesList`, otherwise it will be deleted in this function. void TrContentRenderer::onCommandBufferRequestReceived(TrCommandBufferBase *req) @@ -251,7 +245,7 @@ namespace renderer onStartFrame(); { // Execute the default command buffers first. - executeCommandBuffers(false); + executeCommandBuffersAtDefaultFrame(); // Skip the XR frame in the following conditions: bool shouldSkipXRFrame = false; @@ -289,24 +283,22 @@ namespace renderer shouldSkipXRFrame = false; } - if (!shouldSkipXRFrame && - getContent()->used && - xrDevice->enabled()) + if (!shouldSkipXRFrame && getContent()->used && xrDevice->enabled()) { // Execute the XR frame switch (xrDevice->getStereoRenderingMode()) { case xr::TrStereoRenderingMode::MultiPass: { - executeCommandBuffers(true, xrDevice->getActiveEyeId()); + executeCommandBuffersAtXRFrame(xrDevice->getActiveEyeId()); break; } case xr::TrStereoRenderingMode::SinglePass: case xr::TrStereoRenderingMode::SinglePassInstanced: case xr::TrStereoRenderingMode::SinglePassMultiview: { - executeCommandBuffers(true, 0); - executeCommandBuffers(true, 1); + executeCommandBuffersAtXRFrame(0); + executeCommandBuffersAtXRFrame(1); break; } default: @@ -322,13 +314,19 @@ namespace renderer // TODO(yorkie): implement the transparents render pass. } - void TrContentRenderer::onRenderTexturesRenderPass() + void TrContentRenderer::onOffscreenRenderPass() { - if (commandBuffersOnRenderTexture.size() > 0) + if (commandBuffersOnOffscreenPass.size() > 0) { - vector> commandbuffers = commandBuffersOnRenderTexture; - commandBuffersOnRenderTexture.clear(); - constellation->renderer->getRHI()->SubmitGPUCommandBuffer(commandbuffers); + constellation->renderer->executeCommandBuffers(commandBuffersOnOffscreenPass, + this, + ExecutingPassType::kOffscreenPass); + for (auto commandbuffer : commandBuffersOnOffscreenPass) + { + if (commandbuffer != nullptr) [[likely]] + delete commandbuffer; + } + commandBuffersOnOffscreenPass.clear(); } } @@ -367,31 +365,42 @@ namespace renderer isGraphicsContextsInitialized = true; } - void TrContentRenderer::executeCommandBuffers(bool asXRFrame, int viewIndex) + void TrContentRenderer::executeCommandBuffersAtDefaultFrame() { - if (getContent() == nullptr) // FIXME: just skip executing command buffers if content is null, when content process is crashed. + if (getContent() == nullptr) [[unlikely]] return; - if (!asXRFrame) + vector list; { - vector commandBufferRequests; + unique_lock lock(commandBufferRequestsMutex); + if (defaultCommandBufferRequests.size() > 0) { - unique_lock lock(commandBufferRequestsMutex); - commandBufferRequests = defaultCommandBufferRequests; + list = defaultCommandBufferRequests; defaultCommandBufferRequests.clear(); } - constellation->renderer->executeCommandBuffers(commandBufferRequests, this); - for (auto req : commandBufferRequests) - delete req; } - else + + if (list.size() > 0) { - unique_lock lock(commandBufferRequestsMutex); - executeStereoFrame(viewIndex, [this](int stereoIdOfFrame, vector &commandBufferRequests) - { return constellation->renderer->executeCommandBuffers(commandBufferRequests, this); }); + constellation->renderer->executeCommandBuffers(list, this, ExecutingPassType::kDefaultFrame); + for (auto req : list) + delete req; } } + void TrContentRenderer::executeCommandBuffersAtXRFrame(int viewIndex) + { + if (getContent() == nullptr) [[unlikely]] + return; + + unique_lock lock(commandBufferRequestsMutex); + auto exec_commandbuffers = [this](int _, vector &list) + { + return constellation->renderer->executeCommandBuffers(list, this, ExecutingPassType::kXRFrame); + }; + executeStereoFrame(viewIndex, exec_commandbuffers); + } + bool TrContentRenderer::executeStereoFrame(int viewIndex, function &)> exec) { bool called = false; diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index cf7c6aa11..bc0b404c4 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -99,6 +99,15 @@ namespace renderer { onCommandBufferRequestReceived(req); } + + /** + * Schedule a command buffer to be executed at offscreen pass. + */ + void scheduleCommandBufferAtOffscreenPass(TrCommandBufferBase *req) + { + commandBuffersOnOffscreenPass.push_back(req); + } + /** * Mark the last frame has OOM error. */ @@ -124,9 +133,6 @@ namespace renderer drawCallsCountPerFrame += count; } - // Schedule a GPU command buffer to be executed in the post stage for render textures. - void scheduleGPUCommandBufferOnRenderTexture(std::shared_ptr); - private: // private lifecycle /** * The callback function to handle the command buffer request received. @@ -136,7 +142,7 @@ namespace renderer void onCommandBufferRequestReceived(TrCommandBufferBase *req); void onOpaquesRenderPass(chrono::time_point time); void onTransparentsRenderPass(chrono::time_point time); - void onRenderTexturesRenderPass(); + void onOffscreenRenderPass(); void onStartFrame(); void onEndFrame(); @@ -149,14 +155,13 @@ namespace renderer * is called in the render thread which is allowed to use the graphics APIs. */ void initializeGraphicsContextsOnce(); - /** - * Execute command buffers from content's list. - * - * @param asXRFrame If the frame execution intent is for XR rendering, yes means only the command buffers in XR frame - * could be executed. - * @param viewIndex Used when `asXRFrame` is true, it specific the `viewIndex`. - */ - void executeCommandBuffers(bool asXRFrame, int viewIndex = 0); + + // Executes the command buffers at the default frame + void executeCommandBuffersAtDefaultFrame(); + void executeCommandBuffersAtOffscreenPass(); + // Executes the command buffers at the XR frame with the view index. + void executeCommandBuffersAtXRFrame(int viewIndex); + bool executeStereoFrame(int viewIndex, std::function &)> exec); void executeBackupFrame(int viewIndex, std::function &)> exec); size_t getPendingStereoFramesCount(); @@ -183,7 +188,8 @@ namespace renderer std::atomic defaultCommandQueueSkipTimes = 0; // The recorded command buffers which render to other render textures, such as shadow maps, reflection maps, etc. - std::vector> commandBuffersOnRenderTexture; + // TODO(yorkie): support multi-stage offscreen pass? + std::vector commandBuffersOnOffscreenPass; std::vector stereoFramesList; std::unique_ptr stereoFrameForBackup = nullptr; diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index 410a468f7..b4285f23d 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -67,7 +67,6 @@ ContextGLApp::ContextGLApp(string name, ContextGLApp *from) : ContextGLStorage(name, from) , m_ContentRenderer(from->m_ContentRenderer) , m_CurrentDefaultRenderTarget(from->m_CurrentDefaultRenderTarget) - , m_CurrentCommandEncoder(from->m_CurrentCommandEncoder) , m_GLObjectManager(from->m_GLObjectManager) { m_Programs = OpenGLNamesStorage(&from->m_Programs); @@ -98,7 +97,6 @@ void ContextGLApp::onFrameWillStart(ContextGLHost *host_context) glBindFramebuffer(GL_FRAMEBUFFER, m_CurrentDefaultRenderTarget); glClear(GL_STENCIL_BUFFER_BIT); - updateCurrentCommandEncoder(); ContextGLStorage::restore(); } @@ -110,7 +108,6 @@ void ContextGLApp::onFrameEnded(ContextGLHost *host_context) void ContextGLApp::onProgramChanged(int program) { m_ProgramId = program; - m_CurrentCommandEncoder->getOrStartRecordingRenderPass().setPipeline(gles::GPURenderPipelineImpl(program)); } void ContextGLApp::onArrayBufferChanged(int vao) @@ -126,18 +123,7 @@ void ContextGLApp::onElementBufferChanged(int ebo) void ContextGLApp::onFramebufferChanged(int fbo) { if (!m_FramebufferId.has_value() || m_FramebufferId != fbo) - { - // TODO(yorkie): support scheduling GPU command buffer to transparent objects. - if (m_CurrentCommandEncoder != nullptr && - !m_CurrentCommandEncoder->isRenderPassWith(m_CurrentDefaultRenderTarget)) - { - auto commandbuffer = m_CurrentCommandEncoder->finish(); - if (commandbuffer != nullptr) [[likely]] - contentRendererChecked().scheduleGPUCommandBufferOnRenderTexture(move(commandbuffer)); - } m_FramebufferId = fbo; - updateCurrentCommandEncoder(); - } } void ContextGLApp::onRenderbufferChanged(int rbo) @@ -312,6 +298,17 @@ void ContextGLApp::RecordSamplerOnDeleted(GLuint sampler) m_Samplers.erase(sampler); } +void ContextGLApp::setViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ + glViewport(x, y, width, height); + onViewportChanged(x, y, width, height); +} + +void ContextGLApp::setScissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ + glScissor(x, y, width, height); +} + GLuint ContextGLApp::createProgram(uint32_t id) { GLuint program = ObjectManagerRef().CreateProgram(id); @@ -355,7 +352,6 @@ void ContextGLApp::bindFramebuffer(GLenum target, uint32_t id, GLuint &framebuff void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) { - m_CurrentCommandEncoder->getOrStartRecordingRenderPass().draw(count, 1, first, 0); if (shouleExecuteDrawOnCurrent(count)) { glDrawArrays(mode, first, count); @@ -365,7 +361,6 @@ void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) void ContextGLApp::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) { - m_CurrentCommandEncoder->getOrStartRecordingRenderPass().drawIndexed(count, 1, 0, 0, 0); if (shouleExecuteDrawOnCurrent(count)) { glDrawElements(mode, count, type, indices); @@ -448,6 +443,12 @@ bool ContextGLApp::IsChanged(ContextGLApp *other) return false; } +bool ContextGLApp::IsDefaultRenderTargetBinding() const +{ + return !m_FramebufferId.has_value() || + m_FramebufferId == m_CurrentDefaultRenderTarget; +} + renderer::TrContentRenderer &ContextGLApp::contentRendererChecked() const { auto contentRenderer = m_ContentRenderer.lock(); @@ -455,20 +456,6 @@ renderer::TrContentRenderer &ContextGLApp::contentRendererChecked() const return *contentRenderer; } -void ContextGLApp::updateCurrentCommandEncoder() -{ - auto rhi = contentRendererChecked().getRendererRef().getRHI(); - assert(rhi != nullptr && "RHI must not be null"); - - auto command_encoder = rhi->CreateCommandEncoder(); - if (gles::GPUCommandEncoderImpl *impl = dynamic_cast(command_encoder.get())) - { - command_encoder.release(); - m_CurrentCommandEncoder = unique_ptr(impl); - } - assert(m_CurrentCommandEncoder != nullptr && "Current command encoder must not be null"); -} - bool ContextGLApp::shouleExecuteDrawOnCurrent(GLsizei count) { assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); @@ -482,11 +469,6 @@ bool ContextGLApp::shouleExecuteDrawOnCurrent(GLsizei count) DEBUG(LOG_TAG_ERROR, "Skip this draw: the framebuffer is not complete."); return false; } - if (m_FramebufferId.value() != m_CurrentDefaultRenderTarget) - { - // TODO(yorkie): should record the GPU command buffer and draw parameters - return false; - } return true; } diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index e673b1390..fe7a15662 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -52,6 +52,11 @@ class ContextGLApp : public ContextGLStorage void RecordSamplerOnDeleted(GLuint sampler); public: // GLES Implementations + // State + void setViewport(GLint x, GLint y, GLsizei width, GLsizei height); + void setScissor(GLint x, GLint y, GLsizei width, GLsizei height); + + // Program functions GLuint createProgram(uint32_t id); void deleteProgram(uint32_t id, GLuint &program); void useProgram(uint32_t id, GLuint &program); @@ -67,6 +72,8 @@ class ContextGLApp : public ContextGLStorage void MarkAsDirty(); bool IsDirty(); bool IsChanged(ContextGLApp *other); + // Returns if the GL_FRAMEBUFFER binding is the default render target. + bool IsDefaultRenderTargetBinding() const; public: renderer::TrContentRenderer &contentRendererChecked() const; @@ -76,18 +83,13 @@ class ContextGLApp : public ContextGLStorage } private: - // This updates the current `GPUCommandEncoder` to be used for recording commands. - void updateCurrentCommandEncoder(); - [[nodiscard]] bool shouleExecuteDrawOnCurrent(GLsizei count); void onAfterDraw(int drawCount); private: bool m_Dirty = false; std::weak_ptr m_ContentRenderer; - GLuint m_CurrentDefaultRenderTarget; - std::shared_ptr m_CurrentCommandEncoder = nullptr; std::shared_ptr m_GLObjectManager; OpenGLNamesStorage m_Programs; diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index 97a8df131..aa34e829c 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -8,7 +8,7 @@ #include #include #include -#include "common/classes.hpp" +#include #include #include #include @@ -26,20 +26,29 @@ enum FrameExecutionCode kFrameExecutionSkipped = 4, }; +enum class ExecutingPassType +{ + // Default frame's command buffers are scheduled from the main scripting thread which are used to initialize some + // graphic resources such as: program, textures, and etc. + kDefaultFrame, + // The command buffers in XRFrame is commonly used to dispatch draw calls in each rendering frame. + kXRFrame, + kOffscreenPass, +}; + /** * The options to be used when making a RHI API call. */ class ApiCallOptions final { public: - /** - * Executes this call in the default queue. - */ - bool isDefaultQueue; - /** - * Should print the information of this call. - */ bool printsCall; + ExecutingPassType executingPassType; + + bool isDefaultQueue() const + { + return executingPassType == ExecutingPassType::kDefaultFrame; + } }; /** @@ -112,18 +121,11 @@ class TrRenderHardwareInterface /** * Executes the commands from the given command queue with the device frame, and it also returns a boolean value indicating if * there are any commands to execute. - * - * @param commandBuffers the command buffer queue. - * @param content the content renderer. - * @param deviceFrame the XR device frame that stores the frame context: views, projection matrices, etc. - * @param isDefaultQueue a boolean value indicating if the command queue is the default queue or XR frame queue. - * @returns a boolean value indicating if there are any commands to execute. - */ - virtual bool ExecuteCommandBuffer( - vector &commandBuffers, - renderer::TrContentRenderer *content, - xr::DeviceFrame *deviceFrame, - bool isDefaultQueue) = 0; + */ + virtual bool ExecuteCommandBuffer(vector &commandBuffers, + renderer::TrContentRenderer *, + xr::DeviceFrame *, + ExecutingPassType) = 0; /** * Enables the graphics debug log, which is useful when you want to debug the backend graphics api. diff --git a/src/renderer/render_api_metal.mm b/src/renderer/render_api_metal.mm index b8a090a82..c6b8ed40d 100644 --- a/src/renderer/render_api_metal.mm +++ b/src/renderer/render_api_metal.mm @@ -91,9 +91,10 @@ void DisableGraphicsDebugLog() {} bool ExecuteCommandBuffer() { return true; } bool ExecuteCommandBuffer( - vector &commandBuffers, - renderer::TrContentRenderer *contentRenderer, xr::DeviceFrame *deviceFrame, - bool isDefaultQueue) { + vector &list, + renderer::TrContentRenderer *content_renderer, + xr::DeviceFrame *device_frame, + ExecutingPassType pass_type) { return true; } diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index cdb504289..7fa40e736 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -69,10 +69,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface public: // Execute command buffer bool ExecuteCommandBuffer(); - bool ExecuteCommandBuffer(vector &commandBuffers, - renderer::TrContentRenderer *content, - xr::DeviceFrame *deviceFrame, - bool isDefaultQueue) override; + bool ExecuteCommandBuffer(vector &list, + renderer::TrContentRenderer *, + xr::DeviceFrame *, + ExecutingPassType) override; private: /** @@ -107,6 +107,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface commandTypeToStr(commandType).c_str()); DEBUG(LOG_TAG_ERROR, " command: %d", commandType); DEBUG(LOG_TAG_ERROR, " content: %d", contentId); + DEBUG(LOG_TAG_ERROR, " context: %d", req->contextId); if (help != nullptr) DEBUG(LOG_TAG_ERROR, " detail: %s", help); @@ -328,7 +329,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface res.renderer = string((const char *)glGetString(GL_RENDERER)); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::ContextInit()", options.isDefaultQueue); + DEBUG(DEBUG_TAG, "[%d] GL::ContextInit()", options.isDefaultQueue()); DEBUG(DEBUG_TAG, " MAX_COMBINED_TEXTURE_IMAGE_UNITS = %d", res.maxCombinedTextureImageUnits); DEBUG(DEBUG_TAG, " MAX_CUBE_MAP_TEXTURE_SIZE = %d", res.maxCubeMapTextureSize); DEBUG(DEBUG_TAG, " MAX_FRAGMENT_UNIFORM_VECTORS = %d", res.maxFragmentUniformVectors); @@ -384,7 +385,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface } if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::Context2Init()", options.isDefaultQueue); + DEBUG(DEBUG_TAG, "[%d] GL::Context2Init()", options.isDefaultQueue()); DEBUG(DEBUG_TAG, " GL_MAX_3D_TEXTURE_SIZE = %d", res.max3DTextureSize); DEBUG(DEBUG_TAG, " GL_MAX_ARRAY_TEXTURE_LAYERS = %d", res.maxArrayTextureLayers); DEBUG(DEBUG_TAG, " GL_MAX_COLOR_ATTACHMENTS = %d", res.maxColorAttachments); @@ -408,7 +409,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { GLuint program = reqContentRenderer->getOpenGLContext()->createProgram(req->clientId); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateProgram(%d) => %d", options.isDefaultQueue, req->clientId, program); + DEBUG(DEBUG_TAG, "[%d] GL::CreateProgram(%d) => %d", options.isDefaultQueue(), req->clientId, program); } TR_OPENGL_FUNC void OnDeleteProgram(DeleteProgramCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -417,7 +418,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint program; reqContentRenderer->getOpenGLContext()->deleteProgram(req->clientId, program); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteProgram(%d)", options.isDefaultQueue, program); + DEBUG(DEBUG_TAG, "[%d] GL::DeleteProgram(%d)", options.isDefaultQueue(), program); } TR_OPENGL_FUNC void OnLinkProgram(LinkProgramCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -526,7 +527,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::LinkProgram(%d)", options.isDefaultQueue, program); + DEBUG(DEBUG_TAG, "[%d] GL::LinkProgram(%d)", options.isDefaultQueue(), program); } reqContentRenderer->sendCommandBufferResponse(res); } @@ -537,7 +538,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint program; reqContentRenderer->getOpenGLContext()->useProgram(req->clientId, program); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::UseProgram(%d)", options.isDefaultQueue, program); + DEBUG(DEBUG_TAG, "[%d] GL::UseProgram(%d)", options.isDefaultQueue(), program); } TR_OPENGL_FUNC void OnBindAttribLocation(BindAttribLocationCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -550,7 +551,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::BindAttribLocation(program=%d, index=%d, name=%s)", - options.isDefaultQueue, + options.isDefaultQueue(), program, req->attribIndex, req->attribName.c_str()); @@ -567,7 +568,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::GetProgramParameter(%s) => %d", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glEnumToString(req->pname).c_str(), res.value); reqContentRenderer->sendCommandBufferResponse(res); @@ -589,7 +590,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::GetProgramInfoLog: \"%s\"(%d)", - options.isDefaultQueue, + options.isDefaultQueue(), res.infoLog.c_str(), retSize); reqContentRenderer->sendCommandBufferResponse(res); @@ -604,7 +605,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glAttachShader(program, shader); reqContentRenderer->getOpenGLContext()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::AttachShader(program=%d, shader=%d)", options.isDefaultQueue, program, shader); + DEBUG(DEBUG_TAG, "[%d] GL::AttachShader(program=%d, shader=%d)", options.isDefaultQueue(), program, shader); } TR_OPENGL_FUNC void OnDetachShader(DetachShaderCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -616,7 +617,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDetachShader(program, shader); reqContentRenderer->getOpenGLContext()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DetachShader(program=%d, shader=%d)", options.isDefaultQueue, program, shader); + DEBUG(DEBUG_TAG, "[%d] GL::DetachShader(program=%d, shader=%d)", options.isDefaultQueue(), program, shader); } TR_OPENGL_FUNC void OnCreateShader(CreateShaderCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -626,7 +627,12 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint shader = glObjectManager.CreateShader(req->clientId, req->shaderType); reqContentRenderer->getOpenGLContext()->RecordShaderOnCreated(shader); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateShader(%d, type=%s) => %d", options.isDefaultQueue, req->clientId, gles::glEnumToString(req->shaderType).c_str(), shader); + DEBUG(DEBUG_TAG, + "[%d] GL::CreateShader(%d, type=%s) => %d", + options.isDefaultQueue(), + req->clientId, + gles::glEnumToString(req->shaderType).c_str(), + shader); } TR_OPENGL_FUNC void OnDeleteShader(DeleteShaderCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -638,7 +644,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->RecordShaderOnDeleted(shader); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteShader(%d)", options.isDefaultQueue, shader); + DEBUG(DEBUG_TAG, "[%d] GL::DeleteShader(%d)", options.isDefaultQueue(), shader); } TR_OPENGL_FUNC void OnShaderSource(ShaderSourceCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -675,7 +681,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::ShaderSource(%d)", options.isDefaultQueue, shader); + DEBUG(DEBUG_TAG, "[%d] GL::ShaderSource(%d)", options.isDefaultQueue(), shader); } TR_OPENGL_FUNC void OnCompileShader(CompileShaderCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -738,7 +744,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface } if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CompileShader(%d)", options.isDefaultQueue, shader); + DEBUG(DEBUG_TAG, "[%d] GL::CompileShader(%d)", options.isDefaultQueue(), shader); } TR_OPENGL_FUNC void OnGetShaderSource(GetShaderSourceCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -771,7 +777,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface delete[] source; if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetShaderSource(): %s", options.isDefaultQueue, res.source.c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::GetShaderSource(): %s", options.isDefaultQueue(), res.source.c_str()); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnGetShaderParameter(GetShaderParamCommandBufferRequest *req, @@ -785,7 +791,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GetShaderParamCommandBufferResponse res(req, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetShaderParameter: %d", options.isDefaultQueue, res.value); + DEBUG(DEBUG_TAG, "[%d] GL::GetShaderParameter: %d", options.isDefaultQueue(), res.value); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnGetShaderInfoLog(GetShaderInfoLogCommandBufferRequest *req, @@ -803,7 +809,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface delete[] log; if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetShaderInfoLog: %s", options.isDefaultQueue, res.infoLog.c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::GetShaderInfoLog: %s", options.isDefaultQueue(), res.infoLog.c_str()); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnCreateBuffer(CreateBufferCommandBufferRequest *req, @@ -814,7 +820,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint buffer = glObjectManager.CreateBuffer(req->clientId); reqContentRenderer->getOpenGLContext()->RecordBufferOnCreated(buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateBuffer(%d) => buffer(%d)", options.isDefaultQueue, req->clientId, buffer); + DEBUG(DEBUG_TAG, + "[%d] GL::CreateBuffer(%d) => buffer(%d)", + options.isDefaultQueue(), + req->clientId, + buffer); } TR_OPENGL_FUNC void OnDeleteBuffer(DeleteBufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -825,7 +835,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteBuffer(req->buffer); reqContentRenderer->getOpenGLContext()->RecordBufferOnDeleted(buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteBuffer(%d)", options.isDefaultQueue, buffer); + DEBUG(DEBUG_TAG, "[%d] GL::DeleteBuffer(%d)", options.isDefaultQueue(), buffer); } TR_OPENGL_FUNC void OnBindBuffer(BindBufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -854,7 +864,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { DEBUG(DEBUG_TAG, "[%d] GL::BindBuffer(%s, buffer=%d)", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glEnumToString(target).c_str(), buffer); } @@ -873,7 +883,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { DEBUG(DEBUG_TAG, "[%d] GL::BufferData(%s, size=%d, data=%p, usage=%s)", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glEnumToString(target).c_str(), size, data, @@ -891,7 +901,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { glBufferSubData(req->target, req->offset, req->dataSize, req->data); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BufferSubData(%d)", options.isDefaultQueue, req->target); + DEBUG(DEBUG_TAG, "[%d] GL::BufferSubData(%d)", options.isDefaultQueue(), req->target); } TR_OPENGL_FUNC void OnCreateFramebuffer( CreateFramebufferCommandBufferRequest *req, @@ -902,7 +912,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint framebuffer = glObjectManager.CreateFramebuffer(req->clientId); reqContentRenderer->getOpenGLContext()->RecordFramebufferOnCreated(framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateFramebuffer(#%d) => %d", options.isDefaultQueue, req->clientId, framebuffer); + DEBUG(DEBUG_TAG, "[%d] GL::CreateFramebuffer(#%d) => %d", options.isDefaultQueue(), req->clientId, framebuffer); } TR_OPENGL_FUNC void OnDeleteFramebuffer( DeleteFramebufferCommandBufferRequest *req, @@ -914,17 +924,22 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteFramebuffer(req->framebuffer); reqContentRenderer->getOpenGLContext()->RecordFramebufferOnDeleted(framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteFramebuffer: %d", options.isDefaultQueue, req->framebuffer); + DEBUG(DEBUG_TAG, "[%d] GL::DeleteFramebuffer: %d", options.isDefaultQueue(), req->framebuffer); } TR_OPENGL_FUNC void OnBindFramebuffer( BindFramebufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { + auto app_context = reqContentRenderer->getOpenGLContext(); + GLuint framebuffer; - reqContentRenderer->getOpenGLContext()->bindFramebuffer(req->target, req->framebuffer, framebuffer); + app_context->bindFramebuffer(req->target, req->framebuffer, framebuffer); + if (!app_context->IsDefaultRenderTargetBinding()) + reqContentRenderer->scheduleCommandBufferAtOffscreenPass(new BindFramebufferCommandBufferRequest(*req)); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BindFramebuffer(%d)", options.isDefaultQueue, framebuffer); + DEBUG(DEBUG_TAG, "[%d] GL::BindFramebuffer(%d)", options.isDefaultQueue(), framebuffer); } TR_OPENGL_FUNC void OnFramebufferRenderbuffer(FramebufferRenderbufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -941,7 +956,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { DEBUG(DEBUG_TAG, "[%d] GL::FramebufferRenderbuffer(%s, attachment=%s, renderbuffertarget=%s, renderbuffer(%d))", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glEnumToString(target).c_str(), gles::glFramebufferAttachmentToString(attachment).c_str(), gles::glEnumToString(renderbuffertarget).c_str(), @@ -966,7 +981,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { DEBUG(DEBUG_TAG, "[%d] GL::FramebufferTexture2D(0x%x, 0x%x, 0x%x, %d, level=%d)", - options.isDefaultQueue, + options.isDefaultQueue(), target, attachment, textarget, @@ -981,7 +996,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLenum ret = glCheckFramebufferStatus(req->target); CheckFramebufferStatusCommandBufferResponse res(req, ret); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CheckFramebufferStatus() => %d", options.isDefaultQueue, res.status); + DEBUG(DEBUG_TAG, "[%d] GL::CheckFramebufferStatus() => %d", options.isDefaultQueue(), res.status); } TR_OPENGL_FUNC void OnCreateRenderbuffer( CreateRenderbufferCommandBufferRequest *req, @@ -994,7 +1009,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::CreateRenderbuffer(#%d) => renderbuffer(%d)", - options.isDefaultQueue, + options.isDefaultQueue(), req->clientId, renderbuffer); } @@ -1008,7 +1023,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteRenderbuffer(req->renderbuffer); reqContentRenderer->getOpenGLContext()->RecordRenderbufferOnDeleted(renderbuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteRenderbuffer(%d)", options.isDefaultQueue, renderbuffer); + DEBUG(DEBUG_TAG, "[%d] GL::DeleteRenderbuffer(%d)", options.isDefaultQueue(), renderbuffer); } TR_OPENGL_FUNC void OnBindRenderbuffer(BindRenderbufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1024,7 +1039,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::BindRenderbuffer(%s, renderbuffer(%d))", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glEnumToString(target).c_str(), renderbuffer); } @@ -1038,15 +1053,27 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto height = req->height; glRenderbufferStorage(target, internalformat, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es3/glRenderbufferStorage") != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::RenderbufferStorage(%s, internal_format=%d, width=%d, height=%d)", options.isDefaultQueue, gles::glEnumToString(target).c_str(), internalformat, width, height); + { + DEBUG(DEBUG_TAG, + "[%d] GL::RenderbufferStorage(%s, internal_format=%d, width=%d, height=%d)", + options.isDefaultQueue(), + gles::glEnumToString(target).c_str(), + internalformat, + width, + height); + } } - TR_OPENGL_FUNC void OnReadBuffer(ReadBufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnReadBuffer(ReadBufferCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glReadBuffer(req->mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::ReadBuffer(%d)", options.isDefaultQueue, req->mode); + DEBUG(DEBUG_TAG, "[%d] GL::ReadBuffer(%d)", options.isDefaultQueue(), req->mode); } - TR_OPENGL_FUNC void OnBindBufferBase(BindBufferBaseCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnBindBufferBase(BindBufferBaseCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); auto target = req->target; @@ -1054,9 +1081,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto buffer = glObjectManager.FindBuffer(req->buffer); glBindBufferBase(target, index, buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BindBufferBase(%d, index=%d, target=%d)", options.isDefaultQueue, buffer, index, target); + DEBUG(DEBUG_TAG, "[%d] GL::BindBufferBase(%d, index=%d, target=%d)", options.isDefaultQueue(), buffer, index, target); } - TR_OPENGL_FUNC void OnBindBufferRange(BindBufferRangeCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnBindBufferRange(BindBufferRangeCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto target = req->target; auto index = req->index; @@ -1065,9 +1094,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto size = req->bufferSize; glBindBufferRange(target, index, buffer, offset, size); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BindBufferRange(%d)", options.isDefaultQueue, buffer); + DEBUG(DEBUG_TAG, "[%d] GL::BindBufferRange(%d)", options.isDefaultQueue(), buffer); } - TR_OPENGL_FUNC void OnBlitFramebuffer(BlitFramebufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnBlitFramebuffer(BlitFramebufferCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glBlitFramebuffer( req->srcX0, @@ -1081,7 +1112,12 @@ class RHI_OpenGL : public TrRenderHardwareInterface req->mask, req->filter); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlitFramebuffer(%d, %d, filter=%d)", options.isDefaultQueue, req->srcX0, req->srcY0, req->filter); + DEBUG(DEBUG_TAG, + "[%d] GL::BlitFramebuffer(%d, %d, filter=%d)", + options.isDefaultQueue(), + req->srcX0, + req->srcY0, + req->filter); } TR_OPENGL_FUNC void OnRenderbufferStorageMultisample(RenderbufferStorageMultisampleCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1094,15 +1130,24 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto height = req->height; glRenderbufferStorageMultisample(target, samples, internalformat, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::RenderbufferStorageMultisample(0x%x, samples=%d, internalformat=0x%x, size=[%d,%d])", options.isDefaultQueue, target, samples, internalformat, width, height); + DEBUG(DEBUG_TAG, + "[%d] GL::RenderbufferStorageMultisample(0x%x, samples=%d, internalformat=0x%x, size=[%d,%d])", + options.isDefaultQueue(), + target, + samples, + internalformat, + width, + height); } - TR_OPENGL_FUNC void OnCreateVertexArray(CreateVertexArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnCreateVertexArray(CreateVertexArrayCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); GLuint vao = glObjectManager.CreateVertexArray(req->clientId); reqContentRenderer->getOpenGLContext()->RecordVertexArrayObjectOnCreated(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateVertexArray(%d) => %d", options.isDefaultQueue, req->clientId, vao); + DEBUG(DEBUG_TAG, "[%d] GL::CreateVertexArray(%d) => %d", options.isDefaultQueue(), req->clientId, vao); } TR_OPENGL_FUNC void OnDeleteVertexArray(DeleteVertexArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1111,7 +1156,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteVertexArray(req->vertexArray); reqContentRenderer->getOpenGLContext()->RecordVertexArrayObjectOnDeleted(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteVertexArray(%d)", options.isDefaultQueue, vao); + DEBUG(DEBUG_TAG, "[%d] GL::DeleteVertexArray(%d)", options.isDefaultQueue(), vao); } TR_OPENGL_FUNC void OnBindVertexArray(BindVertexArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1127,7 +1172,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glBindVertexArray(vao); reqContentRenderer->getOpenGLContext()->onVertexArrayObjectChanged(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BindVertexArray(%d)", options.isDefaultQueue, vao); + DEBUG(DEBUG_TAG, "[%d] GL::BindVertexArray(%d)", options.isDefaultQueue(), vao); } TR_OPENGL_FUNC void OnCreateTexture( CreateTextureCommandBufferRequest *req, @@ -1138,7 +1183,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint texture = glObjectManager.CreateTexture(req->clientId); reqContentRenderer->getOpenGLContext()->RecordTextureOnCreated(texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateTexture(#%d) => texture(%d)", options.isDefaultQueue, req->clientId, texture); + DEBUG(DEBUG_TAG, "[%d] GL::CreateTexture(#%d) => texture(%d)", options.isDefaultQueue(), req->clientId, texture); } TR_OPENGL_FUNC void OnDeleteTexture( DeleteTextureCommandBufferRequest *req, @@ -1150,7 +1195,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteTexture(req->texture); reqContentRenderer->getOpenGLContext()->RecordTextureOnDeleted(texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteTexture(%d)", options.isDefaultQueue, texture); + DEBUG(DEBUG_TAG, "[%d] GL::DeleteTexture(%d)", options.isDefaultQueue(), texture); } TR_OPENGL_FUNC void OnBindTexture(BindTextureCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1170,7 +1215,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glGetIntegerv(GL_ACTIVE_TEXTURE, &activeUnit); DEBUG(DEBUG_TAG, "[%d] GL::BindTexture(%s, texture(%d)) for active(%d) program(%d)", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glEnumToString(target).c_str(), texture, activeUnit, @@ -1219,7 +1264,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLint currentTexture; glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤tTexture); - DEBUG(DEBUG_TAG, "[%d] GL::TexImage2D(%s [%d,%d]) => texture(%d)", options.isDefaultQueue, gles::glEnumToString(target).c_str(), width, height, currentTexture); + DEBUG(DEBUG_TAG, "[%d] GL::TexImage2D(%s [%d,%d]) => texture(%d)", options.isDefaultQueue(), gles::glEnumToString(target).c_str(), width, height, currentTexture); DEBUG(DEBUG_TAG, " level: %d", level); DEBUG(DEBUG_TAG, " internalformat: %s", gles::glTextureInternalFormatToString(internalformat).c_str()); DEBUG(DEBUG_TAG, " width: %d", width); @@ -1230,7 +1275,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface DEBUG(DEBUG_TAG, " data: %p", pixels); } } - TR_OPENGL_FUNC void OnTexSubImage2D(TextureSubImage2DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnTexSubImage2D(TextureSubImage2DCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glTexSubImage2D( req->target, @@ -1243,9 +1290,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface req->pixelType, req->pixels); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::TexSubImage2D: %d", options.isDefaultQueue, req->target); + DEBUG(DEBUG_TAG, "[%d] GL::TexSubImage2D: %d", options.isDefaultQueue(), req->target); } - TR_OPENGL_FUNC void OnCopyTexImage2D(CopyTextureImage2DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnCopyTexImage2D(CopyTextureImage2DCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glCopyTexImage2D( req->target, @@ -1257,7 +1306,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface req->height, req->border); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CopyTexImage2D: %d", options.isDefaultQueue, req->target); + DEBUG(DEBUG_TAG, "[%d] GL::CopyTexImage2D: %d", options.isDefaultQueue(), req->target); } TR_OPENGL_FUNC void OnCopyTexSubImage2D(CopyTextureSubImage2DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1273,31 +1322,37 @@ class RHI_OpenGL : public TrRenderHardwareInterface req->width, req->height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CopyTexSubImage2D: %d", options.isDefaultQueue, req->target); + DEBUG(DEBUG_TAG, "[%d] GL::CopyTexSubImage2D: %d", options.isDefaultQueue(), req->target); } - TR_OPENGL_FUNC void OnTexParameteri(TextureParameteriCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnTexParameteri(TextureParameteriCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glTexParameteri(req->target, req->pname, req->param); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(options.printsCall ? DEBUG_TAG : LOG_TAG_ERROR, "[%d] GL::TexParameteri(target=%s, pname=%s, param=%d)", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glEnumToString(req->target).c_str(), gles::glTextureParameterToString(req->pname).c_str(), req->param); } - TR_OPENGL_FUNC void OnTexParameterf(TextureParameterfCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnTexParameterf(TextureParameterfCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glTexParameterf(req->target, req->pname, req->param); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(options.printsCall ? DEBUG_TAG : LOG_TAG_ERROR, "[%d] GL::TexParameterf(target=%s, pname=%s, param=%f)", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glEnumToString(req->target).c_str(), gles::glTextureParameterToString(req->pname).c_str(), req->param); } - TR_OPENGL_FUNC void OnActiveTexture(ActiveTextureCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnActiveTexture(ActiveTextureCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto textureUnit = req->activeUnit; glActiveTexture(textureUnit); @@ -1306,24 +1361,28 @@ class RHI_OpenGL : public TrRenderHardwareInterface { GLint currentProgram; glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); - DEBUG(DEBUG_TAG, "[%d] GL::ActiveTexture(%s)", options.isDefaultQueue, gles::glEnumToString(textureUnit).c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::ActiveTexture(%s)", options.isDefaultQueue(), gles::glEnumToString(textureUnit).c_str()); DEBUG(DEBUG_TAG, " program: %d", currentProgram); DEBUG(DEBUG_TAG, " id: %d", textureUnit - GL_TEXTURE0); } } - TR_OPENGL_FUNC void OnGenerateMipmap(GenerateMipmapCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnGenerateMipmap(GenerateMipmapCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glGenerateMipmap(req->target); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::GenerateMipmap: %d", options.isDefaultQueue, req->target); + DEBUG(DEBUG_TAG, "[%d] GL::GenerateMipmap: %d", options.isDefaultQueue(), req->target); GLuint currentTextureBinding; glGetIntegerv(req->target == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_3D, (GLint *)¤tTextureBinding); DEBUG(DEBUG_TAG, " current texture binding: %d", currentTextureBinding); } } - TR_OPENGL_FUNC void OnTexImage3D(TextureImage3DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnTexImage3D(TextureImage3DCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto target = req->target; auto level = req->level; @@ -1338,10 +1397,20 @@ class RHI_OpenGL : public TrRenderHardwareInterface glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::TexImage3D(target=%s, level=%d, size=[%d,%d,%d], pixels=%p)", options.isDefaultQueue, gles::glEnumToString(target).c_str(), level, width, height, depth, pixels); + DEBUG(DEBUG_TAG, + "[%d] GL::TexImage3D(target=%s, level=%d, size=[%d,%d,%d], pixels=%p)", + options.isDefaultQueue(), + gles::glEnumToString(target).c_str(), + level, + width, + height, + depth, + pixels); } } - TR_OPENGL_FUNC void OnTexSubImage3D(TextureSubImage3DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnTexSubImage3D(TextureSubImage3DCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto target = req->target; auto level = req->level; @@ -1357,7 +1426,18 @@ class RHI_OpenGL : public TrRenderHardwareInterface glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::TexSubImage3D(target=0x%x, level=%d, offset=[%d,%d,%d], size=[%d,%d,%d], pixels=%p)", options.isDefaultQueue, target, level, xoffset, yoffset, zoffset, width, height, depth, pixels); + DEBUG(DEBUG_TAG, + "[%d] GL::TexSubImage3D(target=0x%x, level=%d, offset=[%d,%d,%d], size=[%d,%d,%d], pixels=%p)", + options.isDefaultQueue(), + target, + level, + xoffset, + yoffset, + zoffset, + width, + height, + depth, + pixels); } } TR_OPENGL_FUNC void OnTexStorage2D(TextureStorage2DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -1370,7 +1450,14 @@ class RHI_OpenGL : public TrRenderHardwareInterface glTexStorage2D(target, levels, internalformat, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::TexStorage2D(target=0x%x, levels=%d, internalformat=0x%x, size=[%d,%d])", options.isDefaultQueue, target, levels, internalformat, width, height); + DEBUG(DEBUG_TAG, + "[%d] GL::TexStorage2D(target=0x%x, levels=%d, internalformat=0x%x, size=[%d,%d])", + options.isDefaultQueue(), + target, + levels, + internalformat, + width, + height); } } TR_OPENGL_FUNC void OnTexStorage3D(TextureStorage3DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -1384,7 +1471,15 @@ class RHI_OpenGL : public TrRenderHardwareInterface glTexStorage3D(target, levels, internalformat, width, height, depth); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::TexStorage3D(target=0x%x, levels=%d, internalformat=0x%x, size=[%d,%d,%d])", options.isDefaultQueue, target, levels, internalformat, width, height, depth); + DEBUG(DEBUG_TAG, + "[%d] GL::TexStorage3D(target=0x%x, levels=%d, internalformat=0x%x, size=[%d,%d,%d])", + options.isDefaultQueue(), + target, + levels, + internalformat, + width, + height, + depth); } } TR_OPENGL_FUNC void OnEnableVertexAttribArray(EnableVertexAttribArrayCommandBufferRequest *req, @@ -1399,7 +1494,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface EnsureVertexArrayObject(reqContentRenderer->getOpenGLContext()); glEnableVertexAttribArray(req->index); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::EnableVertexAttribArray(%d)", options.isDefaultQueue, req->index); + DEBUG(DEBUG_TAG, "[%d] GL::EnableVertexAttribArray(%d)", options.isDefaultQueue(), req->index); } TR_OPENGL_FUNC void OnDisableVertexAttribArray(DisableVertexAttribArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1413,7 +1508,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface EnsureVertexArrayObject(reqContentRenderer->getOpenGLContext()); glDisableVertexAttribArray(req->index); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DisableVertexAttribArray(%d)", options.isDefaultQueue, req->index); + DEBUG(DEBUG_TAG, "[%d] GL::DisableVertexAttribArray(%d)", options.isDefaultQueue(), req->index); } TR_OPENGL_FUNC void OnVertexAttribPointer(VertexAttribPointerCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1427,7 +1522,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glVertexAttribPointer(index, size, type, normalized, stride, (const char *)NULL + offset); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::VertexAttribPointer(%d)", options.isDefaultQueue, index); + DEBUG(DEBUG_TAG, "[%d] GL::VertexAttribPointer(%d)", options.isDefaultQueue(), index); DEBUG(DEBUG_TAG, " size=%d", size); DEBUG(DEBUG_TAG, " type=%s", gles::glEnumToString(type).c_str()); DEBUG(DEBUG_TAG, " normalized=%s", normalized ? "Yes" : "No"); @@ -1452,7 +1547,16 @@ class RHI_OpenGL : public TrRenderHardwareInterface glVertexAttribIPointer(index, size, type, stride, (const char *)NULL + offset); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::VertexAttribIPointer(%d) size=%d type=0x%x stride=%d offset=%d", options.isDefaultQueue, index, size, type, stride, offset); + { + DEBUG(DEBUG_TAG, + "[%d] GL::VertexAttribIPointer(%d) size=%d type=0x%x stride=%d offset=%d", + options.isDefaultQueue(), + index, + size, + type, + stride, + offset); + } } TR_OPENGL_FUNC void OnVertexAttribDivisor(VertexAttribDivisorCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1462,9 +1566,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto divisor = req->divisor; glVertexAttribDivisor(index, divisor); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::VertexAttribDivisor(%d, %d)", options.isDefaultQueue, index, divisor); + DEBUG(DEBUG_TAG, "[%d] GL::VertexAttribDivisor(%d, %d)", options.isDefaultQueue(), index, divisor); } - TR_OPENGL_FUNC void OnUniformBlockBinding(UniformBlockBindingCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnUniformBlockBinding(UniformBlockBindingCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); auto program = glObjectManager.FindProgram(req->program); @@ -1472,19 +1578,30 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto uniformBlockBinding = req->uniformBlockBinding; glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::UniformBlockBinding(program=%d, %d, %d)", options.isDefaultQueue, program, uniformBlockIndex, uniformBlockBinding); + { + DEBUG(DEBUG_TAG, + "[%d] GL::UniformBlockBinding(program=%d, %d, %d)", + options.isDefaultQueue(), + program, + uniformBlockIndex, + uniformBlockBinding); + } } - TR_OPENGL_FUNC void OnUniform1f(Uniform1fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnUniform1f(Uniform1fCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glUniform1f(req->location, req->v0); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { auto glContext = reqContentRenderer->getOpenGLContext(); - DEBUG(DEBUG_TAG, "[%d] GL::Uniform1f(%d, %f)", options.isDefaultQueue, req->location, req->v0); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform1f(%d, %f)", options.isDefaultQueue(), req->location, req->v0); DEBUG(DEBUG_TAG, " Program: %d", glContext->program()); } } - TR_OPENGL_FUNC void OnUniform1fv(Uniform1fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnUniform1fv(Uniform1fvCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto location = req->location; auto count = req->values.size(); @@ -1502,7 +1619,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (i < count - 1) valuesStr += ","; } - DEBUG(DEBUG_TAG, "[%d] GL::Uniform1fv(%d, count=%d, values=[%s])", options.isDefaultQueue, location, count, valuesStr.c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform1fv(%d, count=%d, values=[%s])", options.isDefaultQueue(), location, count, valuesStr.c_str()); DEBUG(DEBUG_TAG, " Content: %d", contentId); DEBUG(DEBUG_TAG, " Program: %d", glContext->program()); } @@ -1512,7 +1629,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto loc = req->location; glUniform1i(loc, req->v0); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform1i(%d): %d", options.isDefaultQueue, loc, req->v0); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform1i(%d): %d", options.isDefaultQueue(), loc, req->v0); } TR_OPENGL_FUNC void OnUniform1iv(Uniform1ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1521,13 +1638,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform1iv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform1iv(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform1iv(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniform2f(Uniform2fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glUniform2f(req->location, req->v0, req->v1); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform2f(%d)", options.isDefaultQueue, req->location); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform2f(%d)", options.isDefaultQueue(), req->location); } TR_OPENGL_FUNC void OnUniform2fv(Uniform2fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1536,13 +1653,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform2fv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform2fv(%d, count=%d)", options.isDefaultQueue, loc, count); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform2fv(%d, count=%d)", options.isDefaultQueue(), loc, count); } TR_OPENGL_FUNC void OnUniform2i(Uniform2iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glUniform2i(req->location, req->v0, req->v1); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform2i(%d, %d, %d)", options.isDefaultQueue, req->location, req->v0, req->v1); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform2i(%d, %d, %d)", options.isDefaultQueue(), req->location, req->v0, req->v1); } TR_OPENGL_FUNC void OnUniform2iv(Uniform2ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1551,7 +1668,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform2iv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform2iv(%d)", options.isDefaultQueue, req->location); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform2iv(%d)", options.isDefaultQueue(), req->location); } TR_OPENGL_FUNC void OnUniform3f(Uniform3fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1562,7 +1679,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glUniform3f(loc, v0, v1, v2); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::Uniform3f(%d): (%f, %f, %f)", options.isDefaultQueue, loc, v0, v1, v2); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform3f(%d): (%f, %f, %f)", options.isDefaultQueue(), loc, v0, v1, v2); } } TR_OPENGL_FUNC void OnUniform3fv(Uniform3fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -1572,7 +1689,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform3fv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform3fv(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform3fv(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniform3i(Uniform3iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1582,7 +1699,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto v2 = req->v2; glUniform3i(loc, v0, v1, v2); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform3i(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform3i(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniform3iv(Uniform3ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1591,7 +1708,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform3iv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform3iv(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform3iv(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniform4f(Uniform4fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1603,7 +1720,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glUniform4f(loc, v0, v1, v2, v3); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform4f(%d): (%f, %f, %f, %f)", options.isDefaultQueue, loc, v0, v1, v2, v3); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform4f(%d): (%f, %f, %f, %f)", options.isDefaultQueue(), loc, v0, v1, v2, v3); } TR_OPENGL_FUNC void OnUniform4fv(Uniform4fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1612,7 +1729,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform4fv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform4fv(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform4fv(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniform4i(Uniform4iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1623,7 +1740,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto v3 = req->v3; glUniform4i(loc, v0, v1, v2, v3); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform4i(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform4i(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniform4iv(Uniform4ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1632,7 +1749,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform4iv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform4iv(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::Uniform4iv(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniformMatrix2fv(UniformMatrix2fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1645,7 +1762,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniformMatrix2fv(loc, count, transpose, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::UniformMatrix2fv(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::UniformMatrix2fv(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniformMatrix3fv(UniformMatrix3fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1658,7 +1775,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniformMatrix3fv(loc, count, transpose, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::UniformMatrix3fv(%d)", options.isDefaultQueue, loc); + DEBUG(DEBUG_TAG, "[%d] GL::UniformMatrix3fv(%d)", options.isDefaultQueue(), loc); } TR_OPENGL_FUNC void OnUniformMatrix4fv(UniformMatrix4fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1730,7 +1847,14 @@ class RHI_OpenGL : public TrRenderHardwareInterface { GLint currentProgram; glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); - DEBUG(DEBUG_TAG, "[%d] GL::UniformMatrix4fv(%d, values=[%d, use_placeholder=%s], count=%d, transpose=%s)", options.isDefaultQueue, location, matrixValuesSize, usePlaceholder ? "true" : "false", count, transpose ? "true" : "false"); + DEBUG(DEBUG_TAG, + "[%d] GL::UniformMatrix4fv(%d, values=[%d, use_placeholder=%s], count=%d, transpose=%s)", + options.isDefaultQueue(), + location, + matrixValuesSize, + usePlaceholder ? "true" : "false", + count, + transpose ? "true" : "false"); DEBUG(DEBUG_TAG, " Program: %d", currentProgram); for (int i = 0; i < count; i++) { @@ -1755,7 +1879,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->drawArrays(mode, first, count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DumpDrawCallInfo(DEBUG_TAG, "DrawArrays", options.isDefaultQueue, mode, count, 0, nullptr); + DumpDrawCallInfo(DEBUG_TAG, "DrawArrays", options.isDefaultQueue(), mode, count, 0, nullptr); } TR_OPENGL_FUNC void OnDrawElements(DrawElementsCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1766,7 +1890,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->drawElements(mode, count, type, indices); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DumpDrawCallInfo(DEBUG_TAG, "DrawElements", options.isDefaultQueue, mode, count, type, indices); + DumpDrawCallInfo(DEBUG_TAG, "DrawElements", options.isDefaultQueue(), mode, count, type, indices); } TR_OPENGL_FUNC void OnDrawBuffers(DrawBuffersCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1775,7 +1899,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDrawBuffers(n, (const GLenum *)buffers); if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es2/glDrawBuffers") != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::DrawBuffers()", options.isDefaultQueue); + DEBUG(DEBUG_TAG, "[%d] GL::DrawBuffers()", options.isDefaultQueue()); GLint bindingFramebuffer; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bindingFramebuffer); DEBUG(DEBUG_TAG, " framebuffer: %d", bindingFramebuffer); @@ -1796,7 +1920,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDrawArraysInstanced(mode, first, count, instanceCount); reqContentRenderer->increaseDrawCallsCount(count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DumpDrawCallInfo(DEBUG_TAG, "DrawArraysInstanced", options.isDefaultQueue, mode, count, 0, nullptr); + DumpDrawCallInfo(DEBUG_TAG, "DrawArraysInstanced", options.isDefaultQueue(), mode, count, 0, nullptr); } TR_OPENGL_FUNC void OnDrawElementsInstanced(DrawElementsInstancedCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1812,7 +1936,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDrawElementsInstanced(mode, count, type, indices, instanceCount); reqContentRenderer->increaseDrawCallsCount(count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DumpDrawCallInfo(DEBUG_TAG, "DrawElementsInstanced", options.isDefaultQueue, mode, count, type, indices); + DumpDrawCallInfo(DEBUG_TAG, "DrawElementsInstanced", options.isDefaultQueue(), mode, count, type, indices); } TR_OPENGL_FUNC void OnDrawRangeElements(DrawRangeElementsCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1829,7 +1953,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDrawRangeElements(mode, start, end, count, type, indices); reqContentRenderer->increaseDrawCallsCount(count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DumpDrawCallInfo(DEBUG_TAG, "DrawRangeElements", options.isDefaultQueue, mode, count, type, indices); + DumpDrawCallInfo(DEBUG_TAG, "DrawRangeElements", options.isDefaultQueue(), mode, count, type, indices); } TR_OPENGL_FUNC void OnHint(HintCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1837,13 +1961,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto mode = req->mode; glHint(target, mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Hint(0x%x, 0x%x)", options.isDefaultQueue, target, mode); + DEBUG(DEBUG_TAG, "[%d] GL::Hint(0x%x, 0x%x)", options.isDefaultQueue(), target, mode); } TR_OPENGL_FUNC void OnLineWidth(LineWidthCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glLineWidth(req->width); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::LineWidth(%f)", options.isDefaultQueue, req->width); + DEBUG(DEBUG_TAG, "[%d] GL::LineWidth(%f)", options.isDefaultQueue(), req->width); } TR_OPENGL_FUNC void OnPixelStorei(PixelStoreiCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1851,24 +1975,23 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto param = req->param; glPixelStorei(pname, param); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::PixelStorei(0x%x, %d)", options.isDefaultQueue, pname, param); + DEBUG(DEBUG_TAG, "[%d] GL::PixelStorei(0x%x, %d)", options.isDefaultQueue(), pname, param); } TR_OPENGL_FUNC void OnPolygonOffset(PolygonOffsetCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glPolygonOffset(req->factor, req->units); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::PolygonOffset(%f, %f)", options.isDefaultQueue, req->factor, req->units); + DEBUG(DEBUG_TAG, "[%d] GL::PolygonOffset(%f, %f)", options.isDefaultQueue(), req->factor, req->units); } TR_OPENGL_FUNC void OnSetViewport(SetViewportCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto width = req->width; - auto height = req->height; auto x = req->x; auto y = req->y; - glViewport(x, y, width, height); - reqContentRenderer->getOpenGLContext()->onViewportChanged(x, y, width, height); + auto width = req->width; + auto height = req->height; + reqContentRenderer->getOpenGLContext()->setViewport(x, y, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::SetViewport(x=%d, y=%d, w=%d, h=%d)", options.isDefaultQueue, x, y, width, height); + DEBUG(DEBUG_TAG, "[%d] GL::SetViewport(x=%d, y=%d, w=%d, h=%d)", options.isDefaultQueue(), x, y, width, height); } TR_OPENGL_FUNC void OnSetScissor(SetScissorCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1876,9 +1999,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto y = req->y; auto width = req->width; auto height = req->height; - glScissor(x, y, width, height); + reqContentRenderer->getOpenGLContext()->setScissor(x, y, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::SetScissor(x=%d, y=%d, w=%d, h=%d)", options.isDefaultQueue, x, y, width, height); + DEBUG(DEBUG_TAG, "[%d] GL::SetScissor(x=%d, y=%d, w=%d, h=%d)", options.isDefaultQueue(), x, y, width, height); } TR_OPENGL_FUNC void OnGetSupportedExtensions(GetExtensionsCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1893,7 +2016,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface res.extensions.push_back(reinterpret_cast(ret)); } if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetSupportedExtensions(): extensions(%d)", options.isDefaultQueue, numOfExtensions); + DEBUG(DEBUG_TAG, "[%d] GL::GetSupportedExtensions(): extensions(%d)", options.isDefaultQueue(), numOfExtensions); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnDepthMask(DepthMaskCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -1901,19 +2024,19 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDepthMask(req->flag); reqContentRenderer->getOpenGLContext()->onSetDepthMask(req->flag); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DepthMask(%d)", options.isDefaultQueue, req->flag); + DEBUG(DEBUG_TAG, "[%d] GL::DepthMask(%d)", options.isDefaultQueue(), req->flag); } TR_OPENGL_FUNC void OnDepthFunc(DepthFuncCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glDepthFunc(req->func); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DepthFunc(%s)", options.isDefaultQueue, gles::glDepthFuncToString(req->func).c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::DepthFunc(%s)", options.isDefaultQueue(), gles::glDepthFuncToString(req->func).c_str()); } TR_OPENGL_FUNC void OnDepthRange(DepthRangeCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glDepthRangef(req->n, req->f); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DepthRange(%f, %f)", options.isDefaultQueue, req->n, req->f); + DEBUG(DEBUG_TAG, "[%d] GL::DepthRange(%f, %f)", options.isDefaultQueue(), req->n, req->f); } TR_OPENGL_FUNC void OnStencilFunc(StencilFuncCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1925,7 +2048,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->onSetStencilFunc(GL_FRONT_AND_BACK, func, ref, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilFunc(%d, %d, %d)", options.isDefaultQueue, func, ref, mask); + DEBUG(DEBUG_TAG, "[%d] GL::StencilFunc(%d, %d, %d)", options.isDefaultQueue(), func, ref, mask); } TR_OPENGL_FUNC void OnStencilFuncSeparate(StencilFuncSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1940,7 +2063,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->onSetStencilFunc(face, func, ref, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilFuncSeparate: %d", options.isDefaultQueue, func); + DEBUG(DEBUG_TAG, "[%d] GL::StencilFuncSeparate: %d", options.isDefaultQueue(), func); } TR_OPENGL_FUNC void OnStencilMask(StencilMaskCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1949,7 +2072,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->onSetStencilMask(GL_FRONT_AND_BACK, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilMask(%d)", options.isDefaultQueue, mask); + DEBUG(DEBUG_TAG, "[%d] GL::StencilMask(%d)", options.isDefaultQueue(), mask); } TR_OPENGL_FUNC void OnStencilMaskSeparate(StencilMaskSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1961,7 +2084,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->onSetStencilMask(face, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilMaskSeparate(%d)", options.isDefaultQueue, mask); + DEBUG(DEBUG_TAG, "[%d] GL::StencilMaskSeparate(%d)", options.isDefaultQueue(), mask); } TR_OPENGL_FUNC void OnStencilOp(StencilOpCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1973,7 +2096,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->onSetStencilOp(GL_FRONT_AND_BACK, fail, zfail, zpass); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilOp(%d, %d, %d)", options.isDefaultQueue, fail, zfail, zpass); + DEBUG(DEBUG_TAG, "[%d] GL::StencilOp(%d, %d, %d)", options.isDefaultQueue(), fail, zfail, zpass); } TR_OPENGL_FUNC void OnStencilOpSeparate(StencilOpSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1988,19 +2111,19 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->onSetStencilOp(face, fail, zfail, zpass); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilOpSeparate(%d)", options.isDefaultQueue, fail); + DEBUG(DEBUG_TAG, "[%d] GL::StencilOpSeparate(%d)", options.isDefaultQueue(), fail); } TR_OPENGL_FUNC void OnBlendColor(BlendColorCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glBlendColor(req->red, req->green, req->blue, req->alpha); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlendColor(%f, %f, %f, %f)", options.isDefaultQueue, req->red, req->green, req->blue, req->alpha); + DEBUG(DEBUG_TAG, "[%d] GL::BlendColor(%f, %f, %f, %f)", options.isDefaultQueue(), req->red, req->green, req->blue, req->alpha); } TR_OPENGL_FUNC void OnBlendEquation(BlendEquationCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glBlendEquation(req->mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlendEquation(%d)", options.isDefaultQueue, req->mode); + DEBUG(DEBUG_TAG, "[%d] GL::BlendEquation(%d)", options.isDefaultQueue(), req->mode); } TR_OPENGL_FUNC void OnBlendEquationSeparate(BlendEquationSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2008,14 +2131,14 @@ class RHI_OpenGL : public TrRenderHardwareInterface { glBlendEquationSeparate(req->modeRGB, req->modeAlpha); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlendEquationSeparate(%d, %d)", options.isDefaultQueue, req->modeRGB, req->modeAlpha); + DEBUG(DEBUG_TAG, "[%d] GL::BlendEquationSeparate(%d, %d)", options.isDefaultQueue(), req->modeRGB, req->modeAlpha); } TR_OPENGL_FUNC void OnBlendFunc(BlendFuncCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glBlendFunc(req->sfactor, req->dfactor); reqContentRenderer->getOpenGLContext()->onSetBlendFunc(req->sfactor, req->dfactor); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlendFunc(%d)", options.isDefaultQueue, req->sfactor); + DEBUG(DEBUG_TAG, "[%d] GL::BlendFunc(%d)", options.isDefaultQueue(), req->sfactor); } TR_OPENGL_FUNC void OnBlendFuncSeparate(BlendFuncSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2031,7 +2154,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::BlendFuncSeparate(%s, %s, %s, %s)", - options.isDefaultQueue, + options.isDefaultQueue(), gles::glBlendFuncToString(srcRGB).c_str(), gles::glBlendFuncToString(dstRGB).c_str(), gles::glBlendFuncToString(srcAlpha).c_str(), @@ -2048,7 +2171,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->onSetColorMask(r, g, b, a); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::ColorMask(%d, %d, %d, %d)", options.isDefaultQueue, r, g, b, a); + DEBUG(DEBUG_TAG, "[%d] GL::ColorMask(%d, %d, %d, %d)", options.isDefaultQueue(), r, g, b, a); } TR_OPENGL_FUNC void OnCullFace(CullFaceCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -2056,7 +2179,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glCullFace(mode); reqContentRenderer->getOpenGLContext()->onSetCullFace(mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CullFace(%s)", options.isDefaultQueue, gles::glEnumToString(mode).c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::CullFace(%s)", options.isDefaultQueue(), gles::glEnumToString(mode).c_str()); } TR_OPENGL_FUNC void OnFrontFace(FrontFaceCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -2064,7 +2187,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glFrontFace(mode); reqContentRenderer->getOpenGLContext()->onSetFrontFace(mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::FrontFace(%s)", options.isDefaultQueue, gles::glEnumToString(mode).c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::FrontFace(%s)", options.isDefaultQueue(), gles::glEnumToString(mode).c_str()); } TR_OPENGL_FUNC void OnEnable(EnableCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -2083,9 +2206,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface cap == GL_SAMPLE_COVERAGE || cap == GL_SCISSOR_TEST || cap == GL_STENCIL_TEST) - DEBUG(DEBUG_TAG, "[%d] GL::Enable(%s)", options.isDefaultQueue, gles::glEnumToString(cap).c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::Enable(%s)", options.isDefaultQueue(), gles::glEnumToString(cap).c_str()); else - DEBUG(DEBUG_TAG, "[%d] GL::Enable(0x%x)", options.isDefaultQueue, cap); + DEBUG(DEBUG_TAG, "[%d] GL::Enable(0x%x)", options.isDefaultQueue(), cap); } } TR_OPENGL_FUNC void OnDisable(DisableCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -2105,45 +2228,53 @@ class RHI_OpenGL : public TrRenderHardwareInterface cap == GL_SAMPLE_COVERAGE || cap == GL_SCISSOR_TEST || cap == GL_STENCIL_TEST) - DEBUG(DEBUG_TAG, "[%d] GL::Disable(%s)", options.isDefaultQueue, gles::glEnumToString(cap).c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::Disable(%s)", options.isDefaultQueue(), gles::glEnumToString(cap).c_str()); else - DEBUG(DEBUG_TAG, "[%d] GL::Disable(0x%x)", options.isDefaultQueue, cap); + DEBUG(DEBUG_TAG, "[%d] GL::Disable(0x%x)", options.isDefaultQueue(), cap); } } - TR_OPENGL_FUNC void OnGetBooleanv(GetBooleanvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnGetBooleanv(GetBooleanvCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { GLboolean value; glGetBooleanv(req->pname, &value); GetBooleanvCommandBufferResponse res(req, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetBooleanv(0x%x) => %d", options.isDefaultQueue, req->pname, res.value); + DEBUG(DEBUG_TAG, "[%d] GL::GetBooleanv(0x%x) => %d", options.isDefaultQueue(), req->pname, res.value); reqContentRenderer->sendCommandBufferResponse(res); } - TR_OPENGL_FUNC void OnGetIntegerv(GetIntegervCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnGetIntegerv(GetIntegervCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { GLint value; glGetIntegerv(req->pname, &value); GetIntegervCommandBufferResponse res(req, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetIntegerv(0x%x) => %d", options.isDefaultQueue, req->pname, res.value); + DEBUG(DEBUG_TAG, "[%d] GL::GetIntegerv(0x%x) => %d", options.isDefaultQueue(), req->pname, res.value); reqContentRenderer->sendCommandBufferResponse(res); } - TR_OPENGL_FUNC void OnGetFloatv(GetFloatvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnGetFloatv(GetFloatvCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { GLfloat value; glGetFloatv(req->pname, &value); GetFloatvCommandBufferResponse res(req, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetFloatv(0x%x) => %f", options.isDefaultQueue, req->pname); + DEBUG(DEBUG_TAG, "[%d] GL::GetFloatv(0x%x) => %f", options.isDefaultQueue(), req->pname); reqContentRenderer->sendCommandBufferResponse(res); } - TR_OPENGL_FUNC void OnGetString(GetStringCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnGetString(GetStringCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { const GLubyte *ret = glGetString(req->pname); // returns null-terminated string string value = reinterpret_cast(ret); GetStringCommandBufferResponse res(req, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetString(0x%x) => %s", options.isDefaultQueue, req->pname, res.value.c_str()); + DEBUG(DEBUG_TAG, "[%d] GL::GetString(0x%x) => %s", options.isDefaultQueue(), req->pname, res.value.c_str()); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnGetShaderPrecisionFormat(GetShaderPrecisionFormatCommandBufferRequest *req, @@ -2161,7 +2292,14 @@ class RHI_OpenGL : public TrRenderHardwareInterface GetShaderPrecisionFormatCommandBufferResponse res(req, range[0], range[1], precision); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::GetShaderPrecisionFormat(0x%x, 0x%x) => (%d, %d, %d)", options.isDefaultQueue, req->shadertype, req->precisiontype, res.rangeMin, res.rangeMax, res.precision); + DEBUG(DEBUG_TAG, + "[%d] GL::GetShaderPrecisionFormat(0x%x, 0x%x) => (%d, %d, %d)", + options.isDefaultQueue(), + req->shadertype, + req->precisiontype, + res.rangeMin, + res.rangeMax, + res.precision); } reqContentRenderer->sendCommandBufferResponse(res); } @@ -2169,7 +2307,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { GetErrorCommandBufferResponse res(req, glGetError()); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetError() => %d", options.isDefaultQueue, res.error); + DEBUG(DEBUG_TAG, "[%d] GL::GetError() => %d", options.isDefaultQueue(), res.error); reqContentRenderer->sendCommandBufferResponse(res); } }; @@ -2294,50 +2432,70 @@ void RHI_OpenGL::DisableGraphicsDebugLog() #endif } -bool RHI_OpenGL::ExecuteCommandBuffer( - vector &commandBuffers, - renderer::TrContentRenderer *contentRenderer, - xr::DeviceFrame *deviceFrame, - bool isDefaultQueue) +bool RHI_OpenGL::ExecuteCommandBuffer(vector &list, + renderer::TrContentRenderer *content_renderer, + xr::DeviceFrame *device_frame, + ExecutingPassType pass_type) { - bool isBufferEmpty = commandBuffers.empty(); - if (isBufferEmpty) - { - if (!isDefaultQueue) // Just skip logging if the queue is the default queue - DEBUG(DEBUG_TAG, "The command buffers is empty, discard this execution"); - return false; - } - - // Execute all the command buffers - contentRenderer->onCommandBuffersExecuting(); - auto contentGlContext = contentRenderer->getOpenGLContext(); - auto contextBaseState = ContextGLApp("tmp", contentGlContext); - ApiCallOptions callOptions; callOptions.printsCall = GetRenderer()->isTracingEnabled; + callOptions.executingPassType = pass_type; - for (auto commandBuffer : commandBuffers) + bool isBufferEmpty = list.empty(); + if (isBufferEmpty) { - assert(commandBuffer != nullptr && "commandBuffer must not be nullptr"); - CommandBufferType commandType = commandBuffer->type; - callOptions.isDefaultQueue = commandBuffer->renderingInfo.isValid() == false; - -#define ADD_COMMAND_BUFFER_HANDLER(commandType, requestType, handlerName) \ - case COMMAND_BUFFER_##commandType##_REQ: \ - { \ - auto cbRequest = dynamic_cast(commandBuffer); \ - if (cbRequest != nullptr) \ - On##handlerName(cbRequest, contentRenderer, callOptions); \ - break; \ + // Just skip logging if the queue is the default queue + if (callOptions.executingPassType == ExecutingPassType::kXRFrame) + DEBUG(DEBUG_TAG, "The command buffers in XRFrame is empty, discard this execution"); + return false; } -#define ADD_COMMAND_BUFFER_HANDLER_WITH_DEVICE_FRAME(commandType, requestType, handlerName) \ + // Execute all the command buffers + content_renderer->onCommandBuffersExecuting(); + ContextGLApp *contentGlContext = content_renderer->getOpenGLContext(); + ContextGLApp contextBaseState = ContextGLApp("tmp", contentGlContext); + + for (auto commandbuffer : list) + { + assert(commandbuffer != nullptr && "command buffer must not be nullptr"); + CommandBufferType commandType = commandbuffer->type; + +#define ADD_COMMAND_BUFFER_HANDLER(commandType, RequestType, handlerName) \ + case COMMAND_BUFFER_##commandType##_REQ: \ + { \ + auto cbRequest = dynamic_cast(commandbuffer); \ + if (cbRequest != nullptr) \ + { \ + if (pass_type == ExecutingPassType::kXRFrame && \ + !contentGlContext->IsDefaultRenderTargetBinding()) \ + { \ + auto copied_commandbuffer = new RequestType(*cbRequest, true); \ + content_renderer->scheduleCommandBufferAtOffscreenPass(copied_commandbuffer); \ + } \ + else \ + { \ + On##handlerName(cbRequest, content_renderer, callOptions); \ + } \ + } \ + break; \ + } + +#define ADD_COMMAND_BUFFER_HANDLER_WITH_DEVICE_FRAME(commandType, RequestType, handlerName) \ case COMMAND_BUFFER_##commandType##_REQ: \ { \ - auto cbRequest = dynamic_cast(commandBuffer); \ + auto cbRequest = dynamic_cast(commandbuffer); \ if (cbRequest != nullptr) \ { \ - On##handlerName(cbRequest, contentRenderer, callOptions, deviceFrame); \ + if (pass_type == ExecutingPassType::kXRFrame && \ + !contentGlContext->IsDefaultRenderTargetBinding()) \ + { \ + auto copied_commandbuffer = new RequestType(*cbRequest, true); \ + content_renderer->scheduleCommandBufferAtOffscreenPass(copied_commandbuffer); \ + } \ + else \ + { \ + On##handlerName(cbRequest, content_renderer, callOptions, device_frame); \ + } \ } \ break; \ } @@ -2480,15 +2638,15 @@ bool RHI_OpenGL::ExecuteCommandBuffer( * JSAR Implementation doesn't support clear commands. */ if (TR_UNLIKELY(callOptions.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Clear(%d): Unsupported", isDefaultQueue, commandType); + DEBUG(DEBUG_TAG, "[%d] GL::Clear(%d): Unsupported", callOptions.isDefaultQueue(), commandType); break; } case COMMAND_BUFFER_METRICS_PAINTING_REQ: { - auto paintingMetricsReq = dynamic_cast(commandBuffer); + auto paintingMetricsReq = dynamic_cast(commandbuffer); if (paintingMetricsReq != nullptr) { - auto content = contentRenderer->getContent(); + auto content = content_renderer->getContent(); auto category = paintingMetricsReq->category; if (category == commandbuffers::MetricsCategory::FirstContentfulPaint) content->reportDocumentEvent(TrDocumentEventType::FCP); @@ -2496,13 +2654,17 @@ bool RHI_OpenGL::ExecuteCommandBuffer( break; } default: - DEBUG(LOG_TAG_ERROR, "[%d] GL::Unknown command type: %s(%d)", isDefaultQueue, commandTypeToStr(commandType).c_str(), commandType); + DEBUG(LOG_TAG_ERROR, + "[%d] GL::Unknown command type: %s(%d)", + callOptions.isDefaultQueue(), + commandTypeToStr(commandType).c_str(), + commandType); break; } } // Fire the content's `onCommandBuffersExecuted` event - contentRenderer->onCommandBuffersExecuted(); + content_renderer->onCommandBuffersExecuted(); if (contentGlContext->IsDirty()) return false; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index f7e4b2885..159da6297 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -144,7 +144,7 @@ namespace renderer auto content = contentRenderer->getContent(); if (content == nullptr || content->disableRendering) [[unlikely]] continue; - contentRenderer->onRenderTexturesRenderPass(); + contentRenderer->onOffscreenRenderPass(); } } glHostContext->restore(); @@ -339,27 +339,29 @@ namespace renderer DEBUG(LOG_TAG_RENDERER, "Renderer watchers has been stopped."); } - bool TrRenderer::executeCommandBuffers(vector &commandBuffers, - TrContentRenderer *contentRenderer) + bool TrRenderer::executeCommandBuffers(vector &list, + TrContentRenderer *content_renderer, + ExecutingPassType pass_type) { - auto xrDevice = constellation->xrDevice.get(); - assert(xrDevice != nullptr); - if (xrDevice->enabled()) + auto xr_device = constellation->xrDevice.get(); + assert(xr_device != nullptr); + + if (xr_device->enabled()) [[likely]] { - if (xrDevice->isRenderedAsMultipass()) + if (xr_device->isRenderedAsMultipass()) { - xr::MultiPassFrame deviceFrame(xrDevice, 0); - return rhi->ExecuteCommandBuffer(commandBuffers, contentRenderer, &deviceFrame, true); + xr::MultiPassFrame device_frame(xr_device, 0); + return rhi->ExecuteCommandBuffer(list, content_renderer, &device_frame, pass_type); } else { - xr::SinglePassFrame deviceFrame(xrDevice, 0); - return rhi->ExecuteCommandBuffer(commandBuffers, contentRenderer, &deviceFrame, true); + xr::SinglePassFrame device_frame(xr_device, 0); + return rhi->ExecuteCommandBuffer(list, content_renderer, &device_frame, pass_type); } } else { - return rhi->ExecuteCommandBuffer(commandBuffers, contentRenderer, nullptr, true); + return rhi->ExecuteCommandBuffer(list, content_renderer, nullptr, pass_type); } } diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index 64bbdda43..226e5c843 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -7,17 +7,18 @@ #include #include -#include "common/classes.hpp" -#include "common/viewport.hpp" -#include "common/ipc.hpp" -#include "common/command_buffers/command_buffers.hpp" -#include "common/frame_request/types.hpp" -#include "common/analytics/perf_counter.hpp" -#include "common/collision/ray.hpp" -#include "xr/device.hpp" +#include +#include +#include +#include +#include +#include +#include +#include #include "./gles/context_storage.hpp" #include "./content_renderer.hpp" +#include "./render_api.hpp" using namespace std; using namespace commandbuffers; @@ -224,7 +225,9 @@ namespace renderer private: void startWatchers(); void stopWatchers(); - bool executeCommandBuffers(vector &commandBuffers, TrContentRenderer *contentRenderer); + bool executeCommandBuffers(vector &list, + TrContentRenderer *, + ExecutingPassType); void calcFps(); public: diff --git a/src/runtime/content.cpp b/src/runtime/content.cpp index 060ad1b60..2ddcd86c8 100644 --- a/src/runtime/content.cpp +++ b/src/runtime/content.cpp @@ -271,10 +271,11 @@ void TrContentRuntime::recvCommandBuffers(WorkerThread &worker, uint32_t timeout } auto contentRenderer = renderer->getContentRenderer(id, contextId); - if (TR_UNLIKELY(contentRenderer == nullptr)) + if (contentRenderer == nullptr) [[unlikely]] { + DEBUG(LOG_TAG_ERROR, "Failed to dispatch command buffer request(%d):", commandBuffer->type); DEBUG(LOG_TAG_ERROR, - "There is no available ContentRenderer for the content(%d) with context(%d)", + " There is no available ContentRenderer for the content(%d) with context(%d)", id, static_cast(contextId)); delete commandBuffer; diff --git a/src/runtime/unity_entry.cpp b/src/runtime/unity_entry.cpp index 0e93aa443..95f817daa 100644 --- a/src/runtime/unity_entry.cpp +++ b/src/runtime/unity_entry.cpp @@ -62,7 +62,7 @@ class UnityEmbedder final : public TrEmbedder deviceType = graphics->GetRenderer(); // set the backend api to the renderer. - RHI* rhi = RHIFactory::CreateRHI(deviceType, constellation.get()); + RHI *rhi = RHIFactory::CreateRHI(deviceType, constellation.get()); assert(rhi != nullptr && "Failed to create RHI for Unity embedder."); /** diff --git a/tests/command_buffers_base.cpp b/tests/command_buffers_base.cpp index 9b71a9562..85f7f0100 100644 --- a/tests/command_buffers_base.cpp +++ b/tests/command_buffers_base.cpp @@ -11,6 +11,14 @@ class FooCommand FooCommand(int a) : a(a) { } + FooCommand(const FooCommand& that, bool clone = false) + : a(that.a) // Copy constructor + { + if (clone) + { + // Perform deep copy if necessary + } + } public: int a; From e4fd6ef99b229384ad9e62f1e6b082c7a5b4c343 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 9 Jul 2025 13:41:24 +0800 Subject: [PATCH 07/27] update --- src/common/command_buffers/details/buffer.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/common/command_buffers/details/buffer.hpp b/src/common/command_buffers/details/buffer.hpp index 3c334d74b..e0bc53f38 100644 --- a/src/common/command_buffers/details/buffer.hpp +++ b/src/common/command_buffers/details/buffer.hpp @@ -124,8 +124,9 @@ namespace commandbuffers { auto dataSegment = message.getSegment(0); auto dataSize = dataSegment->getSize(); - data = malloc(dataSize); - memcpy(data, dataSegment->getData(), dataSize); + this->dataSize = dataSize; + this->data = malloc(dataSize); + memcpy(this->data, dataSegment->getData(), dataSize); } public: @@ -184,8 +185,9 @@ namespace commandbuffers { auto dataSegment = message.getSegment(0); auto dataSize = dataSegment->getSize(); - data = malloc(dataSize); - memcpy(data, dataSegment->getData(), dataSize); + this->dataSize = dataSize; + this->data = malloc(dataSize); + memcpy(this->data, dataSegment->getData(), dataSize); } public: From 44500b729e45b1c0abaf94a7debaead35f102e56 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 9 Jul 2025 23:50:48 +0800 Subject: [PATCH 08/27] update --- src/bindings/webgl/rendering_context-inl.hpp | 71 +++-- src/client/graphics/webgl_context.cpp | 14 +- src/client/graphics/webgl_context.hpp | 4 + src/common/command_buffers/base.hpp | 33 ++- src/common/command_buffers/details/buffer.hpp | 62 ++++- .../command_buffers/details/draw_calls.hpp | 40 +++ .../command_buffers/details/metrics.hpp | 2 +- .../command_buffers/details/program.hpp | 28 ++ src/common/command_buffers/details/shader.hpp | 52 ++++ .../command_buffers/details/texture.hpp | 21 +- .../command_buffers/details/uniforms.hpp | 30 ++ .../details/webgl_context_init.hpp | 32 +++ src/common/command_buffers/shared.cpp | 20 +- .../command_buffers/webgl_constants.hpp | 183 +++++++++++++ src/common/debug.cpp | 63 ++++- src/renderer/content_renderer.cpp | 72 ++--- src/renderer/content_renderer.hpp | 16 +- src/renderer/gles/context_app.cpp | 14 +- src/renderer/gles/context_app.hpp | 2 +- src/renderer/gles/framebuffer_attachment.cpp | 15 +- src/renderer/render_api.hpp | 6 + src/renderer/render_api_metal.mm | 2 +- src/renderer/render_api_opengles.cpp | 258 +++++++++--------- 23 files changed, 799 insertions(+), 241 deletions(-) diff --git a/src/bindings/webgl/rendering_context-inl.hpp b/src/bindings/webgl/rendering_context-inl.hpp index 363d09fe2..027b00974 100644 --- a/src/bindings/webgl/rendering_context-inl.hpp +++ b/src/bindings/webgl/rendering_context-inl.hpp @@ -860,33 +860,62 @@ namespace webgl Napi::TypeError::New(env, "framebufferTexture2D() takes 5 arguments.").ThrowAsJavaScriptException(); return env.Undefined(); } - auto jsTexture = info[3]; - if (!jsTexture.IsObject() || WebGLTexture::IsInstanceOf(jsTexture)) + + auto target = info[0].ToNumber().Int32Value(); + auto attachment = info[1].ToNumber().Int32Value(); + auto textarget = info[2].ToNumber().Int32Value(); + auto level = info[4].ToNumber().Int32Value(); + + if (target != WEBGL_FRAMEBUFFER && + target != WEBGL2_DRAW_FRAMEBUFFER && + target != WEBGL2_READ_FRAMEBUFFER) [[unlikely]] { - glContext_->setError("framebufferTexture2d", client_graphics::WebGLError::kInvalidOperation, "texture isn't 0 or the name of an existing texture object"); + glContext_->setError("framebufferTexture2d", + client_graphics::WebGLError::kInvalidEnum, + "target must be FRAMEBUFFER"); return env.Undefined(); } - auto target = info[0].As().Int32Value(); - auto attachment = info[1].As().Int32Value(); - auto textarget = info[2].As().Int32Value(); - auto texture = Napi::ObjectWrap::Unwrap(jsTexture.As()); - auto level = info[4].As().Int32Value(); - - if (target != WEBGL_FRAMEBUFFER) + Napi::Value jsTexture = info[3]; + WebGLTexture *textureObject = nullptr; + if (jsTexture.IsNumber()) { - glContext_->setError("framebufferTexture2d", client_graphics::WebGLError::kInvalidEnum, "target must be FRAMEBUFFER"); - return env.Undefined(); + // Only the number 0 is allowed to reset the texture binding. + if (jsTexture.ToNumber().Int32Value() != 0) + { + glContext_->setError("framebufferTexture2d", + client_graphics::WebGLError::kInvalidOperation, + "texture must be 0 if it is a number"); + return env.Undefined(); + } + else + { + textureObject = nullptr; + } + } + else if (jsTexture.IsNull()) // `null` means reset framebuffer's texture + { + textureObject = nullptr; + } + else if (jsTexture.IsObject()) + { + if (!WebGLTexture::IsInstanceOf(jsTexture)) + { + glContext_->setError("framebufferTexture2d", + client_graphics::WebGLError::kInvalidOperation, + "texture is not a valid WebGLTexture object."); + return env.Undefined(); + } + else + { + textureObject = Napi::ObjectWrap::Unwrap(jsTexture.ToObject()); + } } - if (textarget != WEBGL_TEXTURE_2D && - textarget != WEBGL_TEXTURE_CUBE_MAP_POSITIVE_X && - textarget != WEBGL_TEXTURE_CUBE_MAP_NEGATIVE_X && - textarget != WEBGL_TEXTURE_CUBE_MAP_POSITIVE_Y && - textarget != WEBGL_TEXTURE_CUBE_MAP_NEGATIVE_Y && - textarget != WEBGL_TEXTURE_CUBE_MAP_POSITIVE_Z && - textarget != WEBGL_TEXTURE_CUBE_MAP_NEGATIVE_Z) + else { - glContext_->setError("framebufferTexture2d", client_graphics::WebGLError::kInvalidEnum, "textarget must be TEXTURE_2D or one of the TEXTURE_CUBE_MAP_* targets"); + glContext_->setError("framebufferTexture2d", + client_graphics::WebGLError::kInvalidOperation, + "texture must be a number, null or a WebGLTexture object"); return env.Undefined(); } @@ -894,7 +923,7 @@ namespace webgl static_cast(target), static_cast(attachment), static_cast(textarget), - texture->handle(), + textureObject != nullptr ? textureObject->handle() : nullptr, level); return env.Undefined(); } diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index 1350f7617..d2946f7c1 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -54,21 +54,23 @@ namespace client_graphics static TrIdGeneratorBase idGen(commandbuffers::MinimumContextId); id = idGen.get(); if (id >= commandbuffers::MinimumContextId + commandbuffers::MaxinumContextsCountPerContent) - throw std::runtime_error("Too many contexts created in the content process."); + throw runtime_error("Too many contexts created in the content process."); auto createReq = CreateWebGLContextRequest(); sendCommandBufferRequestDirectly(createReq, true); - auto sentAt = std::chrono::system_clock::now(); + auto sentAt = chrono::system_clock::now(); auto initCommandBuffer = WebGL1ContextInitCommandBufferRequest(); sendCommandBufferRequest(initCommandBuffer, true); auto resp = recvCommandBufferResponse(COMMAND_BUFFER_WEBGL_CONTEXT_INIT_RES, 3000); - auto respondAt = std::chrono::system_clock::now(); - std::cout << "Received WebGL context response in " << std::chrono::duration_cast(respondAt - sentAt).count() << "ms" << std::endl; - if (resp == nullptr) + if (resp == nullptr) [[unlikely]] throw std::runtime_error("Failed to initialize WebGL context"); + auto respondAt = chrono::system_clock::now(); + cout << "Received `WebGL1Context` response in " << chrono::duration_cast(respondAt - sentAt).count() << "ms" << endl; + cout << resp->toString(" ") << endl; + viewport_ = resp->drawingViewport; maxCombinedTextureImageUnits = resp->maxCombinedTextureImageUnits; maxCubeMapTextureSize = resp->maxCubeMapTextureSize; @@ -491,7 +493,7 @@ namespace client_graphics auto req = FramebufferTexture2DCommandBufferRequest(static_cast(target), static_cast(attachment), static_cast(textarget), - texture->id, + texture != nullptr ? texture->id : 0, level); sendCommandBufferRequest(req); } diff --git a/src/client/graphics/webgl_context.hpp b/src/client/graphics/webgl_context.hpp index 34b618f1d..eda45dd20 100644 --- a/src/client/graphics/webgl_context.hpp +++ b/src/client/graphics/webgl_context.hpp @@ -23,6 +23,10 @@ #include "./webgl_sampler.hpp" #include "./webgl_vertex_array.hpp" +#define WEBGL_DEBUG 1 +// Uncomment to enable WebGL debugging mode. +// #undef WEBGL_DEBUG + namespace client_graphics { enum class WebGLError diff --git a/src/common/command_buffers/base.hpp b/src/common/command_buffers/base.hpp index ca350846f..71e9de878 100644 --- a/src/common/command_buffers/base.hpp +++ b/src/common/command_buffers/base.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "./shared.hpp" #include "../xr/types.hpp" @@ -55,7 +58,7 @@ namespace commandbuffers : TrIpcSerializableBase(type, size) { } - TrCommandBufferBase(const TrCommandBufferBase& that) + TrCommandBufferBase(const TrCommandBufferBase &that) : TrIpcSerializableBase(that.type, that.size) , id(that.id) , contextId(that.contextId) @@ -63,6 +66,12 @@ namespace commandbuffers { } + public: + virtual std::string toString(const char *prefix = "") const + { + return ""; + } + public: /** * The Id of the command buffer. @@ -98,6 +107,14 @@ namespace commandbuffers : TrCommandBufferBase(that) { } + + public: + virtual std::string toString(const char *_ /* ignore prefix in request */ = nullptr) const override + { + std::stringstream ss; + ss << "GL::" << commandTypeToStr(this->type); + return ss.str(); + } }; class TrCommandBufferResponse : public TrCommandBufferBase @@ -115,6 +132,14 @@ namespace commandbuffers { } + public: + virtual std::string toString(const char *prefix = "") const override + { + std::stringstream ss; + ss << prefix << commandTypeToStr(this->type); + return ss.str(); + } + public: int requestId; }; @@ -139,12 +164,6 @@ namespace commandbuffers { } ~TrCommandBufferSimpleRequest() = default; - - public: - inline void print() - { - DEBUG(LOG_TAG_RENDERER, "GL::%s()", commandTypeToStr(Type).c_str()); - } }; /** diff --git a/src/common/command_buffers/details/buffer.hpp b/src/common/command_buffers/details/buffer.hpp index e0bc53f38..b448b6755 100644 --- a/src/common/command_buffers/details/buffer.hpp +++ b/src/common/command_buffers/details/buffer.hpp @@ -2,6 +2,7 @@ #include "../shared.hpp" #include "../base.hpp" +#include "../webgl_constants.hpp" namespace commandbuffers { @@ -257,9 +258,26 @@ namespace commandbuffers { } + // Returns if this bind operation is to switch the framebuffer to default. + bool isBindToDefault() const + { + // TODO(yorkie): We use 0, -1 to indicate the client want's to bind to the app's default render target. + return framebuffer <= 0; + } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << "bindFramebuffer("; + isBindToDefault() + ? ss << "default" + : ss << framebuffer; + ss << ")"; + return ss.str(); + } + public: uint32_t target; - uint32_t framebuffer; + int32_t framebuffer; }; class FramebufferRenderbufferCommandBufferRequest final @@ -286,6 +304,18 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << "attachment=" << WebGLHelper::WebGLFramebufferAttachmentToString(attachment) << ", " + << "renderbuffertarget=" << WebGLHelper::WebGLEnumToString(renderbufferTarget) << ", " + << "renderbuffer=" << renderbuffer + << ")"; + return ss.str(); + } + public: uint32_t target; uint32_t attachment; @@ -318,6 +348,19 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << "attachment=" << WebGLHelper::WebGLFramebufferAttachmentToString(attachment) << ", " + << "textarget=" << WebGLHelper::WebGLEnumToString(textarget) << ", " + << "texture=" << texture << ", " + << "level=" << level + << ")"; + return ss.str(); + } + public: uint32_t target; uint32_t attachment; @@ -384,6 +427,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } + public: uint32_t clientId; }; @@ -456,6 +506,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << internalformat << ", " + << "[" << width << "x" << height << "])"; + return ss.str(); + } + public: uint32_t target; uint32_t internalformat; diff --git a/src/common/command_buffers/details/draw_calls.hpp b/src/common/command_buffers/details/draw_calls.hpp index 7595b15ae..017e457b5 100644 --- a/src/common/command_buffers/details/draw_calls.hpp +++ b/src/common/command_buffers/details/draw_calls.hpp @@ -25,6 +25,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << "GL::DrawArrays(mode=" << mode << ", " + << first << ", " + << count << ")"; + return ss.str(); + } + public: int mode; int first; @@ -54,6 +63,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << "GL::DrawArraysInstanced(mode=" << mode << ", " + << first << ", " + << count << ", " + << instanceCount << ")"; + return ss.str(); + } + public: int mode; int first; @@ -84,6 +103,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << "GL::DrawElements(mode=" << mode << ", " + << count << ", " + << indicesType << ", " + << indicesOffset << ")"; + return ss.str(); + } + public: int mode; int count; @@ -116,6 +145,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << "GL::DrawElementsInstanced(mode=" << mode << ", " + << count << ", " + << indicesType << ", " + << indicesOffset << ", " + << instanceCount << ")"; + return ss.str(); + } + public: int mode; int count; diff --git a/src/common/command_buffers/details/metrics.hpp b/src/common/command_buffers/details/metrics.hpp index e66cc05d2..6a0e14ec6 100644 --- a/src/common/command_buffers/details/metrics.hpp +++ b/src/common/command_buffers/details/metrics.hpp @@ -29,7 +29,7 @@ namespace commandbuffers } public: - inline std::string toString() + inline std::string toString(const char* line_prefix) const override { if (category == MetricsCategory::FirstContentfulPaint) return "FCP"; diff --git a/src/common/command_buffers/details/program.hpp b/src/common/command_buffers/details/program.hpp index 7e8b150ba..660ec232c 100644 --- a/src/common/command_buffers/details/program.hpp +++ b/src/common/command_buffers/details/program.hpp @@ -22,6 +22,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } + public: uint32_t clientId; }; @@ -43,6 +50,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } + public: uint32_t clientId; }; @@ -64,6 +78,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } + public: uint32_t clientId; }; @@ -349,6 +370,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } + public: uint32_t clientId; }; diff --git a/src/common/command_buffers/details/shader.hpp b/src/common/command_buffers/details/shader.hpp index 1580e0e34..5bca1b2d8 100644 --- a/src/common/command_buffers/details/shader.hpp +++ b/src/common/command_buffers/details/shader.hpp @@ -2,6 +2,7 @@ #include "../shared.hpp" #include "../base.hpp" +#include "../webgl_constants.hpp" namespace commandbuffers { @@ -24,6 +25,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << program << ", " + << shader << ")"; + return ss.str(); + } + public: uint32_t program; uint32_t shader; @@ -48,6 +58,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << program << ", " + << shader << ")"; + return ss.str(); + } + public: uint32_t program; uint32_t shader; @@ -72,6 +91,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << clientId << ", " + << WebGLHelper::WebGLEnumToString(shaderType) << ")"; + return ss.str(); + } + public: uint32_t clientId; uint32_t shaderType; @@ -94,6 +122,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << shader << ")"; + return ss.str(); + } + public: uint32_t shader; }; @@ -114,6 +150,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << shader << ")"; + return ss.str(); + } + public: uint32_t shader; }; @@ -158,6 +202,14 @@ namespace commandbuffers { return string(sourceStr, sourceSize); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << shader << ", " + << "TEXT(" << sourceSize << "))"; + return ss.str(); + } public: TrCommandBufferMessage *serialize() override diff --git a/src/common/command_buffers/details/texture.hpp b/src/common/command_buffers/details/texture.hpp index b0e9a3518..5f18180f1 100644 --- a/src/common/command_buffers/details/texture.hpp +++ b/src/common/command_buffers/details/texture.hpp @@ -82,10 +82,22 @@ namespace commandbuffers , level(that.level) , format(that.format) , pixelType(that.pixelType) + , ownPixelsMemory(that.ownPixelsMemory) { if (clone) { - // TODO(yorkie): implement the clone + if (ownPixelsMemory) + { + this->pixelsByteLength = that.pixelsByteLength; + this->pixels = malloc(that.pixelsByteLength); + if (this->pixels != nullptr) [[likely]] + memcpy(this->pixels, that.pixels, this->pixelsByteLength); + } + else + { + this->pixelsByteLength = that.pixelsByteLength; + this->pixels = that.pixels; + } } } virtual ~TextureImageNDCommandBufferRequest() @@ -183,7 +195,7 @@ namespace commandbuffers { pixelsByteLength = pixelsSegment->getSize(); pixels = malloc(pixelsByteLength); - if (pixels != nullptr) + if (pixels != nullptr) [[likely]] { ownPixelsMemory = true; memcpy(pixels, pixelsSegment->getData(), pixelsByteLength); @@ -205,7 +217,7 @@ namespace commandbuffers int level; int format; int pixelType; - bool ownPixelsMemory = false; // if true the pixels memory will be managed by this object. + bool ownPixelsMemory = false; // if `true` the pixels memory will be managed by this object. void *pixels = nullptr; size_t pixelsByteLength = 0; }; @@ -224,6 +236,9 @@ namespace commandbuffers TextureImage2DCommandBufferRequest(const TextureImage2DCommandBufferRequest &that, bool clone = false) : TextureImageNDCommandBufferRequest(that, clone) , internalformat(that.internalformat) + , width(that.width) + , height(that.height) + , border(that.border) { } diff --git a/src/common/command_buffers/details/uniforms.hpp b/src/common/command_buffers/details/uniforms.hpp index c103ea986..6a4417ba4 100644 --- a/src/common/command_buffers/details/uniforms.hpp +++ b/src/common/command_buffers/details/uniforms.hpp @@ -84,6 +84,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << location << "," + << v0 << ")"; + return ss.str(); + } + public: uint32_t location; float v0; @@ -638,6 +647,27 @@ namespace commandbuffers if (valuesSegment != nullptr) values = valuesSegment->toVec(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream values_ss; + if (isComputationGraph()) + { + values_ss << "Placeholder()"; + } + else + { + values_ss << "float[" << values.size() << "]"; + } + + std::stringstream ss; + ss << TrCommandBufferRequest::toString(line_prefix) << "(" + << location << ", " + << "values={" << values_ss.str() << ", " + << "count=" << count() << ", " + << "transpose=" << (transpose ? "Yes" : "No") + << ")"; + return ss.str(); + } public: uint32_t location; diff --git a/src/common/command_buffers/details/webgl_context_init.hpp b/src/common/command_buffers/details/webgl_context_init.hpp index 1e2f0fb02..90fcce643 100644 --- a/src/common/command_buffers/details/webgl_context_init.hpp +++ b/src/common/command_buffers/details/webgl_context_init.hpp @@ -73,6 +73,22 @@ namespace commandbuffers version = message.getSegment(1)->toString(); renderer = message.getSegment(2)->toString(); } + std::string toString(const char* line_prefix = " ") const override + { + std::stringstream ss; + ss << line_prefix << "MAX_COMBINED_TEXTURE_IMAGE_UNITS = " << maxCombinedTextureImageUnits << std::endl + << line_prefix << "MAX_CUBE_MAP_TEXTURE_SIZE = " << maxCubeMapTextureSize << std::endl + << line_prefix << "MAX_FRAGMENT_UNIFORM_VECTORS = " << maxFragmentUniformVectors << std::endl + << line_prefix << "MAX_RENDERBUFFER_SIZE = " << maxRenderbufferSize << std::endl + << line_prefix << "MAX_TEXTURE_IMAGE_UNITS = " << maxTextureImageUnits << std::endl; + if (!vendor.empty()) + ss << line_prefix << "VENDOR = \"" << vendor << "\"" << std::endl; + if (!version.empty()) + ss << line_prefix << "VERSION = \"" << version << "\"" << std::endl; + if (!renderer.empty()) + ss << line_prefix << "RENDERER = \"" << renderer << "\""; + return ss.str(); + } public: TrViewport drawingViewport; @@ -145,6 +161,22 @@ namespace commandbuffers { } + public: + std::string toString(const char* line_prefix) const override + { + std::stringstream ss; + ss << line_prefix << "GL_MAX_3D_TEXTURE_SIZE = " << max3DTextureSize << std::endl + << line_prefix << "GL_MAX_ARRAY_TEXTURE_LAYERS = " << maxArrayTextureLayers << std::endl + << line_prefix << "GL_MAX_COLOR_ATTACHMENTS = " << maxColorAttachments << std::endl + << line_prefix << "GL_MAX_COMBINED_UNIFORM_BLOCKS = " << maxCombinedUniformBlocks << std::endl + << line_prefix << "GL_MAX_DRAW_BUFFERS = " << maxDrawBuffers << std::endl + << line_prefix << "GL_MAX_ELEMENTS_INDICES = " << maxElementsIndices << std::endl + << line_prefix << "GL_MAX_ELEMENTS_VERTICES = " << maxElementsVertices << std::endl + << line_prefix << "EXT_OVR_multiview.MAX_VIEWS_OVR = " << OVR_maxViews << std::endl + << line_prefix << "EXT_texture_filter_anisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT" << maxTextureMaxAnisotropy; + return ss.str(); + } + public: int max3DTextureSize; int maxArrayTextureLayers; diff --git a/src/common/command_buffers/shared.cpp b/src/common/command_buffers/shared.cpp index d53449f01..3f9f2e69b 100644 --- a/src/common/command_buffers/shared.cpp +++ b/src/common/command_buffers/shared.cpp @@ -7,13 +7,25 @@ namespace commandbuffers { switch (type) { -#define XX(commandType, requestType) \ - case COMMAND_BUFFER_##commandType##_REQ: \ - { \ - return #requestType; \ + +// Request +#define XX(COMMAND_TYPE, STR) \ + case COMMAND_BUFFER_##COMMAND_TYPE##_REQ: \ + { \ + return #STR; \ } TR_COMMAND_BUFFER_REQUESTS_MAP(XX) #undef XX + +// Response +#define XX(COMMAND_TYPE, STR) \ + case COMMAND_BUFFER_##COMMAND_TYPE##_RES: \ + { \ + return #STR; \ + } + TR_COMMAND_BUFFER_RESPONSES_MAP(XX) +#undef XX + case COMMAND_BUFFER_UNKNOWN: default: return "Unknown"; diff --git a/src/common/command_buffers/webgl_constants.hpp b/src/common/command_buffers/webgl_constants.hpp index 4217bc35c..2a94c44e3 100644 --- a/src/common/command_buffers/webgl_constants.hpp +++ b/src/common/command_buffers/webgl_constants.hpp @@ -1,5 +1,8 @@ #pragma once +#include +#include + /** * This is a list of constants that are used in the WebGLRenderingContext class. * @@ -792,6 +795,21 @@ const int WEBGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1; const int WEBGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2; const int WEBGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3; const int WEBGL_COLOR_ATTACHMENT0 = 0x8CE0; +const int WEBGL_COLOR_ATTACHMENT1 = 0x8CE1; +const int WEBGL_COLOR_ATTACHMENT2 = 0x8CE2; +const int WEBGL_COLOR_ATTACHMENT3 = 0x8CE3; +const int WEBGL_COLOR_ATTACHMENT4 = 0x8CE4; +const int WEBGL_COLOR_ATTACHMENT5 = 0x8CE5; +const int WEBGL_COLOR_ATTACHMENT6 = 0x8CE6; +const int WEBGL_COLOR_ATTACHMENT7 = 0x8CE7; +const int WEBGL_COLOR_ATTACHMENT8 = 0x8CE8; +const int WEBGL_COLOR_ATTACHMENT9 = 0x8CE9; +const int WEBGL_COLOR_ATTACHMENT10 = 0x8CEA; +const int WEBGL_COLOR_ATTACHMENT11 = 0x8CEB; +const int WEBGL_COLOR_ATTACHMENT12 = 0x8CEC; +const int WEBGL_COLOR_ATTACHMENT13 = 0x8CED; +const int WEBGL_COLOR_ATTACHMENT14 = 0x8CEE; +const int WEBGL_COLOR_ATTACHMENT15 = 0x8CEF; const int WEBGL_DEPTH_ATTACHMENT = 0x8D00; const int WEBGL_STENCIL_ATTACHMENT = 0x8D20; const int WEBGL_DEPTH_STENCIL_ATTACHMENT = 0x821A; @@ -1145,3 +1163,168 @@ const int WEBGL2_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF; * Default value is 1000k. */ const int WEBGL_MAX_COUNT_PER_DRAWCALL = 1000 * 1000; + +/** + * This class `WebGLHelper` provides the static helpers. + */ +class WebGLHelper +{ +public: + // Convert a common WebGL enum to string label. + static std::string WebGLEnumToString(int e) + { +#define CASE(x) \ + case x: \ + { \ + return #x; \ + } + + switch (e) + { + // States + CASE(WEBGL_FRONT); + CASE(WEBGL_BACK); + CASE(WEBGL_FRONT_AND_BACK); + CASE(WEBGL_CW); + CASE(WEBGL_CCW); + // Buffer Types + CASE(WEBGL_UNSIGNED_BYTE); + CASE(WEBGL_UNSIGNED_SHORT); + CASE(WEBGL_UNSIGNED_INT); + // Capabilities + CASE(WEBGL_BLEND); + CASE(WEBGL_CULL_FACE); + CASE(WEBGL_DEPTH_TEST); + CASE(WEBGL_DITHER); + CASE(WEBGL_POLYGON_OFFSET_FILL); + CASE(WEBGL2_RASTERIZER_DISCARD); + CASE(WEBGL_SAMPLE_ALPHA_TO_COVERAGE); + CASE(WEBGL_SAMPLE_COVERAGE); + CASE(WEBGL_SCISSOR_TEST); + CASE(WEBGL_STENCIL_TEST); + // Buffer Targets + CASE(WEBGL_ARRAY_BUFFER); + CASE(WEBGL_ELEMENT_ARRAY_BUFFER); + CASE(WEBGL2_PIXEL_PACK_BUFFER); + CASE(WEBGL2_PIXEL_UNPACK_BUFFER); + CASE(WEBGL2_COPY_READ_BUFFER); + CASE(WEBGL2_COPY_WRITE_BUFFER); + CASE(WEBGL2_TRANSFORM_FEEDBACK_BUFFER); + CASE(WEBGL2_UNIFORM_BUFFER); + // Buffer Usage + CASE(WEBGL_STREAM_DRAW); + CASE(WEBGL2_STREAM_READ); + CASE(WEBGL2_STREAM_COPY); + CASE(WEBGL_STATIC_DRAW); + CASE(WEBGL2_STATIC_READ); + CASE(WEBGL2_STATIC_COPY); + CASE(WEBGL_DYNAMIC_DRAW); + CASE(WEBGL2_DYNAMIC_READ); + CASE(WEBGL2_DYNAMIC_COPY); + // Framebuffer Targets + CASE(WEBGL2_DRAW_FRAMEBUFFER); + CASE(WEBGL2_READ_FRAMEBUFFER); + // Binding Targets + CASE(WEBGL_FRAMEBUFFER); + CASE(WEBGL_RENDERBUFFER); + // Draw Modes + CASE(WEBGL_POINTS); + CASE(WEBGL_LINES); + CASE(WEBGL_LINE_LOOP); + CASE(WEBGL_LINE_STRIP); + CASE(WEBGL_TRIANGLES); + CASE(WEBGL_TRIANGLE_STRIP); + CASE(WEBGL_TRIANGLE_FAN); + // Shader Types + CASE(WEBGL_VERTEX_SHADER); + CASE(WEBGL_FRAGMENT_SHADER); + // Texture Targets + CASE(WEBGL_TEXTURE_2D); + CASE(WEBGL2_TEXTURE_3D); + CASE(WEBGL_TEXTURE_CUBE_MAP); + CASE(WEBGL_TEXTURE_CUBE_MAP_POSITIVE_X); + CASE(WEBGL_TEXTURE_CUBE_MAP_NEGATIVE_X); + CASE(WEBGL_TEXTURE_CUBE_MAP_POSITIVE_Y); + CASE(WEBGL_TEXTURE_CUBE_MAP_NEGATIVE_Y); + CASE(WEBGL_TEXTURE_CUBE_MAP_POSITIVE_Z); + CASE(WEBGL_TEXTURE_CUBE_MAP_NEGATIVE_Z); + CASE(WEBGL2_TEXTURE_2D_ARRAY); + // Texture Units + CASE(WEBGL_TEXTURE0); + CASE(WEBGL_TEXTURE1); + CASE(WEBGL_TEXTURE2); + CASE(WEBGL_TEXTURE3); + CASE(WEBGL_TEXTURE4); + CASE(WEBGL_TEXTURE5); + CASE(WEBGL_TEXTURE6); + CASE(WEBGL_TEXTURE7); + CASE(WEBGL_TEXTURE8); + CASE(WEBGL_TEXTURE9); + CASE(WEBGL_TEXTURE10); + CASE(WEBGL_TEXTURE11); + CASE(WEBGL_TEXTURE12); + CASE(WEBGL_TEXTURE13); + CASE(WEBGL_TEXTURE14); + CASE(WEBGL_TEXTURE15); + CASE(WEBGL_TEXTURE16); + CASE(WEBGL_TEXTURE17); + CASE(WEBGL_TEXTURE18); + CASE(WEBGL_TEXTURE19); + CASE(WEBGL_TEXTURE20); + CASE(WEBGL_TEXTURE21); + CASE(WEBGL_TEXTURE22); + CASE(WEBGL_TEXTURE23); + CASE(WEBGL_TEXTURE24); + CASE(WEBGL_TEXTURE25); + CASE(WEBGL_TEXTURE26); + CASE(WEBGL_TEXTURE27); + CASE(WEBGL_TEXTURE28); + CASE(WEBGL_TEXTURE29); + CASE(WEBGL_TEXTURE30); + CASE(WEBGL_TEXTURE31); + default: + std::stringstream ss; + ss << "0x" << std::hex << e; + return ss.str(); + } +#undef CASE + } + + // Convert a WebGL framebuffer attachment to string label. + static std::string WebGLFramebufferAttachmentToString(int attachment) + { +#define CASE(x) \ + case x: \ + { \ + return #x; \ + } + switch (attachment) + { + // Framebuffer Attachments + CASE(WEBGL_COLOR_ATTACHMENT0); + CASE(WEBGL_COLOR_ATTACHMENT1); + CASE(WEBGL_COLOR_ATTACHMENT2); + CASE(WEBGL_COLOR_ATTACHMENT3); + CASE(WEBGL_COLOR_ATTACHMENT4); + CASE(WEBGL_COLOR_ATTACHMENT5); + CASE(WEBGL_COLOR_ATTACHMENT6); + CASE(WEBGL_COLOR_ATTACHMENT7); + CASE(WEBGL_COLOR_ATTACHMENT8); + CASE(WEBGL_COLOR_ATTACHMENT9); + CASE(WEBGL_COLOR_ATTACHMENT10); + CASE(WEBGL_COLOR_ATTACHMENT11); + CASE(WEBGL_COLOR_ATTACHMENT12); + CASE(WEBGL_COLOR_ATTACHMENT13); + CASE(WEBGL_COLOR_ATTACHMENT14); + CASE(WEBGL_COLOR_ATTACHMENT15); + CASE(WEBGL_DEPTH_ATTACHMENT); + CASE(WEBGL_STENCIL_ATTACHMENT); + CASE(WEBGL_DEPTH_STENCIL_ATTACHMENT); + default: + std::stringstream ss; + ss << "0x" << std::hex << attachment; + return ss.str(); + } +#undef CASE + } +}; diff --git a/src/common/debug.cpp b/src/common/debug.cpp index 1c90c70ca..660a2403f 100644 --- a/src/common/debug.cpp +++ b/src/common/debug.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "debug.hpp" @@ -25,6 +26,7 @@ #endif #endif + #ifndef TRANSMUTE_STANDALONE void SET_UNITY_LOG_HANDLE(IUnityLog *log) { @@ -36,17 +38,17 @@ IUnityLog *GET_UNITY_LOG_HANDLE() } #endif +using namespace std; using system_clock = std::chrono::system_clock; using milliseconds = std::chrono::milliseconds; -inline std::string -fetchTimestamp() +inline string fetchTimestamp() { using namespace std::chrono; auto now = system_clock::now(); auto now_c = system_clock::to_time_t(now); - auto ms = std::chrono::duration_cast(now.time_since_epoch()) % 1000; + auto ms = duration_cast(now.time_since_epoch()) % 1000; struct tm tm_info; localtime_r(&now_c, &tm_info); @@ -54,7 +56,7 @@ fetchTimestamp() char timestamp[32]; strftime(timestamp, sizeof(timestamp), "%m-%d %H:%M:%S", &tm_info); snprintf(timestamp + 14, sizeof(timestamp) - 14, ".%03d", static_cast(ms.count())); - return std::string(timestamp); + return string(timestamp); } namespace stylized_shell @@ -107,10 +109,24 @@ namespace stylized_shell void DEBUG(const char *tag, const char *format, ...) { va_list args; - va_start(args, format); + #ifdef __ANDROID__ + va_start(args, format); __android_log_vprint(ANDROID_LOG_DEBUG, tag, format, args); + va_end(args); #else + va_start(args, format); + int out_len = vsnprintf(nullptr, 0, format, args); + va_end(args); + + if (out_len < 0) [[unlikely]] + return; + + vector out_buf(out_len + 1); + va_start(args, format); + vsnprintf(out_buf.data(), out_buf.size(), format, args); + va_end(args); + FILE *stream = stdout; bool stylized = false; if (strcmp(tag, LOG_TAG_ERROR) == 0) @@ -119,13 +135,40 @@ void DEBUG(const char *tag, const char *format, ...) stylized = true; } - stylized_shell::start(stream, stylized, stylized_shell::Style::kDefault, stylized_shell::TextColor::kRed); - fprintf(stream, "%s ", fetchTimestamp().c_str()); - vfprintf(stream, format, args); - fprintf(stream, "\n"); + stylized_shell::start(stream, + stylized, + stylized_shell::Style::kDefault, + stylized_shell::TextColor::kRed); + { + string timestamp = fetchTimestamp(); + const char *p = out_buf.data(); + bool is_new_line = true; + + while (*p != '\0') + { + if (is_new_line) + { + fprintf(stream, "%s ", timestamp.c_str()); + is_new_line = false; + } + + if (*p == '\n') + { + fputc('\n', stream); + is_new_line = true; + } + else + { + fputc(*p, stream); + } + p++; + } + + if (!is_new_line) + fputc('\n', stream); + } stylized_shell::end(stream, stylized); #endif - va_end(args); } void SET_THREAD_NAME(const std::string &name) diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index ab02e7dfd..53301c3e2 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -89,12 +89,16 @@ namespace renderer void TrContentRenderer::onCommandBuffersExecuted() { - auto contentRef = getContent(); - contentRef->onCommandBuffersExecuted(); - if (lastFrameHasOutOfMemoryError || lastFrameErrorsCount > 20) + getContent()->onCommandBuffersExecuted(); + + // FIXME(yorkie): dispose this content once there is OOM or too many(>=20) graphic errors in a frame. + if (lastFrameHasOutOfMemoryError || lastFrameErrorsCount > 20) [[unlikely]] { - DEBUG(LOG_TAG_ERROR, "Disposing the content(%d) due to the frame OOM or occurred errors(%d) > 10", contentRef->id, lastFrameErrorsCount); - contentRef->dispose(); + DEBUG(LOG_TAG_ERROR, + "Disposing the content(%d) due to the frame OOM or occurred errors(%d) > 10", + getContent()->id, + lastFrameErrorsCount); + getContent()->dispose(); } } @@ -229,16 +233,6 @@ namespace renderer // Check and initialize the graphics contexts on host frame. initializeGraphicsContextsOnce(); - /** - * Update the pending stereo frames count for each WebXR session if the WebXR device is enabled. - */ - if (xrDevice->enabled()) - { - auto pendingStereoFramesCount = getPendingStereoFramesCount(); - for (auto session : getContent()->getXRSessions()) - session->setPendingStereoFramesCount(pendingStereoFramesCount); - } - /** * Execute the content's command buffers. */ @@ -318,6 +312,11 @@ namespace renderer { if (commandBuffersOnOffscreenPass.size() > 0) { + if (usingProgramOnOffscreenPassStarted.has_value()) + glUseProgram(usingProgramOnOffscreenPassStarted.value()); + if (bindingVaoOnOffscreenPassStarted.has_value()) + glBindVertexArray(bindingVaoOnOffscreenPassStarted.value()); + constellation->renderer->executeCommandBuffers(commandBuffersOnOffscreenPass, this, ExecutingPassType::kOffscreenPass); @@ -326,7 +325,10 @@ namespace renderer if (commandbuffer != nullptr) [[likely]] delete commandbuffer; } + commandBuffersOnOffscreenPass.clear(); + usingProgramOnOffscreenPassStarted = nullopt; + bindingVaoOnOffscreenPassStarted = nullopt; } } @@ -334,6 +336,15 @@ namespace renderer { frameStartTime = chrono::system_clock::now(); + // Update the pending stereo frames count for each WebXR session if the WebXR device is enabled. + if (xrDevice->enabled()) [[likely]] + { + size_t pendings = getPendingStereoFramesCount(); + for (auto session : getContent()->getXRSessions()) + session->setPendingStereoFramesCount(pendings); + } + + // ContextApp: onStart glContext->onFrameWillStart(constellation->renderer->glHostContext); if (constellation->renderer->isAppContextSummaryEnabled) glContext->print(); @@ -354,7 +365,7 @@ namespace renderer void TrContentRenderer::initializeGraphicsContextsOnce() { - if (TR_LIKELY(isGraphicsContextsInitialized)) + if (isGraphicsContextsInitialized) [[likely]] return; auto idStrBase = GetContentRendererId(getContent(), contextId); @@ -394,15 +405,12 @@ namespace renderer return; unique_lock lock(commandBufferRequestsMutex); - auto exec_commandbuffers = [this](int _, vector &list) - { - return constellation->renderer->executeCommandBuffers(list, this, ExecutingPassType::kXRFrame); - }; - executeStereoFrame(viewIndex, exec_commandbuffers); + executeStereoFrame(viewIndex); } - bool TrContentRenderer::executeStereoFrame(int viewIndex, function &)> exec) + bool TrContentRenderer::executeStereoFrame(int viewIndex) { + auto renderer = constellation->renderer; bool called = false; for (auto it = stereoFramesList.begin(); it != stereoFramesList.end();) { @@ -428,8 +436,8 @@ namespace renderer viewIndex == 0 || (viewIndex == 1 && frame->ended(0))) { - auto &commandBuffers = frame->getCommandBuffers(viewIndex); - exec(frame->getId(), commandBuffers); + auto &list = frame->getCommandBuffers(viewIndex); + renderer->executeCommandBuffers(list, this, ExecutingPassType::kXRFrame); frame->clearCommandBuffers(viewIndex); frame->resetFlush(viewIndex); } @@ -467,9 +475,8 @@ namespace renderer continue; } - auto id = frame->getId(); - auto commandBuffers = frame->getCommandBuffers(viewIndex); - auto isStateChanged = exec(id, commandBuffers); + auto &list = frame->getCommandBuffers(viewIndex); + bool isStateChanged = renderer->executeCommandBuffers(list, this, ExecutingPassType::kXRFrame); frame->idempotent(viewIndex, !isStateChanged); frame->finishPass(viewIndex); @@ -515,18 +522,17 @@ namespace renderer // When the `called` is false, it means the current frames are not ended, so we need to render by the last frame. if (called == false) - executeBackupFrame(viewIndex, exec); + executeBackupFrame(viewIndex); return called; } - void TrContentRenderer::executeBackupFrame(int viewIndex, - function &)> exec) + void TrContentRenderer::executeBackupFrame(int viewIndex) { - auto &commandBufferInLastFrame = stereoFrameForBackup->getCommandBuffers(viewIndex); - if (commandBufferInLastFrame.size() > 0) + auto &list = stereoFrameForBackup->getCommandBuffers(viewIndex); + if (list.size() > 0) { TrBackupGLContextScope contextScopeForBackup(this); - exec(stereoFrameForBackup->getId(), commandBufferInLastFrame); + constellation->renderer->executeCommandBuffers(list, this, ExecutingPassType::kCachedXRFrame); } } diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index bc0b404c4..7e2ea669c 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -105,6 +105,14 @@ namespace renderer */ void scheduleCommandBufferAtOffscreenPass(TrCommandBufferBase *req) { + if (req == nullptr) [[unlikely]] + return; + + if (commandBuffersOnOffscreenPass.size() == 0) + { + usingProgramOnOffscreenPassStarted = glContext->program(); + bindingVaoOnOffscreenPassStarted = glContext->vertexArrayObject(); + } commandBuffersOnOffscreenPass.push_back(req); } @@ -155,15 +163,15 @@ namespace renderer * is called in the render thread which is allowed to use the graphics APIs. */ void initializeGraphicsContextsOnce(); - + // Executes the command buffers at the default frame void executeCommandBuffersAtDefaultFrame(); void executeCommandBuffersAtOffscreenPass(); // Executes the command buffers at the XR frame with the view index. void executeCommandBuffersAtXRFrame(int viewIndex); - bool executeStereoFrame(int viewIndex, std::function &)> exec); - void executeBackupFrame(int viewIndex, std::function &)> exec); + bool executeStereoFrame(int viewIndex); + void executeBackupFrame(int viewIndex); size_t getPendingStereoFramesCount(); public: @@ -190,6 +198,8 @@ namespace renderer // The recorded command buffers which render to other render textures, such as shadow maps, reflection maps, etc. // TODO(yorkie): support multi-stage offscreen pass? std::vector commandBuffersOnOffscreenPass; + std::optional usingProgramOnOffscreenPassStarted; + std::optional bindingVaoOnOffscreenPassStarted; std::vector stereoFramesList; std::unique_ptr stereoFrameForBackup = nullptr; diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index b4285f23d..024b8bd53 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -336,15 +336,16 @@ void ContextGLApp::useProgram(uint32_t id, GLuint &program) onProgramChanged(program); } -void ContextGLApp::bindFramebuffer(GLenum target, uint32_t id, GLuint &framebuffer) +void ContextGLApp::bindFramebuffer(GLenum target, optional id, GLuint &framebuffer) { - /** - * TODO(yorkie): Now we use 0 or -1 to indicate the default render target, should we use enum instead? - */ - if (id == 0 || id == -1) + if (!id.has_value()) + { framebuffer = currentDefaultRenderTarget(); + } else - framebuffer = ObjectManagerRef().FindFramebuffer(id); + { + framebuffer = ObjectManagerRef().FindFramebuffer(id.value()); + } glBindFramebuffer(target, framebuffer); onFramebufferChanged(framebuffer); @@ -447,6 +448,7 @@ bool ContextGLApp::IsDefaultRenderTargetBinding() const { return !m_FramebufferId.has_value() || m_FramebufferId == m_CurrentDefaultRenderTarget; + return true; } renderer::TrContentRenderer &ContextGLApp::contentRendererChecked() const diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index fe7a15662..9891094ab 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -62,7 +62,7 @@ class ContextGLApp : public ContextGLStorage void useProgram(uint32_t id, GLuint &program); // Framebuffer functions - void bindFramebuffer(GLenum target, uint32_t id, GLuint &framebuffer); + void bindFramebuffer(GLenum target, std::optional id, GLuint &framebuffer); // Draw functions void drawArrays(GLenum mode, GLint first, GLsizei count); diff --git a/src/renderer/gles/framebuffer_attachment.cpp b/src/renderer/gles/framebuffer_attachment.cpp index 0242458dc..5f7ed5456 100644 --- a/src/renderer/gles/framebuffer_attachment.cpp +++ b/src/renderer/gles/framebuffer_attachment.cpp @@ -85,8 +85,6 @@ unique_ptr GLFramebufferAttachment::FromCurrent(GLenum GLint is_texture_array = 0; glBindTexture(GL_TEXTURE_2D_ARRAY, attachment_texture); glGetTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_DEPTH, &is_texture_array); - glGetTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_WIDTH, &attachment_object->width_); - glGetTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_HEIGHT, &attachment_object->height_); if (is_texture_array > 0) { @@ -99,12 +97,13 @@ unique_ptr GLFramebufferAttachment::FromCurrent(GLenum : GL_TEXTURE_2D; } - glGetTexLevelParameteriv(attachment_object->texture_target_, - 0, - GL_TEXTURE_INTERNAL_FORMAT, - &attachment_object->texture_internal_format_); + GLenum textarget = attachment_object->texture_target_; + glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_WIDTH, &attachment_object->width_); + glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_HEIGHT, &attachment_object->height_); + glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &attachment_object->texture_internal_format_); glBindTexture(GL_TEXTURE_2D_ARRAY, current_texture_binding); + glGetError(); // Clear any errors from the previous call } else if (attachment_type == GL_NONE) { @@ -120,7 +119,7 @@ void GLFramebufferAttachment::print(const char *prefix) const { if (isTexture()) DEBUG(LOG_TAG_RENDERER, - " [%s]: FramebufferAttachment(Texture(%u, %s, [%dx%d], %s), multiview(%s, base=%d), samples(%d))", + "%s: FramebufferAttachment(Texture(%u, %s, [%dx%d], %s), multiview(%s, base=%d), samples(%d))", prefix, id_, gles::glTextureTargetToString(texture_target_).c_str(), @@ -132,7 +131,7 @@ void GLFramebufferAttachment::print(const char *prefix) const samples_); else if (isRenderbuffer()) DEBUG(LOG_TAG_RENDERER, - " [%s]: FramebufferAttachment(Renderbuffer(%u, [%dx%d]), samples(%d))", + "%s: FramebufferAttachment(Renderbuffer(%u, [%dx%d]), samples(%d))", prefix, id_, width_, diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index aa34e829c..330ad314e 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -33,6 +33,7 @@ enum class ExecutingPassType kDefaultFrame, // The command buffers in XRFrame is commonly used to dispatch draw calls in each rendering frame. kXRFrame, + kCachedXRFrame, kOffscreenPass, }; @@ -93,6 +94,11 @@ class TrRenderHardwareInterface friend class RHIFactory; public: + TrRenderHardwareInterface(RHIBackendType backend_type, std::unique_ptr gpu_device = nullptr) + : backendType(backend_type) + , gpuDevice(std::move(gpu_device)) + { + } virtual ~TrRenderHardwareInterface() = default; /** diff --git a/src/renderer/render_api_metal.mm b/src/renderer/render_api_metal.mm index c6b8ed40d..0207386af 100644 --- a/src/renderer/render_api_metal.mm +++ b/src/renderer/render_api_metal.mm @@ -135,7 +135,7 @@ bool ExecuteCommandBuffer( static Class MTLDepthStencilDescriptorClass; // const int kVertexSize = 12 + 4; -RHI_Metal::RHI_Metal() { +RHI_Metal::RHI_Metal() : TrRenderHardwareInterface(RHIBackendType::Metal) { m_VertexDescriptor = [MTLVertexDescriptorClass vertexDescriptor]; } diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 7fa40e736..b06ce61f8 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -9,6 +9,7 @@ #include "gles/common.hpp" #include "gles/context_storage.hpp" +#include "gles/framebuffer.hpp" #include "gles/object_manager.hpp" #include "gles/gpu_device_impl.hpp" @@ -53,9 +54,20 @@ class RHI_OpenGL : public TrRenderHardwareInterface { private: bool m_DebugEnabled = true; + float m_TmpMatrixL[16]; + float m_TmpMatrixR[16]; + float m_TmpMatrices[32]; public: - RHI_OpenGL(RHIBackendType backendType); + RHI_OpenGL(RHIBackendType backend_type) + : TrRenderHardwareInterface(backend_type, make_unique()) + { + memset(m_TmpMatrixL, 0, 16); + memset(m_TmpMatrixR, 0, 16); + memset(m_TmpMatrices, 0, 32); + + OnCreated(); + } ~RHI_OpenGL() { } @@ -123,6 +135,33 @@ class RHI_OpenGL : public TrRenderHardwareInterface } return error; } + void PrintDebugInfo(const TrCommandBufferRequest *request, + const char *result, + const TrCommandBufferResponse *response, + const ApiCallOptions &options) + { + assert(request != nullptr); + + string pass_type = ""; + if (options.executingPassType == ExecutingPassType::kXRFrame) + pass_type = "XR"; + else if (options.executingPassType == ExecutingPassType::kCachedXRFrame) + pass_type = "XR(Cached)"; + else if (options.executingPassType == ExecutingPassType::kOffscreenPass) + pass_type = "OFFSCREEN"; + else + pass_type = "INIT"; + + // Print request line + if (result == nullptr) + DEBUG(DEBUG_TAG, "[%s] %s", pass_type.c_str(), request->toString().c_str()); + else + DEBUG(DEBUG_TAG, "[%s] %s => %s", pass_type.c_str(), request->toString().c_str(), result); + + // Print response lines + if (response != nullptr) + DEBUG(DEBUG_TAG, "%s", response->toString(" " /* use 4 spaces as prefix in response */).c_str()); + } void DumpDrawCallInfo(const char *logTag, string funcName, bool isDefaultQueue, @@ -132,11 +171,8 @@ class RHI_OpenGL : public TrRenderHardwareInterface const GLvoid *indices) { DEBUG(logTag, - "[%d] GL::%s(mode=%s, count=%d, type=%s, indices=%p)", - isDefaultQueue, - funcName.c_str(), + " mode=%s, type=%s, indices=%p)", gles::glEnumToString(mode).c_str(), - count, gles::glEnumToString(type).c_str(), indices); @@ -147,12 +183,19 @@ class RHI_OpenGL : public TrRenderHardwareInterface // Print bond framebuffer { - GLint framebuffer; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer); + GLint binding_fbo; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &binding_fbo); DEBUG(logTag, " Framebuffer: %d (%s)", - framebuffer, + binding_fbo, glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE ? "Complete" : "Incomplete"); + + auto color0 = GLFramebufferAttachment::FromCurrent(GL_COLOR_ATTACHMENT0); + auto depth = GLFramebufferAttachment::FromCurrent(GL_DEPTH_ATTACHMENT); + if (color0 != nullptr) + color0->print(" Color0"); + if (depth != nullptr) + depth->print(" Depth"); } // Print LINK_STATUS, VALIDATE_STATUS @@ -328,22 +371,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface res.version = string((const char *)glGetString(GL_VERSION)); res.renderer = string((const char *)glGetString(GL_RENDERER)); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, "[%d] GL::ContextInit()", options.isDefaultQueue()); - DEBUG(DEBUG_TAG, " MAX_COMBINED_TEXTURE_IMAGE_UNITS = %d", res.maxCombinedTextureImageUnits); - DEBUG(DEBUG_TAG, " MAX_CUBE_MAP_TEXTURE_SIZE = %d", res.maxCubeMapTextureSize); - DEBUG(DEBUG_TAG, " MAX_FRAGMENT_UNIFORM_VECTORS = %d", res.maxFragmentUniformVectors); - DEBUG(DEBUG_TAG, " MAX_RENDERBUFFER_SIZE = %d", res.maxRenderbufferSize); - DEBUG(DEBUG_TAG, " MAX_TEXTURE_IMAGE_UNITS = %d", res.maxTextureImageUnits); - DEBUG(DEBUG_TAG, " MAX_TEXTURE_SIZE = %d", res.maxTextureSize); - DEBUG(DEBUG_TAG, " MAX_VARYING_VECTORS = %d", res.maxVaryingVectors); - DEBUG(DEBUG_TAG, " MAX_VERTEX_ATTRIBS = %d", res.maxVertexAttribs); - DEBUG(DEBUG_TAG, " MAX_VERTEX_TEXTURE_IMAGE_UNITS = %d", res.maxVertexTextureImageUnits); - DEBUG(DEBUG_TAG, " MAX_VERTEX_UNIFORM_VECTORS = %d", res.maxVertexUniformVectors); - DEBUG(DEBUG_TAG, " VENDOR = %s", res.vendor.c_str()); - DEBUG(DEBUG_TAG, " VERSION = %s", res.version.c_str()); - DEBUG(DEBUG_TAG, " RENDERER = %s", res.renderer.c_str()); - } + PrintDebugInfo(req, nullptr, &res, options); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnContext2Init(WebGL2ContextInitCommandBufferRequest *req, @@ -384,23 +412,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glGetFloatv(WEBGL2_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &res.maxTextureMaxAnisotropy); } if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, "[%d] GL::Context2Init()", options.isDefaultQueue()); - DEBUG(DEBUG_TAG, " GL_MAX_3D_TEXTURE_SIZE = %d", res.max3DTextureSize); - DEBUG(DEBUG_TAG, " GL_MAX_ARRAY_TEXTURE_LAYERS = %d", res.maxArrayTextureLayers); - DEBUG(DEBUG_TAG, " GL_MAX_COLOR_ATTACHMENTS = %d", res.maxColorAttachments); - DEBUG(DEBUG_TAG, " GL_MAX_COMBINED_UNIFORM_BLOCKS = %d", res.maxCombinedUniformBlocks); - DEBUG(DEBUG_TAG, " GL_MAX_DRAW_BUFFERS = %d", res.maxDrawBuffers); - DEBUG(DEBUG_TAG, " GL_MAX_ELEMENTS_INDICES = %d", res.maxElementsIndices); - DEBUG(DEBUG_TAG, " GL_MAX_ELEMENTS_VERTICES = %d", res.maxElementsVertices); - DEBUG(DEBUG_TAG, " GL_MAX_FRAGMENT_INPUT_COMPONENTS = %d", res.maxFragmentInputComponents); - DEBUG(DEBUG_TAG, " GL_MAX_FRAGMENT_UNIFORM_BLOCKS = %d", res.maxFragmentUniformBlocks); - DEBUG(DEBUG_TAG, " GL_MAX_FRAGMENT_UNIFORM_COMPONENTS = %d", res.maxFragmentUniformComponents); - DEBUG(DEBUG_TAG, " EXT_OVR_multiview.MAX_VIEWS_OVR = %d", res.OVR_maxViews); - DEBUG(DEBUG_TAG, - " EXT_texture_filter_anisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT = %f", - res.maxTextureMaxAnisotropy); - } + PrintDebugInfo(req, nullptr, &res, options); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnCreateProgram(CreateProgramCommandBufferRequest *req, @@ -409,7 +421,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { GLuint program = reqContentRenderer->getOpenGLContext()->createProgram(req->clientId); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateProgram(%d) => %d", options.isDefaultQueue(), req->clientId, program); + PrintDebugInfo(req, to_string(program).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnDeleteProgram(DeleteProgramCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -418,7 +430,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint program; reqContentRenderer->getOpenGLContext()->deleteProgram(req->clientId, program); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteProgram(%d)", options.isDefaultQueue(), program); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnLinkProgram(LinkProgramCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -538,7 +550,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint program; reqContentRenderer->getOpenGLContext()->useProgram(req->clientId, program); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::UseProgram(%d)", options.isDefaultQueue(), program); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBindAttribLocation(BindAttribLocationCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -605,7 +617,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glAttachShader(program, shader); reqContentRenderer->getOpenGLContext()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::AttachShader(program=%d, shader=%d)", options.isDefaultQueue(), program, shader); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnDetachShader(DetachShaderCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -617,7 +629,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDetachShader(program, shader); reqContentRenderer->getOpenGLContext()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DetachShader(program=%d, shader=%d)", options.isDefaultQueue(), program, shader); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnCreateShader(CreateShaderCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -627,12 +639,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint shader = glObjectManager.CreateShader(req->clientId, req->shaderType); reqContentRenderer->getOpenGLContext()->RecordShaderOnCreated(shader); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, - "[%d] GL::CreateShader(%d, type=%s) => %d", - options.isDefaultQueue(), - req->clientId, - gles::glEnumToString(req->shaderType).c_str(), - shader); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnDeleteShader(DeleteShaderCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -644,7 +651,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->RecordShaderOnDeleted(shader); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteShader(%d)", options.isDefaultQueue(), shader); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnShaderSource(ShaderSourceCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -681,7 +688,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::ShaderSource(%d)", options.isDefaultQueue(), shader); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnCompileShader(CompileShaderCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -744,7 +751,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface } if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CompileShader(%d)", options.isDefaultQueue(), shader); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnGetShaderSource(GetShaderSourceCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -934,12 +941,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto app_context = reqContentRenderer->getOpenGLContext(); GLuint framebuffer; - app_context->bindFramebuffer(req->target, req->framebuffer, framebuffer); - if (!app_context->IsDefaultRenderTargetBinding()) - reqContentRenderer->scheduleCommandBufferAtOffscreenPass(new BindFramebufferCommandBufferRequest(*req)); - + app_context->bindFramebuffer(req->target, + req->isBindToDefault() ? nullopt : make_optional(req->framebuffer), + framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BindFramebuffer(%d)", options.isDefaultQueue(), framebuffer); + PrintDebugInfo(req, to_string(framebuffer).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnFramebufferRenderbuffer(FramebufferRenderbufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -954,16 +960,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, - "[%d] GL::FramebufferRenderbuffer(%s, attachment=%s, renderbuffertarget=%s, renderbuffer(%d))", - options.isDefaultQueue(), - gles::glEnumToString(target).c_str(), - gles::glFramebufferAttachmentToString(attachment).c_str(), - gles::glEnumToString(renderbuffertarget).c_str(), - renderbuffer); - GLint bindingFramebuffer; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bindingFramebuffer); - DEBUG(DEBUG_TAG, " framebuffer: %d", bindingFramebuffer); + PrintDebugInfo(req, nullptr, nullptr, options); + + GLint binding_framebuffer; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &binding_framebuffer); + DEBUG(DEBUG_TAG, " framebuffer: %d", binding_framebuffer); } } TR_OPENGL_FUNC void OnFramebufferTexture2D(FramebufferTexture2DCommandBufferRequest *req, @@ -976,18 +977,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto textarget = req->textarget; auto texture = glObjectManager.FindTexture(req->texture); auto level = req->level; + glFramebufferTexture2D(target, attachment, textarget, texture, level); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, - "[%d] GL::FramebufferTexture2D(0x%x, 0x%x, 0x%x, %d, level=%d)", - options.isDefaultQueue(), - target, - attachment, - textarget, - texture, - level); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnCheckFramebufferStatus(CheckFramebufferStatusCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1007,11 +1000,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint renderbuffer = glObjectManager.CreateRenderbuffer(req->clientId); reqContentRenderer->getOpenGLContext()->RecordRenderbufferOnCreated(renderbuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, - "[%d] GL::CreateRenderbuffer(#%d) => renderbuffer(%d)", - options.isDefaultQueue(), - req->clientId, - renderbuffer); + PrintDebugInfo(req, to_string(renderbuffer).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnDeleteRenderbuffer( DeleteRenderbufferCommandBufferRequest *req, @@ -1053,15 +1042,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto height = req->height; glRenderbufferStorage(target, internalformat, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es3/glRenderbufferStorage") != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, - "[%d] GL::RenderbufferStorage(%s, internal_format=%d, width=%d, height=%d)", - options.isDefaultQueue(), - gles::glEnumToString(target).c_str(), - internalformat, - width, - height); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnReadBuffer(ReadBufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1595,7 +1576,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { auto glContext = reqContentRenderer->getOpenGLContext(); - DEBUG(DEBUG_TAG, "[%d] GL::Uniform1f(%d, %f)", options.isDefaultQueue(), req->location, req->v0); + PrintDebugInfo(req, nullptr, nullptr, options); DEBUG(DEBUG_TAG, " Program: %d", glContext->program()); } } @@ -1792,8 +1773,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface return; } - float *matrixToUse = nullptr; - bool needToFreeMatrix = false; // Set `true` if the matrix allocation is operated. + GLfloat *matrixToUse = nullptr; bool usePlaceholder = false; size_t matrixValuesSize = req->values.size(); @@ -1811,21 +1791,19 @@ class RHI_OpenGL : public TrRenderHardwareInterface { auto matrixL = deviceFrame->computeMatrixByGraph(req->computationGraph4values, activeXRSession->id, 0); auto matrixR = deviceFrame->computeMatrixByGraph(req->computationGraph4values, activeXRSession->id, 1); - matrixToUse = new float[32]; - needToFreeMatrix = true; matrixValuesSize = 32; count = 2; - memcpy(matrixToUse, glm::value_ptr(matrixL), 16 * sizeof(float)); - memcpy(matrixToUse + 16, glm::value_ptr(matrixR), 16 * sizeof(float)); + memcpy(m_TmpMatrices, glm::value_ptr(matrixL), 16 * sizeof(float)); + memcpy(m_TmpMatrices + 16, glm::value_ptr(matrixR), 16 * sizeof(float)); + matrixToUse = m_TmpMatrices; } else { auto matrix = deviceFrame->computeMatrixByGraph(req->computationGraph4values, activeXRSession->id, 0); - matrixToUse = new float[16]; - needToFreeMatrix = true; matrixValuesSize = 16; count = 1; - memcpy(matrixToUse, glm::value_ptr(matrix), 16 * sizeof(float)); + memcpy(m_TmpMatrices, glm::value_ptr(matrix), 16 * sizeof(float)); + matrixToUse = m_TmpMatrices; } usePlaceholder = true; } @@ -1845,17 +1823,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface glUniformMatrix4fv(location, count, transpose, matrixToUse); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - GLint currentProgram; - glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); - DEBUG(DEBUG_TAG, - "[%d] GL::UniformMatrix4fv(%d, values=[%d, use_placeholder=%s], count=%d, transpose=%s)", - options.isDefaultQueue(), - location, - matrixValuesSize, - usePlaceholder ? "true" : "false", - count, - transpose ? "true" : "false"); - DEBUG(DEBUG_TAG, " Program: %d", currentProgram); + PrintDebugInfo(req, nullptr, nullptr, options); + + GLint using_program; + glGetIntegerv(GL_CURRENT_PROGRAM, &using_program); + DEBUG(DEBUG_TAG, " Program: %d", using_program); for (int i = 0; i < count; i++) { float *m = matrixToUse + i * 16; @@ -1866,10 +1838,6 @@ class RHI_OpenGL : public TrRenderHardwareInterface DEBUG(DEBUG_TAG, " %+.3f %+.3f %+.3f %+.3f", m[12], m[13], m[14], m[15]); } } - - // Free the matrix if it is allocated. - if (needToFreeMatrix) - delete[] matrixToUse; } TR_OPENGL_FUNC void OnDrawArrays(DrawArraysCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1879,7 +1847,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->drawArrays(mode, first, count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + { + PrintDebugInfo(req, nullptr, nullptr, options); DumpDrawCallInfo(DEBUG_TAG, "DrawArrays", options.isDefaultQueue(), mode, count, 0, nullptr); + } } TR_OPENGL_FUNC void OnDrawElements(DrawElementsCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1890,7 +1861,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->drawElements(mode, count, type, indices); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + { + PrintDebugInfo(req, nullptr, nullptr, options); DumpDrawCallInfo(DEBUG_TAG, "DrawElements", options.isDefaultQueue(), mode, count, type, indices); + } } TR_OPENGL_FUNC void OnDrawBuffers(DrawBuffersCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1920,7 +1894,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDrawArraysInstanced(mode, first, count, instanceCount); reqContentRenderer->increaseDrawCallsCount(count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + { + PrintDebugInfo(req, nullptr, nullptr, options); DumpDrawCallInfo(DEBUG_TAG, "DrawArraysInstanced", options.isDefaultQueue(), mode, count, 0, nullptr); + } } TR_OPENGL_FUNC void OnDrawElementsInstanced(DrawElementsInstancedCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1936,7 +1913,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDrawElementsInstanced(mode, count, type, indices, instanceCount); reqContentRenderer->increaseDrawCallsCount(count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + { + PrintDebugInfo(req, nullptr, nullptr, options); DumpDrawCallInfo(DEBUG_TAG, "DrawElementsInstanced", options.isDefaultQueue(), mode, count, type, indices); + } } TR_OPENGL_FUNC void OnDrawRangeElements(DrawRangeElementsCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2312,14 +2292,6 @@ class RHI_OpenGL : public TrRenderHardwareInterface } }; -RHI_OpenGL::RHI_OpenGL(RHIBackendType type) -{ - backendType = type; - gpuDevice = unique_ptr(new gles::GPUDeviceImpl()); - - OnCreated(); -} - void RHI_OpenGL::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces *interfaces) { switch (type) @@ -2441,25 +2413,39 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectorisTracingEnabled; callOptions.executingPassType = pass_type; - bool isBufferEmpty = list.empty(); - if (isBufferEmpty) - { - // Just skip logging if the queue is the default queue - if (callOptions.executingPassType == ExecutingPassType::kXRFrame) - DEBUG(DEBUG_TAG, "The command buffers in XRFrame is empty, discard this execution"); + if (list.empty()) return false; - } // Execute all the command buffers content_renderer->onCommandBuffersExecuting(); ContextGLApp *contentGlContext = content_renderer->getOpenGLContext(); ContextGLApp contextBaseState = ContextGLApp("tmp", contentGlContext); + bool should_copy_to_offscreen_pass = false; for (auto commandbuffer : list) { assert(commandbuffer != nullptr && "command buffer must not be nullptr"); CommandBufferType commandType = commandbuffer->type; + if (commandType == COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ) + { + auto req = dynamic_cast(commandbuffer); + assert(req != nullptr); + + if (pass_type == ExecutingPassType::kXRFrame && + (req->target == GL_FRAMEBUFFER || + req->target == GL_DRAW_FRAMEBUFFER)) + { + if (req->isBindToDefault()) // Stop copying commandbuffers into offscreen pass if it is to bind to default. + should_copy_to_offscreen_pass = false; + else + { + GLuint framebuffer = contentGlContext->ObjectManagerRef().FindFramebuffer(req->framebuffer); + should_copy_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); + } + } + } + #define ADD_COMMAND_BUFFER_HANDLER(commandType, RequestType, handlerName) \ case COMMAND_BUFFER_##commandType##_REQ: \ { \ @@ -2467,7 +2453,7 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectorIsDefaultRenderTargetBinding()) \ + should_copy_to_offscreen_pass == true) \ { \ auto copied_commandbuffer = new RequestType(*cbRequest, true); \ content_renderer->scheduleCommandBufferAtOffscreenPass(copied_commandbuffer); \ @@ -2487,7 +2473,7 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectorIsDefaultRenderTargetBinding()) \ + should_copy_to_offscreen_pass == true) \ { \ auto copied_commandbuffer = new RequestType(*cbRequest, true); \ content_renderer->scheduleCommandBufferAtOffscreenPass(copied_commandbuffer); \ From dadcac0f9d938853dd78fae07a72b2b0e43cc09b Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Thu, 10 Jul 2025 14:01:40 +0800 Subject: [PATCH 09/27] update --- src/common/command_buffers/base.hpp | 4 +- src/common/command_buffers/details/buffer.hpp | 147 ++++++++ src/common/command_buffers/details/states.hpp | 220 ++++++++++++ src/common/command_buffers/macros.hpp | 316 +++++++++--------- src/common/command_buffers/receiver.cpp | 4 +- src/common/command_buffers/sender.cpp | 4 +- src/common/command_buffers/shared.cpp | 8 +- src/common/command_buffers/shared.hpp | 4 +- src/renderer/gles/framebuffer_attachment.cpp | 16 +- src/renderer/render_api_opengles.cpp | 104 ++---- src/xr/frame.cpp | 2 +- 11 files changed, 580 insertions(+), 249 deletions(-) diff --git a/src/common/command_buffers/base.hpp b/src/common/command_buffers/base.hpp index 71e9de878..c2f5c3321 100644 --- a/src/common/command_buffers/base.hpp +++ b/src/common/command_buffers/base.hpp @@ -111,9 +111,7 @@ namespace commandbuffers public: virtual std::string toString(const char *_ /* ignore prefix in request */ = nullptr) const override { - std::stringstream ss; - ss << "GL::" << commandTypeToStr(this->type); - return ss.str(); + return commandTypeToStr(this->type); } }; diff --git a/src/common/command_buffers/details/buffer.hpp b/src/common/command_buffers/details/buffer.hpp index b448b6755..bf7769214 100644 --- a/src/common/command_buffers/details/buffer.hpp +++ b/src/common/command_buffers/details/buffer.hpp @@ -22,6 +22,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } + public: uint32_t clientId; }; @@ -42,6 +49,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << buffer << ")"; + return ss.str(); + } + public: uint32_t buffer; }; @@ -64,6 +78,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << buffer + << ")"; + return ss.str(); + } + public: uint32_t target; uint32_t buffer; @@ -129,6 +153,16 @@ namespace commandbuffers this->data = malloc(dataSize); memcpy(this->data, dataSegment->getData(), dataSize); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << "Buffer(" << dataSize << "), " + << usage + << ")"; + return ss.str(); + } public: uint32_t target; @@ -190,6 +224,16 @@ namespace commandbuffers this->data = malloc(dataSize); memcpy(this->data, dataSegment->getData(), dataSize); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << "offset=" << offset << ", " + << "Buffer(" << dataSize << ")" + << ")"; + return ss.str(); + } public: uint32_t target; @@ -214,6 +258,12 @@ namespace commandbuffers , clientId(that.clientId) { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } public: uint32_t clientId; @@ -235,6 +285,12 @@ namespace commandbuffers , framebuffer(that.framebuffer) { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << framebuffer << ")"; + return ss.str(); + } public: uint32_t framebuffer; @@ -386,6 +442,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) + << ")"; + return ss.str(); + } + public: uint32_t target; }; @@ -406,6 +471,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << line_prefix << TrCommandBufferSimpleResponse::toString(line_prefix) << "(" << status << ")"; + return ss.str(); + } + public: uint32_t status; }; @@ -455,6 +527,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << renderbuffer << ")"; + return ss.str(); + } + public: uint32_t renderbuffer; }; @@ -478,6 +557,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << renderbuffer << ")"; + return ss.str(); + } + public: uint32_t target; uint32_t renderbuffer; @@ -540,6 +628,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(mode) << ")"; + return ss.str(); + } + public: uint32_t mode; }; @@ -565,6 +661,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << index << ", " + << buffer << ")"; + return ss.str(); + } + public: uint32_t target; uint32_t index; @@ -596,6 +702,18 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << index << ", " + << buffer << ", " + << offset << ", " + << bufferSize << ")"; + return ss.str(); + } + public: uint32_t target; uint32_t index; @@ -648,6 +766,24 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << srcX0 << ", " + << srcY0 << ", " + << srcX1 << ", " + << srcY1 << ", " + << dstX0 << ", " + << dstY0 << ", " + << dstX1 << ", " + << dstY1 << ", " + << mask << ", " + << filter + << ")"; + return ss.str(); + } + public: uint32_t srcX0; uint32_t srcY0; @@ -691,6 +827,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << samples << ", " + << internalformat << ", " + << "[" << width << "x" << height << "])"; + return ss.str(); + } + public: uint32_t target; uint32_t samples; diff --git a/src/common/command_buffers/details/states.hpp b/src/common/command_buffers/details/states.hpp index 5f45ee8f5..37003e669 100644 --- a/src/common/command_buffers/details/states.hpp +++ b/src/common/command_buffers/details/states.hpp @@ -28,6 +28,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << x << ", " + << y << ", " + << width << ", " + << height << ")"; + return ss.str(); + } + public: int x; int y; @@ -58,6 +69,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << x << ", " + << y << ", " + << width << ", " + << height << ")"; + return ss.str(); + } + public: int x; int y; @@ -83,6 +105,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << target << ", " + << mode << ")"; + return ss.str(); + } + public: int target; int mode; @@ -104,6 +135,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << width << ")"; + return ss.str(); + } + public: float width; }; @@ -126,6 +165,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << pname << ", " + << param << ")"; + return ss.str(); + } + public: int pname; int param; @@ -149,6 +197,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << factor << ", " + << units << ")"; + return ss.str(); + } + public: float factor; float units; @@ -170,6 +227,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << (flag ? "true" : "false") << ")"; + return ss.str(); + } + public: bool flag; }; @@ -190,6 +255,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << func << ")"; + return ss.str(); + } + public: int func; }; @@ -212,6 +284,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << n << ", " + << f << ")"; + return ss.str(); + } + public: float n; float f; @@ -237,6 +318,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << func << ", " + << ref << ", " + << mask << ")"; + return ss.str(); + } + public: int func; int ref; @@ -266,6 +357,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << face << ", " + << func << ", " + << ref << ", " + << mask << ")"; + return ss.str(); + } + public: int face; int func; @@ -290,6 +392,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << mask << ")"; + return ss.str(); + } + public: int mask; }; @@ -313,6 +422,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << face << ", " + << mask << ")"; + return ss.str(); + } + public: int face; int mask; @@ -338,6 +456,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << fail << ", " + << zfail << ", " + << zpass << ")"; + return ss.str(); + } + public: int fail; int zfail; @@ -367,6 +495,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << face << ", " + << fail << ", " + << zfail << ", " + << zpass << ")"; + return ss.str(); + } + public: int face; int fail; @@ -396,6 +535,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << red << ", " + << green << ", " + << blue << ", " + << alpha << ")"; + return ss.str(); + } + public: float red; float green; @@ -419,6 +569,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << mode << ")"; + return ss.str(); + } + public: int mode; }; @@ -442,6 +599,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << modeRGB << ", " + << modeAlpha << ")"; + return ss.str(); + } + public: int modeRGB; int modeAlpha; @@ -465,6 +631,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << sfactor << ", " + << dfactor << ")"; + return ss.str(); + } + public: int sfactor; int dfactor; @@ -493,6 +668,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << srcRGB << ", " + << dstRGB << ", " + << srcAlpha << ", " + << dstAlpha << ")"; + return ss.str(); + } + public: int srcRGB; int dstRGB; @@ -523,6 +709,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << (red ? "true" : "false") << ", " + << (green ? "true" : "false") << ", " + << (blue ? "true" : "false") << ", " + << (alpha ? "true" : "false") << ")"; + return ss.str(); + } + public: bool red; bool green; @@ -546,6 +743,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << mode << ")"; + return ss.str(); + } + public: int mode; }; @@ -566,6 +770,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << mode << ")"; + return ss.str(); + } + public: int mode; }; @@ -587,6 +798,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(cap) + << ")"; + return ss.str(); + } + public: int cap; }; diff --git a/src/common/command_buffers/macros.hpp b/src/common/command_buffers/macros.hpp index 3dc34ae00..43e2c8100 100644 --- a/src/common/command_buffers/macros.hpp +++ b/src/common/command_buffers/macros.hpp @@ -1,161 +1,161 @@ #pragma once -#define TR_COMMAND_BUFFER_REQUESTS_MAP(XX) \ - XX(CREATE_WEBGL_CONTEXT, CreateWebGLContextRequest) \ - XX(REMOVE_WEBGL_CONTEXT, RemoveWebGLContextRequest) \ - XX(WEBGL_CONTEXT_INIT, WebGL1ContextInitCommandBufferRequest) \ - XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferRequest) \ - XX(CREATE_PROGRAM, CreateProgramCommandBufferRequest) \ - XX(DELETE_PROGRAM, DeleteProgramCommandBufferRequest) \ - XX(LINK_PROGRAM, LinkProgramCommandBufferRequest) \ - XX(USE_PROGRAM, UseProgramCommandBufferRequest) \ - XX(BIND_ATTRIB_LOCATION, BindAttribLocationCommandBufferRequest) \ - XX(GET_PROGRAM_PARAM, GetProgramParamCommandBufferRequest) \ - XX(GET_PROGRAM_INFO_LOG, GetProgramInfoLogCommandBufferRequest) \ - XX(ATTACH_SHADER, AttachShaderCommandBufferRequest) \ - XX(DETACH_SHADER, DetachShaderCommandBufferRequest) \ - XX(CREATE_SHADER, CreateShaderCommandBufferRequest) \ - XX(DELETE_SHADER, DeleteShaderCommandBufferRequest) \ - XX(SHADER_SOURCE, ShaderSourceCommandBufferRequest) \ - XX(COMPILE_SHADER, CompileShaderCommandBufferRequest) \ - XX(GET_SHADER_SOURCE, GetShaderSourceCommandBufferRequest) \ - XX(GET_SHADER_PARAM, GetShaderParamCommandBufferRequest) \ - XX(GET_SHADER_INFO_LOG, GetShaderInfoLogCommandBufferRequest) \ - XX(CREATE_BUFFER, CreateBufferCommandBufferRequest) \ - XX(DELETE_BUFFER, DeleteBufferCommandBufferRequest) \ - XX(BIND_BUFFER, BindBufferCommandBufferRequest) \ - XX(BUFFER_DATA, BufferDataCommandBufferRequest) \ - XX(BUFFER_SUB_DATA, BufferSubDataCommandBufferRequest) \ - XX(CREATE_FRAMEBUFFER, CreateFramebufferCommandBufferRequest) \ - XX(DELETE_FRAMEBUFFER, DeleteFramebufferCommandBufferRequest) \ - XX(BIND_FRAMEBUFFER, BindFramebufferCommandBufferRequest) \ - XX(FRAMEBUFFER_RENDERBUFFER, FramebufferRenderbufferCommandBufferRequest) \ - XX(FRAMEBUFFER_TEXTURE2D, FramebufferTexture2DCommandBufferRequest) \ - XX(CHECK_FRAMEBUFFER_STATUS, CheckFramebufferStatusCommandBufferRequest) \ - XX(CREATE_RENDERBUFFER, CreateRenderbufferCommandBufferRequest) \ - XX(DELETE_RENDERBUFFER, DeleteRenderbufferCommandBufferRequest) \ - XX(BIND_RENDERBUFFER, BindRenderbufferCommandBufferRequest) \ - XX(RENDERBUFFER_STORAGE, RenderbufferStorageCommandBufferRequest) \ - XX(READ_BUFFER, ReadBufferCommandBufferRequest) \ - XX(BIND_BUFFER_BASE, BindBufferBaseCommandBufferRequest) \ - XX(BIND_BUFFER_RANGE, BindBufferRangeCommandBufferRequest) \ - XX(BLIT_FRAMEBUFFER, BlitFramebufferCommandBufferRequest) \ - XX(RENDERBUFFER_STORAGE_MULTISAMPLE, RenderbufferStorageMultisampleCommandBufferRequest) \ - XX(CREATE_VERTEX_ARRAY, CreateVertexArrayCommandBufferRequest) \ - XX(DELETE_VERTEX_ARRAY, DeleteVertexArrayCommandBufferRequest) \ - XX(BIND_VERTEX_ARRAY, BindVertexArrayCommandBufferRequest) \ - XX(IS_VERTEX_ARRAY, IsVertexArrayCommandBufferRequest) \ - XX(CREATE_TEXTURE, CreateTextureCommandBufferRequest) \ - XX(DELETE_TEXTURE, DeleteTextureCommandBufferRequest) \ - XX(BIND_TEXTURE, BindTextureCommandBufferRequest) \ - XX(TEXTURE_IMAGE_2D, TextureImage2DCommandBufferRequest) \ - XX(TEXTURE_SUB_IMAGE_2D, TextureSubImage2DCommandBufferRequest) \ - XX(COPY_TEXTURE_IMAGE_2D, CopyTextureImage2DCommandBufferRequest) \ - XX(COPY_TEXTURE_SUB_IMAGE_2D, CopyTextureSubImage2DCommandBufferRequest) \ - XX(TEXTURE_PARAMETERI, TextureParameteriCommandBufferRequest) \ - XX(TEXTURE_PARAMETERF, TextureParameterfCommandBufferRequest) \ - XX(ACTIVE_TEXTURE, ActiveTextureCommandBufferRequest) \ - XX(GENERATE_MIPMAP, GenerateMipmapCommandBufferRequest) \ - XX(TEXTURE_IMAGE_3D, TextureImage3DCommandBufferRequest) \ - XX(TEXTURE_SUB_IMAGE_3D, TextureSubImage3DCommandBufferRequest) \ - XX(TEXTURE_STORAGE_2D, TextureStorage2DCommandBufferRequest) \ - XX(TEXTURE_STORAGE_3D, TextureStorage3DCommandBufferRequest) \ - XX(ENABLE_VERTEX_ATTRIB_ARRAY, EnableVertexAttribArrayCommandBufferRequest) \ - XX(DISABLE_VERTEX_ATTRIB_ARRAY, DisableVertexAttribArrayCommandBufferRequest) \ - XX(VERTEX_ATTRIB_POINTER, VertexAttribPointerCommandBufferRequest) \ - XX(VERTEX_ATTRIB_IPOINTER, VertexAttribIPointerCommandBufferRequest) \ - XX(VERTEX_ATTRIB_DIVISOR, VertexAttribDivisorCommandBufferRequest) \ - XX(UNIFORM_BLOCK_BINDING, UniformBlockBindingCommandBufferRequest) \ - XX(UNIFORM1F, Uniform1fCommandBufferRequest) \ - XX(UNIFORM1FV, Uniform1fvCommandBufferRequest) \ - XX(UNIFORM1I, Uniform1iCommandBufferRequest) \ - XX(UNIFORM1IV, Uniform1ivCommandBufferRequest) \ - XX(UNIFORM2F, Uniform2fCommandBufferRequest) \ - XX(UNIFORM2FV, Uniform2fvCommandBufferRequest) \ - XX(UNIFORM2I, Uniform2iCommandBufferRequest) \ - XX(UNIFORM2IV, Uniform2ivCommandBufferRequest) \ - XX(UNIFORM3F, Uniform3fCommandBufferRequest) \ - XX(UNIFORM3FV, Uniform3fvCommandBufferRequest) \ - XX(UNIFORM3I, Uniform3iCommandBufferRequest) \ - XX(UNIFORM3IV, Uniform3ivCommandBufferRequest) \ - XX(UNIFORM4F, Uniform4fCommandBufferRequest) \ - XX(UNIFORM4FV, Uniform4fvCommandBufferRequest) \ - XX(UNIFORM4I, Uniform4iCommandBufferRequest) \ - XX(UNIFORM4IV, Uniform4ivCommandBufferRequest) \ - XX(UNIFORM_MATRIX2FV, UniformMatrix2fvCommandBufferRequest) \ - XX(UNIFORM_MATRIX3FV, UniformMatrix3fvCommandBufferRequest) \ - XX(UNIFORM_MATRIX4FV, UniformMatrix4fvCommandBufferRequest) \ - XX(DRAW_ARRAYS, DrawArraysCommandBufferRequest) \ - XX(DRAW_ELEMENTS, DrawElementsCommandBufferRequest) \ - XX(DRAW_ARRAYS_INSTANCED, DrawArraysInstancedCommandBufferRequest) \ - XX(DRAW_ELEMENTS_INSTANCED, DrawElementsInstancedCommandBufferRequest) \ - XX(DRAW_RANGE_ELEMENTS, DrawRangeElementsCommandBufferRequest) \ - XX(DRAW_BUFFERS, DrawBuffersCommandBufferRequest) \ - XX(HINT, HintCommandBufferRequest) \ - XX(LINE_WIDTH, LineWidthCommandBufferRequest) \ - XX(PIXEL_STOREI, PixelStoreiCommandBufferRequest) \ - XX(POLYGON_OFFSET, PolygonOffsetCommandBufferRequest) \ - XX(SET_VIEWPORT, SetViewportCommandBufferRequest) \ - XX(SET_SCISSOR, SetScissorCommandBufferRequest) \ - XX(GET_EXTENSIONS, GetExtensionsCommandBufferRequest) \ - XX(CLEAR, ClearCommandBufferRequest) \ - XX(CLEAR_COLOR, ClearColorCommandBufferRequest) \ - XX(CLEAR_DEPTH, ClearDepthCommandBufferRequest) \ - XX(CLEAR_STENCIL, ClearStencilCommandBufferRequest) \ - XX(DEPTH_MASK, DepthMaskCommandBufferRequest) \ - XX(DEPTH_FUNC, DepthFuncCommandBufferRequest) \ - XX(DEPTH_RANGE, DepthRangeCommandBufferRequest) \ - XX(STENCIL_FUNC, StencilFuncCommandBufferRequest) \ - XX(STENCIL_FUNC_SEPARATE, StencilFuncSeparateCommandBufferRequest) \ - XX(STENCIL_MASK, StencilMaskCommandBufferRequest) \ - XX(STENCIL_MASK_SEPARATE, StencilMaskSeparateCommandBufferRequest) \ - XX(STENCIL_OP, StencilOpCommandBufferRequest) \ - XX(STENCIL_OP_SEPARATE, StencilOpSeparateCommandBufferRequest) \ - XX(BLEND_COLOR, BlendColorCommandBufferRequest) \ - XX(BLEND_EQUATION, BlendEquationCommandBufferRequest) \ - XX(BLEND_EQUATION_SEPARATE, BlendEquationSeparateCommandBufferRequest) \ - XX(BLEND_FUNC, BlendFuncCommandBufferRequest) \ - XX(BLEND_FUNC_SEPARATE, BlendFuncSeparateCommandBufferRequest) \ - XX(COLOR_MASK, ColorMaskCommandBufferRequest) \ - XX(CULL_FACE, CullFaceCommandBufferRequest) \ - XX(FRONT_FACE, FrontFaceCommandBufferRequest) \ - XX(ENABLE, EnableCommandBufferRequest) \ - XX(DISABLE, DisableCommandBufferRequest) \ - XX(GET_BOOLEANV, GetBooleanvCommandBufferRequest) \ - XX(GET_INTEGERV, GetIntegervCommandBufferRequest) \ - XX(GET_FLOATV, GetFloatvCommandBufferRequest) \ - XX(GET_STRING, GetStringCommandBufferRequest) \ - XX(GET_SHADER_PRECISION_FORMAT, GetShaderPrecisionFormatCommandBufferRequest) \ - XX(GET_ERROR, GetErrorCommandBufferRequest) \ - XX(CREATE_SAMPLER, CreateSamplerCommandBufferRequest) \ - XX(DELETE_SAMPLER, DeleteSamplerCommandBufferRequest) \ - XX(BIND_SAMPLER, BindSamplerCommandBufferRequest) \ - XX(SAMPLER_PARAMETERI, SamplerParameteriCommandBufferRequest) \ - XX(SAMPLER_PARAMETERF, SamplerParameterfCommandBufferRequest) \ - XX(GET_SAMPLER_PARAMETER, GetSamplerParameterCommandBufferRequest) \ - XX(IS_SAMPLER, IsSamplerCommandBufferRequest) \ - XX(XRFRAME_START, XRFrameStartCommandBufferRequest) \ - XX(XRFRAME_FLUSH, XRFrameFlushCommandBufferRequest) \ - XX(XRFRAME_END, XRFrameEndCommandBufferRequest) \ - XX(METRICS_PAINTING, PaintingMetricsCommandBufferRequest) +#define TR_COMMAND_BUFFER_REQUESTS_MAP(XX) \ + XX(CREATE_WEBGL_CONTEXT, CreateWebGLContextRequest, "GL::CreateContext") \ + XX(REMOVE_WEBGL_CONTEXT, RemoveWebGLContextRequest, "GL::RemoveContext") \ + XX(WEBGL_CONTEXT_INIT, WebGL1ContextInitCommandBufferRequest, "GL::ContextInit") \ + XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferRequest, "GL::ContextInit") \ + XX(CREATE_PROGRAM, CreateProgramCommandBufferRequest, "GL::CreateProgram") \ + XX(DELETE_PROGRAM, DeleteProgramCommandBufferRequest, "GL::DeleteProgram") \ + XX(LINK_PROGRAM, LinkProgramCommandBufferRequest, "GL::LinkProgram") \ + XX(USE_PROGRAM, UseProgramCommandBufferRequest, "GL::UseProgram") \ + XX(BIND_ATTRIB_LOCATION, BindAttribLocationCommandBufferRequest, "GL::BindAttribLocation") \ + XX(GET_PROGRAM_PARAM, GetProgramParamCommandBufferRequest, "GL::GetProgramParam") \ + XX(GET_PROGRAM_INFO_LOG, GetProgramInfoLogCommandBufferRequest, "GL::GetProgramInfoLog") \ + XX(ATTACH_SHADER, AttachShaderCommandBufferRequest, "GL::AttachShader") \ + XX(DETACH_SHADER, DetachShaderCommandBufferRequest, "GL::DetachShader") \ + XX(CREATE_SHADER, CreateShaderCommandBufferRequest, "GL::CreateShader") \ + XX(DELETE_SHADER, DeleteShaderCommandBufferRequest, "GL::DeleteShader") \ + XX(SHADER_SOURCE, ShaderSourceCommandBufferRequest, "GL::ShaderSource") \ + XX(COMPILE_SHADER, CompileShaderCommandBufferRequest, "GL::CompileShader") \ + XX(GET_SHADER_SOURCE, GetShaderSourceCommandBufferRequest, "GL::GetShaderSource") \ + XX(GET_SHADER_PARAM, GetShaderParamCommandBufferRequest, "GL::GetShaderParam") \ + XX(GET_SHADER_INFO_LOG, GetShaderInfoLogCommandBufferRequest, "GL::GetShaderInfoLog") \ + XX(CREATE_BUFFER, CreateBufferCommandBufferRequest, "GL::CreateBuffer") \ + XX(DELETE_BUFFER, DeleteBufferCommandBufferRequest, "GL::DeleteBuffer") \ + XX(BIND_BUFFER, BindBufferCommandBufferRequest, "GL::BindBuffer") \ + XX(BUFFER_DATA, BufferDataCommandBufferRequest, "GL::BufferData") \ + XX(BUFFER_SUB_DATA, BufferSubDataCommandBufferRequest, "GL::BufferSubData") \ + XX(CREATE_FRAMEBUFFER, CreateFramebufferCommandBufferRequest, "GL::CreateFramebuffer") \ + XX(DELETE_FRAMEBUFFER, DeleteFramebufferCommandBufferRequest, "GL::DeleteFramebuffer") \ + XX(BIND_FRAMEBUFFER, BindFramebufferCommandBufferRequest, "GL::BindFramebuffer") \ + XX(FRAMEBUFFER_RENDERBUFFER, FramebufferRenderbufferCommandBufferRequest, "GL::FramebufferRenderbuffer") \ + XX(FRAMEBUFFER_TEXTURE2D, FramebufferTexture2DCommandBufferRequest, "GL::FramebufferTexture2D") \ + XX(CHECK_FRAMEBUFFER_STATUS, CheckFramebufferStatusCommandBufferRequest, "GL::CheckFramebufferStatus") \ + XX(CREATE_RENDERBUFFER, CreateRenderbufferCommandBufferRequest, "GL::CreateRenderbuffer") \ + XX(DELETE_RENDERBUFFER, DeleteRenderbufferCommandBufferRequest, "GL::DeleteRenderbuffer") \ + XX(BIND_RENDERBUFFER, BindRenderbufferCommandBufferRequest, "GL::BindRenderbuffer") \ + XX(RENDERBUFFER_STORAGE, RenderbufferStorageCommandBufferRequest, "GL::RenderbufferStorage") \ + XX(READ_BUFFER, ReadBufferCommandBufferRequest, "GL::ReadBuffer") \ + XX(BIND_BUFFER_BASE, BindBufferBaseCommandBufferRequest, "GL::BindBufferBase") \ + XX(BIND_BUFFER_RANGE, BindBufferRangeCommandBufferRequest, "GL::BindBufferRange") \ + XX(BLIT_FRAMEBUFFER, BlitFramebufferCommandBufferRequest, "GL::BlitFramebuffer") \ + XX(RENDERBUFFER_STORAGE_MULTISAMPLE, RenderbufferStorageMultisampleCommandBufferRequest, "GL::RenderbufferStorageMultisample") \ + XX(CREATE_VERTEX_ARRAY, CreateVertexArrayCommandBufferRequest, "GL::CreateVertexArray") \ + XX(DELETE_VERTEX_ARRAY, DeleteVertexArrayCommandBufferRequest, "GL::DeleteVertexArray") \ + XX(BIND_VERTEX_ARRAY, BindVertexArrayCommandBufferRequest, "GL::BindVertexArray") \ + XX(IS_VERTEX_ARRAY, IsVertexArrayCommandBufferRequest, "GL::IsVertexArray") \ + XX(CREATE_TEXTURE, CreateTextureCommandBufferRequest, "GL::CreateTexture") \ + XX(DELETE_TEXTURE, DeleteTextureCommandBufferRequest, "GL::DeleteTexture") \ + XX(BIND_TEXTURE, BindTextureCommandBufferRequest, "GL::BindTexture") \ + XX(TEXTURE_IMAGE_2D, TextureImage2DCommandBufferRequest, "GL::TextureImage2D") \ + XX(TEXTURE_SUB_IMAGE_2D, TextureSubImage2DCommandBufferRequest, "GL::TextureSubImage2D") \ + XX(COPY_TEXTURE_IMAGE_2D, CopyTextureImage2DCommandBufferRequest, "GL::CopyTextureImage2D") \ + XX(COPY_TEXTURE_SUB_IMAGE_2D, CopyTextureSubImage2DCommandBufferRequest, "GL::CopyTextureSubImage2D") \ + XX(TEXTURE_PARAMETERI, TextureParameteriCommandBufferRequest, "GL::TextureParameteri") \ + XX(TEXTURE_PARAMETERF, TextureParameterfCommandBufferRequest, "GL::TextureParameterf") \ + XX(ACTIVE_TEXTURE, ActiveTextureCommandBufferRequest, "GL::ActiveTexture") \ + XX(GENERATE_MIPMAP, GenerateMipmapCommandBufferRequest, "GL::GenerateMipmap") \ + XX(TEXTURE_IMAGE_3D, TextureImage3DCommandBufferRequest, "GL::TextureImage3D") \ + XX(TEXTURE_SUB_IMAGE_3D, TextureSubImage3DCommandBufferRequest, "GL::TextureSubImage3D") \ + XX(TEXTURE_STORAGE_2D, TextureStorage2DCommandBufferRequest, "GL::TextureStorage2D") \ + XX(TEXTURE_STORAGE_3D, TextureStorage3DCommandBufferRequest, "GL::TextureStorage3D") \ + XX(ENABLE_VERTEX_ATTRIB_ARRAY, EnableVertexAttribArrayCommandBufferRequest, "GL::EnableVertexAttribArray") \ + XX(DISABLE_VERTEX_ATTRIB_ARRAY, DisableVertexAttribArrayCommandBufferRequest, "GL::DisableVertexAttribArray") \ + XX(VERTEX_ATTRIB_POINTER, VertexAttribPointerCommandBufferRequest, "GL::VertexAttribPointer") \ + XX(VERTEX_ATTRIB_IPOINTER, VertexAttribIPointerCommandBufferRequest, "GL::VertexAttribIPointer") \ + XX(VERTEX_ATTRIB_DIVISOR, VertexAttribDivisorCommandBufferRequest, "GL::VertexAttribDivisor") \ + XX(UNIFORM_BLOCK_BINDING, UniformBlockBindingCommandBufferRequest, "GL::UniformBlockBinding") \ + XX(UNIFORM1F, Uniform1fCommandBufferRequest, "GL::Uniform1f") \ + XX(UNIFORM1FV, Uniform1fvCommandBufferRequest, "GL::Uniform1fv") \ + XX(UNIFORM1I, Uniform1iCommandBufferRequest, "GL::Uniform1i") \ + XX(UNIFORM1IV, Uniform1ivCommandBufferRequest, "GL::Uniform1iv") \ + XX(UNIFORM2F, Uniform2fCommandBufferRequest, "GL::Uniform2f") \ + XX(UNIFORM2FV, Uniform2fvCommandBufferRequest, "GL::Uniform2fv") \ + XX(UNIFORM2I, Uniform2iCommandBufferRequest, "GL::Uniform2i") \ + XX(UNIFORM2IV, Uniform2ivCommandBufferRequest, "GL::Uniform2iv") \ + XX(UNIFORM3F, Uniform3fCommandBufferRequest, "GL::Uniform3f") \ + XX(UNIFORM3FV, Uniform3fvCommandBufferRequest, "GL::Uniform3fv") \ + XX(UNIFORM3I, Uniform3iCommandBufferRequest, "GL::Uniform3i") \ + XX(UNIFORM3IV, Uniform3ivCommandBufferRequest, "GL::Uniform3iv") \ + XX(UNIFORM4F, Uniform4fCommandBufferRequest, "GL::Uniform4f") \ + XX(UNIFORM4FV, Uniform4fvCommandBufferRequest, "GL::Uniform4fv") \ + XX(UNIFORM4I, Uniform4iCommandBufferRequest, "GL::Uniform4i") \ + XX(UNIFORM4IV, Uniform4ivCommandBufferRequest, "GL::Uniform4iv") \ + XX(UNIFORM_MATRIX2FV, UniformMatrix2fvCommandBufferRequest, "GL::UniformMatrix2fv") \ + XX(UNIFORM_MATRIX3FV, UniformMatrix3fvCommandBufferRequest, "GL::UniformMatrix3fv") \ + XX(UNIFORM_MATRIX4FV, UniformMatrix4fvCommandBufferRequest, "GL::UniformMatrix4fv") \ + XX(DRAW_ARRAYS, DrawArraysCommandBufferRequest, "GL::DrawArrays") \ + XX(DRAW_ELEMENTS, DrawElementsCommandBufferRequest, "GL::DrawElements") \ + XX(DRAW_ARRAYS_INSTANCED, DrawArraysInstancedCommandBufferRequest, "GL::DrawArraysInstanced") \ + XX(DRAW_ELEMENTS_INSTANCED, DrawElementsInstancedCommandBufferRequest, "GL::DrawElementsInstanced") \ + XX(DRAW_RANGE_ELEMENTS, DrawRangeElementsCommandBufferRequest, "GL::DrawRangeElements") \ + XX(DRAW_BUFFERS, DrawBuffersCommandBufferRequest, "GL::DrawBuffers") \ + XX(HINT, HintCommandBufferRequest, "GL::Hint") \ + XX(LINE_WIDTH, LineWidthCommandBufferRequest, "GL::LineWidth") \ + XX(PIXEL_STOREI, PixelStoreiCommandBufferRequest, "GL::PixelStorei") \ + XX(POLYGON_OFFSET, PolygonOffsetCommandBufferRequest, "GL::PolygonOffset") \ + XX(SET_VIEWPORT, SetViewportCommandBufferRequest, "GL::SetViewport") \ + XX(SET_SCISSOR, SetScissorCommandBufferRequest, "GL::SetScissor") \ + XX(GET_EXTENSIONS, GetExtensionsCommandBufferRequest, "GL::GetExtensions") \ + XX(CLEAR, ClearCommandBufferRequest, "GL::Clear") \ + XX(CLEAR_COLOR, ClearColorCommandBufferRequest, "GL::ClearColor") \ + XX(CLEAR_DEPTH, ClearDepthCommandBufferRequest, "GL::ClearDepth") \ + XX(CLEAR_STENCIL, ClearStencilCommandBufferRequest, "GL::ClearStencil") \ + XX(DEPTH_MASK, DepthMaskCommandBufferRequest, "GL::DepthMask") \ + XX(DEPTH_FUNC, DepthFuncCommandBufferRequest, "GL::DepthFunc") \ + XX(DEPTH_RANGE, DepthRangeCommandBufferRequest, "GL::DepthRange") \ + XX(STENCIL_FUNC, StencilFuncCommandBufferRequest, "GL::StencilFunc") \ + XX(STENCIL_FUNC_SEPARATE, StencilFuncSeparateCommandBufferRequest, "GL::StencilFuncSeparate") \ + XX(STENCIL_MASK, StencilMaskCommandBufferRequest, "GL::StencilMask") \ + XX(STENCIL_MASK_SEPARATE, StencilMaskSeparateCommandBufferRequest, "GL::StencilMaskSeparate") \ + XX(STENCIL_OP, StencilOpCommandBufferRequest, "GL::StencilOp") \ + XX(STENCIL_OP_SEPARATE, StencilOpSeparateCommandBufferRequest, "GL::StencilOpSeparate") \ + XX(BLEND_COLOR, BlendColorCommandBufferRequest, "GL::BlendColor") \ + XX(BLEND_EQUATION, BlendEquationCommandBufferRequest, "GL::BlendEquation") \ + XX(BLEND_EQUATION_SEPARATE, BlendEquationSeparateCommandBufferRequest, "GL::BlendEquationSeparate") \ + XX(BLEND_FUNC, BlendFuncCommandBufferRequest, "GL::BlendFunc") \ + XX(BLEND_FUNC_SEPARATE, BlendFuncSeparateCommandBufferRequest, "GL::BlendFuncSeparate") \ + XX(COLOR_MASK, ColorMaskCommandBufferRequest, "GL::ColorMask") \ + XX(CULL_FACE, CullFaceCommandBufferRequest, "GL::CullFace") \ + XX(FRONT_FACE, FrontFaceCommandBufferRequest, "GL::FrontFace") \ + XX(ENABLE, EnableCommandBufferRequest, "GL::Enable") \ + XX(DISABLE, DisableCommandBufferRequest, "GL::Disable") \ + XX(GET_BOOLEANV, GetBooleanvCommandBufferRequest, "GL::GetBooleanv") \ + XX(GET_INTEGERV, GetIntegervCommandBufferRequest, "GL::GetIntegerv") \ + XX(GET_FLOATV, GetFloatvCommandBufferRequest, "GL::GetFloatv") \ + XX(GET_STRING, GetStringCommandBufferRequest, "GL::GetString") \ + XX(GET_SHADER_PRECISION_FORMAT, GetShaderPrecisionFormatCommandBufferRequest, "GL::GetShaderPrecisionFormat") \ + XX(GET_ERROR, GetErrorCommandBufferRequest, "GL::GetError") \ + XX(CREATE_SAMPLER, CreateSamplerCommandBufferRequest, "GL::CreateSampler") \ + XX(DELETE_SAMPLER, DeleteSamplerCommandBufferRequest, "GL::DeleteSampler") \ + XX(BIND_SAMPLER, BindSamplerCommandBufferRequest, "GL::BindSampler") \ + XX(SAMPLER_PARAMETERI, SamplerParameteriCommandBufferRequest, "GL::SamplerParameteri") \ + XX(SAMPLER_PARAMETERF, SamplerParameterfCommandBufferRequest, "GL::SamplerParameterf") \ + XX(GET_SAMPLER_PARAMETER, GetSamplerParameterCommandBufferRequest, "GL::GetSamplerParameter") \ + XX(IS_SAMPLER, IsSamplerCommandBufferRequest, "GL::IsSampler") \ + XX(XRFRAME_START, XRFrameStartCommandBufferRequest, "XR::FrameStart") \ + XX(XRFRAME_FLUSH, XRFrameFlushCommandBufferRequest, "XR::FrameFlush") \ + XX(XRFRAME_END, XRFrameEndCommandBufferRequest, "XR::FrameEnd") \ + XX(METRICS_PAINTING, PaintingMetricsCommandBufferRequest, "Metrics::Painting") -#define TR_COMMAND_BUFFER_RESPONSES_MAP(XX) \ - XX(WEBGL_CONTEXT_INIT, WebGL1ContextInitCommandBufferResponse) \ - XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferResponse) \ - XX(GET_EXTENSIONS, GetExtensionsCommandBufferResponse) \ - XX(LINK_PROGRAM, LinkProgramCommandBufferResponse) \ - XX(GET_PROGRAM_PARAM, GetProgramParamCommandBufferResponse) \ - XX(GET_PROGRAM_INFO_LOG, GetProgramInfoLogCommandBufferResponse) \ - XX(GET_SHADER_SOURCE, GetShaderSourceCommandBufferResponse) \ - XX(GET_SHADER_PARAM, GetShaderParamCommandBufferResponse) \ - XX(GET_SHADER_INFO_LOG, GetShaderInfoLogCommandBufferResponse) \ - XX(CHECK_FRAMEBUFFER_STATUS, CheckFramebufferStatusCommandBufferResponse) \ - XX(IS_VERTEX_ARRAY, IsVertexArrayCommandBufferResponse) \ - XX(GET_SAMPLER_PARAMETER, GetSamplerParameterCommandBufferResponse) \ - XX(IS_SAMPLER, IsSamplerCommandBufferResponse) \ - XX(GET_BOOLEANV, GetBooleanvCommandBufferResponse) \ - XX(GET_INTEGERV, GetIntegervCommandBufferResponse) \ - XX(GET_FLOATV, GetFloatvCommandBufferResponse) \ - XX(GET_STRING, GetStringCommandBufferResponse) \ - XX(GET_SHADER_PRECISION_FORMAT, GetShaderPrecisionFormatCommandBufferResponse) \ - XX(GET_ERROR, GetErrorCommandBufferResponse) +#define TR_COMMAND_BUFFER_RESPONSES_MAP(XX) \ + XX(WEBGL_CONTEXT_INIT, WebGL1ContextInitCommandBufferResponse, "GL::ContextInit") \ + XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferResponse, "GL::ContextInit") \ + XX(GET_EXTENSIONS, GetExtensionsCommandBufferResponse, "GL::GetExtensions") \ + XX(LINK_PROGRAM, LinkProgramCommandBufferResponse, "GL::LinkProgram") \ + XX(GET_PROGRAM_PARAM, GetProgramParamCommandBufferResponse, "GL::GetProgramParam") \ + XX(GET_PROGRAM_INFO_LOG, GetProgramInfoLogCommandBufferResponse, "GL::GetProgramInfoLog") \ + XX(GET_SHADER_SOURCE, GetShaderSourceCommandBufferResponse, "GL::GetShaderSource") \ + XX(GET_SHADER_PARAM, GetShaderParamCommandBufferResponse, "GL::GetShaderParam") \ + XX(GET_SHADER_INFO_LOG, GetShaderInfoLogCommandBufferResponse, "GL::GetShaderInfoLog") \ + XX(CHECK_FRAMEBUFFER_STATUS, CheckFramebufferStatusCommandBufferResponse, "GL::CheckFramebufferStatus") \ + XX(IS_VERTEX_ARRAY, IsVertexArrayCommandBufferResponse, "GL::IsVertexArray") \ + XX(GET_SAMPLER_PARAMETER, GetSamplerParameterCommandBufferResponse, "GL::GetSamplerParameter") \ + XX(IS_SAMPLER, IsSamplerCommandBufferResponse, "GL::IsSampler") \ + XX(GET_BOOLEANV, GetBooleanvCommandBufferResponse, "GL::GetBooleanv") \ + XX(GET_INTEGERV, GetIntegervCommandBufferResponse, "GL::GetIntegerv") \ + XX(GET_FLOATV, GetFloatvCommandBufferResponse, "GL::GetFloatv") \ + XX(GET_STRING, GetStringCommandBufferResponse, "GL::GetString") \ + XX(GET_SHADER_PRECISION_FORMAT, GetShaderPrecisionFormatCommandBufferResponse, "GL::GetShaderPrecisionFormat") \ + XX(GET_ERROR, GetErrorCommandBufferResponse, "GL::GetError") diff --git a/src/common/command_buffers/receiver.cpp b/src/common/command_buffers/receiver.cpp index 68ea75db3..99f6657ac 100644 --- a/src/common/command_buffers/receiver.cpp +++ b/src/common/command_buffers/receiver.cpp @@ -13,7 +13,7 @@ namespace commandbuffers TrCommandBufferBase *req = nullptr; switch (message.type) { -#define XX(commandType, requestType) \ +#define XX(commandType, requestType, _) \ case COMMAND_BUFFER_##commandType##_REQ: \ { \ req = TrCommandBufferBase::CreateFromMessage(message); \ @@ -37,7 +37,7 @@ namespace commandbuffers TrCommandBufferResponse *resp = nullptr; switch (message.type) { -#define XX(commandType, responseType) \ +#define XX(commandType, responseType, _) \ case COMMAND_BUFFER_##commandType##_RES: \ { \ resp = TrCommandBufferBase::CreateFromMessage(message); \ diff --git a/src/common/command_buffers/sender.cpp b/src/common/command_buffers/sender.cpp index 2bfbe7783..704132fec 100644 --- a/src/common/command_buffers/sender.cpp +++ b/src/common/command_buffers/sender.cpp @@ -9,7 +9,7 @@ namespace commandbuffers TrCommandBufferMessage *message = nullptr; switch (req.type) { -#define XX(commandType, requestType) \ +#define XX(commandType, requestType, _) \ case COMMAND_BUFFER_##commandType##_REQ: \ { \ message = dynamic_cast(&req)->serialize(); \ @@ -49,7 +49,7 @@ namespace commandbuffers TrCommandBufferMessage *message = nullptr; switch (res.type) { -#define XX(commandType, responseType) \ +#define XX(commandType, responseType, _) \ case COMMAND_BUFFER_##commandType##_RES: \ { \ message = dynamic_cast(&res)->serialize(); \ diff --git a/src/common/command_buffers/shared.cpp b/src/common/command_buffers/shared.cpp index 3f9f2e69b..d18a1eb58 100644 --- a/src/common/command_buffers/shared.cpp +++ b/src/common/command_buffers/shared.cpp @@ -9,19 +9,19 @@ namespace commandbuffers { // Request -#define XX(COMMAND_TYPE, STR) \ +#define XX(COMMAND_TYPE, _, STR) \ case COMMAND_BUFFER_##COMMAND_TYPE##_REQ: \ { \ - return #STR; \ + return STR; \ } TR_COMMAND_BUFFER_REQUESTS_MAP(XX) #undef XX // Response -#define XX(COMMAND_TYPE, STR) \ +#define XX(COMMAND_TYPE, _, STR) \ case COMMAND_BUFFER_##COMMAND_TYPE##_RES: \ { \ - return #STR; \ + return STR; \ } TR_COMMAND_BUFFER_RESPONSES_MAP(XX) #undef XX diff --git a/src/common/command_buffers/shared.hpp b/src/common/command_buffers/shared.hpp index 4e19e358d..e802334eb 100644 --- a/src/common/command_buffers/shared.hpp +++ b/src/common/command_buffers/shared.hpp @@ -244,7 +244,7 @@ namespace commandbuffers // Check this command type is a request type. template concept is_commandbuffer_request = ( -#define XX(name, type) Type == COMMAND_BUFFER_##name##_REQ || +#define XX(name, type, _) Type == COMMAND_BUFFER_##name##_REQ || TR_COMMAND_BUFFER_REQUESTS_MAP(XX) #undef XX false); @@ -252,7 +252,7 @@ namespace commandbuffers // Check this command type is a response type. template concept is_commandbuffer_response = ( -#define XX(name, type) Type == COMMAND_BUFFER_##name##_REQ || +#define XX(name, type, _) Type == COMMAND_BUFFER_##name##_REQ || TR_COMMAND_BUFFER_RESPONSES_MAP(XX) #undef XX false); diff --git a/src/renderer/gles/framebuffer_attachment.cpp b/src/renderer/gles/framebuffer_attachment.cpp index 5f7ed5456..198e8fae8 100644 --- a/src/renderer/gles/framebuffer_attachment.cpp +++ b/src/renderer/gles/framebuffer_attachment.cpp @@ -85,6 +85,7 @@ unique_ptr GLFramebufferAttachment::FromCurrent(GLenum GLint is_texture_array = 0; glBindTexture(GL_TEXTURE_2D_ARRAY, attachment_texture); glGetTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_DEPTH, &is_texture_array); + glBindTexture(GL_TEXTURE_2D_ARRAY, current_texture_binding); if (is_texture_array > 0) { @@ -98,12 +99,17 @@ unique_ptr GLFramebufferAttachment::FromCurrent(GLenum } GLenum textarget = attachment_object->texture_target_; - glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_WIDTH, &attachment_object->width_); - glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_HEIGHT, &attachment_object->height_); - glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &attachment_object->texture_internal_format_); + glGetIntegerv(textarget, ¤t_texture_binding); + { + glBindTexture(textarget, attachment_texture); + glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_WIDTH, &attachment_object->width_); + glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_HEIGHT, &attachment_object->height_); + glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &attachment_object->texture_internal_format_); + glBindTexture(textarget, current_texture_binding); + } - glBindTexture(GL_TEXTURE_2D_ARRAY, current_texture_binding); - glGetError(); // Clear any errors from the previous call + // Clear any errors from the previous call + glGetError(); } else if (attachment_type == GL_NONE) { diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index b06ce61f8..dcc119455 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -190,6 +190,16 @@ class RHI_OpenGL : public TrRenderHardwareInterface binding_fbo, glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE ? "Complete" : "Incomplete"); + // Print viewport & scissor + { + GLint viewport[4]; + GLint scissor[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + glGetIntegerv(GL_SCISSOR_BOX, scissor); + DEBUG(logTag, " Viewport: (%d, %d, %d, %d)", viewport[0], viewport[1], viewport[2], viewport[3]); + DEBUG(logTag, " Scissor: (%d, %d, %d, %d)", scissor[0], scissor[1], scissor[2], scissor[3]); + } + auto color0 = GLFramebufferAttachment::FromCurrent(GL_COLOR_ATTACHMENT0); auto depth = GLFramebufferAttachment::FromCurrent(GL_DEPTH_ATTACHMENT); if (color0 != nullptr) @@ -198,15 +208,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface depth->print(" Depth"); } - // Print LINK_STATUS, VALIDATE_STATUS + // Print LINK_STATUS { - GLint linkStatus, validateStatus; + GLint linkStatus; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); - glGetProgramiv(program, GL_VALIDATE_STATUS, &validateStatus); DEBUG(logTag, " Program: LINK_STATUS=%s", linkStatus == GL_TRUE ? "Ok" : "Failed"); - DEBUG(logTag, " Program: VALIDATE_STATUS=%s", validateStatus == GL_TRUE ? "Ok" : "Failed"); - if (linkStatus != GL_TRUE || validateStatus != GL_TRUE) + if (linkStatus != GL_TRUE) { GLchar infoLog[512]; glGetProgramInfoLog(program, 512, nullptr, infoLog); @@ -849,12 +857,12 @@ class RHI_OpenGL : public TrRenderHardwareInterface ApiCallOptions &options) { auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); - auto target = req->target; - auto buffer = glObjectManager.FindBuffer(req->buffer); - if (req->buffer != 0 && buffer == 0) + uint32_t target = req->target; + GLuint buffer = glObjectManager.FindBuffer(req->buffer); + if (req->buffer != 0 && buffer == 0) [[unlikely]] { reqContentRenderer->increaseFrameErrorsCount(); - DEBUG(DEBUG_TAG, "Could not find buffer(cid=%d) to bind", req->buffer); + DEBUG(LOG_TAG_ERROR, "Could not find buffer(cid=%d) to bind", req->buffer); glObjectManager.PrintBuffers(); return; } @@ -868,13 +876,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glBindBuffer(target, buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, - "[%d] GL::BindBuffer(%s, buffer=%d)", - options.isDefaultQueue(), - gles::glEnumToString(target).c_str(), - buffer); - } + PrintDebugInfo(req, to_string(buffer).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnBufferData(BufferDataCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -919,7 +921,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint framebuffer = glObjectManager.CreateFramebuffer(req->clientId); reqContentRenderer->getOpenGLContext()->RecordFramebufferOnCreated(framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateFramebuffer(#%d) => %d", options.isDefaultQueue(), req->clientId, framebuffer); + PrintDebugInfo(req, to_string(framebuffer).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnDeleteFramebuffer( DeleteFramebufferCommandBufferRequest *req, @@ -931,7 +933,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteFramebuffer(req->framebuffer); reqContentRenderer->getOpenGLContext()->RecordFramebufferOnDeleted(framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteFramebuffer: %d", options.isDefaultQueue(), req->framebuffer); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBindFramebuffer( BindFramebufferCommandBufferRequest *req, @@ -989,7 +991,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLenum ret = glCheckFramebufferStatus(req->target); CheckFramebufferStatusCommandBufferResponse res(req, ret); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CheckFramebufferStatus() => %d", options.isDefaultQueue(), res.status); + PrintDebugInfo(req, nullptr, &res, options); } TR_OPENGL_FUNC void OnCreateRenderbuffer( CreateRenderbufferCommandBufferRequest *req, @@ -1012,7 +1014,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteRenderbuffer(req->renderbuffer); reqContentRenderer->getOpenGLContext()->RecordRenderbufferOnDeleted(renderbuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteRenderbuffer(%d)", options.isDefaultQueue(), renderbuffer); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBindRenderbuffer(BindRenderbufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1026,11 +1028,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getOpenGLContext()->onRenderbufferChanged(renderbuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es3/glBindRenderbuffer") != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, - "[%d] GL::BindRenderbuffer(%s, renderbuffer(%d))", - options.isDefaultQueue(), - gles::glEnumToString(target).c_str(), - renderbuffer); + { + PrintDebugInfo(req, to_string(renderbuffer).c_str(), nullptr, options); + } } TR_OPENGL_FUNC void OnRenderbufferStorage(RenderbufferStorageCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1050,7 +1050,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { glReadBuffer(req->mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::ReadBuffer(%d)", options.isDefaultQueue(), req->mode); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBindBufferBase(BindBufferBaseCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1062,7 +1062,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto buffer = glObjectManager.FindBuffer(req->buffer); glBindBufferBase(target, index, buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BindBufferBase(%d, index=%d, target=%d)", options.isDefaultQueue(), buffer, index, target); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBindBufferRange(BindBufferRangeCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1075,7 +1075,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto size = req->bufferSize; glBindBufferRange(target, index, buffer, offset, size); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BindBufferRange(%d)", options.isDefaultQueue(), buffer); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBlitFramebuffer(BlitFramebufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1093,12 +1093,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface req->mask, req->filter); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, - "[%d] GL::BlitFramebuffer(%d, %d, filter=%d)", - options.isDefaultQueue(), - req->srcX0, - req->srcY0, - req->filter); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnRenderbufferStorageMultisample(RenderbufferStorageMultisampleCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1111,14 +1106,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto height = req->height; glRenderbufferStorageMultisample(target, samples, internalformat, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, - "[%d] GL::RenderbufferStorageMultisample(0x%x, samples=%d, internalformat=0x%x, size=[%d,%d])", - options.isDefaultQueue(), - target, - samples, - internalformat, - width, - height); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnCreateVertexArray(CreateVertexArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2175,21 +2163,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glEnable(cap); reqContentRenderer->getOpenGLContext()->onCapabilityEnabled(cap, true); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - if (cap == GL_BLEND || - cap == GL_CULL_FACE || - cap == GL_DEPTH_TEST || - cap == GL_DITHER || - cap == GL_POLYGON_OFFSET_FILL || - cap == GL_RASTERIZER_DISCARD || - cap == GL_SAMPLE_ALPHA_TO_COVERAGE || - cap == GL_SAMPLE_COVERAGE || - cap == GL_SCISSOR_TEST || - cap == GL_STENCIL_TEST) - DEBUG(DEBUG_TAG, "[%d] GL::Enable(%s)", options.isDefaultQueue(), gles::glEnumToString(cap).c_str()); - else - DEBUG(DEBUG_TAG, "[%d] GL::Enable(0x%x)", options.isDefaultQueue(), cap); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnDisable(DisableCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -2197,21 +2171,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDisable(cap); reqContentRenderer->getOpenGLContext()->onCapabilityEnabled(cap, false); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - if (cap == GL_BLEND || - cap == GL_CULL_FACE || - cap == GL_DEPTH_TEST || - cap == GL_DITHER || - cap == GL_POLYGON_OFFSET_FILL || - cap == GL_RASTERIZER_DISCARD || - cap == GL_SAMPLE_ALPHA_TO_COVERAGE || - cap == GL_SAMPLE_COVERAGE || - cap == GL_SCISSOR_TEST || - cap == GL_STENCIL_TEST) - DEBUG(DEBUG_TAG, "[%d] GL::Disable(%s)", options.isDefaultQueue(), gles::glEnumToString(cap).c_str()); - else - DEBUG(DEBUG_TAG, "[%d] GL::Disable(0x%x)", options.isDefaultQueue(), cap); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnGetBooleanv(GetBooleanvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, diff --git a/src/xr/frame.cpp b/src/xr/frame.cpp index 710a406ca..1c331759f 100644 --- a/src/xr/frame.cpp +++ b/src/xr/frame.cpp @@ -347,7 +347,7 @@ namespace xr commandbuffers::TrCommandBufferBase *newReq = nullptr; switch (srcReq->type) { -#define XX(commandType, requestType) \ +#define XX(commandType, requestType, _) \ case commandbuffers::COMMAND_BUFFER_##commandType##_REQ: \ { \ newReq = dynamic_cast(srcReq); \ From 4f2132104555aca3e569c76581054c0b1ed9b6dd Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Thu, 10 Jul 2025 19:31:11 +0800 Subject: [PATCH 10/27] 80% working --- fixtures/html/three/portal.js | 20 +- src/client/graphics/webgl_context.cpp | 36 +- src/common/command_buffers/details/buffer.hpp | 2 +- src/common/command_buffers/details/clear.hpp | 32 ++ .../command_buffers/details/uniforms.hpp | 169 ++++++++- src/renderer/content_renderer.cpp | 59 ++- src/renderer/content_renderer.hpp | 51 +-- src/renderer/gles/context_app.cpp | 25 +- src/renderer/gles/context_app.hpp | 8 +- src/renderer/gles/context_host.cpp | 15 + src/renderer/gles/context_storage.cpp | 15 +- src/renderer/gles/context_storage.hpp | 12 + src/renderer/render_api.hpp | 12 +- src/renderer/render_api_opengles.cpp | 344 ++++++++++-------- src/renderer/renderer.hpp | 2 +- 15 files changed, 557 insertions(+), 245 deletions(-) diff --git a/fixtures/html/three/portal.js b/fixtures/html/three/portal.js index 3d28573f4..c15900b92 100644 --- a/fixtures/html/three/portal.js +++ b/fixtures/html/three/portal.js @@ -2,15 +2,15 @@ import * as THREE from 'three'; import * as CameraUtils from 'three/addons/utils/CameraUtils.js'; const scene = new THREE.Scene(); -const camera = new THREE.PerspectiveCamera(75, 1.0, 0.1, 1000); +const camera = new THREE.PerspectiveCamera(60, 1.6, 0.1, 100); // Create lights const light = new THREE.DirectionalLight(0xffffff, 0.5); light.position.set(0, 1, 1); scene.add(light); +let scale; let renderer; -let cameraControls; let smallSphereOne, smallSphereTwo; let portalCamera, leftPortal, rightPortal, leftPortalTexture, reflectedPosition, rightPortalTexture, bottomLeftCorner, bottomRightCorner, topLeftCorner; @@ -33,7 +33,7 @@ let portalCamera, leftPortal, rightPortal, leftPortalTexture, reflectedPosition, scene.add(smallSphereTwo); // portals - portalCamera = new THREE.PerspectiveCamera(45, 1.0, 0.1, 500.0); + portalCamera = new THREE.PerspectiveCamera(45, 1.0, 0.01, 100.0); scene.add(portalCamera); //frustumHelper = new THREE.CameraHelper( portalCamera ); //scene.add( frustumHelper ); @@ -114,7 +114,7 @@ let portalCamera, leftPortal, rightPortal, leftPortalTexture, reflectedPosition, } }); const size = box.getSize(new THREE.Vector3()); - const scale = 0.3 / Math.max(size.x, size.y, size.z); + scale = 0.3 / Math.max(size.x, size.y, size.z); console.info('Scaling scene by', scale); scene.scale.set(scale, scale, scale); })(); @@ -123,17 +123,19 @@ let portalCamera, leftPortal, rightPortal, leftPortalTexture, reflectedPosition, function renderPortal(thisPortalMesh, otherPortalMesh, thisPortalTexture) { // set the portal camera position to be reflected about the portal plane thisPortalMesh.worldToLocal(reflectedPosition.copy(camera.position)); - reflectedPosition.x *= - 1.0; reflectedPosition.z *= - 1.0; + // reflectedPosition.x *= - 1.0; + // reflectedPosition.z *= - 1.0; otherPortalMesh.localToWorld(reflectedPosition); portalCamera.position.copy(reflectedPosition); + let unit = 50.05; // grab the corners of the other portal // - note: the portal is viewed backwards; flip the left/right coordinates - otherPortalMesh.localToWorld(bottomLeftCorner.set(50.05, - 50.05, 0.0)); - otherPortalMesh.localToWorld(bottomRightCorner.set(- 50.05, - 50.05, 0.0)); - otherPortalMesh.localToWorld(topLeftCorner.set(50.05, 50.05, 0.0)); + otherPortalMesh.localToWorld(bottomLeftCorner.set(unit, - unit, 0.0)); + otherPortalMesh.localToWorld(bottomRightCorner.set(- unit, - unit, 0.0)); + otherPortalMesh.localToWorld(topLeftCorner.set(unit, unit, 0.0)); // set the projection matrix to encompass the portal's frame - CameraUtils.frameCorners(portalCamera, bottomLeftCorner, bottomRightCorner, topLeftCorner, false); + // CameraUtils.frameCorners(portalCamera, bottomLeftCorner, bottomRightCorner, topLeftCorner, false); // render the portal thisPortalTexture.texture.colorSpace = renderer.outputColorSpace; diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index d2946f7c1..c358f0ca1 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -982,8 +982,8 @@ namespace client_graphics if (runsInXRFrame && ( /** - * Match for three.js matrix uniforms - */ + * Match for three.js matrix uniforms + */ locationName == "projectionMatrix" || locationName == "projectionMatrices" || locationName == "projectionMatrices[0]" || @@ -991,15 +991,15 @@ namespace client_graphics locationName == "viewMatrices" || locationName == "viewMatrices[0]" || /** - * Match for Babylon.js matrix uniforms - */ + * Match for Babylon.js matrix uniforms + */ locationName == "projection" || locationName == "view" || locationName == "viewProjection" || locationName == "viewProjectionR" /** - * TODO: Compatibility with other libraries: Babylon.js, etc. - */ + * TODO: Compatibility with other libraries: Babylon.js, etc. + */ )) { bool forMultiview = false; @@ -1036,11 +1036,13 @@ namespace client_graphics computationGraph.multiview = forMultiview; req.computationGraph4values = computationGraph; } - else + + // Also copy the input values to the request for non-XR cases + // TODO(yorkie): skip copying values if the current binding fbo is default? { size_t length = values.size(); - if (length % 16 != 0) - throw std::runtime_error("uniformMatrix4fv() must take 16x float elements array but accept " + std::to_string(length) + "."); + if (length % 16 != 0) [[unlikely]] + throw runtime_error("uniformMatrix4fv() must take 16x float elements array but accept " + std::to_string(length) + "."); req.values.resize(length); auto valuesSrc = values.data(); @@ -1131,29 +1133,29 @@ namespace client_graphics void WebGLContext::clearColor(float red, float green, float blue, float alpha) { - // auto req = ClearColorCommandBufferRequest(red, green, blue, alpha); - // sendCommandBufferRequest(req); + auto req = ClearColorCommandBufferRequest(red, green, blue, alpha); + sendCommandBufferRequest(req); clearColor_ = glm::vec4(red, green, blue, alpha); } void WebGLContext::clearDepth(float depth) { - // auto req = ClearDepthCommandBufferRequest(depth); - // sendCommandBufferRequest(req); + auto req = ClearDepthCommandBufferRequest(depth); + sendCommandBufferRequest(req); clearDepth_ = depth; } void WebGLContext::clearStencil(int s) { - // auto req = ClearStencilCommandBufferRequest(s); - // sendCommandBufferRequest(req); + auto req = ClearStencilCommandBufferRequest(s); + sendCommandBufferRequest(req); clearStencil_ = s; } void WebGLContext::clear(int mask) { - // auto req = ClearCommandBufferRequest(mask); - // sendCommandBufferRequest(req); + auto req = ClearCommandBufferRequest(mask); + sendCommandBufferRequest(req); } void WebGLContext::depthMask(bool flag) diff --git a/src/common/command_buffers/details/buffer.hpp b/src/common/command_buffers/details/buffer.hpp index bf7769214..f0715a607 100644 --- a/src/common/command_buffers/details/buffer.hpp +++ b/src/common/command_buffers/details/buffer.hpp @@ -323,7 +323,7 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { std::stringstream ss; - ss << "bindFramebuffer("; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "("; isBindToDefault() ? ss << "default" : ss << framebuffer; diff --git a/src/common/command_buffers/details/clear.hpp b/src/common/command_buffers/details/clear.hpp index 9bb56cd32..3552b0d42 100644 --- a/src/common/command_buffers/details/clear.hpp +++ b/src/common/command_buffers/details/clear.hpp @@ -21,6 +21,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << mask << ")"; + return ss.str(); + } + public: int mask; }; @@ -48,6 +55,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << r << ", " + << g << ", " + << b << ", " + << a << ")"; + return ss.str(); + } + public: float r; float g; @@ -72,6 +90,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << depth << ")"; + return ss.str(); + } + public: float depth; }; @@ -93,6 +118,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << stencil << ")"; + return ss.str(); + } + public: int stencil; }; diff --git a/src/common/command_buffers/details/uniforms.hpp b/src/common/command_buffers/details/uniforms.hpp index 6a4417ba4..338f50c51 100644 --- a/src/common/command_buffers/details/uniforms.hpp +++ b/src/common/command_buffers/details/uniforms.hpp @@ -156,6 +156,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << ")," + << v0 << ")"; + return ss.str(); + } + public: uint32_t location; int v0; @@ -195,6 +204,22 @@ namespace commandbuffers if (valuesSegment != nullptr) values = valuesSegment->toVec(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << "),"; + + ss << "["; + for (size_t i = 0; i < values.size(); ++i) + { + ss << values[i]; + if (i < values.size() - 1) + ss << ", "; + } + ss << "])"; + return ss.str(); + } public: uint32_t location; @@ -221,6 +246,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << ")," + << v0 << "," + << v1 << ")"; + return ss.str(); + } + public: uint32_t location; float v0; @@ -262,6 +297,23 @@ namespace commandbuffers values = valuesSegment->toVec(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << "),"; + + ss << "["; + for (size_t i = 0; i < values.size(); ++i) + { + ss << values[i]; + if (i < values.size() - 1) + ss << ", "; + } + ss << "])"; + return ss.str(); + } + public: uint32_t location; std::vector values; @@ -287,6 +339,16 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << ")," + << v0 << "," + << v1 << ")"; + return ss.str(); + } + public: uint32_t location; int v0; @@ -327,6 +389,22 @@ namespace commandbuffers if (valuesSegment != nullptr) values = valuesSegment->toVec(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << "),"; + + ss << "["; + for (size_t i = 0; i < values.size(); ++i) + { + ss << values[i]; + if (i < values.size() - 1) + ss << ", "; + } + ss << "])"; + return ss.str(); + } public: uint32_t location; @@ -355,6 +433,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << ")," + << v0 << "," + << v1 << "," + << v2 << ")"; + return ss.str(); + } + public: uint32_t location; float v0; @@ -396,6 +485,22 @@ namespace commandbuffers if (valuesSegment != nullptr) values = valuesSegment->toVec(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << "),"; + + ss << "["; + for (size_t i = 0; i < values.size(); ++i) + { + ss << values[i]; + if (i < values.size() - 1) + ss << ", "; + } + ss << "])"; + return ss.str(); + } public: uint32_t location; @@ -424,6 +529,17 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << ")," + << v0 << "," + << v1 << "," + << v2 << ")"; + return ss.str(); + } + public: uint32_t location; int v0; @@ -465,6 +581,22 @@ namespace commandbuffers if (valuesSegment != nullptr) values = valuesSegment->toVec(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << "Loc(" << location << "),"; + + ss << "["; + for (size_t i = 0; i < values.size(); ++i) + { + ss << values[i]; + if (i < values.size() - 1) + ss << ", "; + } + ss << "])"; + return ss.str(); + } public: uint32_t location; @@ -503,6 +635,17 @@ namespace commandbuffers void deserialize(TrCommandBufferMessage &message) override final { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferRequest::toString(line_prefix) << "(" + << "Loc(" << location << ")," + << v0 << "," + << v1 << "," + << v2 << "," + << v3 << ")"; + return ss.str(); + } public: uint32_t location; @@ -545,6 +688,22 @@ namespace commandbuffers if (valuesSegment != nullptr) values = valuesSegment->toVec(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferRequest::toString(line_prefix) << "(" + << "Loc(" << location << "),"; + + ss << "["; + for (size_t i = 0; i < values.size(); ++i) + { + ss << values[i]; + if (i < values.size() - 1) + ss << ", "; + } + ss << "])"; + return ss.str(); + } public: uint32_t location; @@ -650,14 +809,8 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { std::stringstream values_ss; - if (isComputationGraph()) - { - values_ss << "Placeholder()"; - } - else - { - values_ss << "float[" << values.size() << "]"; - } + values_ss << "float[" << values.size() << "], " + << "ComputationGraph=" << (isComputationGraph() ? "Placeholder()" : "None"); std::stringstream ss; ss << TrCommandBufferRequest::toString(line_prefix) << "(" diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index 53301c3e2..40252c4af 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -28,12 +28,14 @@ namespace renderer string contextName = contentRenderer->glContext->name(); contentRenderer->glContextForBackup = make_unique(contextName + "~backup", contentRenderer->glContext.get()); - contentRenderer->usingBackupContext = true; + // Switch the current pass to cached XR frame pass. + previousPass = contentRenderer->currentPass; + contentRenderer->currentPass = ExecutingPassType::kCachedXRFrame; } TrBackupGLContextScope::~TrBackupGLContextScope() { - contentRenderer->usingBackupContext = false; + contentRenderer->currentPass = previousPass; } TrContentRenderer::TrContentRenderer(shared_ptr content, uint8_t contextId, TrConstellation *constellation) @@ -45,7 +47,6 @@ namespace renderer , targetFrameRate(constellation->renderer->clientDefaultFrameRate) , glContext(nullptr) , glContextForBackup(nullptr) - , usingBackupContext(false) { assert(xrDevice != nullptr); stereoFrameForBackup = make_unique(true, 0xf); @@ -109,9 +110,21 @@ namespace renderer return contentRef->sendCommandBufferResponse(res); } - ContextGLApp *TrContentRenderer::getOpenGLContext() const + ContextGLApp *TrContentRenderer::getContextGL() const { - return usingBackupContext ? glContextForBackup.get() : glContext.get(); + if (currentPass == ExecutingPassType::kCachedXRFrame) + return glContextForBackup.get(); + else if (currentPass == ExecutingPassType::kOffscreenPass) + { + if (glContextOnOffscreenPass.has_value()) + return const_cast(&glContextOnOffscreenPass.value()); + else + return nullptr; + } + else + { + return glContext.get(); + } } pid_t TrContentRenderer::getContentPid() const @@ -129,6 +142,26 @@ namespace renderer return *constellation->renderer; } + void TrContentRenderer::resetOffscreenPassGLContext(std::optional framebuffer) + { + if (framebuffer == std::nullopt) + { + glContextOnOffscreenPass = std::nullopt; + } + else + { + std::string contextName = GetContentRendererId(getContent(), contextId) + "~offscreen"; + glContextOnOffscreenPass = ContextGLApp(contextName, getContextGL(), framebuffer); + } + } + + void TrContentRenderer::scheduleCommandBufferAtOffscreenPass(TrCommandBufferBase *req) + { + if (req == nullptr) [[unlikely]] + return; + commandBuffersOnOffscreenPass.push_back(req); + } + // The `req` argument is a pointer to `TrCommandBufferBase` in the heap, it will be stored in the corresponding queues // such as `defaultCommandBufferRequests` or `stereoFramesList`, otherwise it will be deleted in this function. void TrContentRenderer::onCommandBufferRequestReceived(TrCommandBufferBase *req) @@ -279,6 +312,8 @@ namespace renderer if (!shouldSkipXRFrame && getContent()->used && xrDevice->enabled()) { + currentPass = ExecutingPassType::kXRFrame; + // Execute the XR frame switch (xrDevice->getStereoRenderingMode()) { @@ -310,13 +345,13 @@ namespace renderer void TrContentRenderer::onOffscreenRenderPass() { + currentPass = ExecutingPassType::kOffscreenPass; if (commandBuffersOnOffscreenPass.size() > 0) { - if (usingProgramOnOffscreenPassStarted.has_value()) - glUseProgram(usingProgramOnOffscreenPassStarted.value()); - if (bindingVaoOnOffscreenPassStarted.has_value()) - glBindVertexArray(bindingVaoOnOffscreenPassStarted.value()); + assert(glContextOnOffscreenPass.has_value() && + "The offscreen pass context is not initialized, please call `initializeGraphicsContextsOnce()` first."); + glContextOnOffscreenPass->restore(); constellation->renderer->executeCommandBuffers(commandBuffersOnOffscreenPass, this, ExecutingPassType::kOffscreenPass); @@ -327,14 +362,15 @@ namespace renderer } commandBuffersOnOffscreenPass.clear(); - usingProgramOnOffscreenPassStarted = nullopt; - bindingVaoOnOffscreenPassStarted = nullopt; + glContextOnOffscreenPass = nullopt; } + currentPass = ExecutingPassType::kDefaultFrame; } void TrContentRenderer::onStartFrame() { frameStartTime = chrono::system_clock::now(); + currentPass = ExecutingPassType::kDefaultFrame; // Update the pending stereo frames count for each WebXR session if the WebXR device is enabled. if (xrDevice->enabled()) [[likely]] @@ -361,6 +397,7 @@ namespace renderer frameEndTime = chrono::system_clock::now(); frameDuration = chrono::duration_cast(frameEndTime - frameStartTime); maxFrameDuration = max(maxFrameDuration, frameDuration); + currentPass = ExecutingPassType::kDefaultFrame; } void TrContentRenderer::initializeGraphicsContextsOnce() diff --git a/src/renderer/content_renderer.hpp b/src/renderer/content_renderer.hpp index 7e2ea669c..4ee88e213 100644 --- a/src/renderer/content_renderer.hpp +++ b/src/renderer/content_renderer.hpp @@ -16,6 +16,7 @@ #include #include "./gles/context_storage.hpp" +#include "./render_api.hpp" using namespace std; using namespace commandbuffers; @@ -43,15 +44,16 @@ namespace renderer private: TrContentRenderer *contentRenderer; + ExecutingPassType previousPass = ExecutingPassType::kDefaultFrame; }; class TrContentRenderer final : public std::enable_shared_from_this { + friend class ::TrInspector; + friend class xr::TrXRSession; friend class TrContentRuntime; friend class TrBackupGLContextScope; friend class TrRenderer; - friend class ::TrInspector; - friend class xr::TrXRSession; public: /** @@ -81,7 +83,8 @@ namespace renderer public: bool sendCommandBufferResponse(TrCommandBufferResponse &res); - ContextGLApp *getOpenGLContext() const; + // Returns the current using GL context. + ContextGLApp *getContextGL() const; inline shared_ptr getContent() const { return content.lock(); @@ -100,47 +103,25 @@ namespace renderer onCommandBufferRequestReceived(req); } - /** - * Schedule a command buffer to be executed at offscreen pass. - */ - void scheduleCommandBufferAtOffscreenPass(TrCommandBufferBase *req) - { - if (req == nullptr) [[unlikely]] - return; - - if (commandBuffersOnOffscreenPass.size() == 0) - { - usingProgramOnOffscreenPassStarted = glContext->program(); - bindingVaoOnOffscreenPassStarted = glContext->vertexArrayObject(); - } - commandBuffersOnOffscreenPass.push_back(req); - } - - /** - * Mark the last frame has OOM error. - */ + // State updates inline void markOccurOutOfMemoryError() { lastFrameHasOutOfMemoryError = true; } - /** - * Increase the frame errors count. - */ inline void increaseFrameErrorsCount() { lastFrameErrorsCount++; } - /** - * Increase the draw calls count. - * - * @param count The count to be increased. - */ inline void increaseDrawCallsCount(int count = 1) { drawCallsPerFrame += 1; drawCallsCountPerFrame += count; } + // Offscreen pass controls + void resetOffscreenPassGLContext(std::optional framebuffer); + void scheduleCommandBufferAtOffscreenPass(TrCommandBufferBase *req); + private: // private lifecycle /** * The callback function to handle the command buffer request received. @@ -181,12 +162,13 @@ namespace renderer private: std::weak_ptr content; TrConstellation *constellation = nullptr; + xr::Device *xrDevice = nullptr; + + bool isGraphicsContextsInitialized = false; + ExecutingPassType currentPass = ExecutingPassType::kDefaultFrame; // TODO(yorkie): Remove this when gpu device is ready, because WebGPU is context-less. std::unique_ptr glContext; std::unique_ptr glContextForBackup; - bool isGraphicsContextsInitialized = false; - bool usingBackupContext = false; - xr::Device *xrDevice = nullptr; private: // command buffers & rendering frames std::shared_mutex commandBufferRequestsMutex; @@ -198,8 +180,7 @@ namespace renderer // The recorded command buffers which render to other render textures, such as shadow maps, reflection maps, etc. // TODO(yorkie): support multi-stage offscreen pass? std::vector commandBuffersOnOffscreenPass; - std::optional usingProgramOnOffscreenPassStarted; - std::optional bindingVaoOnOffscreenPassStarted; + std::optional glContextOnOffscreenPass; std::vector stereoFramesList; std::unique_ptr stereoFrameForBackup = nullptr; diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index 024b8bd53..45cf4d8a9 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -63,12 +63,15 @@ ContextGLApp::ContextGLApp(string name, shared_ptr } } -ContextGLApp::ContextGLApp(string name, ContextGLApp *from) +ContextGLApp::ContextGLApp(string name, ContextGLApp *from, optional defaultRenderTarget) : ContextGLStorage(name, from) , m_ContentRenderer(from->m_ContentRenderer) - , m_CurrentDefaultRenderTarget(from->m_CurrentDefaultRenderTarget) + , m_CurrentDefaultRenderTarget(defaultRenderTarget.value_or(from->m_CurrentDefaultRenderTarget)) , m_GLObjectManager(from->m_GLObjectManager) { + m_FramebufferId = m_CurrentDefaultRenderTarget; + m_ProgramId = from->m_ProgramId; + m_Programs = OpenGLNamesStorage(&from->m_Programs); m_Shaders = OpenGLNamesStorage(&from->m_Shaders); m_Buffers = OpenGLNamesStorage(&from->m_Buffers); @@ -309,6 +312,24 @@ void ContextGLApp::setScissor(GLint x, GLint y, GLsizei width, GLsizei height) glScissor(x, y, width, height); } +void ContextGLApp::setClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + glClearColor(red, green, blue, alpha); + m_ClearColor = {red, green, blue, alpha}; +} + +void ContextGLApp::setClearDepth(GLfloat depth) +{ + glClearDepthf(depth); + m_ClearDepth = depth; +} + +void ContextGLApp::setClearStencil(GLint s) +{ + glClearStencil(s); + m_ClearStencil = s; +} + GLuint ContextGLApp::createProgram(uint32_t id) { GLuint program = ObjectManagerRef().CreateProgram(id); diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index 9891094ab..43f7d0350 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -13,8 +13,11 @@ class ContextGLHost; class ContextGLApp : public ContextGLStorage { public: + // Create a new context for the content renderer. ContextGLApp(std::string name, std::shared_ptr); - ContextGLApp(std::string name, ContextGLApp *from); + // Create a new context which inherits from another context. And `defaultRenderTarget` is the default framebuffer to + // be used in this context. + ContextGLApp(std::string name, ContextGLApp *from, std::optional defaultRenderTarget = std::nullopt); public: // Initialize the render target(framebuffer) for this context. @@ -55,6 +58,9 @@ class ContextGLApp : public ContextGLStorage // State void setViewport(GLint x, GLint y, GLsizei width, GLsizei height); void setScissor(GLint x, GLint y, GLsizei width, GLsizei height); + void setClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void setClearDepth(GLfloat depth); + void setClearStencil(GLint s); // Program functions GLuint createProgram(uint32_t id); diff --git a/src/renderer/gles/context_host.cpp b/src/renderer/gles/context_host.cpp index 474de97be..86ee87158 100644 --- a/src/renderer/gles/context_host.cpp +++ b/src/renderer/gles/context_host.cpp @@ -26,6 +26,21 @@ void ContextGLHost::recordFromHost() is_framebuffer_changed = true; } + // Record clear values + { + GLfloat clear_color[4]; + glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color); + m_ClearColor = {clear_color[0], clear_color[1], clear_color[2], clear_color[3]}; + + GLfloat clear_depth; + glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clear_depth); + m_ClearDepth = clear_depth; + + GLint clear_stencil; + glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clear_stencil); + m_ClearStencil = clear_stencil; + } + // Record objects glGetIntegerv(GL_CURRENT_PROGRAM, &m_ProgramId); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &m_ArrayBufferId); diff --git a/src/renderer/gles/context_storage.cpp b/src/renderer/gles/context_storage.cpp index 5a05ed952..20fdc4b85 100644 --- a/src/renderer/gles/context_storage.cpp +++ b/src/renderer/gles/context_storage.cpp @@ -146,6 +146,17 @@ void ContextGLStorage::restore() m_StencilTestEnabled ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST); m_ScissorTestEnabled ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST); + // Restore the clear values + if (m_ClearColor.has_value()) + { + const auto &color = m_ClearColor.value(); + glClearColor(color[0], color[1], color[2], color[3]); + } + if (m_ClearDepth.has_value()) + glClearDepthf(m_ClearDepth.value()); + if (m_ClearStencil.has_value()) + glClearStencil(m_ClearStencil.value()); + // Blend state restore /** * NOTE: The blend function state should not depend on the blend state, it causes the host blend state would be passed to @@ -219,10 +230,10 @@ void ContextGLStorage::restore() glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ElementArrayBufferId); } - if (m_FramebufferId.has_value()) - glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferId.value()); if (m_RenderbufferId >= 0) glBindRenderbuffer(GL_RENDERBUFFER, m_RenderbufferId.value()); + if (m_FramebufferId.has_value()) + glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferId.value()); bindBuffersError = glGetError(); for (auto it = m_TextureBindingsWithUnit.begin(); it != m_TextureBindingsWithUnit.end(); it++) diff --git a/src/renderer/gles/context_storage.hpp b/src/renderer/gles/context_storage.hpp index e273e7247..c27ec9fd3 100644 --- a/src/renderer/gles/context_storage.hpp +++ b/src/renderer/gles/context_storage.hpp @@ -315,22 +315,32 @@ class ContextGLStorage bool is_force_changed_ = false; protected: /** Global States */ + // Clear values + std::optional> m_ClearColor; // [red, green, blue, alpha] + std::optional m_ClearDepth; + std::optional m_ClearStencil; + // Culling & face GLboolean m_CullFaceEnabled; GLenum m_CullFace; GLenum m_FrontFace; + // Color GLboolean m_ColorMask[4]; // [reg, green, blue, alpha] + // Depth GLboolean m_DepthTestEnabled; GLboolean m_DepthMask; // If depth buffer writing is enabled GLenum m_DepthFunc = GL_LEQUAL; GLfloat m_DepthRange[2] = {0.0f, 1.0f}; + // Dither GLboolean m_DitherEnabled; + // Blending GLboolean m_BlendEnabled; OpenGLBlendingFunc m_BlendFunc; + // Stencil GLboolean m_StencilTestEnabled; GLuint m_StencilMask; @@ -339,9 +349,11 @@ class ContextGLStorage StencilFuncParameters m_StencilFuncBack; StencilOpParameters m_StencilOp; StencilOpParameters m_StencilOpBack; + // Scissor GLboolean m_ScissorTestEnabled; Rect m_ScissorBox; + // Others GLfloat m_LineWidth = 1.0f; PolygonOffsetParameters m_PolygonOffset; diff --git a/src/renderer/render_api.hpp b/src/renderer/render_api.hpp index 330ad314e..329f59b56 100644 --- a/src/renderer/render_api.hpp +++ b/src/renderer/render_api.hpp @@ -46,10 +46,20 @@ class ApiCallOptions final bool printsCall; ExecutingPassType executingPassType; - bool isDefaultQueue() const + inline bool isDefaultQueue() const { return executingPassType == ExecutingPassType::kDefaultFrame; } + // Returns `true` if the current executing the XR or cached XR pass. + inline bool isXRFramePass() const + { + return executingPassType == ExecutingPassType::kXRFrame || + executingPassType == ExecutingPassType::kCachedXRFrame; + } + inline bool isOffscreenPass() const + { + return executingPassType == ExecutingPassType::kOffscreenPass; + } }; /** diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index dcc119455..eadb19c05 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -128,7 +128,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->markOccurOutOfMemoryError(); { // Check memory - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); glObjectManager.PrintMemoryUsage(); } } @@ -427,7 +427,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - GLuint program = reqContentRenderer->getOpenGLContext()->createProgram(req->clientId); + GLuint program = reqContentRenderer->getContextGL()->createProgram(req->clientId); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, to_string(program).c_str(), nullptr, options); } @@ -436,7 +436,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface ApiCallOptions &options) { GLuint program; - reqContentRenderer->getOpenGLContext()->deleteProgram(req->clientId, program); + reqContentRenderer->getContextGL()->deleteProgram(req->clientId, program); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -444,10 +444,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto glContext = reqContentRenderer->getOpenGLContext(); + auto glContext = reqContentRenderer->getContextGL(); auto program = glContext->ObjectManagerRef().FindProgram(req->clientId); glLinkProgram(program); - reqContentRenderer->getOpenGLContext()->MarkAsDirty(); + reqContentRenderer->getContextGL()->MarkAsDirty(); /** * Check the link status of the program. @@ -556,7 +556,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface ApiCallOptions &options) { GLuint program; - reqContentRenderer->getOpenGLContext()->useProgram(req->clientId, program); + reqContentRenderer->getContextGL()->useProgram(req->clientId, program); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -564,7 +564,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto glContext = reqContentRenderer->getOpenGLContext(); + auto glContext = reqContentRenderer->getContextGL(); auto program = glContext->ObjectManagerRef().FindProgram(req->program); glBindAttribLocation(program, req->attribIndex, req->attribName.c_str()); @@ -580,7 +580,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto glContext = reqContentRenderer->getOpenGLContext(); + auto glContext = reqContentRenderer->getContextGL(); auto program = glContext->ObjectManagerRef().FindProgram(req->clientId); GLint value; glGetProgramiv(program, req->pname, &value); @@ -597,7 +597,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto glContext = reqContentRenderer->getOpenGLContext(); + auto glContext = reqContentRenderer->getContextGL(); auto program = glContext->ObjectManagerRef().FindProgram(req->clientId); GLint retSize; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &retSize); @@ -619,11 +619,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto glContext = reqContentRenderer->getOpenGLContext(); + auto glContext = reqContentRenderer->getContextGL(); GLuint program = glContext->ObjectManagerRef().FindProgram(req->program); GLuint shader = glContext->ObjectManagerRef().FindShader(req->shader); glAttachShader(program, shader); - reqContentRenderer->getOpenGLContext()->MarkAsDirty(); + reqContentRenderer->getContextGL()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -631,11 +631,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint program = glObjectManager.FindProgram(req->program); GLuint shader = glObjectManager.FindShader(req->shader); glDetachShader(program, shader); - reqContentRenderer->getOpenGLContext()->MarkAsDirty(); + reqContentRenderer->getContextGL()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -643,9 +643,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint shader = glObjectManager.CreateShader(req->clientId, req->shaderType); - reqContentRenderer->getOpenGLContext()->RecordShaderOnCreated(shader); + reqContentRenderer->getContextGL()->RecordShaderOnCreated(shader); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -653,10 +653,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto shader = glObjectManager.FindShader(req->shader); glObjectManager.DeleteShader(req->shader); - reqContentRenderer->getOpenGLContext()->RecordShaderOnDeleted(shader); + reqContentRenderer->getContextGL()->RecordShaderOnDeleted(shader); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); @@ -665,7 +665,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto shader = glObjectManager.FindShader(req->shader); auto source = req->source(); @@ -693,7 +693,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface const char *sourceStr = fixedSource.c_str(); size_t sourceSize = fixedSource.size(); glShaderSource(shader, 1, &sourceStr, (const GLint *)&sourceSize); - reqContentRenderer->getOpenGLContext()->MarkAsDirty(); + reqContentRenderer->getContextGL()->MarkAsDirty(); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); @@ -702,10 +702,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto shader = glObjectManager.FindShader(req->shader); glCompileShader(shader); - reqContentRenderer->getOpenGLContext()->MarkAsDirty(); + reqContentRenderer->getContextGL()->MarkAsDirty(); GLint compileStatus; glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); @@ -765,7 +765,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GetShaderSourceCommandBufferResponse res(req); GLint sourceSize; GLuint shader = glObjectManager.FindShader(req->shader); @@ -799,7 +799,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint shader = glObjectManager.FindShader(req->shader); GLint value; glGetShaderiv(shader, req->pname, &value); @@ -813,7 +813,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint shader = glObjectManager.FindShader(req->shader); GLint logSize; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); @@ -831,9 +831,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint buffer = glObjectManager.CreateBuffer(req->clientId); - reqContentRenderer->getOpenGLContext()->RecordBufferOnCreated(buffer); + reqContentRenderer->getContextGL()->RecordBufferOnCreated(buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::CreateBuffer(%d) => buffer(%d)", @@ -845,10 +845,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto buffer = glObjectManager.FindBuffer(req->buffer); glObjectManager.DeleteBuffer(req->buffer); - reqContentRenderer->getOpenGLContext()->RecordBufferOnDeleted(buffer); + reqContentRenderer->getContextGL()->RecordBufferOnDeleted(buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::DeleteBuffer(%d)", options.isDefaultQueue(), buffer); } @@ -856,7 +856,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); uint32_t target = req->target; GLuint buffer = glObjectManager.FindBuffer(req->buffer); if (req->buffer != 0 && buffer == 0) [[unlikely]] @@ -869,9 +869,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface /** Update the app states for next restore. */ if (target == GL_ARRAY_BUFFER) - reqContentRenderer->getOpenGLContext()->onArrayBufferChanged(buffer); + reqContentRenderer->getContextGL()->onArrayBufferChanged(buffer); else if (target == GL_ELEMENT_ARRAY_BUFFER) - reqContentRenderer->getOpenGLContext()->onElementBufferChanged(buffer); + reqContentRenderer->getContextGL()->onElementBufferChanged(buffer); // TODO: support other targets? glBindBuffer(target, buffer); @@ -917,9 +917,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint framebuffer = glObjectManager.CreateFramebuffer(req->clientId); - reqContentRenderer->getOpenGLContext()->RecordFramebufferOnCreated(framebuffer); + reqContentRenderer->getContextGL()->RecordFramebufferOnCreated(framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, to_string(framebuffer).c_str(), nullptr, options); } @@ -928,10 +928,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint framebuffer = glObjectManager.FindFramebuffer(req->framebuffer); glObjectManager.DeleteFramebuffer(req->framebuffer); - reqContentRenderer->getOpenGLContext()->RecordFramebufferOnDeleted(framebuffer); + reqContentRenderer->getContextGL()->RecordFramebufferOnDeleted(framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -940,20 +940,23 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto app_context = reqContentRenderer->getOpenGLContext(); + auto app_context = reqContentRenderer->getContextGL(); GLuint framebuffer; app_context->bindFramebuffer(req->target, req->isBindToDefault() ? nullopt : make_optional(req->framebuffer), framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + { + DEBUG(LOG_TAG_ERROR, "context name=> %s", app_context->name()); PrintDebugInfo(req, to_string(framebuffer).c_str(), nullptr, options); + } } TR_OPENGL_FUNC void OnFramebufferRenderbuffer(FramebufferRenderbufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto target = req->target; auto attachment = req->attachment; auto renderbuffertarget = req->renderbufferTarget; @@ -973,7 +976,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto target = req->target; auto attachment = req->attachment; auto textarget = req->textarget; @@ -998,9 +1001,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint renderbuffer = glObjectManager.CreateRenderbuffer(req->clientId); - reqContentRenderer->getOpenGLContext()->RecordRenderbufferOnCreated(renderbuffer); + reqContentRenderer->getContextGL()->RecordRenderbufferOnCreated(renderbuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, to_string(renderbuffer).c_str(), nullptr, options); } @@ -1009,10 +1012,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint renderbuffer = glObjectManager.FindRenderbuffer(req->renderbuffer); glObjectManager.DeleteRenderbuffer(req->renderbuffer); - reqContentRenderer->getOpenGLContext()->RecordRenderbufferOnDeleted(renderbuffer); + reqContentRenderer->getContextGL()->RecordRenderbufferOnDeleted(renderbuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1020,12 +1023,12 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto &target = req->target; auto renderbuffer = glObjectManager.FindRenderbuffer(req->renderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer); - reqContentRenderer->getOpenGLContext()->onRenderbufferChanged(renderbuffer); + reqContentRenderer->getContextGL()->onRenderbufferChanged(renderbuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es3/glBindRenderbuffer") != GL_NO_ERROR || options.printsCall)) { @@ -1056,7 +1059,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto target = req->target; auto index = req->index; auto buffer = glObjectManager.FindBuffer(req->buffer); @@ -1112,24 +1115,24 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint vao = glObjectManager.CreateVertexArray(req->clientId); - reqContentRenderer->getOpenGLContext()->RecordVertexArrayObjectOnCreated(vao); + reqContentRenderer->getContextGL()->RecordVertexArrayObjectOnCreated(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::CreateVertexArray(%d) => %d", options.isDefaultQueue(), req->clientId, vao); } TR_OPENGL_FUNC void OnDeleteVertexArray(DeleteVertexArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint vao = glObjectManager.FindVertexArray(req->vertexArray); glObjectManager.DeleteVertexArray(req->vertexArray); - reqContentRenderer->getOpenGLContext()->RecordVertexArrayObjectOnDeleted(vao); + reqContentRenderer->getContextGL()->RecordVertexArrayObjectOnDeleted(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::DeleteVertexArray(%d)", options.isDefaultQueue(), vao); } TR_OPENGL_FUNC void OnBindVertexArray(BindVertexArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto vao = glObjectManager.FindVertexArray(req->vertexArray); if (req->vertexArray != 0 && vao == 0) { @@ -1139,7 +1142,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface return; } glBindVertexArray(vao); - reqContentRenderer->getOpenGLContext()->onVertexArrayObjectChanged(vao); + reqContentRenderer->getContextGL()->onVertexArrayObjectChanged(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::BindVertexArray(%d)", options.isDefaultQueue(), vao); } @@ -1148,9 +1151,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint texture = glObjectManager.CreateTexture(req->clientId); - reqContentRenderer->getOpenGLContext()->RecordTextureOnCreated(texture); + reqContentRenderer->getContextGL()->RecordTextureOnCreated(texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::CreateTexture(#%d) => texture(%d)", options.isDefaultQueue(), req->clientId, texture); } @@ -1159,10 +1162,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint texture = glObjectManager.FindTexture(req->texture); glObjectManager.DeleteTexture(req->texture); - reqContentRenderer->getOpenGLContext()->RecordTextureOnDeleted(texture); + reqContentRenderer->getContextGL()->RecordTextureOnDeleted(texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::DeleteTexture(%d)", options.isDefaultQueue(), texture); } @@ -1170,13 +1173,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto target = req->target; auto texture = glObjectManager.FindTexture(req->texture); - GetRenderer()->getOpenGLContext()->recordTextureBindingFromHost(); + GetRenderer()->getContextGL()->recordTextureBindingFromHost(); glBindTexture(target, texture); - auto contentGlContext = reqContentRenderer->getOpenGLContext(); + auto contentGlContext = reqContentRenderer->getContextGL(); contentGlContext->onTextureBindingChanged(target, texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { @@ -1197,7 +1200,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { GLenum target = req->target; GLint level = req->level; - GLint internalformat = req->internalformat; + GLint internalformat = GL_RGBA; // req->internalformat; GLsizei width = req->width; GLsizei height = req->height; @@ -1325,7 +1328,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { auto textureUnit = req->activeUnit; glActiveTexture(textureUnit); - reqContentRenderer->getOpenGLContext()->onActiveTextureUnitChanged(textureUnit); + reqContentRenderer->getContextGL()->onActiveTextureUnitChanged(textureUnit); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { GLint currentProgram; @@ -1460,7 +1463,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface * `enableVertexAttribArray()`. */ if (backendType == RHIBackendType::OpenGLCore) - EnsureVertexArrayObject(reqContentRenderer->getOpenGLContext()); + EnsureVertexArrayObject(reqContentRenderer->getContextGL()); glEnableVertexAttribArray(req->index); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::EnableVertexAttribArray(%d)", options.isDefaultQueue(), req->index); @@ -1474,7 +1477,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface * `disableVertexAttribArray()`. */ if (backendType == RHIBackendType::OpenGLCore) - EnsureVertexArrayObject(reqContentRenderer->getOpenGLContext()); + EnsureVertexArrayObject(reqContentRenderer->getContextGL()); glDisableVertexAttribArray(req->index); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::DisableVertexAttribArray(%d)", options.isDefaultQueue(), req->index); @@ -1516,16 +1519,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glVertexAttribIPointer(index, size, type, stride, (const char *)NULL + offset); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, - "[%d] GL::VertexAttribIPointer(%d) size=%d type=0x%x stride=%d offset=%d", - options.isDefaultQueue(), - index, - size, - type, - stride, - offset); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnVertexAttribDivisor(VertexAttribDivisorCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1535,26 +1529,20 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto divisor = req->divisor; glVertexAttribDivisor(index, divisor); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::VertexAttribDivisor(%d, %d)", options.isDefaultQueue(), index, divisor); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniformBlockBinding(UniformBlockBindingCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getOpenGLContext()->ObjectManagerRef(); + auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); auto program = glObjectManager.FindProgram(req->program); auto uniformBlockIndex = req->uniformBlockIndex; auto uniformBlockBinding = req->uniformBlockBinding; glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, - "[%d] GL::UniformBlockBinding(program=%d, %d, %d)", - options.isDefaultQueue(), - program, - uniformBlockIndex, - uniformBlockBinding); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform1f(Uniform1fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1563,7 +1551,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glUniform1f(req->location, req->v0); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - auto glContext = reqContentRenderer->getOpenGLContext(); + auto glContext = reqContentRenderer->getContextGL(); PrintDebugInfo(req, nullptr, nullptr, options); DEBUG(DEBUG_TAG, " Program: %d", glContext->program()); } @@ -1579,16 +1567,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface glUniform1fv(location, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - auto glContext = reqContentRenderer->getOpenGLContext(); + PrintDebugInfo(req, nullptr, nullptr, options); + + auto glContext = reqContentRenderer->getContextGL(); auto contentId = reqContentRenderer->getContent()->id; - std::string valuesStr = ""; - for (int i = 0; i < count; i++) - { - valuesStr += std::to_string(value[i]); - if (i < count - 1) - valuesStr += ","; - } - DEBUG(DEBUG_TAG, "[%d] GL::Uniform1fv(%d, count=%d, values=[%s])", options.isDefaultQueue(), location, count, valuesStr.c_str()); DEBUG(DEBUG_TAG, " Content: %d", contentId); DEBUG(DEBUG_TAG, " Program: %d", glContext->program()); } @@ -1598,7 +1580,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto loc = req->location; glUniform1i(loc, req->v0); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform1i(%d): %d", options.isDefaultQueue(), loc, req->v0); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform1iv(Uniform1ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1607,13 +1589,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform1iv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform1iv(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform2f(Uniform2fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glUniform2f(req->location, req->v0, req->v1); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform2f(%d)", options.isDefaultQueue(), req->location); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform2fv(Uniform2fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1622,13 +1604,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform2fv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform2fv(%d, count=%d)", options.isDefaultQueue(), loc, count); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform2i(Uniform2iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glUniform2i(req->location, req->v0, req->v1); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform2i(%d, %d, %d)", options.isDefaultQueue(), req->location, req->v0, req->v1); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform2iv(Uniform2ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1637,7 +1619,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform2iv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform2iv(%d)", options.isDefaultQueue(), req->location); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform3f(Uniform3fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1647,9 +1629,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto v2 = req->v2; glUniform3f(loc, v0, v1, v2); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, "[%d] GL::Uniform3f(%d): (%f, %f, %f)", options.isDefaultQueue(), loc, v0, v1, v2); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform3fv(Uniform3fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1658,7 +1638,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform3fv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform3fv(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform3i(Uniform3iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1668,7 +1648,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto v2 = req->v2; glUniform3i(loc, v0, v1, v2); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform3i(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform3iv(Uniform3ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1677,7 +1657,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform3iv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform3iv(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform4f(Uniform4fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1689,7 +1669,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glUniform4f(loc, v0, v1, v2, v3); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform4f(%d): (%f, %f, %f, %f)", options.isDefaultQueue(), loc, v0, v1, v2, v3); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform4fv(Uniform4fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1698,7 +1678,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform4fv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform4fv(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform4i(Uniform4iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1765,20 +1745,27 @@ class RHI_OpenGL : public TrRenderHardwareInterface bool usePlaceholder = false; size_t matrixValuesSize = req->values.size(); - if (req->isComputationGraph() && deviceFrame != nullptr) + /** + * NOTE(yorkie): Only the `XRFrame` pass can use the computation graph to compute the matrix values. + * + * Computation graph is a feature to allow the content to use the host's live values to set the uniform matrices + * in XRFrame pass to avoid the latency of the XR session. Therefore, we should disable using it for other passes. + */ + if (options.isXRFramePass() && + deviceFrame != nullptr && + req->isComputationGraph()) { - auto activeXRSession = content->getActiveXRSession(); - if (TR_UNLIKELY(activeXRSession == nullptr)) + auto active_xr_session = content->getActiveXRSession(); + if (active_xr_session == nullptr) [[unlikely]] { DEBUG(LOG_TAG_ERROR, "ComputationGraph() only works content which is enabled XR session."); return; } - bool isForMultiview = req->computationGraph4values.multiview; - if (isForMultiview) + if (req->computationGraph4values.multiview) { - auto matrixL = deviceFrame->computeMatrixByGraph(req->computationGraph4values, activeXRSession->id, 0); - auto matrixR = deviceFrame->computeMatrixByGraph(req->computationGraph4values, activeXRSession->id, 1); + auto matrixL = deviceFrame->computeMatrixByGraph(req->computationGraph4values, active_xr_session->id, 0); + auto matrixR = deviceFrame->computeMatrixByGraph(req->computationGraph4values, active_xr_session->id, 1); matrixValuesSize = 32; count = 2; memcpy(m_TmpMatrices, glm::value_ptr(matrixL), 16 * sizeof(float)); @@ -1787,7 +1774,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface } else { - auto matrix = deviceFrame->computeMatrixByGraph(req->computationGraph4values, activeXRSession->id, 0); + auto matrix = deviceFrame->computeMatrixByGraph(req->computationGraph4values, active_xr_session->id, 0); matrixValuesSize = 16; count = 1; memcpy(m_TmpMatrices, glm::value_ptr(matrix), 16 * sizeof(float)); @@ -1796,15 +1783,19 @@ class RHI_OpenGL : public TrRenderHardwareInterface usePlaceholder = true; } - if (TR_UNLIKELY(matrixToUse == nullptr)) + // If the matrix is not computed by computation graph, we should use the values directly. + if (matrixToUse == nullptr) { matrixToUse = req->values.data(); matrixValuesSize = req->values.size(); } - if (TR_UNLIKELY(matrixToUse == nullptr)) + if (matrixToUse == nullptr) [[unlikely]] { - DEBUG(LOG_TAG_ERROR, "UniformMatrix4fv() fails to read the matrix value, placeholderType=%d, deviceFrame=%p", req->computationGraph4values.placeholderId, deviceFrame); + DEBUG(LOG_TAG_ERROR, + "UniformMatrix4fv() fails to read the matrix value, placeholderType=%d, deviceFrame=%p", + req->computationGraph4values.placeholderId, + deviceFrame); return; } @@ -1833,7 +1824,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto first = req->first; auto count = req->count; - reqContentRenderer->getOpenGLContext()->drawArrays(mode, first, count); + reqContentRenderer->getContextGL()->drawArrays(mode, first, count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { PrintDebugInfo(req, nullptr, nullptr, options); @@ -1847,7 +1838,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto type = req->indicesType; auto indices = reinterpret_cast(req->indicesOffset); - reqContentRenderer->getOpenGLContext()->drawElements(mode, count, type, indices); + reqContentRenderer->getContextGL()->drawElements(mode, count, type, indices); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { PrintDebugInfo(req, nullptr, nullptr, options); @@ -1921,7 +1912,10 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDrawRangeElements(mode, start, end, count, type, indices); reqContentRenderer->increaseDrawCallsCount(count); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + { + PrintDebugInfo(req, nullptr, nullptr, options); DumpDrawCallInfo(DEBUG_TAG, "DrawRangeElements", options.isDefaultQueue(), mode, count, type, indices); + } } TR_OPENGL_FUNC void OnHint(HintCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1929,13 +1923,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto mode = req->mode; glHint(target, mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Hint(0x%x, 0x%x)", options.isDefaultQueue(), target, mode); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnLineWidth(LineWidthCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glLineWidth(req->width); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::LineWidth(%f)", options.isDefaultQueue(), req->width); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnPixelStorei(PixelStoreiCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1943,13 +1937,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto param = req->param; glPixelStorei(pname, param); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::PixelStorei(0x%x, %d)", options.isDefaultQueue(), pname, param); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnPolygonOffset(PolygonOffsetCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glPolygonOffset(req->factor, req->units); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::PolygonOffset(%f, %f)", options.isDefaultQueue(), req->factor, req->units); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnSetViewport(SetViewportCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1957,9 +1951,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto y = req->y; auto width = req->width; auto height = req->height; - reqContentRenderer->getOpenGLContext()->setViewport(x, y, width, height); + reqContentRenderer->getContextGL()->setViewport(x, y, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::SetViewport(x=%d, y=%d, w=%d, h=%d)", options.isDefaultQueue(), x, y, width, height); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnSetScissor(SetScissorCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1967,9 +1961,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto y = req->y; auto width = req->width; auto height = req->height; - reqContentRenderer->getOpenGLContext()->setScissor(x, y, width, height); + reqContentRenderer->getContextGL()->setScissor(x, y, width, height); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::SetScissor(x=%d, y=%d, w=%d, h=%d)", options.isDefaultQueue(), x, y, width, height); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnGetSupportedExtensions(GetExtensionsCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1990,7 +1984,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface TR_OPENGL_FUNC void OnDepthMask(DepthMaskCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glDepthMask(req->flag); - reqContentRenderer->getOpenGLContext()->onSetDepthMask(req->flag); + reqContentRenderer->getContextGL()->onSetDepthMask(req->flag); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::DepthMask(%d)", options.isDefaultQueue(), req->flag); } @@ -2013,7 +2007,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint mask = req->mask; glStencilFunc(func, ref, mask); - reqContentRenderer->getOpenGLContext()->onSetStencilFunc(GL_FRONT_AND_BACK, func, ref, mask); + reqContentRenderer->getContextGL()->onSetStencilFunc(GL_FRONT_AND_BACK, func, ref, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::StencilFunc(%d, %d, %d)", options.isDefaultQueue(), func, ref, mask); @@ -2028,7 +2022,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint mask = req->mask; glStencilFuncSeparate(face, func, ref, mask); - reqContentRenderer->getOpenGLContext()->onSetStencilFunc(face, func, ref, mask); + reqContentRenderer->getContextGL()->onSetStencilFunc(face, func, ref, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::StencilFuncSeparate: %d", options.isDefaultQueue(), func); @@ -2037,7 +2031,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { GLuint mask = req->mask; glStencilMask(mask); - reqContentRenderer->getOpenGLContext()->onSetStencilMask(GL_FRONT_AND_BACK, mask); + reqContentRenderer->getContextGL()->onSetStencilMask(GL_FRONT_AND_BACK, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::StencilMask(%d)", options.isDefaultQueue(), mask); @@ -2049,7 +2043,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLenum face = req->face; GLuint mask = req->mask; glStencilMaskSeparate(face, mask); - reqContentRenderer->getOpenGLContext()->onSetStencilMask(face, mask); + reqContentRenderer->getContextGL()->onSetStencilMask(face, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::StencilMaskSeparate(%d)", options.isDefaultQueue(), mask); @@ -2061,7 +2055,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLenum zpass = req->zpass; glStencilOp(fail, zfail, zpass); - reqContentRenderer->getOpenGLContext()->onSetStencilOp(GL_FRONT_AND_BACK, fail, zfail, zpass); + reqContentRenderer->getContextGL()->onSetStencilOp(GL_FRONT_AND_BACK, fail, zfail, zpass); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::StencilOp(%d, %d, %d)", options.isDefaultQueue(), fail, zfail, zpass); @@ -2076,7 +2070,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLenum zpass = req->zpass; glStencilOpSeparate(face, fail, zfail, zpass); - reqContentRenderer->getOpenGLContext()->onSetStencilOp(face, fail, zfail, zpass); + reqContentRenderer->getContextGL()->onSetStencilOp(face, fail, zfail, zpass); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::StencilOpSeparate(%d)", options.isDefaultQueue(), fail); @@ -2104,7 +2098,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface TR_OPENGL_FUNC void OnBlendFunc(BlendFuncCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glBlendFunc(req->sfactor, req->dfactor); - reqContentRenderer->getOpenGLContext()->onSetBlendFunc(req->sfactor, req->dfactor); + reqContentRenderer->getContextGL()->onSetBlendFunc(req->sfactor, req->dfactor); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::BlendFunc(%d)", options.isDefaultQueue(), req->sfactor); } @@ -2117,7 +2111,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto srcAlpha = req->srcAlpha; auto dstAlpha = req->dstAlpha; glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); - reqContentRenderer->getOpenGLContext()->onSetBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + reqContentRenderer->getContextGL()->onSetBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, @@ -2136,7 +2130,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLboolean a = req->alpha; glColorMask(r, g, b, a); - reqContentRenderer->getOpenGLContext()->onSetColorMask(r, g, b, a); + reqContentRenderer->getContextGL()->onSetColorMask(r, g, b, a); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::ColorMask(%d, %d, %d, %d)", options.isDefaultQueue(), r, g, b, a); @@ -2145,7 +2139,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { auto mode = req->mode; glCullFace(mode); - reqContentRenderer->getOpenGLContext()->onSetCullFace(mode); + reqContentRenderer->getContextGL()->onSetCullFace(mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::CullFace(%s)", options.isDefaultQueue(), gles::glEnumToString(mode).c_str()); } @@ -2153,7 +2147,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { auto mode = req->mode; glFrontFace(mode); - reqContentRenderer->getOpenGLContext()->onSetFrontFace(mode); + reqContentRenderer->getContextGL()->onSetFrontFace(mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) DEBUG(DEBUG_TAG, "[%d] GL::FrontFace(%s)", options.isDefaultQueue(), gles::glEnumToString(mode).c_str()); } @@ -2161,7 +2155,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { auto cap = req->cap; glEnable(cap); - reqContentRenderer->getOpenGLContext()->onCapabilityEnabled(cap, true); + reqContentRenderer->getContextGL()->onCapabilityEnabled(cap, true); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -2169,7 +2163,46 @@ class RHI_OpenGL : public TrRenderHardwareInterface { auto cap = req->cap; glDisable(cap); - reqContentRenderer->getOpenGLContext()->onCapabilityEnabled(cap, false); + reqContentRenderer->getContextGL()->onCapabilityEnabled(cap, false); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + TR_OPENGL_FUNC void OnClearColor(ClearColorCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) + { + GLfloat r = TR_OPENGL_GET_NUMBER(req->r); + GLfloat g = TR_OPENGL_GET_NUMBER(req->g); + GLfloat b = TR_OPENGL_GET_NUMBER(req->b); + GLfloat a = TR_OPENGL_GET_NUMBER(req->a); + + reqContentRenderer->getContextGL()->setClearColor(r, g, b, a); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + TR_OPENGL_FUNC void OnClearDepth(ClearDepthCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) + { + reqContentRenderer->getContextGL()->setClearDepth(TR_OPENGL_GET_NUMBER(req->depth)); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + TR_OPENGL_FUNC void OnClearStencil(ClearStencilCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) + { + reqContentRenderer->getContextGL()->setClearStencil(req->stencil); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, nullptr, nullptr, options); + } + TR_OPENGL_FUNC void OnClear(ClearCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + { + if (options.executingPassType != ExecutingPassType::kOffscreenPass) [[unlikely]] + return; + + GLbitfield mask = req->mask; + glClear(mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -2273,12 +2306,12 @@ bool RHI_OpenGL::SupportsWebGL2() int RHI_OpenGL::GetDrawingBufferWidth() { - return GetRenderer()->getOpenGLContext()->viewport().width(); + return GetRenderer()->getContextGL()->viewport().width(); } int RHI_OpenGL::GetDrawingBufferHeight() { - return GetRenderer()->getOpenGLContext()->viewport().height(); + return GetRenderer()->getContextGL()->viewport().height(); } #ifdef ANDROID @@ -2378,7 +2411,7 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectoronCommandBuffersExecuting(); - ContextGLApp *contentGlContext = content_renderer->getOpenGLContext(); + ContextGLApp *contentGlContext = content_renderer->getContextGL(); ContextGLApp contextBaseState = ContextGLApp("tmp", contentGlContext); bool should_copy_to_offscreen_pass = false; @@ -2402,6 +2435,11 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectorObjectManagerRef().FindFramebuffer(req->framebuffer); should_copy_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); + if (should_copy_to_offscreen_pass == true) + { + content_renderer->resetOffscreenPassGLContext(framebuffer); + DEBUG(DEBUG_TAG, "... enter offscreen pass, framebuffer: %d", framebuffer); + } } } } @@ -2564,6 +2602,10 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vector(commandbuffer); @@ -2602,7 +2632,7 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vector Date: Thu, 10 Jul 2025 22:31:41 +0800 Subject: [PATCH 11/27] update --- .../command_buffers/details/texture.hpp | 9 ++ .../command_buffers/webgl_constants.hpp | 25 +++++ src/renderer/gles/context_host.cpp | 11 +- src/renderer/gles/context_storage.cpp | 103 ++++++++++-------- src/renderer/gles/context_storage.hpp | 35 +++++- src/renderer/render_api_opengles.cpp | 30 ++--- 6 files changed, 142 insertions(+), 71 deletions(-) diff --git a/src/common/command_buffers/details/texture.hpp b/src/common/command_buffers/details/texture.hpp index 5f18180f1..ef8df7882 100644 --- a/src/common/command_buffers/details/texture.hpp +++ b/src/common/command_buffers/details/texture.hpp @@ -63,6 +63,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << texture << ")"; + return ss.str(); + } + public: int target; int texture; diff --git a/src/common/command_buffers/webgl_constants.hpp b/src/common/command_buffers/webgl_constants.hpp index 2a94c44e3..f3279e267 100644 --- a/src/common/command_buffers/webgl_constants.hpp +++ b/src/common/command_buffers/webgl_constants.hpp @@ -1170,6 +1170,31 @@ const int WEBGL_MAX_COUNT_PER_DRAWCALL = 1000 * 1000; class WebGLHelper { public: + // Convert a WebGL error code to string label. + static std::string WebGLErrorToString(int error) + { +#define CASE(x) \ + case x: \ + { \ + return #x; \ + } + + switch (error) + { + CASE(WEBGL_NO_ERROR); + CASE(WEBGL_INVALID_ENUM); + CASE(WEBGL_INVALID_VALUE); + CASE(WEBGL_INVALID_OPERATION); + CASE(WEBGL_OUT_OF_MEMORY); + CASE(WEBGL_CONTEXT_LOST_WEBGL); + default: + std::stringstream ss; + ss << "0x" << std::hex << error; + return ss.str(); + } +#undef CASE + } + // Convert a common WebGL enum to string label. static std::string WebGLEnumToString(int e) { diff --git a/src/renderer/gles/context_host.cpp b/src/renderer/gles/context_host.cpp index 86ee87158..96d7af8c0 100644 --- a/src/renderer/gles/context_host.cpp +++ b/src/renderer/gles/context_host.cpp @@ -75,8 +75,15 @@ void ContextGLHost::recordFromHost() m_ScissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST); // Global States - glGetIntegerv(GL_CULL_FACE_MODE, (GLint *)&m_CullFace); - glGetIntegerv(GL_FRONT_FACE, (GLint *)&m_FrontFace); + { + GLenum cullface, frontface; + glGetIntegerv(GL_CULL_FACE_MODE, (GLint *)&cullface); + glGetIntegerv(GL_FRONT_FACE, (GLint *)&frontface); + m_CullFace = cullface; + m_FrontFace = frontface; + } + + // Color mask glGetBooleanv(GL_COLOR_WRITEMASK, (GLboolean *)&m_ColorMask); /** * Recording the depth parameters. diff --git a/src/renderer/gles/context_storage.cpp b/src/renderer/gles/context_storage.cpp index 20fdc4b85..7b64a6dbd 100644 --- a/src/renderer/gles/context_storage.cpp +++ b/src/renderer/gles/context_storage.cpp @@ -123,6 +123,8 @@ void ContextGLStorage::resetProgram(int programToReset) void ContextGLStorage::restore() { + glGetError(); // Clear the error state before restoring + GLenum setViewportError; GLenum useProgramError; GLenum bindBuffersError; @@ -138,66 +140,81 @@ void ContextGLStorage::restore() } setViewportError = glGetError(); - // Restore the capabilities - m_CullFaceEnabled ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE); - m_DepthTestEnabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); - m_DitherEnabled ? glEnable(GL_DITHER) : glDisable(GL_DITHER); - m_BlendEnabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND); - m_StencilTestEnabled ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST); - m_ScissorTestEnabled ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST); + { + GLErrorGuard guard("restoreCapabilities"); + m_CullFaceEnabled ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE); + m_DepthTestEnabled ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); + m_DitherEnabled ? glEnable(GL_DITHER) : glDisable(GL_DITHER); + m_BlendEnabled ? glEnable(GL_BLEND) : glDisable(GL_BLEND); + m_StencilTestEnabled ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST); + m_ScissorTestEnabled ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST); + } - // Restore the clear values - if (m_ClearColor.has_value()) { - const auto &color = m_ClearColor.value(); - glClearColor(color[0], color[1], color[2], color[3]); + GLErrorGuard guard("restoreClearValues"); + if (m_ClearColor.has_value()) + { + const auto &color = m_ClearColor.value(); + glClearColor(color[0], color[1], color[2], color[3]); + } + if (m_ClearDepth.has_value()) + glClearDepthf(m_ClearDepth.value()); + if (m_ClearStencil.has_value()) + glClearStencil(m_ClearStencil.value()); } - if (m_ClearDepth.has_value()) - glClearDepthf(m_ClearDepth.value()); - if (m_ClearStencil.has_value()) - glClearStencil(m_ClearStencil.value()); - // Blend state restore /** * NOTE: The blend function state should not depend on the blend state, it causes the host blend state would be passed to * the app context when the blend state is disabled. */ - if (!m_BlendFunc.isSeparate()) - glBlendFunc(m_BlendFunc.src(), m_BlendFunc.dst()); - else - glBlendFuncSeparate(m_BlendFunc.srcRGB(), m_BlendFunc.dstRGB(), m_BlendFunc.srcAlpha(), m_BlendFunc.dstAlpha()); - - // Cull state restore - glCullFace(m_CullFace); - if (m_FrontFace == GL_CW || m_FrontFace == GL_CCW) - glFrontFace(m_FrontFace); - - // Color state restore - glColorMask(m_ColorMask[0], m_ColorMask[1], m_ColorMask[2], m_ColorMask[3]); + { + GLErrorGuard guard("restoreBlendStates"); + if (!m_BlendFunc.isSeparate()) + glBlendFunc(m_BlendFunc.src(), m_BlendFunc.dst()); + else + glBlendFuncSeparate(m_BlendFunc.srcRGB(), m_BlendFunc.dstRGB(), m_BlendFunc.srcAlpha(), m_BlendFunc.dstAlpha()); + } - // Depth state restore - glDepthMask(m_DepthMask); - glDepthFunc(m_DepthFunc); // TODO: valid depth func enum? - glDepthRangef(m_DepthRange[0], m_DepthRange[1]); + { + GLErrorGuard guard("restoreCullState"); + if (m_CullFace.has_value()) + glCullFace(m_CullFace.value()); + if (m_FrontFace.has_value()) + glFrontFace(m_FrontFace.value()); + } - // Stencil state restore { - glStencilMask(m_StencilMask); - if (m_StencilMask != m_StencilMaskBack) - glStencilMaskSeparate(GL_BACK, m_StencilMaskBack); - glStencilFunc(m_StencilFunc.func, m_StencilFunc.ref, m_StencilFunc.mask); - if (m_StencilFunc != m_StencilFuncBack) - glStencilFuncSeparate(GL_BACK, m_StencilFuncBack.func, m_StencilFuncBack.ref, m_StencilFuncBack.mask); - glStencilOp(m_StencilOp.sfail, m_StencilOp.dpfail, m_StencilOp.dppass); - if (m_StencilOp != m_StencilOpBack) - glStencilOpSeparate(GL_BACK, m_StencilOpBack.sfail, m_StencilOpBack.dpfail, m_StencilOpBack.dppass); + GLErrorGuard guard("restoreColorDepthStencilState"); + glColorMask(m_ColorMask[0], m_ColorMask[1], m_ColorMask[2], m_ColorMask[3]); + + // Depth state restore + glDepthMask(m_DepthMask); + glDepthFunc(m_DepthFunc); // TODO: valid depth func enum? + glDepthRangef(m_DepthRange[0], m_DepthRange[1]); + + // Stencil state restore + { + glStencilMask(m_StencilMask); + if (m_StencilMask != m_StencilMaskBack) + glStencilMaskSeparate(GL_BACK, m_StencilMaskBack); + glStencilFunc(m_StencilFunc.func, m_StencilFunc.ref, m_StencilFunc.mask); + if (m_StencilFunc != m_StencilFuncBack) + glStencilFuncSeparate(GL_BACK, m_StencilFuncBack.func, m_StencilFuncBack.ref, m_StencilFuncBack.mask); + glStencilOp(m_StencilOp.sfail, m_StencilOp.dpfail, m_StencilOp.dppass); + if (m_StencilOp != m_StencilOpBack) + glStencilOpSeparate(GL_BACK, m_StencilOpBack.sfail, m_StencilOpBack.dpfail, m_StencilOpBack.dppass); + } } // Scissor state restore - glScissor(m_ScissorBox.x, m_ScissorBox.y, m_ScissorBox.width, m_ScissorBox.height); + { + GLErrorGuard guard("restoreScissorState"); + glScissor(m_ScissorBox.x, m_ScissorBox.y, m_ScissorBox.width, m_ScissorBox.height); + } // Restoring other states { + GLErrorGuard guard("restoreOtherStates"); glLineWidth(m_LineWidth); glPolygonOffset(m_PolygonOffset.factor, m_PolygonOffset.units); } diff --git a/src/renderer/gles/context_storage.hpp b/src/renderer/gles/context_storage.hpp index c27ec9fd3..266e81edd 100644 --- a/src/renderer/gles/context_storage.hpp +++ b/src/renderer/gles/context_storage.hpp @@ -5,10 +5,34 @@ #include #include #include +#include #include "./common.hpp" #include "./object_manager.hpp" +class GLErrorGuard +{ +public: + GLErrorGuard(std::string name, bool clearError = true) + : name_(std::move(name)) + { + if (clearError) + glGetError(); + } + ~GLErrorGuard() + { + GLenum err = glGetError(); + if (err != GL_NO_ERROR) + DEBUG(LOG_TAG_ERROR, + "Occurs error in %s: %s", + name_.c_str(), + WebGLHelper::WebGLErrorToString(err).c_str()); + } + +private: + std::string name_; +}; + class OpenGLTextureBinding { public: @@ -200,11 +224,14 @@ class ContextGLStorage ContextGLStorage(std::string name) : name_(name) { - glGetBooleanv(GL_CULL_FACE, &m_CullFaceEnabled); - glGetBooleanv(GL_DEPTH_TEST, &m_DepthTestEnabled); } ContextGLStorage(std::string name, ContextGLStorage *from) : name_(name) + , m_ClearColor(from->m_ClearColor) + , m_ClearDepth(from->m_ClearDepth) + , m_ClearStencil(from->m_ClearStencil) + , m_CullFace(from->m_CullFace) + , m_FrontFace(from->m_FrontFace) { // Viewport viewport_[0] = from->viewport_[0]; @@ -322,8 +349,8 @@ class ContextGLStorage // Culling & face GLboolean m_CullFaceEnabled; - GLenum m_CullFace; - GLenum m_FrontFace; + std::optional m_CullFace; + std::optional m_FrontFace; // Color GLboolean m_ColorMask[4]; // [reg, green, blue, alpha] diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index eadb19c05..aeaf45589 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -835,11 +835,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint buffer = glObjectManager.CreateBuffer(req->clientId); reqContentRenderer->getContextGL()->RecordBufferOnCreated(buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, - "[%d] GL::CreateBuffer(%d) => buffer(%d)", - options.isDefaultQueue(), - req->clientId, - buffer); + PrintDebugInfo(req, to_string(buffer).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnDeleteBuffer(DeleteBufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -850,7 +846,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteBuffer(req->buffer); reqContentRenderer->getContextGL()->RecordBufferOnDeleted(buffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteBuffer(%d)", options.isDefaultQueue(), buffer); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBindBuffer(BindBufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -947,10 +943,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface req->isBindToDefault() ? nullopt : make_optional(req->framebuffer), framebuffer); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(LOG_TAG_ERROR, "context name=> %s", app_context->name()); PrintDebugInfo(req, to_string(framebuffer).c_str(), nullptr, options); - } } TR_OPENGL_FUNC void OnFramebufferRenderbuffer(FramebufferRenderbufferCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1155,7 +1148,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint texture = glObjectManager.CreateTexture(req->clientId); reqContentRenderer->getContextGL()->RecordTextureOnCreated(texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateTexture(#%d) => texture(%d)", options.isDefaultQueue(), req->clientId, texture); + PrintDebugInfo(req, to_string(texture).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnDeleteTexture( DeleteTextureCommandBufferRequest *req, @@ -1167,7 +1160,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteTexture(req->texture); reqContentRenderer->getContextGL()->RecordTextureOnDeleted(texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteTexture(%d)", options.isDefaultQueue(), texture); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBindTexture(BindTextureCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1183,15 +1176,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface contentGlContext->onTextureBindingChanged(target, texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { + PrintDebugInfo(req, to_string(texture).c_str(), nullptr, options); + GLint activeUnit; glGetIntegerv(GL_ACTIVE_TEXTURE, &activeUnit); - DEBUG(DEBUG_TAG, - "[%d] GL::BindTexture(%s, texture(%d)) for active(%d) program(%d)", - options.isDefaultQueue(), - gles::glEnumToString(target).c_str(), - texture, - activeUnit, - contentGlContext->program()); + DEBUG(DEBUG_TAG, " active: %d", activeUnit); } } TR_OPENGL_FUNC void OnTexImage2D(TextureImage2DCommandBufferRequest *req, @@ -1200,7 +1189,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { GLenum target = req->target; GLint level = req->level; - GLint internalformat = GL_RGBA; // req->internalformat; + GLint internalformat = req->internalformat; GLsizei width = req->width; GLsizei height = req->height; @@ -2436,10 +2425,7 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectorObjectManagerRef().FindFramebuffer(req->framebuffer); should_copy_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); if (should_copy_to_offscreen_pass == true) - { content_renderer->resetOffscreenPassGLContext(framebuffer); - DEBUG(DEBUG_TAG, "... enter offscreen pass, framebuffer: %d", framebuffer); - } } } } From ab0c499f05d091594b0790683efe99e219a9a7fb Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Sun, 13 Jul 2025 00:25:22 +0800 Subject: [PATCH 12/27] update for fixing blocking link program --- src/bindings/webgl/uniform_location.hpp | 2 +- src/client/graphics/webgl_context.cpp | 536 +++++++++--------- src/client/graphics/webgl_context.hpp | 25 +- src/client/graphics/webgl_program.hpp | 22 +- .../graphics/webgl_uniform_location.hpp | 19 +- src/client/per_process.cpp | 69 ++- src/client/per_process.hpp | 19 + src/common/command_buffers/details/buffer.hpp | 3 +- .../command_buffers/details/texture.hpp | 51 ++ .../command_buffers/details/uniforms.hpp | 175 ++++-- .../command_buffers/details/vertex_array.hpp | 28 + .../command_buffers/details/vertex_attrib.hpp | 37 ++ src/common/ipc_message.hpp | 8 + src/renderer/render_api_opengles.cpp | 220 +++---- 14 files changed, 771 insertions(+), 443 deletions(-) diff --git a/src/bindings/webgl/uniform_location.hpp b/src/bindings/webgl/uniform_location.hpp index 3cd70a350..4da22f5a0 100644 --- a/src/bindings/webgl/uniform_location.hpp +++ b/src/bindings/webgl/uniform_location.hpp @@ -21,7 +21,7 @@ namespace webgl */ int value() const { - return handle_.has_value() ? handle_->index : -1; + return handle_.has_value() ? handle_->index.value_or(-1) : -1; } /** * @returns the name of the uniform location. diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index c358f0ca1..2df9eb852 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -14,17 +14,17 @@ namespace client_graphics using namespace crates::webgl; #ifndef TR_WEBGL_STRICT -#define NOT_IMPLEMENTED() throw std::runtime_error("Not implemented") +#define NOT_IMPLEMENTED() throw runtime_error("Not implemented") #else #define NOT_IMPLEMENTED() #endif -#define ASSERT_MAX_COUNT_PER_DRAWCALL(count, funcName) \ - if (TR_UNLIKELY(count >= WEBGL_MAX_COUNT_PER_DRAWCALL)) \ - { \ - string msg = "The " funcName " count(" + std::to_string(count) + ") exceeds" + \ - " the maximum count(" + std::to_string(WEBGL_MAX_COUNT_PER_DRAWCALL) + ") per draw call."; \ - throw std::runtime_error(msg); \ +#define ASSERT_MAX_COUNT_PER_DRAWCALL(COUNT, FUNC_SYMBOL) \ + if (TR_UNLIKELY(COUNT >= WEBGL_MAX_COUNT_PER_DRAWCALL)) \ + { \ + string msg = "The " FUNC_SYMBOL " count(" + to_string(COUNT) + ") exceeds" + \ + " the maximum count(" + to_string(WEBGL_MAX_COUNT_PER_DRAWCALL) + ") per draw call."; \ + throw runtime_error(msg); \ } void WebGLState::Restore(WebGLState &state, shared_ptr context) @@ -65,7 +65,7 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_WEBGL_CONTEXT_INIT_RES, 3000); if (resp == nullptr) [[unlikely]] - throw std::runtime_error("Failed to initialize WebGL context"); + throw runtime_error("Failed to initialize WebGL context"); auto respondAt = chrono::system_clock::now(); cout << "Received `WebGL1Context` response in " << chrono::duration_cast(respondAt - sentAt).count() << "ms" << endl; @@ -94,15 +94,15 @@ namespace client_graphics sendCommandBufferRequestDirectly(req, true); } - std::shared_ptr WebGLContext::createProgram() + shared_ptr WebGLContext::createProgram() { - auto program = std::make_shared(); + auto program = make_shared(); auto req = CreateProgramCommandBufferRequest(program->id); sendCommandBufferRequest(req); return program; } - void WebGLContext::deleteProgram(std::shared_ptr program) + void WebGLContext::deleteProgram(shared_ptr program) { if (program == nullptr || program->isDeleted()) return; @@ -111,142 +111,138 @@ namespace client_graphics program->markDeleted(); } - class LinkProgramException : public std::runtime_error + class LinkProgramException : public runtime_error { public: - LinkProgramException(WebGLProgram &program, const std::string &detail) - : std::runtime_error(getMessage(program, detail)) + LinkProgramException(WebGLProgram &program, const string &detail) + : runtime_error(getMessage(program, detail)) { } private: - std::string getMessage(WebGLProgram &program, const std::string &detail) + string getMessage(WebGLProgram &program, const string &detail) { - return "Failed to link program(" + std::to_string(program.id) + "): " + detail; + return "Failed to link program(" + to_string(program.id) + "): " + detail; } }; - void WebGLContext::linkProgram(std::shared_ptr program) + void WebGLContext::linkProgram(shared_ptr program) { - if (program == nullptr || !program->isValid()) + if (program == nullptr || !program->isValid()) [[unlikely]] return; auto req = LinkProgramCommandBufferRequest(program->id); if (!sendCommandBufferRequest(req, true)) throw LinkProgramException(*program, "Failed to send the command buffer."); - auto resp = recvCommandBufferResponse(COMMAND_BUFFER_LINK_PROGRAM_RES); - if (resp == nullptr) - { - string msg = "Failed to link program(" + to_string(program->id) + "): timeout."; - throw LinkProgramException(*program, "Timeout."); - } - if (!resp->success) - { - delete resp; - throw LinkProgramException(*program, "Not successful."); - } - - /** - * Mark the program as linked. - */ - program->setLinkStatus(true); - - /** - * Update the program's active attributes and uniforms. - */ + auto onLinkProgramResponse = [this, program](const LinkProgramCommandBufferResponse &resp) { - int index = 0; - for (auto &activeInfo : resp->activeAttribs) - program->setActiveAttrib(index++, activeInfo); - index = 0; - for (auto &activeInfo : resp->activeUniforms) - program->setActiveUniform(index++, activeInfo); - } + // Set the program completed. + program->setCompleted(resp.success); - /** - * Update the program's attribute locations. - */ - for (auto &attribLocation : resp->attribLocations) - program->setAttribLocation(attribLocation.name, attribLocation.location); + // Directly return if the link failed. + if (!resp.success) [[unlikely]] + return; - /** - * See https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getUniformLocation#name - * - * When uniforms declared as an array, the valid name might be like the followings: - * - * - foo - * - foo[0] - * - foo[1] - */ - for (auto &uniformLocation : resp->uniformLocations) - { - auto name = uniformLocation.name; - auto location = uniformLocation.location; - auto size = uniformLocation.size; + /** + * Update the program's active attributes and uniforms. + */ + { + int index = 0; + for (auto &activeInfo : resp.activeAttribs) + program->setActiveAttrib(index++, activeInfo); + index = 0; + for (auto &activeInfo : resp.activeUniforms) + program->setActiveUniform(index++, activeInfo); + } /** - * FIXME: The OpenGL returns "foo[0]" from `glGetActiveUniform()`, thus we need to handle it here: - * - * 1. check if the name ends with "[0]" - * 2. grab the name without "[0]" - * 3. set the uniform location for the name without "[0]" - * 4. set the uniform location for the name with "[0]" and the index - * 5. repeat 4 for the rest of the indices - * - * After the above steps, we will have the names looks like: foo, foo[0], foo[1], foo[2], ... + * Update the program's attribute locations. */ - std::string arraySuffix = "[0]"; - int endedAt = name.length() - arraySuffix.length(); - bool endsWithArray = name.size() > arraySuffix.size() && name.rfind(arraySuffix) != std::string::npos; + for (auto &attribLocation : resp.attribLocations) + program->setAttribLocation(attribLocation.name, attribLocation.location); /** - * Check if size is 1 and not ends with [0], WebGL developers might use 1-size array such as: `[0]`. + * See https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/getUniformLocation#name + * + * When uniforms declared as an array, the valid name might be like the followings: + * + * - foo + * - foo[0] + * - foo[1] */ - if (size == 1 && !endsWithArray) - { - program->setUniformLocation(name, location); - } - else if (endsWithArray) + for (auto &uniformLocation : resp.uniformLocations) { - auto arrayName = name.substr(0, endedAt); - program->setUniformLocation(arrayName, location); - program->setUniformLocation(name, location); - for (int i = 1; i < size; i++) - program->setUniformLocation(arrayName + "[" + std::to_string(i) + "]", location + i); + auto name = uniformLocation.name; + auto location = uniformLocation.location; + auto size = uniformLocation.size; + + /** + * FIXME: The OpenGL returns "foo[0]" from `glGetActiveUniform()`, thus we need to handle it here: + * + * 1. check if the name ends with "[0]" + * 2. grab the name without "[0]" + * 3. set the uniform location for the name without "[0]" + * 4. set the uniform location for the name with "[0]" and the index + * 5. repeat 4 for the rest of the indices + * + * After the above steps, we will have the names looks like: foo, foo[0], foo[1], foo[2], ... + */ + string arraySuffix = "[0]"; + int endedAt = name.length() - arraySuffix.length(); + bool endsWithArray = name.size() > arraySuffix.size() && name.rfind(arraySuffix) != string::npos; + + /** + * Check if size is 1 and not ends with [0], WebGL developers might use 1-size array such as: `[0]`. + */ + if (size == 1 && !endsWithArray) + { + program->setUniformLocation(name, location); + } + else if (endsWithArray) + { + auto arrayName = name.substr(0, endedAt); + program->setUniformLocation(arrayName, location); + program->setUniformLocation(name, location); + for (int i = 1; i < size; i++) + program->setUniformLocation(arrayName + "[" + to_string(i) + "]", location + i); + } + else + { + // TODO: warning size is invalid? + continue; + } } - else - { - // TODO: warning size is invalid? - continue; - } - } - if (isWebGL2_ == true) - { - /** + if (isWebGL2_ == true) + { + /** * Save the uniform block indices to the program object */ - for (auto &uniformBlock : resp->uniformBlocks) - program->setUniformBlockIndex(uniformBlock.name, uniformBlock.index); - } - delete resp; + for (auto &uniformBlock : resp.uniformBlocks) + program->setUniformBlockIndex(uniformBlock.name, uniformBlock.index); + } + }; + recvResponseAsync(COMMAND_BUFFER_LINK_PROGRAM_RES, onLinkProgramResponse); + + // Mark the program linked successfully. + program->setLinkStatus(true); } - void WebGLContext::useProgram(std::shared_ptr program) + void WebGLContext::useProgram(shared_ptr program) { auto req = UseProgramCommandBufferRequest(program == nullptr ? 0 : program->id); sendCommandBufferRequest(req); clientState_.program = program; } - void WebGLContext::bindAttribLocation(std::shared_ptr program, uint32_t index, const std::string &name) + void WebGLContext::bindAttribLocation(shared_ptr program, uint32_t index, const string &name) { auto req = BindAttribLocationCommandBufferRequest(program->id, index, name); sendCommandBufferRequest(req); } - int WebGLContext::getProgramParameter(std::shared_ptr program, int pname) + int WebGLContext::getProgramParameter(shared_ptr program, int pname) { /** * The following parameters are carried when linkProgram() is responded, thus we could return them from the client-side @@ -265,10 +261,10 @@ namespace client_graphics if (resp != nullptr) return resp->value; else - throw std::runtime_error("Failed to get program parameter: timeout."); + throw runtime_error("Failed to get program parameter: timeout."); } - std::string WebGLContext::getProgramInfoLog(std::shared_ptr program) + string WebGLContext::getProgramInfoLog(shared_ptr program) { auto req = GetProgramInfoLogCommandBufferRequest(program->id); sendCommandBufferRequest(req, true); @@ -276,56 +272,56 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_PROGRAM_INFO_LOG_RES); if (resp != nullptr) { - std::string log(resp->infoLog); + string log(resp->infoLog); delete resp; return log; } else { - throw std::runtime_error("Failed to get program info log: timeout."); + throw runtime_error("Failed to get program info log: timeout."); } } - std::shared_ptr WebGLContext::createShader(WebGLShaderType type) + shared_ptr WebGLContext::createShader(WebGLShaderType type) { - auto shader = std::make_shared(type); + auto shader = make_shared(type); auto req = CreateShaderCommandBufferRequest(shader->id, static_cast(type)); sendCommandBufferRequest(req); return shader; } - void WebGLContext::deleteShader(std::shared_ptr shader) + void WebGLContext::deleteShader(shared_ptr shader) { auto req = DeleteShaderCommandBufferRequest(shader->id); sendCommandBufferRequest(req); shader->markDeleted(); } - void WebGLContext::shaderSource(std::shared_ptr shader, const std::string &source) + void WebGLContext::shaderSource(shared_ptr shader, const string &source) { auto req = ShaderSourceCommandBufferRequest(shader->id, GLSLSourcePatcher2::GetPatchedSource(source)); sendCommandBufferRequest(req); } - void WebGLContext::compileShader(std::shared_ptr shader) + void WebGLContext::compileShader(shared_ptr shader) { auto req = CompileShaderCommandBufferRequest(shader->id); sendCommandBufferRequest(req); } - void WebGLContext::attachShader(std::shared_ptr program, std::shared_ptr shader) + void WebGLContext::attachShader(shared_ptr program, shared_ptr shader) { auto req = AttachShaderCommandBufferRequest(program->id, shader->id); sendCommandBufferRequest(req); } - void WebGLContext::detachShader(std::shared_ptr program, std::shared_ptr shader) + void WebGLContext::detachShader(shared_ptr program, shared_ptr shader) { auto req = DetachShaderCommandBufferRequest(program->id, shader->id); sendCommandBufferRequest(req); } - std::string WebGLContext::getShaderSource(std::shared_ptr shader) + string WebGLContext::getShaderSource(shared_ptr shader) { auto req = GetShaderSourceCommandBufferRequest(shader->id); sendCommandBufferRequest(req, true); @@ -333,17 +329,17 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_SHADER_SOURCE_RES); if (resp != nullptr) { - std::string source(resp->source); + string source(resp->source); delete resp; return source; } else { - throw std::runtime_error("Failed to get shader source: timeout."); + throw runtime_error("Failed to get shader source: timeout."); } } - int WebGLContext::getShaderParameter(std::shared_ptr shader, int pname) + int WebGLContext::getShaderParameter(shared_ptr shader, int pname) { auto req = GetShaderParamCommandBufferRequest(shader->id, pname); sendCommandBufferRequest(req, true); @@ -357,11 +353,11 @@ namespace client_graphics } else { - throw std::runtime_error("Failed to get shader parameter: timeout."); + throw runtime_error("Failed to get shader parameter: timeout."); } } - std::string WebGLContext::getShaderInfoLog(std::shared_ptr shader) + string WebGLContext::getShaderInfoLog(shared_ptr shader) { auto req = GetShaderInfoLogCommandBufferRequest(shader->id); sendCommandBufferRequest(req, true); @@ -369,32 +365,32 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_SHADER_INFO_LOG_RES); if (resp != nullptr) { - std::string log(resp->infoLog); + string log(resp->infoLog); delete resp; return log; } else { - throw std::runtime_error("Failed to get shader info log: timeout."); + throw runtime_error("Failed to get shader info log: timeout."); } } - std::shared_ptr WebGLContext::createBuffer() + shared_ptr WebGLContext::createBuffer() { - auto buffer = std::make_shared(); + auto buffer = make_shared(); auto req = CreateBufferCommandBufferRequest(buffer->id); sendCommandBufferRequest(req); return buffer; } - void WebGLContext::deleteBuffer(std::shared_ptr buffer) + void WebGLContext::deleteBuffer(shared_ptr buffer) { auto req = DeleteBufferCommandBufferRequest(buffer->id); sendCommandBufferRequest(req); buffer->markDeleted(); } - void WebGLContext::bindBuffer(WebGLBufferBindingTarget target, std::shared_ptr buffer) + void WebGLContext::bindBuffer(WebGLBufferBindingTarget target, shared_ptr buffer) { uint32_t bufferId = 0; if (buffer != nullptr) @@ -437,22 +433,22 @@ namespace client_graphics sendCommandBufferRequest(req); } - std::shared_ptr WebGLContext::createFramebuffer() + shared_ptr WebGLContext::createFramebuffer() { - auto framebuffer = std::make_shared(); + auto framebuffer = make_shared(); auto req = CreateFramebufferCommandBufferRequest(framebuffer->id); sendCommandBufferRequest(req); return framebuffer; } - void WebGLContext::deleteFramebuffer(std::shared_ptr framebuffer) + void WebGLContext::deleteFramebuffer(shared_ptr framebuffer) { auto req = DeleteFramebufferCommandBufferRequest(framebuffer->id); sendCommandBufferRequest(req); framebuffer->markDeleted(); } - void WebGLContext::bindFramebuffer(WebGLFramebufferBindingTarget target, std::shared_ptr framebuffer) + void WebGLContext::bindFramebuffer(WebGLFramebufferBindingTarget target, shared_ptr framebuffer) { uint32_t framebufferId = 0; if (framebuffer == nullptr) @@ -474,7 +470,7 @@ namespace client_graphics WebGLFramebufferBindingTarget target, WebGLFramebufferAttachment attachment, WebGLRenderbufferBindingTarget renderbuffertarget, - std::shared_ptr renderbuffer) + shared_ptr renderbuffer) { auto req = FramebufferRenderbufferCommandBufferRequest(static_cast(target), static_cast(attachment), @@ -487,7 +483,7 @@ namespace client_graphics WebGLFramebufferBindingTarget target, WebGLFramebufferAttachment attachment, WebGLTexture2DTarget textarget, - std::shared_ptr texture, + shared_ptr texture, int level) { auto req = FramebufferTexture2DCommandBufferRequest(static_cast(target), @@ -512,19 +508,19 @@ namespace client_graphics } else { - throw std::runtime_error("Failed to check framebuffer status: timeout."); + throw runtime_error("Failed to check framebuffer status: timeout."); } } - std::shared_ptr WebGLContext::createRenderbuffer() + shared_ptr WebGLContext::createRenderbuffer() { - auto renderbuffer = std::make_shared(); + auto renderbuffer = make_shared(); auto req = CreateRenderbufferCommandBufferRequest(renderbuffer->id); sendCommandBufferRequest(req); return renderbuffer; } - void WebGLContext::deleteRenderbuffer(std::shared_ptr renderbuffer) + void WebGLContext::deleteRenderbuffer(shared_ptr renderbuffer) { if (renderbuffer == nullptr || renderbuffer->isDeleted()) return; @@ -533,7 +529,7 @@ namespace client_graphics renderbuffer->markDeleted(); } - void WebGLContext::bindRenderbuffer(WebGLRenderbufferBindingTarget target, std::shared_ptr renderbuffer) + void WebGLContext::bindRenderbuffer(WebGLRenderbufferBindingTarget target, shared_ptr renderbuffer) { uint32_t renderbufferId = 0; if (renderbuffer != nullptr) @@ -553,15 +549,15 @@ namespace client_graphics sendCommandBufferRequest(req); } - std::shared_ptr WebGLContext::createTexture() + shared_ptr WebGLContext::createTexture() { - auto texture = std::make_shared(); + auto texture = make_shared(); auto req = CreateTextureCommandBufferRequest(texture->id); sendCommandBufferRequest(req); return texture; } - void WebGLContext::deleteTexture(std::shared_ptr texture) + void WebGLContext::deleteTexture(shared_ptr texture) { if (texture == nullptr || texture->isDeleted()) return; @@ -570,7 +566,7 @@ namespace client_graphics texture->markDeleted(); } - void WebGLContext::bindTexture(WebGLTextureTarget target, std::shared_ptr texture) + void WebGLContext::bindTexture(WebGLTextureTarget target, shared_ptr texture) { uint32_t textureId = 0; if (texture == nullptr) @@ -614,7 +610,7 @@ namespace client_graphics else { unsigned char *pixelsToUse = nullptr; - int max_size = std::max(width, height); + int max_size = max(width, height); if (max_size > transmute::ImageProcessor::DEFAULT_MAX_TEXTURE_SIZE) { const auto &downsampled = transmute::ImageProcessor::GetDownsampledImage(pixels, width, height); @@ -631,7 +627,7 @@ namespace client_graphics { unsigned char *unpacked = unpackPixels(type, format, req.width, req.height, pixelsToUse); if (TR_UNLIKELY(unpacked == nullptr)) - throw std::runtime_error("Failed to unpack pixels, the source data is null."); + throw runtime_error("Failed to unpack pixels, the source data is null."); req.setPixels(unpacked, false); } else @@ -673,7 +669,7 @@ namespace client_graphics height, pixels); if (TR_UNLIKELY(unpacked == nullptr)) - throw std::runtime_error("Failed to unpack pixels, the source data is null."); + throw runtime_error("Failed to unpack pixels, the source data is null."); req.setPixels(unpacked, false); } else @@ -741,12 +737,12 @@ namespace client_graphics sendCommandBufferRequest(req); } - void WebGLContext::texParameterfv(WebGLTextureTarget target, WebGLTextureParameterName pname, const std::vector params) + void WebGLContext::texParameterfv(WebGLTextureTarget target, WebGLTextureParameterName pname, const vector params) { NOT_IMPLEMENTED(); } - void WebGLContext::texParameteriv(WebGLTextureTarget target, WebGLTextureParameterName pname, const std::vector params) + void WebGLContext::texParameteriv(WebGLTextureTarget target, WebGLTextureParameterName pname, const vector params) { NOT_IMPLEMENTED(); } @@ -781,148 +777,161 @@ namespace client_graphics sendCommandBufferRequest(req); } - std::optional WebGLContext::getActiveAttrib(std::shared_ptr program, unsigned int index) + optional WebGLContext::getActiveAttrib(shared_ptr program, unsigned int index) { if (program->hasActiveAttrib(index)) return program->getActiveAttrib(index); else - return std::nullopt; + return nullopt; } - std::optional WebGLContext::getActiveUniform(std::shared_ptr program, unsigned int index) + optional WebGLContext::getActiveUniform(shared_ptr program, unsigned int index) { if (program->hasActiveUniform(index)) return program->getActiveUniform(index); else - return std::nullopt; + return nullopt; } - std::optional WebGLContext::getAttribLocation(std::shared_ptr program, const std::string &name) + optional WebGLContext::getAttribLocation(shared_ptr program, const string &name) { if (program->hasAttribLocation(name)) return program->getAttribLocation(name); else - return std::nullopt; + return nullopt; } - std::optional WebGLContext::getUniformLocation(std::shared_ptr program, - const std::string &name) + optional WebGLContext::getUniformLocation(shared_ptr program, + const string &name) { - if (program->hasUniformLocation(name)) - return program->getUniformLocation(name); + if (program->isIncomplete()) + { + return WebGLUniformLocation(program->id, name); + } else - return std::nullopt; + { + if (program->hasUniformLocation(name)) + return program->getUniformLocation(name); + else + return nullopt; + } } void WebGLContext::uniform1f(WebGLUniformLocation location, float v0) { - auto req = Uniform1fCommandBufferRequest(location.index, v0); + auto req = Uniform1fCommandBufferRequest(location.programId, location.name, v0); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } - void WebGLContext::uniform1fv(WebGLUniformLocation location, const std::vector value) + void WebGLContext::uniform1fv(WebGLUniformLocation location, const vector value) { - auto req = Uniform1fvCommandBufferRequest(location.index, value); + auto req = Uniform1fvCommandBufferRequest(location.index.value_or(0), value); sendCommandBufferRequest(req); } void WebGLContext::uniform1i(WebGLUniformLocation location, int v0) { - auto req = Uniform1iCommandBufferRequest(location.index, v0); + auto req = Uniform1iCommandBufferRequest(location.programId, location.name, v0); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } - void WebGLContext::uniform1iv(WebGLUniformLocation location, const std::vector value) + void WebGLContext::uniform1iv(WebGLUniformLocation location, const vector value) { - auto req = Uniform1ivCommandBufferRequest(location.index, value); + auto req = Uniform1ivCommandBufferRequest(location.index.value_or(0), value); sendCommandBufferRequest(req); } void WebGLContext::uniform2f(WebGLUniformLocation location, float v0, float v1) { - auto req = Uniform2fCommandBufferRequest(location.index, v0, v1); + auto req = Uniform2fCommandBufferRequest(location.index.value_or(0), v0, v1); sendCommandBufferRequest(req); } - void WebGLContext::uniform2fv(WebGLUniformLocation location, const std::vector value) + void WebGLContext::uniform2fv(WebGLUniformLocation location, const vector value) { - auto req = Uniform2fvCommandBufferRequest(location.index, value); + auto req = Uniform2fvCommandBufferRequest(location.index.value_or(0), value); sendCommandBufferRequest(req); } void WebGLContext::uniform2i(WebGLUniformLocation location, int v0, int v1) { - auto req = Uniform2iCommandBufferRequest(location.index, v0, v1); + auto req = Uniform2iCommandBufferRequest(location.index.value_or(0), v0, v1); sendCommandBufferRequest(req); } - void WebGLContext::uniform2iv(WebGLUniformLocation location, const std::vector value) + void WebGLContext::uniform2iv(WebGLUniformLocation location, const vector value) { - auto req = Uniform2ivCommandBufferRequest(location.index, value); + auto req = Uniform2ivCommandBufferRequest(location.index.value_or(0), value); sendCommandBufferRequest(req); } void WebGLContext::uniform3f(WebGLUniformLocation location, float v0, float v1, float v2) { - auto req = Uniform3fCommandBufferRequest(location.index, v0, v1, v2); + auto req = Uniform3fCommandBufferRequest(location.index.value_or(0), v0, v1, v2); sendCommandBufferRequest(req); } - void WebGLContext::uniform3fv(WebGLUniformLocation location, const std::vector value) + void WebGLContext::uniform3fv(WebGLUniformLocation location, const vector value) { - auto req = Uniform3fvCommandBufferRequest(location.index, value); + auto req = Uniform3fvCommandBufferRequest(location.index.value_or(0), value); sendCommandBufferRequest(req); } void WebGLContext::uniform3i(WebGLUniformLocation location, int v0, int v1, int v2) { - auto req = Uniform3iCommandBufferRequest(location.index, v0, v1, v2); + auto req = Uniform3iCommandBufferRequest(location.index.value_or(0), v0, v1, v2); sendCommandBufferRequest(req); } - void WebGLContext::uniform3iv(WebGLUniformLocation location, const std::vector value) + void WebGLContext::uniform3iv(WebGLUniformLocation location, const vector value) { - auto req = Uniform3ivCommandBufferRequest(location.index, value); + auto req = Uniform3ivCommandBufferRequest(location.index.value_or(0), value); sendCommandBufferRequest(req); } void WebGLContext::uniform4f(WebGLUniformLocation location, float v0, float v1, float v2, float v3) { - auto req = Uniform4fCommandBufferRequest(location.index, v0, v1, v2, v3); + auto req = Uniform4fCommandBufferRequest(location.index.value_or(0), v0, v1, v2, v3); sendCommandBufferRequest(req); } - void WebGLContext::uniform4fv(WebGLUniformLocation location, const std::vector value) + void WebGLContext::uniform4fv(WebGLUniformLocation location, const vector value) { - auto req = Uniform4fvCommandBufferRequest(location.index, value); + auto req = Uniform4fvCommandBufferRequest(location.index.value_or(0), value); sendCommandBufferRequest(req); } void WebGLContext::uniform4i(WebGLUniformLocation location, int v0, int v1, int v2, int v3) { - auto req = Uniform4iCommandBufferRequest(location.index, v0, v1, v2, v3); + auto req = Uniform4iCommandBufferRequest(location.index.value_or(0), v0, v1, v2, v3); sendCommandBufferRequest(req); } - void WebGLContext::uniform4iv(WebGLUniformLocation location, const std::vector value) + void WebGLContext::uniform4iv(WebGLUniformLocation location, const vector value) { - auto req = Uniform4ivCommandBufferRequest(location.index, value); + auto req = Uniform4ivCommandBufferRequest(location.index.value_or(0), value); sendCommandBufferRequest(req); } void WebGLContext::uniformMatrix2fv(WebGLUniformLocation location, bool transpose, glm::mat2 m) { - std::vector values = { + vector values = { m[0][0], m[0][1], m[1][0], m[1][1]}; uniformMatrix2fv(location, transpose, values); } - void WebGLContext::uniformMatrix2fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGLContext::uniformMatrix2fv(WebGLUniformLocation location, bool transpose, vector values) { - if (values.size() % 4 != 0) - throw std::runtime_error("Invalid matrix size, expected 4 but got " + std::to_string(values.size())); + if (values.size() % 4 != 0) [[unlikely]] + throw runtime_error("Invalid matrix size, expected 4 but got " + to_string(values.size())); - auto req = UniformMatrix2fvCommandBufferRequest(location.index, transpose, values); + auto req = UniformMatrix2fvCommandBufferRequest(location.programId, location.name, transpose, values); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } @@ -934,7 +943,7 @@ namespace client_graphics void WebGLContext::uniformMatrix3fv(WebGLUniformLocation location, bool transpose, glm::mat3 m) { // clang-format off - std::vector values = { + vector values = { m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2]}; @@ -942,12 +951,14 @@ namespace client_graphics uniformMatrix3fv(location, transpose, values); } - void WebGLContext::uniformMatrix3fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGLContext::uniformMatrix3fv(WebGLUniformLocation location, bool transpose, vector values) { - if (values.size() % 9 != 0) - throw std::runtime_error("Invalid matrix size, expected 9 but got " + std::to_string(values.size())); + if (values.size() % 9 != 0) [[unlikely]] + throw runtime_error("Invalid matrix size, expected 9 but got " + to_string(values.size())); - auto req = UniformMatrix3fvCommandBufferRequest(location.index, transpose, values); + auto req = UniformMatrix3fvCommandBufferRequest(location.programId, location.name, transpose, values); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } @@ -959,7 +970,7 @@ namespace client_graphics void WebGLContext::uniformMatrix4fv(WebGLUniformLocation location, bool transpose, glm::mat4 m) { // clang-format off - std::vector values = { + vector values = { m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], m[2][0], m[2][1], m[2][2], m[2][3], @@ -968,9 +979,12 @@ namespace client_graphics uniformMatrix4fv(location, transpose, values); } - void WebGLContext::uniformMatrix4fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGLContext::uniformMatrix4fv(WebGLUniformLocation location, bool transpose, vector values) { - UniformMatrix4fvCommandBufferRequest req(location.index, transpose); + UniformMatrix4fvCommandBufferRequest req(location.programId, location.name, transpose, values); + if (location.index.has_value()) + req.setLocationIndex(location.index); + auto locationName = location.name; bool runsInXRFrame = false; { @@ -1042,18 +1056,20 @@ namespace client_graphics { size_t length = values.size(); if (length % 16 != 0) [[unlikely]] - throw runtime_error("uniformMatrix4fv() must take 16x float elements array but accept " + std::to_string(length) + "."); + throw runtime_error("uniformMatrix4fv() must take 16x float elements array but accept " + to_string(length) + "."); req.values.resize(length); auto valuesSrc = values.data(); - std::copy(valuesSrc, valuesSrc + length, req.values.begin()); + copy(valuesSrc, valuesSrc + length, req.values.begin()); } sendCommandBufferRequest(req); } void WebGLContext::uniformMatrix4fv(WebGLUniformLocation location, bool transpose, MatrixComputationGraph &graphToValues) { - UniformMatrix4fvCommandBufferRequest req(location.index, transpose); + UniformMatrix4fvCommandBufferRequest req(location.programId, location.name, transpose); + if (location.index.has_value()) + req.setLocationIndex(location.index); req.computationGraph4values = graphToValues; sendCommandBufferRequest(req); } @@ -1113,9 +1129,9 @@ namespace client_graphics { if (x < 0 || y < 0 || width < 0 || height < 0) { - string msg = "viewport() arguments must be positive. x: " + std::to_string(x) + ", y: " + std::to_string(y) + - ", width: " + std::to_string(width) + ", height: " + std::to_string(height); - throw std::runtime_error(msg); + string msg = "viewport() arguments must be positive. x: " + to_string(x) + ", y: " + to_string(y) + + ", width: " + to_string(width) + ", height: " + to_string(height); + throw runtime_error(msg); } if (!viewport_.isEqual(width, height, x, y)) { @@ -1281,8 +1297,8 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_BOOLEANV_RES); if (resp == nullptr) { - std::string msg = "Failed to get boolean parameter(" + std::to_string(static_cast(pname)) + "): timeout."; - throw std::runtime_error(msg); + string msg = "Failed to get boolean parameter(" + to_string(static_cast(pname)) + "): timeout."; + throw runtime_error(msg); } auto v = resp->value; delete resp; @@ -1294,7 +1310,7 @@ namespace client_graphics NOT_IMPLEMENTED(); } - std::vector WebGLContext::getParameter(WebGLFloatArrayParameterName pname) + vector WebGLContext::getParameter(WebGLFloatArrayParameterName pname) { if (pname == WebGLFloatArrayParameterName::kViewport) { @@ -1346,7 +1362,7 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_INTEGERV_RES); if (resp == nullptr) - throw std::runtime_error("Failed to get integer parameter: timeout."); + throw runtime_error("Failed to get integer parameter: timeout."); int v = resp->value; delete resp; @@ -1367,11 +1383,11 @@ namespace client_graphics { auto values = getParameter(pname); if (index < 0 || index >= values.size()) - throw std::runtime_error("Index out of range: " + std::to_string(index)); + throw runtime_error("Index out of range: " + to_string(index)); return values[index]; } - std::string WebGLContext::getParameter(WebGLStringParameterName pname) + string WebGLContext::getParameter(WebGLStringParameterName pname) { if (pname == WebGLStringParameterName::kVendor) return vendor; @@ -1386,11 +1402,11 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_STRING_RES); if (resp == nullptr) { - std::string msg = "Failed to get string parameter(" + std::to_string(static_cast(pname)) + "): timeout."; - throw std::runtime_error(msg); + string msg = "Failed to get string parameter(" + to_string(static_cast(pname)) + "): timeout."; + throw runtime_error(msg); } - std::string v(resp->value); + string v(resp->value); delete resp; return v; } @@ -1402,7 +1418,7 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_SHADER_PRECISION_FORMAT_RES); if (resp == nullptr) - throw std::runtime_error("Failed to get shader precision format: timeout."); + throw runtime_error("Failed to get shader precision format: timeout."); WebGLShaderPrecisionFormat format(*resp); delete resp; @@ -1416,7 +1432,7 @@ namespace client_graphics return res; } - std::vector &WebGLContext::getSupportedExtensions() + vector &WebGLContext::getSupportedExtensions() { if (supportedExtensions_.has_value()) return supportedExtensions_.value(); @@ -1426,13 +1442,13 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_EXTENSIONS_RES); if (resp == nullptr) - throw std::runtime_error("Failed to get supported extensions: timeout."); + throw runtime_error("Failed to get supported extensions: timeout."); - std::vector extensionsList; + vector extensionsList; for (size_t i = 0; i < resp->extensions.size(); i++) { // remove GL_ prefix - std::string extension = resp->extensions[i]; + string extension = resp->extensions[i]; if (extension.find("GL_") == 0) extensionsList.push_back(extension.substr(3)); else @@ -1443,7 +1459,7 @@ namespace client_graphics return supportedExtensions_.value(); } - bool WebGLContext::supportsExtension(const std::string &extension) + bool WebGLContext::supportsExtension(const string &extension) { const auto &extensions = getSupportedExtensions(); for (const auto &ext : extensions) @@ -1480,7 +1496,7 @@ namespace client_graphics return success ? sendFlushCommand(connectedSession) : false; } - bool WebGLContext::sendFlushCommand(std::shared_ptr session) + bool WebGLContext::sendFlushCommand(shared_ptr session) { assert(session != nullptr); auto flushReq = session->createFlushFrameCommand(); @@ -1512,7 +1528,7 @@ namespace client_graphics // Wait for the context init response auto resp = recvCommandBufferResponse(COMMAND_BUFFER_WEBGL2_CONTEXT_INIT_RES); if (resp == nullptr) - throw std::runtime_error("Failed to initialize WebGL2 context: timeout."); + throw runtime_error("Failed to initialize WebGL2 context: timeout."); max3DTextureSize = resp->max3DTextureSize; maxArrayTextureLayers = resp->maxArrayTextureLayers; @@ -1550,7 +1566,7 @@ namespace client_graphics delete resp; } - void WebGL2Context::beginQuery(WebGLQueryTarget target, std::shared_ptr query) + void WebGL2Context::beginQuery(WebGLQueryTarget target, shared_ptr query) { NOT_IMPLEMENTED(); } @@ -1560,7 +1576,7 @@ namespace client_graphics NOT_IMPLEMENTED(); } - void WebGL2Context::bindBufferBase(WebGLBufferBindingTarget target, uint32_t index, std::shared_ptr buffer) + void WebGL2Context::bindBufferBase(WebGLBufferBindingTarget target, uint32_t index, shared_ptr buffer) { uint32_t bufferId = 0; if (buffer != nullptr) @@ -1575,7 +1591,7 @@ namespace client_graphics void WebGL2Context::bindBufferRange(WebGLBufferBindingTarget target, uint32_t index, - std::shared_ptr buffer, + shared_ptr buffer, int offset, size_t size) { @@ -1590,12 +1606,12 @@ namespace client_graphics sendCommandBufferRequest(req); } - void WebGL2Context::bindSampler(uint32_t unit, std::shared_ptr sampler) + void WebGL2Context::bindSampler(uint32_t unit, shared_ptr sampler) { NOT_IMPLEMENTED(); } - void WebGL2Context::bindVertexArray(std::shared_ptr vertexArray) + void WebGL2Context::bindVertexArray(shared_ptr vertexArray) { uint32_t vaoId = 0; if (vertexArray != nullptr) @@ -1639,8 +1655,8 @@ namespace client_graphics size_t srcSize, void *srcData, WebGLBufferUsage usage, - std::optional srcOffset, - std::optional length) + optional srcOffset, + optional length) { // TODO: implement the srcOffset and length auto req = BufferDataCommandBufferRequest(static_cast(target), @@ -1654,25 +1670,25 @@ namespace client_graphics int dstByteOffset, size_t srcSize, void *srcData, - std::optional srcOffset, - std::optional length) + optional srcOffset, + optional length) { // TODO: implement the srcOffset and length auto req = BufferSubDataCommandBufferRequest(static_cast(target), dstByteOffset, srcSize, srcData); sendCommandBufferRequest(req); } - void WebGL2Context::clearBufferfv(WebGLFramebufferAttachmentType buffer, int drawbuffer, std::vector values) + void WebGL2Context::clearBufferfv(WebGLFramebufferAttachmentType buffer, int drawbuffer, vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::clearBufferiv(WebGLFramebufferAttachmentType buffer, int drawbuffer, std::vector values) + void WebGL2Context::clearBufferiv(WebGLFramebufferAttachmentType buffer, int drawbuffer, vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::clearBufferuiv(WebGLFramebufferAttachmentType buffer, int drawbuffer, std::vector values) + void WebGL2Context::clearBufferuiv(WebGLFramebufferAttachmentType buffer, int drawbuffer, vector values) { NOT_IMPLEMENTED(); } @@ -1736,37 +1752,37 @@ namespace client_graphics NOT_IMPLEMENTED(); } - std::shared_ptr WebGL2Context::createQuery() + shared_ptr WebGL2Context::createQuery() { NOT_IMPLEMENTED(); return nullptr; } - std::shared_ptr WebGL2Context::createSampler() + shared_ptr WebGL2Context::createSampler() { NOT_IMPLEMENTED(); return nullptr; } - std::shared_ptr WebGL2Context::createVertexArray() + shared_ptr WebGL2Context::createVertexArray() { - auto vao = std::make_shared(); + auto vao = make_shared(); auto req = CreateVertexArrayCommandBufferRequest(vao->id); sendCommandBufferRequest(req); return vao; } - void WebGL2Context::deleteQuery(std::shared_ptr query) + void WebGL2Context::deleteQuery(shared_ptr query) { NOT_IMPLEMENTED(); } - void WebGL2Context::deleteSampler(std::shared_ptr sampler) + void WebGL2Context::deleteSampler(shared_ptr sampler) { NOT_IMPLEMENTED(); } - void WebGL2Context::deleteVertexArray(std::shared_ptr vertexArray) + void WebGL2Context::deleteVertexArray(shared_ptr vertexArray) { if (vertexArray == nullptr || vertexArray->isDeleted()) return; @@ -1786,7 +1802,7 @@ namespace client_graphics sendFirstContentfulPaintMetrics(); } - void WebGL2Context::drawBuffers(const std::vector buffers) + void WebGL2Context::drawBuffers(const vector buffers) { auto commandBuffer = DrawBuffersCommandBufferRequest(buffers.size(), buffers.data()); sendCommandBufferRequest(commandBuffer); @@ -1825,14 +1841,14 @@ namespace client_graphics void WebGL2Context::framebufferTextureLayer( WebGLFramebufferBindingTarget target, WebGLFramebufferAttachment attachment, - std::shared_ptr texture, + shared_ptr texture, int level, int layer) { NOT_IMPLEMENTED(); } - std::string WebGL2Context::getActiveUniformBlockName(std::shared_ptr program, int uniformBlockIndex) + string WebGL2Context::getActiveUniformBlockName(shared_ptr program, int uniformBlockIndex) { NOT_IMPLEMENTED(); return ""; @@ -1843,13 +1859,13 @@ namespace client_graphics int srcByteOffset, size_t dstSize, void *dstData, - std::optional dstOffset, - std::optional length) + optional dstOffset, + optional length) { NOT_IMPLEMENTED(); } - int WebGL2Context::getFragDataLocation(std::shared_ptr program, const std::string &name) + int WebGL2Context::getFragDataLocation(shared_ptr program, const string &name) { NOT_IMPLEMENTED(); return -1; @@ -1924,20 +1940,20 @@ namespace client_graphics auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_INTEGERV_RES); if (resp == nullptr) - throw std::runtime_error("Failed to get integer parameter: timeout."); + throw runtime_error("Failed to get integer parameter: timeout."); int v = resp->value; delete resp; return v; } - std::shared_ptr WebGL2Context::getQuery(WebGLQueryTarget target, int pname) + shared_ptr WebGL2Context::getQuery(WebGLQueryTarget target, int pname) { NOT_IMPLEMENTED(); return nullptr; } - int WebGL2Context::getUniformBlockIndex(std::shared_ptr program, const std::string &uniformBlockName) + int WebGL2Context::getUniformBlockIndex(shared_ptr program, const string &uniformBlockName) { if (program == nullptr || !program->isValid() || !program->hasUniformBlockIndex(uniformBlockName)) return -1; @@ -1945,14 +1961,14 @@ namespace client_graphics return program->getUniformBlockIndex(uniformBlockName); } - void WebGL2Context::invalidateFramebuffer(WebGLFramebufferBindingTarget target, const std::vector attachments) + void WebGL2Context::invalidateFramebuffer(WebGLFramebufferBindingTarget target, const vector attachments) { NOT_IMPLEMENTED(); } void WebGL2Context::invalidateSubFramebuffer( WebGLFramebufferBindingTarget target, - const std::vector attachments, + const vector attachments, int x, int y, size_t width, @@ -1961,17 +1977,17 @@ namespace client_graphics NOT_IMPLEMENTED(); } - bool WebGL2Context::isQuery(std::shared_ptr query) + bool WebGL2Context::isQuery(shared_ptr query) { return query->isValid(); } - bool WebGL2Context::isSampler(std::shared_ptr sampler) + bool WebGL2Context::isSampler(shared_ptr sampler) { return sampler->isValid(); } - bool WebGL2Context::isVertexArray(std::shared_ptr vertexArray) + bool WebGL2Context::isVertexArray(shared_ptr vertexArray) { return vertexArray->isValid(); } @@ -2080,7 +2096,7 @@ namespace client_graphics sendCommandBufferRequest(req); } - void WebGL2Context::uniformBlockBinding(std::shared_ptr program, + void WebGL2Context::uniformBlockBinding(shared_ptr program, int uniformBlockIndex, uint32_t uniformBlockBinding) { @@ -2093,36 +2109,36 @@ namespace client_graphics } else { - throw std::runtime_error("Uniform block index is out of range."); + throw runtime_error("Uniform block index is out of range."); } } - void WebGL2Context::uniformMatrix3x2fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGL2Context::uniformMatrix3x2fv(WebGLUniformLocation location, bool transpose, vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::uniformMatrix4x2fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGL2Context::uniformMatrix4x2fv(WebGLUniformLocation location, bool transpose, vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::uniformMatrix2x3fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGL2Context::uniformMatrix2x3fv(WebGLUniformLocation location, bool transpose, vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::uniformMatrix4x3fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGL2Context::uniformMatrix4x3fv(WebGLUniformLocation location, bool transpose, vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::uniformMatrix2x4fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGL2Context::uniformMatrix2x4fv(WebGLUniformLocation location, bool transpose, vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::uniformMatrix3x4fv(WebGLUniformLocation location, bool transpose, std::vector values) + void WebGL2Context::uniformMatrix3x4fv(WebGLUniformLocation location, bool transpose, vector values) { NOT_IMPLEMENTED(); } @@ -2143,12 +2159,12 @@ namespace client_graphics NOT_IMPLEMENTED(); } - void WebGL2Context::vertexAttribI4iv(uint32_t index, const std::vector values) + void WebGL2Context::vertexAttribI4iv(uint32_t index, const vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::vertexAttribI4uiv(uint32_t index, const std::vector values) + void WebGL2Context::vertexAttribI4uiv(uint32_t index, const vector values) { NOT_IMPLEMENTED(); } diff --git a/src/client/graphics/webgl_context.hpp b/src/client/graphics/webgl_context.hpp index eda45dd20..92e51b200 100644 --- a/src/client/graphics/webgl_context.hpp +++ b/src/client/graphics/webgl_context.hpp @@ -590,23 +590,34 @@ namespace client_graphics */ bool sendCommandBufferRequest(commandbuffers::TrCommandBufferBase &commandBuffer, bool followsFlush = false); - /** - * It receives a command buffer response from the client context. - */ template R *recvCommandBufferResponse(commandbuffers::CommandBufferType responseType, int timeout = 1000) { auto response = clientContext_->recvCommandBufferResponse(timeout); - if (response == nullptr) + if (response == nullptr) [[unlikely]] return nullptr; assert(response->type == responseType); return dynamic_cast(response); } + template + void recvResponseAsync(commandbuffers::CommandBufferType responseType, std::function callback) + { + auto onResponse = [responseType, callback](const commandbuffers::TrCommandBufferBase &response) + { + if (response.type != responseType) [[unlikely]] + { + std::cerr << "recvCommandBufferAsync(): " + << "Unexpected response type(" << response.type << "), expected(" << responseType << ")" + << std::endl; + assert(false && "Unexpected response type"); + } + callback(dynamic_cast(response)); + }; + clientContext_->recvCommandBufferResponseAsync(onResponse); + } + bool sendFlushCommand(std::shared_ptr session); - /** - * It sends a fcp metrics command buffer request to print the real fcp value. - */ void sendFirstContentfulPaintMetrics(); /** diff --git a/src/client/graphics/webgl_program.hpp b/src/client/graphics/webgl_program.hpp index cb6314189..35c4693a0 100644 --- a/src/client/graphics/webgl_program.hpp +++ b/src/client/graphics/webgl_program.hpp @@ -1,7 +1,9 @@ #pragma once #include -#include "common/command_buffers/details/program.hpp" +#include +#include + #include "./webgl_object.hpp" #include "./webgl_active_info.hpp" #include "./webgl_uniform_location.hpp" @@ -17,6 +19,17 @@ namespace client_graphics } public: + // Returns if this program is incomplete, it means the program response has not been received from channel peer. + bool isIncomplete() const + { + return incomplete_; + } + // Calls setCompleted() when the program response is received from channel peer and updates the link status. + void setCompleted(bool linkStatus) + { + linkStatus_ = linkStatus; + incomplete_ = false; + } /** * It sets the link status of the program. * @@ -71,7 +84,7 @@ namespace client_graphics * @param index The index of the active uniform. * @param activeInfo The active uniform information. */ - void setActiveUniform(int index, commandbuffers::ActiveInfo &activeInfo) + void setActiveUniform(int index, const commandbuffers::ActiveInfo &activeInfo) { activeUniforms_[index] = activeInfo; } @@ -117,7 +130,7 @@ namespace client_graphics */ void setUniformLocation(const std::string &name, int location) { - uniformLocations_[name] = WebGLUniformLocation(location, name); + uniformLocations_[name] = WebGLUniformLocation(id, location, name); } /** * @param name The name of the uniform. @@ -196,10 +209,11 @@ namespace client_graphics std::cout << "Uniform locations:" << std::endl; for (auto &pair : uniformLocations_) - std::cout << " " << pair.first << ": " << pair.second.index << std::endl; + std::cout << " " << pair.first << ": " << pair.second.index.value_or(-1) << std::endl; } private: + std::atomic incomplete_ = true; bool linkStatus_ = false; std::map activeAttribs_; std::map activeUniforms_; diff --git a/src/client/graphics/webgl_uniform_location.hpp b/src/client/graphics/webgl_uniform_location.hpp index 2f2b054dd..155448d04 100644 --- a/src/client/graphics/webgl_uniform_location.hpp +++ b/src/client/graphics/webgl_uniform_location.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace client_graphics { @@ -8,18 +9,28 @@ namespace client_graphics { public: WebGLUniformLocation() - : index(0) + : programId(0) + , index(std::nullopt) , name("") { } - WebGLUniformLocation(uint32_t index, const std::string &name) - : index(index) + WebGLUniformLocation(int programId, const std::string &name) + : programId(programId) + , index(std::nullopt) + , name(name) + { + } + WebGLUniformLocation(int programId, uint32_t index, const std::string &name) + : programId(programId) + , index(index) , name(name) { } public: - uint32_t index; + // The id of the program this uniform belongs to. + int programId; + std::optional index; std::string name; }; } diff --git a/src/client/per_process.cpp b/src/client/per_process.cpp index 57779abb1..e9bc851fc 100644 --- a/src/client/per_process.cpp +++ b/src/client/per_process.cpp @@ -406,15 +406,17 @@ void TrClientContextPerProcess::preload() void TrClientContextPerProcess::start() { string pid = to_string(getpid()); - perfFs = std::make_unique(applicationCacheDirectory, pid.c_str()); + perfFs = make_unique(applicationCacheDirectory, pid.c_str()); // Required channels eventChanClient = ipc::TrOneShotClient::MakeAndConnect(eventChanPort, false, id); assert(eventChanClient != nullptr); mediaChanClient = ipc::TrOneShotClient::MakeAndConnect(mediaChanPort, false, id); assert(mediaChanClient != nullptr); - commandBufferChanClient = ipc::TrOneShotClient::MakeAndConnect(commandBufferChanPort, false, id); - assert(commandBufferChanClient != nullptr); + commandBufferChanClient = ipc::TrOneShotClient::MakeAndConnect(commandBufferChanPort, + false, + id); + assert(commandBufferChanClient != nullptr && commandBufferChanClient->isConnected()); if ( !eventChanClient->isConnected() || @@ -431,20 +433,47 @@ void TrClientContextPerProcess::start() } { // Create sender & receiver for media chan. - mediaChanSender = std::make_unique(mediaChanClient); - mediaChanReceiver = std::make_unique(mediaChanClient); - mediaEventsPollingWorker = std::make_unique("TrMediaEventsPolling", [this](WorkerThread &worker) - { - media_comm::TrMediaCommandMessage incomingEvent; - if (mediaChanReceiver->recvCommand(incomingEvent, 100)) - { - onListenMediaEvent(incomingEvent); - } }); + mediaChanSender = make_unique(mediaChanClient); + mediaChanReceiver = make_unique(mediaChanClient); + + auto onPollingMediaEventsWork = [this](WorkerThread &worker) + { + media_comm::TrMediaCommandMessage incomingEvent; + if (mediaChanReceiver->recvCommand(incomingEvent, 100)) + onListenMediaEvent(incomingEvent); + }; + mediaEventsPollingWorker = make_unique("TrMediaEventsPolling", onPollingMediaEventsWork); } { // Create sender & receiver for commandbuffer chan. commandBufferChanSender = new TrCommandBufferSender(commandBufferChanClient); commandBufferChanReceiver = new TrCommandBufferReceiver(commandBufferChanClient); + + // This worker is used to process the asynchronous command buffer responses. + auto onAsyncCommandBufferResponseWork = [this](WorkerThread &worker) + { + unique_lock lock(asyncCommandBufferResponseMutex); + asyncCommandBufferResponseCv.wait(lock, [this]() + { return !asyncCommandBufferResponseCallbacks.empty(); }); + + while (!asyncCommandBufferResponseCallbacks.empty()) + { + auto &responseCallback = asyncCommandBufferResponseCallbacks.front(); + TrCommandBufferResponse *resp = commandBufferChanReceiver->recvCommandBufferResponse(1000); + if (resp != nullptr) [[likely]] + { + cerr << "Received async command buffer response: " << resp->type << endl; + responseCallback(*resp); + delete resp; // End + } + asyncCommandBufferResponseCallbacks.pop_front(); + } + + // Notify the main thread that the async command buffer response is processed. + asyncCommandBufferResponseCv.notify_one(); + }; + asyncCommandBufferResponseWorker = make_unique("TrAsyncCommandBufferResponseWorker", + onAsyncCommandBufferResponseWork); } // XR device initialization @@ -629,9 +658,25 @@ bool TrClientContextPerProcess::sendCommandBufferRequest(TrCommandBufferBase &co TrCommandBufferResponse *TrClientContextPerProcess::recvCommandBufferResponse(int timeout) { + // Wait for the async command buffer responses to be processed. + if (isAsyncCommandBufferResponseScheduled) + { + unique_lock lock(asyncCommandBufferResponseMutex); + asyncCommandBufferResponseCv.wait(lock, [this]() + { return asyncCommandBufferResponseCallbacks.empty(); }); + isAsyncCommandBufferResponseScheduled = false; + } return commandBufferChanReceiver->recvCommandBufferResponse(timeout); } +void TrClientContextPerProcess::recvCommandBufferResponseAsync(AsyncCommandBufferResponseCallback callback) +{ + unique_lock lock(asyncCommandBufferResponseMutex); + isAsyncCommandBufferResponseScheduled = true; + asyncCommandBufferResponseCallbacks.push_back(callback); + asyncCommandBufferResponseCv.notify_one(); +} + void TrClientContextPerProcess::onListenMediaEvent(media_comm::TrMediaCommandMessage &eventMessage) { auto messageType = eventMessage.getType(); diff --git a/src/client/per_process.hpp b/src/client/per_process.hpp index a6320492e..1050754db 100644 --- a/src/client/per_process.hpp +++ b/src/client/per_process.hpp @@ -2,11 +2,13 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -48,6 +50,7 @@ using namespace media_comm; typedef uint32_t FrameRequestId; typedef function AnimationFrameRequestCallback; +typedef function AsyncCommandBufferResponseCallback; /** * `ScriptEnvironment` represents the environment for executing scripts within the application. It encapsulates the @@ -308,10 +311,21 @@ class TrClientContextPerProcess final : public TrEventTarget getXRDeviceClient() @@ -490,6 +504,11 @@ class TrClientContextPerProcess final : public TrEventTarget *commandBufferChanClient = nullptr; TrCommandBufferSender *commandBufferChanSender = nullptr; TrCommandBufferReceiver *commandBufferChanReceiver = nullptr; + unique_ptr asyncCommandBufferResponseWorker = nullptr; + deque asyncCommandBufferResponseCallbacks; + atomic isAsyncCommandBufferResponseScheduled = false; + mutex asyncCommandBufferResponseMutex; + condition_variable asyncCommandBufferResponseCv; private: // xr fields shared_ptr xrDeviceClient = nullptr; diff --git a/src/common/command_buffers/details/buffer.hpp b/src/common/command_buffers/details/buffer.hpp index f0715a607..3760f6c56 100644 --- a/src/common/command_buffers/details/buffer.hpp +++ b/src/common/command_buffers/details/buffer.hpp @@ -159,8 +159,7 @@ namespace commandbuffers ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << WebGLHelper::WebGLEnumToString(target) << ", " << "Buffer(" << dataSize << "), " - << usage - << ")"; + << WebGLHelper::WebGLEnumToString(usage) << ")"; return ss.str(); } diff --git a/src/common/command_buffers/details/texture.hpp b/src/common/command_buffers/details/texture.hpp index ef8df7882..8e4ff0b1c 100644 --- a/src/common/command_buffers/details/texture.hpp +++ b/src/common/command_buffers/details/texture.hpp @@ -212,6 +212,18 @@ namespace commandbuffers } } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ", " + << level << ", " + << WebGLHelper::WebGLEnumToString(format) << ", " + << WebGLHelper::WebGLEnumToString(pixelType) << ", " + << "pixels=" << "Bytes(" << pixelsByteLength << ", " << pixels << ")"; + return ss.str(); + } + protected: void resetPixels() { @@ -478,6 +490,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(activeUnit) << ")"; + return ss.str(); + } + public: uint32_t activeUnit; }; @@ -499,6 +519,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << WebGLHelper::WebGLEnumToString(target) << ")"; + return ss.str(); + } + public: int target; }; @@ -526,6 +554,17 @@ namespace commandbuffers { return width * height * depth * getPixelSize(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TextureImageNDCommandBufferRequest::toString(line_prefix) + << line_prefix << " internalformat=" << WebGLHelper::WebGLEnumToString(internalformat) << std::endl + << line_prefix << " width=" << width << std::endl + << line_prefix << " height=" << height << std::endl + << line_prefix << " depth=" << depth << std::endl + << line_prefix << " border=" << border; + return ss.str(); + } public: int internalformat; @@ -559,6 +598,18 @@ namespace commandbuffers { return width * height * depth * getPixelSize(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TextureImageNDCommandBufferRequest::toString(line_prefix) + << " xoffset=" << xoffset << std::endl + << " yoffset=" << yoffset << std::endl + << " zoffset=" << zoffset << std::endl + << " width=" << width << std::endl + << " height=" << height << std::endl + << " depth=" << depth; + return ss.str(); + } public: int xoffset; diff --git a/src/common/command_buffers/details/uniforms.hpp b/src/common/command_buffers/details/uniforms.hpp index 338f50c51..12df08c3a 100644 --- a/src/common/command_buffers/details/uniforms.hpp +++ b/src/common/command_buffers/details/uniforms.hpp @@ -67,19 +67,93 @@ namespace commandbuffers uint32_t uniformBlockBinding; }; + template + class SetUniformCommandBufferRequest : public TrCommandBufferSimpleRequest + { + public: + SetUniformCommandBufferRequest(uint32_t program, const std::string &location_name) + : TrCommandBufferSimpleRequest() + , program(program) + , location(0) + , locationAvailable(false) + , locationQueryName(location_name) + { + } + SetUniformCommandBufferRequest(const Derived &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , program(that.program) + , location(that.location) + , locationAvailable(that.locationAvailable) + { + if (clone) + locationQueryName = that.locationQueryName; + } + + public: + virtual TrCommandBufferMessage *serialize() override + { + auto message = new TrCommandBufferMessage(this->type, this->size, this); + if (!locationQueryName.empty()) + message->addStringSegment(locationQueryName); + return message; + } + virtual void deserialize(TrCommandBufferMessage &message) override + { + auto nameSegment = message.nextSegment(); + if (nameSegment != nullptr) + locationQueryName = nameSegment->toString(); + } + void setLocationIndex(std::optional loc_index, bool clear_name = false) + { + if (loc_index.has_value()) + { + location = loc_index.value_or(0); + locationAvailable = true; + if (clear_name) + locationQueryName.clear(); + } + } + + std::string locToString() const + { + std::stringstream loc_ss; + loc_ss << "Loc("; + { + if (locationAvailable) + loc_ss << location << ", "; + else + loc_ss << "?" << ", "; + } + loc_ss << locationQueryName + << ")"; + return loc_ss.str(); + } + virtual std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) + << "(" << locToString() << ")"; + return ss.str(); + } + + public: + uint32_t program; + uint32_t location; + bool locationAvailable; + std::string locationQueryName; + }; + class Uniform1fCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: - Uniform1fCommandBufferRequest(uint32_t location, float v0) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform1fCommandBufferRequest(uint32_t program, const std::string &location_name, float v0) + : SetUniformCommandBufferRequest(program, location_name) , v0(v0) { } Uniform1fCommandBufferRequest(const Uniform1fCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , v0(that.v0) { } @@ -88,13 +162,12 @@ namespace commandbuffers { std::stringstream ss; ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << location << "," + << this->locToString() << "," << v0 << ")"; return ss.str(); } public: - uint32_t location; float v0; }; @@ -139,19 +212,17 @@ namespace commandbuffers }; class Uniform1iCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: Uniform1iCommandBufferRequest() = delete; - Uniform1iCommandBufferRequest(uint32_t location, int v0) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform1iCommandBufferRequest(uint32_t program, const std::string &location_name, int v0) + : SetUniformCommandBufferRequest(program, location_name) , v0(v0) { } Uniform1iCommandBufferRequest(const Uniform1iCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , v0(that.v0) { } @@ -160,13 +231,12 @@ namespace commandbuffers { std::stringstream ss; ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << ")," + << this->locToString() << "," << v0 << ")"; return ss.str(); } public: - uint32_t location; int v0; }; @@ -758,19 +828,21 @@ namespace commandbuffers } }; - template - class UniformMatrixNfvCommandBufferRequest : public TrCommandBufferRequest + template + class UniformMatrixNfvCommandBufferRequest : public SetUniformCommandBufferRequest { public: - UniformMatrixNfvCommandBufferRequest(CommandBufferType type, uint32_t location, bool transpose) - : TrCommandBufferRequest(type, sizeof(T)) - , location(location) + UniformMatrixNfvCommandBufferRequest(uint32_t program, + const std::string &location_name, + bool transpose, + std::vector values = {}) + : SetUniformCommandBufferRequest(program, location_name) , transpose(transpose) + , values(values) { } - UniformMatrixNfvCommandBufferRequest(const UniformMatrixNfvCommandBufferRequest &that, bool clone = false) - : TrCommandBufferRequest(that, clone) - , location(that.location) + UniformMatrixNfvCommandBufferRequest(const Derived &that, bool clone = false) + : SetUniformCommandBufferRequest(that, clone) , transpose(that.transpose) , values() , computationGraph4values(that.computationGraph4values) @@ -795,15 +867,17 @@ namespace commandbuffers public: TrCommandBufferMessage *serialize() override final { - auto message = new TrCommandBufferMessage(type, size, this); - if (values.size() > matrixSize - 1 && values.size() % matrixSize == 0) // Check the value size is Nx + TrCommandBufferMessage *message = SetUniformCommandBufferRequest::serialize(); + if (values.size() > matrixSize - 1 && values.size() % matrixSize == 0) [[likely]] message->addVecSegment(values); return message; } void deserialize(TrCommandBufferMessage &message) override final { - auto valuesSegment = message.getSegment(0); - if (valuesSegment != nullptr) + SetUniformCommandBufferRequest::deserialize(message); + + auto valuesSegment = message.nextSegment(); + if (valuesSegment != nullptr) [[likely]] values = valuesSegment->toVec(); } std::string toString(const char *line_prefix) const override @@ -814,7 +888,7 @@ namespace commandbuffers std::stringstream ss; ss << TrCommandBufferRequest::toString(line_prefix) << "(" - << location << ", " + << this->locToString() << ", " << "values={" << values_ss.str() << ", " << "count=" << count() << ", " << "transpose=" << (transpose ? "Yes" : "No") @@ -823,55 +897,40 @@ namespace commandbuffers } public: - uint32_t location; bool transpose; std::vector values; MatrixComputationGraph computationGraph4values; }; class UniformMatrix2fvCommandBufferRequest final - : public UniformMatrixNfvCommandBufferRequest + : public UniformMatrixNfvCommandBufferRequest { using UniformMatrixNfvCommandBufferRequest::UniformMatrixNfvCommandBufferRequest; - - public: - UniformMatrix2fvCommandBufferRequest(uint32_t location, bool transpose, const std::vector &values) - : UniformMatrixNfvCommandBufferRequest(COMMAND_BUFFER_UNIFORM_MATRIX2FV_REQ, location, transpose) - { - this->values = values; - } }; class UniformMatrix3fvCommandBufferRequest final - : public UniformMatrixNfvCommandBufferRequest + : public UniformMatrixNfvCommandBufferRequest { using UniformMatrixNfvCommandBufferRequest::UniformMatrixNfvCommandBufferRequest; - - public: - UniformMatrix3fvCommandBufferRequest(uint32_t location, bool transpose, const std::vector &values) - : UniformMatrixNfvCommandBufferRequest(COMMAND_BUFFER_UNIFORM_MATRIX3FV_REQ, location, transpose) - { - this->values = values; - } }; class UniformMatrix4fvCommandBufferRequest final - : public UniformMatrixNfvCommandBufferRequest + : public UniformMatrixNfvCommandBufferRequest { using UniformMatrixNfvCommandBufferRequest::UniformMatrixNfvCommandBufferRequest; public: - UniformMatrix4fvCommandBufferRequest(uint32_t location, bool transpose) - : UniformMatrixNfvCommandBufferRequest(COMMAND_BUFFER_UNIFORM_MATRIX4FV_REQ, location, transpose) - { - } - UniformMatrix4fvCommandBufferRequest(uint32_t location, bool transpose, const std::vector &values) - : UniformMatrixNfvCommandBufferRequest(COMMAND_BUFFER_UNIFORM_MATRIX4FV_REQ, location, transpose) - { - this->values = values; - } - UniformMatrix4fvCommandBufferRequest(uint32_t location, bool transpose, MatrixComputationGraph computationGraph4values) - : UniformMatrixNfvCommandBufferRequest(COMMAND_BUFFER_UNIFORM_MATRIX4FV_REQ, location, transpose) + UniformMatrix4fvCommandBufferRequest(uint32_t program, + const std::string &location_name, + bool transpose, + MatrixComputationGraph computationGraph4values) + : UniformMatrixNfvCommandBufferRequest(program, location_name, transpose) { this->computationGraph4values = computationGraph4values; } diff --git a/src/common/command_buffers/details/vertex_array.hpp b/src/common/command_buffers/details/vertex_array.hpp index 0be8b6aac..e9799e065 100644 --- a/src/common/command_buffers/details/vertex_array.hpp +++ b/src/common/command_buffers/details/vertex_array.hpp @@ -22,6 +22,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ")"; + return ss.str(); + } + public: uint32_t clientId; }; @@ -43,6 +50,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << vertexArray << ")"; + return ss.str(); + } + public: uint32_t vertexArray; }; @@ -64,6 +78,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << vertexArray << ")"; + return ss.str(); + } + public: uint32_t vertexArray; }; @@ -85,6 +106,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << vertexArray << ")"; + return ss.str(); + } + public: uint32_t vertexArray; }; diff --git a/src/common/command_buffers/details/vertex_attrib.hpp b/src/common/command_buffers/details/vertex_attrib.hpp index 1dc05da7b..ae7d711cc 100644 --- a/src/common/command_buffers/details/vertex_attrib.hpp +++ b/src/common/command_buffers/details/vertex_attrib.hpp @@ -23,6 +23,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ")"; + return ss.str(); + } + public: uint32_t index; }; @@ -45,6 +52,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ")"; + return ss.str(); + } + public: uint32_t index; }; @@ -75,6 +89,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ", " << conponentSize << ", " + << componentType << ", " << normalized << ", " << stride << ", " << offset << ")"; + return ss.str(); + } + public: uint32_t index; uint32_t conponentSize; @@ -108,6 +130,14 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ", " << componentSize << ", " + << componentType << ", " << stride << ", " << offset << ")"; + return ss.str(); + } + public: uint32_t index; uint32_t componentSize; @@ -134,6 +164,13 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ", " << divisor << ")"; + return ss.str(); + } + public: uint32_t index; uint32_t divisor; diff --git a/src/common/ipc_message.hpp b/src/common/ipc_message.hpp index 750e4023c..adc5bd0cc 100644 --- a/src/common/ipc_message.hpp +++ b/src/common/ipc_message.hpp @@ -159,6 +159,13 @@ namespace ipc { return segments.size(); } + // Returns the next segment by the inserted order. + inline TrIpcMessageSegment *nextSegment() + { + if (segmentReadIndex >= segments.size()) [[unlikely]] + return nullptr; + return segments[segmentReadIndex++]; + } /** * It serializes this message, then allocates and copies the serialized buffer and its size into `outData` and `outSize`. @@ -373,6 +380,7 @@ namespace ipc MessageEnum type; uint32_t id; vector segments; + int segmentReadIndex = 0; private: Usage usage = USAGE_NOTSET; diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index aeaf45589..b8f7e601f 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -445,7 +445,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface ApiCallOptions &options) { auto glContext = reqContentRenderer->getContextGL(); - auto program = glContext->ObjectManagerRef().FindProgram(req->clientId); + GLuint program = glContext->ObjectManagerRef().FindProgram(req->clientId); glLinkProgram(program); reqContentRenderer->getContextGL()->MarkAsDirty(); @@ -464,7 +464,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface delete[] errorStr; LinkProgramCommandBufferResponse failureRes(req, false); - reqContentRenderer->sendCommandBufferResponse(failureRes); + // reqContentRenderer->sendCommandBufferResponse(failureRes); return; } @@ -546,9 +546,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface } if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, "[%d] GL::LinkProgram(%d)", options.isDefaultQueue(), program); - } + PrintDebugInfo(req, to_string(program).c_str(), nullptr, options); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnUseProgram(UseProgramCommandBufferRequest *req, @@ -886,32 +884,25 @@ class RHI_OpenGL : public TrRenderHardwareInterface glBufferData(target, size, data, usage); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, - "[%d] GL::BufferData(%s, size=%d, data=%p, usage=%s)", - options.isDefaultQueue(), - gles::glEnumToString(target).c_str(), - size, - data, - gles::glEnumToString(usage).c_str()); - GLint bindingBuffer; + PrintDebugInfo(req, nullptr, nullptr, options); + + GLint binding_buffer; glGetIntegerv(target == GL_ARRAY_BUFFER ? GL_ARRAY_BUFFER_BINDING : GL_ELEMENT_ARRAY_BUFFER_BINDING, - &bindingBuffer); - DEBUG(DEBUG_TAG, " Binding: %d", bindingBuffer); + &binding_buffer); + DEBUG(DEBUG_TAG, " Binding: %d", binding_buffer); } } - TR_OPENGL_FUNC void OnBufferSubData( - BufferSubDataCommandBufferRequest *req, - renderer::TrContentRenderer *reqContentRenderer, - ApiCallOptions &options) + TR_OPENGL_FUNC void OnBufferSubData(BufferSubDataCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { glBufferSubData(req->target, req->offset, req->dataSize, req->data); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BufferSubData(%d)", options.isDefaultQueue(), req->target); + PrintDebugInfo(req, nullptr, nullptr, options); } - TR_OPENGL_FUNC void OnCreateFramebuffer( - CreateFramebufferCommandBufferRequest *req, - renderer::TrContentRenderer *reqContentRenderer, - ApiCallOptions &options) + TR_OPENGL_FUNC void OnCreateFramebuffer(CreateFramebufferCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); GLuint framebuffer = glObjectManager.CreateFramebuffer(req->clientId); @@ -1112,7 +1103,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLuint vao = glObjectManager.CreateVertexArray(req->clientId); reqContentRenderer->getContextGL()->RecordVertexArrayObjectOnCreated(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CreateVertexArray(%d) => %d", options.isDefaultQueue(), req->clientId, vao); + PrintDebugInfo(req, to_string(vao).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnDeleteVertexArray(DeleteVertexArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1121,7 +1112,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glObjectManager.DeleteVertexArray(req->vertexArray); reqContentRenderer->getContextGL()->RecordVertexArrayObjectOnDeleted(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DeleteVertexArray(%d)", options.isDefaultQueue(), vao); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBindVertexArray(BindVertexArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1137,7 +1128,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glBindVertexArray(vao); reqContentRenderer->getContextGL()->onVertexArrayObjectChanged(vao); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BindVertexArray(%d)", options.isDefaultQueue(), vao); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnCreateTexture( CreateTextureCommandBufferRequest *req, @@ -1320,10 +1311,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getContextGL()->onActiveTextureUnitChanged(textureUnit); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - GLint currentProgram; - glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram); - DEBUG(DEBUG_TAG, "[%d] GL::ActiveTexture(%s)", options.isDefaultQueue(), gles::glEnumToString(textureUnit).c_str()); - DEBUG(DEBUG_TAG, " program: %d", currentProgram); + PrintDebugInfo(req, nullptr, nullptr, options); + + GLint using_program; + glGetIntegerv(GL_CURRENT_PROGRAM, &using_program); + DEBUG(DEBUG_TAG, " program: %d", using_program); DEBUG(DEBUG_TAG, " id: %d", textureUnit - GL_TEXTURE0); } } @@ -1334,11 +1326,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface glGenerateMipmap(req->target); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::GenerateMipmap: %d", options.isDefaultQueue(), req->target); + PrintDebugInfo(req, nullptr, nullptr, options); - GLuint currentTextureBinding; - glGetIntegerv(req->target == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_3D, (GLint *)¤tTextureBinding); - DEBUG(DEBUG_TAG, " current texture binding: %d", currentTextureBinding); + GLuint binding_texture; + glGetIntegerv(req->target == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : GL_TEXTURE_BINDING_3D, (GLint *)&binding_texture); + DEBUG(DEBUG_TAG, " texture binding: %d", binding_texture); } } TR_OPENGL_FUNC void OnTexImage3D(TextureImage3DCommandBufferRequest *req, @@ -1356,18 +1348,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto type = req->pixelType; auto pixels = req->pixels; glTexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, - "[%d] GL::TexImage3D(target=%s, level=%d, size=[%d,%d,%d], pixels=%p)", - options.isDefaultQueue(), - gles::glEnumToString(target).c_str(), - level, - width, - height, - depth, - pixels); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnTexSubImage3D(TextureSubImage3DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1385,21 +1368,9 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto type = req->pixelType; auto pixels = req->pixels; glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { - DEBUG(DEBUG_TAG, - "[%d] GL::TexSubImage3D(target=0x%x, level=%d, offset=[%d,%d,%d], size=[%d,%d,%d], pixels=%p)", - options.isDefaultQueue(), - target, - level, - xoffset, - yoffset, - zoffset, - width, - height, - depth, - pixels); - } + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnTexStorage2D(TextureStorage2DCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1455,7 +1426,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface EnsureVertexArrayObject(reqContentRenderer->getContextGL()); glEnableVertexAttribArray(req->index); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::EnableVertexAttribArray(%d)", options.isDefaultQueue(), req->index); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnDisableVertexAttribArray(DisableVertexAttribArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1469,7 +1440,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface EnsureVertexArrayObject(reqContentRenderer->getContextGL()); glDisableVertexAttribArray(req->index); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DisableVertexAttribArray(%d)", options.isDefaultQueue(), req->index); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnVertexAttribPointer(VertexAttribPointerCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1483,7 +1454,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glVertexAttribPointer(index, size, type, normalized, stride, (const char *)NULL + offset); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::VertexAttribPointer(%d)", options.isDefaultQueue(), index); + PrintDebugInfo(req, nullptr, nullptr, options); DEBUG(DEBUG_TAG, " size=%d", size); DEBUG(DEBUG_TAG, " type=%s", gles::glEnumToString(type).c_str()); DEBUG(DEBUG_TAG, " normalized=%s", normalized ? "Yes" : "No"); @@ -1537,13 +1508,29 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - glUniform1f(req->location, req->v0); - if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + optional loc = nullopt; + if (req->locationAvailable) { - auto glContext = reqContentRenderer->getContextGL(); - PrintDebugInfo(req, nullptr, nullptr, options); - DEBUG(DEBUG_TAG, " Program: %d", glContext->program()); + loc = req->location; + } + else + { + GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); + if (program != 0) [[likely]] + loc = glGetUniformLocation(program, req->locationQueryName.c_str()); } + + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, "uniform1f: Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glUniform1f(loc.value(), req->v0); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) + PrintDebugInfo(req, to_string(loc.value()).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnUniform1fv(Uniform1fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1566,10 +1553,29 @@ class RHI_OpenGL : public TrRenderHardwareInterface } TR_OPENGL_FUNC void OnUniform1i(Uniform1iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - glUniform1i(loc, req->v0); + optional loc = nullopt; + if (req->locationAvailable) + { + loc = req->location; + } + else + { + GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); + if (program != 0) [[likely]] + loc = glGetUniformLocation(program, req->locationQueryName.c_str()); + } + + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, "uniform1f: Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glUniform1i(loc.value(), req->v0); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - PrintDebugInfo(req, nullptr, nullptr, options); + PrintDebugInfo(req, to_string(loc.value()).c_str(), nullptr, options); } TR_OPENGL_FUNC void OnUniform1iv(Uniform1ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1678,7 +1684,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto v3 = req->v3; glUniform4i(loc, v0, v1, v2, v3); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform4i(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform4iv(Uniform4ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1687,7 +1693,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniform4iv(loc, count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::Uniform4iv(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniformMatrix2fv(UniformMatrix2fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1700,7 +1706,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniformMatrix2fv(loc, count, transpose, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::UniformMatrix2fv(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniformMatrix3fv(UniformMatrix3fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1713,14 +1719,33 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto value = req->values.data(); glUniformMatrix3fv(loc, count, transpose, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::UniformMatrix3fv(%d)", options.isDefaultQueue(), loc); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniformMatrix4fv(UniformMatrix4fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options, xr::DeviceFrame *deviceFrame) { - auto location = req->location; + optional loc = nullopt; + if (req->locationAvailable) + { + loc = req->location; + } + else + { + GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); + if (program != 0) [[likely]] + loc = glGetUniformLocation(program, req->locationQueryName.c_str()); + } + + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, "uniformMatrix4fv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + auto count = req->count(); auto transpose = req->transpose; auto content = reqContentRenderer->getContent(); @@ -1788,7 +1813,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface return; } - glUniformMatrix4fv(location, count, transpose, matrixToUse); + glUniformMatrix4fv(loc.value(), count, transpose, matrixToUse); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { PrintDebugInfo(req, nullptr, nullptr, options); @@ -1841,7 +1866,8 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDrawBuffers(n, (const GLenum *)buffers); if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es2/glDrawBuffers") != GL_NO_ERROR || options.printsCall)) { - DEBUG(DEBUG_TAG, "[%d] GL::DrawBuffers()", options.isDefaultQueue()); + PrintDebugInfo(req, nullptr, nullptr, options); + GLint bindingFramebuffer; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bindingFramebuffer); DEBUG(DEBUG_TAG, " framebuffer: %d", bindingFramebuffer); @@ -1967,7 +1993,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface res.extensions.push_back(reinterpret_cast(ret)); } if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::GetSupportedExtensions(): extensions(%d)", options.isDefaultQueue(), numOfExtensions); + { + stringstream res_ss; + res_ss << "Extensions(" << numOfExtensions << ")"; + PrintDebugInfo(req, res_ss.str().c_str(), nullptr, options); + } reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnDepthMask(DepthMaskCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -1975,19 +2005,19 @@ class RHI_OpenGL : public TrRenderHardwareInterface glDepthMask(req->flag); reqContentRenderer->getContextGL()->onSetDepthMask(req->flag); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DepthMask(%d)", options.isDefaultQueue(), req->flag); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnDepthFunc(DepthFuncCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glDepthFunc(req->func); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DepthFunc(%s)", options.isDefaultQueue(), gles::glDepthFuncToString(req->func).c_str()); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnDepthRange(DepthRangeCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glDepthRangef(req->n, req->f); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::DepthRange(%f, %f)", options.isDefaultQueue(), req->n, req->f); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnStencilFunc(StencilFuncCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1999,7 +2029,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getContextGL()->onSetStencilFunc(GL_FRONT_AND_BACK, func, ref, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilFunc(%d, %d, %d)", options.isDefaultQueue(), func, ref, mask); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnStencilFuncSeparate(StencilFuncSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2014,7 +2044,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getContextGL()->onSetStencilFunc(face, func, ref, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilFuncSeparate: %d", options.isDefaultQueue(), func); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnStencilMask(StencilMaskCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -2023,7 +2053,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getContextGL()->onSetStencilMask(GL_FRONT_AND_BACK, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilMask(%d)", options.isDefaultQueue(), mask); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnStencilMaskSeparate(StencilMaskSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2035,7 +2065,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getContextGL()->onSetStencilMask(face, mask); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilMaskSeparate(%d)", options.isDefaultQueue(), mask); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnStencilOp(StencilOpCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -2047,7 +2077,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getContextGL()->onSetStencilOp(GL_FRONT_AND_BACK, fail, zfail, zpass); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilOp(%d, %d, %d)", options.isDefaultQueue(), fail, zfail, zpass); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnStencilOpSeparate(StencilOpSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2062,19 +2092,19 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getContextGL()->onSetStencilOp(face, fail, zfail, zpass); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::StencilOpSeparate(%d)", options.isDefaultQueue(), fail); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBlendColor(BlendColorCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glBlendColor(req->red, req->green, req->blue, req->alpha); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlendColor(%f, %f, %f, %f)", options.isDefaultQueue(), req->red, req->green, req->blue, req->alpha); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBlendEquation(BlendEquationCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glBlendEquation(req->mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlendEquation(%d)", options.isDefaultQueue(), req->mode); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBlendEquationSeparate(BlendEquationSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2082,14 +2112,14 @@ class RHI_OpenGL : public TrRenderHardwareInterface { glBlendEquationSeparate(req->modeRGB, req->modeAlpha); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlendEquationSeparate(%d, %d)", options.isDefaultQueue(), req->modeRGB, req->modeAlpha); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBlendFunc(BlendFuncCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { glBlendFunc(req->sfactor, req->dfactor); reqContentRenderer->getContextGL()->onSetBlendFunc(req->sfactor, req->dfactor); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::BlendFunc(%d)", options.isDefaultQueue(), req->sfactor); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnBlendFuncSeparate(BlendFuncSeparateCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -2122,7 +2152,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface reqContentRenderer->getContextGL()->onSetColorMask(r, g, b, a); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::ColorMask(%d, %d, %d, %d)", options.isDefaultQueue(), r, g, b, a); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnCullFace(CullFaceCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -2130,7 +2160,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glCullFace(mode); reqContentRenderer->getContextGL()->onSetCullFace(mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::CullFace(%s)", options.isDefaultQueue(), gles::glEnumToString(mode).c_str()); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnFrontFace(FrontFaceCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -2138,7 +2168,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface glFrontFace(mode); reqContentRenderer->getContextGL()->onSetFrontFace(mode); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, "[%d] GL::FrontFace(%s)", options.isDefaultQueue(), gles::glEnumToString(mode).c_str()); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnEnable(EnableCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { From f5d1731de690b77e7f33850f981e83b489ac2e0f Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Mon, 14 Jul 2025 21:19:31 +0800 Subject: [PATCH 13/27] update --- src/bindings/webgl/rendering_context-inl.hpp | 32 +- src/bindings/webgl/rendering_context.cpp | 10 +- src/client/builtin_scene/client_renderer.cpp | 10 +- src/client/builtin_scene/instanced_mesh.cpp | 11 +- src/client/builtin_scene/instanced_mesh.hpp | 5 +- src/client/builtin_scene/meshes.hpp | 7 +- src/client/graphics/webgl_attrib_location.hpp | 36 ++ src/client/graphics/webgl_context.cpp | 164 +++++++--- src/client/graphics/webgl_context.hpp | 35 +- src/client/graphics/webgl_program.hpp | 30 +- .../graphics/webgl_uniform_location.hpp | 2 +- src/client/per_process.cpp | 1 - .../command_buffers/details/program.hpp | 9 + .../command_buffers/details/texture.hpp | 10 +- .../command_buffers/details/uniforms.hpp | 233 ++++++------- .../command_buffers/details/vertex_attrib.hpp | 224 +++++++++---- src/renderer/gles/context_app.cpp | 39 +++ src/renderer/gles/context_app.hpp | 10 +- src/renderer/render_api_opengles.cpp | 309 +++++++++++++----- 19 files changed, 799 insertions(+), 378 deletions(-) create mode 100644 src/client/graphics/webgl_attrib_location.hpp diff --git a/src/bindings/webgl/rendering_context-inl.hpp b/src/bindings/webgl/rendering_context-inl.hpp index 027b00974..ce775bae1 100644 --- a/src/bindings/webgl/rendering_context-inl.hpp +++ b/src/bindings/webgl/rendering_context-inl.hpp @@ -14,8 +14,8 @@ #include "./program.hpp" #include "./texture.hpp" #include "./shader.hpp" -#include "./uniform_location.hpp" #include "./active_info.hpp" +#include "./uniform_location.hpp" using namespace std; using namespace node; @@ -324,15 +324,8 @@ namespace webgl auto program = Napi::ObjectWrap::Unwrap(info[0].As()); int pname = info[1].As().Int32Value(); - try - { - int v = glContext_->getProgramParameter(program->handle(), pname); - return Napi::Number::New(env, v); - } - catch (const std::exception &e) - { - return env.Undefined(); - } + int v = glContext_->getProgramParameter(program->handle(), pname); + return Napi::Number::New(env, v); } template @@ -1484,12 +1477,13 @@ namespace webgl Napi::TypeError::New(env, "vertexAttribPointer() takes 6 arguments.").ThrowAsJavaScriptException(); return env.Undefined(); } - auto index = info[0].As().Uint32Value(); - auto size = info[1].As().Uint32Value(); - auto type = info[2].As().Uint32Value(); - auto normalized = info[3].As().Value(); - auto stride = info[4].As().Uint32Value(); - auto offset = info[5].As().Uint32Value(); + + auto index = info[0].ToNumber().Uint32Value(); + auto size = info[1].ToNumber().Uint32Value(); + auto type = info[2].ToNumber().Uint32Value(); + auto normalized = info[3].ToBoolean().Value(); + auto stride = info[4].ToNumber().Uint32Value(); + auto offset = info[5].ToNumber().Uint32Value(); glContext_->vertexAttribPointer(index, size, type, normalized, stride, offset); return env.Undefined(); @@ -1574,10 +1568,10 @@ namespace webgl auto program = Napi::ObjectWrap::Unwrap(info[0].As()); std::string name = info[1].As().Utf8Value(); auto loc = glContext_->getAttribLocation(program->handle(), name); - if (loc.has_value()) - return Napi::Number::New(env, loc.value()); - else + if (!loc.has_value()) return Napi::Number::New(env, -1); + else + return Napi::Number::New(env, loc.value().index.value_or(-1)); } template diff --git a/src/bindings/webgl/rendering_context.cpp b/src/bindings/webgl/rendering_context.cpp index 632743abc..c356682ac 100644 --- a/src/bindings/webgl/rendering_context.cpp +++ b/src/bindings/webgl/rendering_context.cpp @@ -1443,11 +1443,11 @@ namespace webgl return env.Undefined(); } - auto index = info[0].As().Uint32Value(); - auto size = info[1].As().Uint32Value(); - auto type = info[2].As().Uint32Value(); - auto stride = info[3].As().Uint32Value(); - auto offset = info[4].As().Uint32Value(); + auto index = info[0].ToNumber().Uint32Value(); + auto size = info[1].ToNumber().Uint32Value(); + auto type = info[2].ToNumber().Uint32Value(); + auto stride = info[3].ToNumber().Uint32Value(); + auto offset = info[4].ToNumber().Uint32Value(); glContext_->vertexAttribIPointer(index, size, type, stride, offset); return env.Undefined(); diff --git a/src/client/builtin_scene/client_renderer.cpp b/src/client/builtin_scene/client_renderer.cpp index fd90b4a44..e19faaf65 100644 --- a/src/client/builtin_scene/client_renderer.cpp +++ b/src/client/builtin_scene/client_renderer.cpp @@ -53,7 +53,10 @@ namespace builtin_scene /** * Configure the vertext attributes. */ - auto configureAttribute = [this](const IVertexAttribute &attrib, int index, size_t stride, size_t offset) + auto configureAttribute = [this](const IVertexAttribute &attrib, + int index, + size_t stride, + size_t offset) { glContext_->vertexAttribPointer(index, attrib.size(), @@ -94,7 +97,10 @@ namespace builtin_scene /** * Configure the instance attributes. */ - auto configureInstanceAttribute = [this](const IVertexAttribute &attrib, int index, size_t stride, size_t offset) + auto configureInstanceAttribute = [this](const IVertexAttribute &attrib, + int index, + size_t stride, + size_t offset) { glContext_->enableVertexAttribArray(index); glContext_->vertexAttribPointer(index, diff --git a/src/client/builtin_scene/instanced_mesh.cpp b/src/client/builtin_scene/instanced_mesh.cpp index 20bddf18b..bb01948a1 100644 --- a/src/client/builtin_scene/instanced_mesh.cpp +++ b/src/client/builtin_scene/instanced_mesh.cpp @@ -223,7 +223,10 @@ namespace builtin_scene } size_t InstancedMeshBase::iterateInstanceAttributes(shared_ptr program, - function callback) const + function callback) const { auto glContext = glContext_.lock(); if (glContext == nullptr) @@ -234,10 +237,10 @@ namespace builtin_scene for (size_t i = 0; i < INSTANCE_ATTRIBUTES.size(); i++) { auto &name = INSTANCE_ATTRIBUTES[i]; - auto index = glContext->getAttribLocation(program, name); - if (index.has_value()) + auto attribLocation = glContext->getAttribLocation(program, name); + if (attribLocation.has_value()) { - auto instanceIndex = index.value(); + auto instanceIndex = attribLocation.value().index.value_or(-1); if (name == "instanceTransform") { for (int i = 0; i < 4; i++) diff --git a/src/client/builtin_scene/instanced_mesh.hpp b/src/client/builtin_scene/instanced_mesh.hpp index e2ae1f615..bb7d7fd3c 100644 --- a/src/client/builtin_scene/instanced_mesh.hpp +++ b/src/client/builtin_scene/instanced_mesh.hpp @@ -193,7 +193,10 @@ namespace builtin_scene * @returns The number of instance attributes. */ size_t iterateInstanceAttributes(std::shared_ptr program, - std::function callback) const; + std::function callback) const; /** * Get the instance count of this mesh. * diff --git a/src/client/builtin_scene/meshes.hpp b/src/client/builtin_scene/meshes.hpp index dcc936786..4acd6f59b 100644 --- a/src/client/builtin_scene/meshes.hpp +++ b/src/client/builtin_scene/meshes.hpp @@ -192,7 +192,10 @@ namespace builtin_scene * @returns The number of enabled attributes. */ inline size_t iterateEnabledAttributes(std::shared_ptr program, - std::function callback) + std::function callback) { auto glContext = glContext_.lock(); assert(glContext != nullptr); @@ -203,7 +206,7 @@ namespace builtin_scene { auto loc = glContext->getAttribLocation(program, attrib.name()); if (loc.has_value()) - callback(attrib, loc.value(), stride, offset); + callback(attrib, loc.value().index.value_or(-1), stride, offset); offset += attrib.byteLength(); }; return handle_->iterateEnabledAttributes(configureAttrib); diff --git a/src/client/graphics/webgl_attrib_location.hpp b/src/client/graphics/webgl_attrib_location.hpp new file mode 100644 index 000000000..ab3458049 --- /dev/null +++ b/src/client/graphics/webgl_attrib_location.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include + +namespace client_graphics +{ + class WebGLAttribLocation + { + public: + WebGLAttribLocation() + : programId(0) + , index(std::nullopt) + , name("") + { + } + WebGLAttribLocation(int programId, const std::string &name) + : programId(programId) + , index(std::nullopt) + , name(name) + { + } + WebGLAttribLocation(int programId, uint32_t index, const std::string &name) + : programId(programId) + , index(index) + , name(name) + { + } + + public: + // The id of the program this uniform belongs to. + int programId; + std::string name; + std::optional index; + }; +} diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index 2df9eb852..9cc398386 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -137,12 +137,12 @@ namespace client_graphics auto onLinkProgramResponse = [this, program](const LinkProgramCommandBufferResponse &resp) { - // Set the program completed. - program->setCompleted(resp.success); - // Directly return if the link failed. if (!resp.success) [[unlikely]] + { + program->setCompleted(false); return; + } /** * Update the program's active attributes and uniforms. @@ -217,11 +217,14 @@ namespace client_graphics if (isWebGL2_ == true) { /** - * Save the uniform block indices to the program object - */ + * Save the uniform block indices to the program object + */ for (auto &uniformBlock : resp.uniformBlocks) program->setUniformBlockIndex(uniformBlock.name, uniformBlock.index); } + + // Mark the program as completed. + program->setCompleted(true); }; recvResponseAsync(COMMAND_BUFFER_LINK_PROGRAM_RES, onLinkProgramResponse); @@ -759,26 +762,69 @@ namespace client_graphics sendCommandBufferRequest(req); } - void WebGLContext::enableVertexAttribArray(unsigned int index) + void WebGLContext::enableVertexAttribArray(const WebGLAttribLocation &index) + { + auto req = EnableVertexAttribArrayCommandBufferRequest(index.programId, index.name); + if (index.index.has_value()) + req.setLoc(index.index); + sendCommandBufferRequest(req); + } + + void WebGLContext::enableVertexAttribArray(int index) + { + auto req = EnableVertexAttribArrayCommandBufferRequest(0, index); + sendCommandBufferRequest(req); + } + + void WebGLContext::disableVertexAttribArray(const WebGLAttribLocation &index) { - auto req = EnableVertexAttribArrayCommandBufferRequest(index); + auto req = DisableVertexAttribArrayCommandBufferRequest(index.programId, index.name); + if (index.index.has_value()) + req.setLoc(index.index); sendCommandBufferRequest(req); } - void WebGLContext::disableVertexAttribArray(unsigned int index) + void WebGLContext::disableVertexAttribArray(int index) { - auto req = DisableVertexAttribArrayCommandBufferRequest(index); + auto req = DisableVertexAttribArrayCommandBufferRequest(0, index); sendCommandBufferRequest(req); } - void WebGLContext::vertexAttribPointer(unsigned int index, size_t size, int type, bool normalized, size_t stride, int offset) + void WebGLContext::vertexAttribPointer(const WebGLAttribLocation &index, + size_t size, + int type, + bool normalized, + size_t stride, + int offset) { - auto req = VertexAttribPointerCommandBufferRequest(index, size, type, normalized, stride, offset); + auto req = VertexAttribPointerCommandBufferRequest(index.programId, + index.name, + size, + type, + normalized, + stride, + offset); + if (index.index.has_value()) + req.setLoc(index.index); + sendCommandBufferRequest(req); + } + + void WebGLContext::vertexAttribPointer(int index, + size_t size, + int type, + bool normalized, + size_t stride, + int offset) + { + auto req = VertexAttribPointerCommandBufferRequest(0, index, size, type, normalized, stride, offset); sendCommandBufferRequest(req); } optional WebGLContext::getActiveAttrib(shared_ptr program, unsigned int index) { + assert(program != nullptr && "Program is not null"); + program->waitForCompleted(); + if (program->hasActiveAttrib(index)) return program->getActiveAttrib(index); else @@ -787,18 +833,24 @@ namespace client_graphics optional WebGLContext::getActiveUniform(shared_ptr program, unsigned int index) { + assert(program != nullptr && "Program is not null"); + program->waitForCompleted(); + if (program->hasActiveUniform(index)) return program->getActiveUniform(index); else return nullopt; } - optional WebGLContext::getAttribLocation(shared_ptr program, const string &name) + optional WebGLContext::getAttribLocation(shared_ptr program, const string &name) { + assert(program != nullptr && "Program is not null"); + program->waitForCompleted(); + if (program->hasAttribLocation(name)) - return program->getAttribLocation(name); - else - return nullopt; + return program->getAttribLocation(name); + else + return nullopt; } optional WebGLContext::getUniformLocation(shared_ptr program, @@ -847,31 +899,41 @@ namespace client_graphics void WebGLContext::uniform2f(WebGLUniformLocation location, float v0, float v1) { - auto req = Uniform2fCommandBufferRequest(location.index.value_or(0), v0, v1); + auto req = Uniform2fCommandBufferRequest(location.programId, location.name, v0, v1); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform2fv(WebGLUniformLocation location, const vector value) { - auto req = Uniform2fvCommandBufferRequest(location.index.value_or(0), value); + auto req = Uniform2fvCommandBufferRequest(location.programId, location.name, value); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform2i(WebGLUniformLocation location, int v0, int v1) { - auto req = Uniform2iCommandBufferRequest(location.index.value_or(0), v0, v1); + auto req = Uniform2iCommandBufferRequest(location.programId, location.name, v0, v1); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform2iv(WebGLUniformLocation location, const vector value) { - auto req = Uniform2ivCommandBufferRequest(location.index.value_or(0), value); + auto req = Uniform2ivCommandBufferRequest(location.programId, location.name, value); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform3f(WebGLUniformLocation location, float v0, float v1, float v2) { - auto req = Uniform3fCommandBufferRequest(location.index.value_or(0), v0, v1, v2); + auto req = Uniform3fCommandBufferRequest(location.programId, location.name, v0, v1, v2); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } @@ -895,25 +957,33 @@ namespace client_graphics void WebGLContext::uniform4f(WebGLUniformLocation location, float v0, float v1, float v2, float v3) { - auto req = Uniform4fCommandBufferRequest(location.index.value_or(0), v0, v1, v2, v3); + auto req = Uniform4fCommandBufferRequest(location.programId, location.name, v0, v1, v2, v3); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform4fv(WebGLUniformLocation location, const vector value) { - auto req = Uniform4fvCommandBufferRequest(location.index.value_or(0), value); + auto req = Uniform4fvCommandBufferRequest(location.programId, location.name, value); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform4i(WebGLUniformLocation location, int v0, int v1, int v2, int v3) { - auto req = Uniform4iCommandBufferRequest(location.index.value_or(0), v0, v1, v2, v3); + auto req = Uniform4iCommandBufferRequest(location.programId, location.name, v0, v1, v2, v3); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform4iv(WebGLUniformLocation location, const vector value) { - auto req = Uniform4ivCommandBufferRequest(location.index.value_or(0), value); + auto req = Uniform4ivCommandBufferRequest(location.programId, location.name, value); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } @@ -1955,6 +2025,9 @@ namespace client_graphics int WebGL2Context::getUniformBlockIndex(shared_ptr program, const string &uniformBlockName) { + assert(program != nullptr && "Program must not be null."); + program->waitForCompleted(); + if (program == nullptr || !program->isValid() || !program->hasUniformBlockIndex(uniformBlockName)) return -1; else @@ -2143,40 +2216,55 @@ namespace client_graphics NOT_IMPLEMENTED(); } - void WebGL2Context::vertexAttribDivisor(uint32_t index, uint32_t divisor) + void WebGL2Context::vertexAttribDivisor(const WebGLAttribLocation &loc, uint32_t divisor) + { + auto req = VertexAttribDivisorCommandBufferRequest(loc.programId, loc.name, divisor); + if (loc.index.has_value()) + req.setLoc(loc.index.value()); + sendCommandBufferRequest(req); + } + + void WebGL2Context::vertexAttribDivisor(int index, uint32_t divisor) { - auto req = VertexAttribDivisorCommandBufferRequest(index, divisor); + auto req = VertexAttribDivisorCommandBufferRequest(0, index, divisor); sendCommandBufferRequest(req); } - void WebGL2Context::vertexAttribI4i(uint32_t index, int x, int y, int z, int w) + void WebGL2Context::vertexAttribI4i(const WebGLAttribLocation &, int x, int y, int z, int w) { NOT_IMPLEMENTED(); } - void WebGL2Context::vertexAttribI4ui(uint32_t index, uint x, uint y, uint z, uint w) + void WebGL2Context::vertexAttribI4ui(const WebGLAttribLocation &, uint x, uint y, uint z, uint w) { NOT_IMPLEMENTED(); } - void WebGL2Context::vertexAttribI4iv(uint32_t index, const vector values) + void WebGL2Context::vertexAttribI4iv(const WebGLAttribLocation &, const vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::vertexAttribI4uiv(uint32_t index, const vector values) + void WebGL2Context::vertexAttribI4uiv(const WebGLAttribLocation &, const vector values) { NOT_IMPLEMENTED(); } - void WebGL2Context::vertexAttribIPointer( - uint32_t index, - int size, - int type, - int stride, - int offset) + void WebGL2Context::vertexAttribIPointer(const WebGLAttribLocation &loc, + int size, + int type, + int stride, + int offset) { - auto commandBuffer = VertexAttribIPointerCommandBufferRequest(index, size, type, stride, offset); - sendCommandBufferRequest(commandBuffer); + auto req = VertexAttribIPointerCommandBufferRequest(loc.programId, loc.name, size, type, stride, offset); + if (loc.index.has_value()) + req.setLoc(loc.index.value()); + sendCommandBufferRequest(req); + } + + void WebGL2Context::vertexAttribIPointer(int index, int size, int type, int stride, int offset) + { + auto req = VertexAttribIPointerCommandBufferRequest(0, index, size, type, stride, offset); + sendCommandBufferRequest(req); } } diff --git a/src/client/graphics/webgl_context.hpp b/src/client/graphics/webgl_context.hpp index 92e51b200..7ae4526cf 100644 --- a/src/client/graphics/webgl_context.hpp +++ b/src/client/graphics/webgl_context.hpp @@ -18,6 +18,7 @@ #include "./webgl_framebuffer.hpp" #include "./webgl_renderbuffer.hpp" #include "./webgl_texture.hpp" +#include "./webgl_attrib_location.hpp" #include "./webgl_uniform_location.hpp" #include "./webgl_query.hpp" #include "./webgl_sampler.hpp" @@ -399,12 +400,15 @@ namespace client_graphics void texParameteriv(WebGLTextureTarget target, WebGLTextureParameterName pname, const std::vector params); void activeTexture(WebGLTextureUnit texture); void generateMipmap(WebGLTextureTarget target); - void enableVertexAttribArray(unsigned int index); - void disableVertexAttribArray(unsigned int index); - void vertexAttribPointer(unsigned int index, size_t size, int type, bool normalized, size_t stride, int offset); + void enableVertexAttribArray(const WebGLAttribLocation &); + void enableVertexAttribArray(int index); + void disableVertexAttribArray(const WebGLAttribLocation &); + void disableVertexAttribArray(int index); + void vertexAttribPointer(const WebGLAttribLocation &, size_t size, int type, bool normalized, size_t stride, int offset); + void vertexAttribPointer(int index, size_t size, int type, bool normalized, size_t stride, int offset); std::optional getActiveAttrib(std::shared_ptr program, unsigned int index); std::optional getActiveUniform(std::shared_ptr program, unsigned int index); - std::optional getAttribLocation(std::shared_ptr program, const std::string &name); + std::optional getAttribLocation(std::shared_ptr program, const std::string &name); std::optional getUniformLocation(std::shared_ptr program, const std::string &name); void uniform1f(WebGLUniformLocation location, float v0); void uniform1fv(WebGLUniformLocation location, const std::vector value); @@ -1147,7 +1151,8 @@ namespace client_graphics * @param index The index of the vertex attribute. * @param divisor The number of instances that will pass between updates of the generic attribute. */ - void vertexAttribDivisor(uint32_t index, uint32_t divisor); + void vertexAttribDivisor(const WebGLAttribLocation &, uint32_t divisor); + void vertexAttribDivisor(int index, uint32_t divisor); /** * It specify integer values for generic vertex attributes. * @@ -1157,7 +1162,7 @@ namespace client_graphics * @param z The z value to set. * @param w The w value to set. */ - void vertexAttribI4i(uint32_t index, int x, int y, int z, int w); + void vertexAttribI4i(const WebGLAttribLocation &, int x, int y, int z, int w); /** * It specify unsigned integer values for generic vertex attributes. * @@ -1167,21 +1172,21 @@ namespace client_graphics * @param z The z value to set. * @param w The w value to set. */ - void vertexAttribI4ui(uint32_t index, uint x, uint y, uint z, uint w); + void vertexAttribI4ui(const WebGLAttribLocation &, uint x, uint y, uint z, uint w); /** * It specify integer values for generic vertex attributes from a vector. * * @param index The index of the vertex attribute. * @param values The values to set. */ - void vertexAttribI4iv(uint32_t index, const std::vector values); + void vertexAttribI4iv(const WebGLAttribLocation &, const std::vector values); /** * It specify unsigned integer values for generic vertex attributes from a vector. * * @param index The index of the vertex attribute. * @param values The values to set. */ - void vertexAttribI4uiv(uint32_t index, const std::vector values); + void vertexAttribI4uiv(const WebGLAttribLocation &, const std::vector values); /** * It specifies integer data formats and locations of vertex attributes in a vertex attributes array. * @@ -1192,12 +1197,12 @@ namespace client_graphics * @param stride The offset in bytes between the beginning of consecutive vertex attributes. * @param offset An offset in bytes of the first component in the vertex attribute array. Must be a multiple of type. */ - void vertexAttribIPointer( - uint32_t index, - int size, - int type, - int stride, - int offset); + void vertexAttribIPointer(const WebGLAttribLocation &, + int size, + int type, + int stride, + int offset); + void vertexAttribIPointer(int index, int size, int type, int stride, int offset); public: // WebGL2 properties int max3DTextureSize; diff --git a/src/client/graphics/webgl_program.hpp b/src/client/graphics/webgl_program.hpp index 35c4693a0..9c7020e05 100644 --- a/src/client/graphics/webgl_program.hpp +++ b/src/client/graphics/webgl_program.hpp @@ -1,11 +1,15 @@ #pragma once #include +#include #include +#include +#include #include #include "./webgl_object.hpp" #include "./webgl_active_info.hpp" +#include "./webgl_attrib_location.hpp" #include "./webgl_uniform_location.hpp" namespace client_graphics @@ -24,11 +28,22 @@ namespace client_graphics { return incomplete_; } + // Waits for the program to be completed, it will block until the program response is received from channel peer. + void waitForCompleted(int timeout = 2000) + { + std::unique_lock lock(setCompletedMutex_); + setCompletedCv_.wait_for(lock, std::chrono::milliseconds(timeout), [this]() + { return !incomplete_; }); + } // Calls setCompleted() when the program response is received from channel peer and updates the link status. void setCompleted(bool linkStatus) { linkStatus_ = linkStatus; incomplete_ = false; + { + std::unique_lock lock(setCompletedMutex_); + setCompletedCv_.notify_all(); + } } /** * It sets the link status of the program. @@ -104,7 +119,7 @@ namespace client_graphics */ void setAttribLocation(const std::string &name, int location) { - attribLocations_[name] = location; + attribLocations_[name] = WebGLAttribLocation(id, location, name); } /** * @param name The name of the attribute. @@ -118,7 +133,7 @@ namespace client_graphics * @param name The name of the attribute. * @returns The attribute location for the given name. */ - int getAttribLocation(const std::string &name) + const WebGLAttribLocation &getAttribLocation(const std::string &name) { return attribLocations_[name]; } @@ -144,7 +159,7 @@ namespace client_graphics * @param name The name of the uniform. * @returns The uniform location for the given name. */ - WebGLUniformLocation getUniformLocation(const std::string &name) + const WebGLUniformLocation &getUniformLocation(const std::string &name) { return uniformLocations_[name]; } @@ -205,7 +220,7 @@ namespace client_graphics std::cout << "Attribute locations:" << std::endl; for (auto &pair : attribLocations_) - std::cout << " " << pair.first << ": " << pair.second << std::endl; + std::cout << " " << pair.first << ": " << pair.second.index.value_or(-1) << std::endl; std::cout << "Uniform locations:" << std::endl; for (auto &pair : uniformLocations_) @@ -214,11 +229,14 @@ namespace client_graphics private: std::atomic incomplete_ = true; + std::mutex setCompletedMutex_; + std::condition_variable setCompletedCv_; + bool linkStatus_ = false; std::map activeAttribs_; std::map activeUniforms_; - std::map attribLocations_; - std::map uniformLocations_; + std::unordered_map attribLocations_; + std::unordered_map uniformLocations_; std::map uniformBlockIndices_; }; } diff --git a/src/client/graphics/webgl_uniform_location.hpp b/src/client/graphics/webgl_uniform_location.hpp index 155448d04..ac084e35a 100644 --- a/src/client/graphics/webgl_uniform_location.hpp +++ b/src/client/graphics/webgl_uniform_location.hpp @@ -30,7 +30,7 @@ namespace client_graphics public: // The id of the program this uniform belongs to. int programId; - std::optional index; std::string name; + std::optional index; }; } diff --git a/src/client/per_process.cpp b/src/client/per_process.cpp index e9bc851fc..50f727b5a 100644 --- a/src/client/per_process.cpp +++ b/src/client/per_process.cpp @@ -462,7 +462,6 @@ void TrClientContextPerProcess::start() TrCommandBufferResponse *resp = commandBufferChanReceiver->recvCommandBufferResponse(1000); if (resp != nullptr) [[likely]] { - cerr << "Received async command buffer response: " << resp->type << endl; responseCallback(*resp); delete resp; // End } diff --git a/src/common/command_buffers/details/program.hpp b/src/common/command_buffers/details/program.hpp index 660ec232c..94e71eb37 100644 --- a/src/common/command_buffers/details/program.hpp +++ b/src/common/command_buffers/details/program.hpp @@ -438,6 +438,15 @@ namespace commandbuffers { } + std::string toString(const char *line_prefix) const override + { + std::stringstream ss; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << clientId << ", " + << WebGLHelper::WebGLEnumToString(pname) << ")"; + return ss.str(); + } + public: uint32_t clientId; uint32_t pname; diff --git a/src/common/command_buffers/details/texture.hpp b/src/common/command_buffers/details/texture.hpp index 8e4ff0b1c..131dad1e3 100644 --- a/src/common/command_buffers/details/texture.hpp +++ b/src/common/command_buffers/details/texture.hpp @@ -558,11 +558,11 @@ namespace commandbuffers { std::stringstream ss; ss << TextureImageNDCommandBufferRequest::toString(line_prefix) - << line_prefix << " internalformat=" << WebGLHelper::WebGLEnumToString(internalformat) << std::endl - << line_prefix << " width=" << width << std::endl - << line_prefix << " height=" << height << std::endl - << line_prefix << " depth=" << depth << std::endl - << line_prefix << " border=" << border; + << " internalformat=" << WebGLHelper::WebGLEnumToString(internalformat) << std::endl + << " width=" << width << std::endl + << " height=" << height << std::endl + << " depth=" << depth << std::endl + << " border=" << border; return ss.str(); } diff --git a/src/common/command_buffers/details/uniforms.hpp b/src/common/command_buffers/details/uniforms.hpp index 12df08c3a..4803971fb 100644 --- a/src/common/command_buffers/details/uniforms.hpp +++ b/src/common/command_buffers/details/uniforms.hpp @@ -67,21 +67,19 @@ namespace commandbuffers uint32_t uniformBlockBinding; }; - template - class SetUniformCommandBufferRequest : public TrCommandBufferSimpleRequest + // The base class for all uniform command buffer requests which stores the program and location information. + class SetUniformCommandBufferRequestBase { public: - SetUniformCommandBufferRequest(uint32_t program, const std::string &location_name) - : TrCommandBufferSimpleRequest() - , program(program) + SetUniformCommandBufferRequestBase(uint32_t program, const std::string &location_name) + : program(program) , location(0) , locationAvailable(false) , locationQueryName(location_name) { } - SetUniformCommandBufferRequest(const Derived &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , program(that.program) + SetUniformCommandBufferRequestBase(const SetUniformCommandBufferRequestBase &that, bool clone = false) + : program(that.program) , location(that.location) , locationAvailable(that.locationAvailable) { @@ -90,19 +88,6 @@ namespace commandbuffers } public: - virtual TrCommandBufferMessage *serialize() override - { - auto message = new TrCommandBufferMessage(this->type, this->size, this); - if (!locationQueryName.empty()) - message->addStringSegment(locationQueryName); - return message; - } - virtual void deserialize(TrCommandBufferMessage &message) override - { - auto nameSegment = message.nextSegment(); - if (nameSegment != nullptr) - locationQueryName = nameSegment->toString(); - } void setLocationIndex(std::optional loc_index, bool clear_name = false) { if (loc_index.has_value()) @@ -113,7 +98,6 @@ namespace commandbuffers locationQueryName.clear(); } } - std::string locToString() const { std::stringstream loc_ss; @@ -128,6 +112,44 @@ namespace commandbuffers << ")"; return loc_ss.str(); } + + public: + uint32_t program; + uint32_t location; + bool locationAvailable; + std::string locationQueryName; + }; + + template + class SetUniformCommandBufferRequest : public TrCommandBufferSimpleRequest, + public SetUniformCommandBufferRequestBase + { + public: + SetUniformCommandBufferRequest(uint32_t program, const std::string &location_name) + : TrCommandBufferSimpleRequest() + , SetUniformCommandBufferRequestBase(program, location_name) + { + } + SetUniformCommandBufferRequest(const Derived &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , SetUniformCommandBufferRequestBase(that, clone) + { + } + + public: + virtual TrCommandBufferMessage *serialize() override + { + auto message = new TrCommandBufferMessage(this->type, this->size, this); + if (!this->locationQueryName.empty()) + message->addStringSegment(this->locationQueryName); + return message; + } + virtual void deserialize(TrCommandBufferMessage &message) override + { + auto nameSegment = message.nextSegment(); + if (nameSegment != nullptr) + this->locationQueryName = nameSegment->toString(); + } virtual std::string toString(const char *line_prefix) const override { std::stringstream ss; @@ -135,12 +157,6 @@ namespace commandbuffers << "(" << locToString() << ")"; return ss.str(); } - - public: - uint32_t program; - uint32_t location; - bool locationAvailable; - std::string locationQueryName; }; class Uniform1fCommandBufferRequest final @@ -297,20 +313,17 @@ namespace commandbuffers }; class Uniform2fCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: - Uniform2fCommandBufferRequest() = delete; - Uniform2fCommandBufferRequest(uint32_t location, float v0, float v1) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform2fCommandBufferRequest(uint32_t program, const std::string &location_name, float v0, float v1) + : SetUniformCommandBufferRequest(program, location_name) , v0(v0) , v1(v1) { } Uniform2fCommandBufferRequest(const Uniform2fCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , v0(that.v0) , v1(that.v1) { @@ -320,32 +333,28 @@ namespace commandbuffers { std::stringstream ss; ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << ")," + << this->locToString() << "," << v0 << "," << v1 << ")"; return ss.str(); } public: - uint32_t location; float v0; float v1; }; class Uniform2fvCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: - Uniform2fvCommandBufferRequest() = delete; - Uniform2fvCommandBufferRequest(uint32_t location, const std::vector &values) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform2fvCommandBufferRequest(uint32_t program, const std::string &location_name, const std::vector &values) + : SetUniformCommandBufferRequest(program, location_name) , values(values) { } Uniform2fvCommandBufferRequest(const Uniform2fvCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , values() { if (clone) @@ -355,14 +364,16 @@ namespace commandbuffers public: TrCommandBufferMessage *serialize() override { - auto message = new TrCommandBufferMessage(type, size, this); + auto message = SetUniformCommandBufferRequest::serialize(); if (values.size() > 1 && values.size() % 2 == 0) // Check the value size is 2x message->addVecSegment(values); return message; } void deserialize(TrCommandBufferMessage &message) override { - auto valuesSegment = message.getSegment(0); + SetUniformCommandBufferRequest::deserialize(message); + + auto valuesSegment = message.nextSegment(); if (valuesSegment != nullptr) values = valuesSegment->toVec(); } @@ -371,7 +382,7 @@ namespace commandbuffers { std::stringstream ss; ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << "),"; + << this->locToString() << ", "; ss << "["; for (size_t i = 0; i < values.size(); ++i) @@ -385,25 +396,21 @@ namespace commandbuffers } public: - uint32_t location; std::vector values; }; class Uniform2iCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: - Uniform2iCommandBufferRequest() = delete; - Uniform2iCommandBufferRequest(uint32_t location, int v0, int v1) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform2iCommandBufferRequest(uint32_t program, const std::string &location_name, int v0, int v1) + : SetUniformCommandBufferRequest(program, location_name) , v0(v0) , v1(v1) { } Uniform2iCommandBufferRequest(const Uniform2iCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , v0(that.v0) , v1(that.v1) { @@ -413,32 +420,28 @@ namespace commandbuffers { std::stringstream ss; ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << ")," - << v0 << "," + << this->locToString() << ", " + << v0 << ", " << v1 << ")"; return ss.str(); } public: - uint32_t location; int v0; int v1; }; class Uniform2ivCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: - Uniform2ivCommandBufferRequest() = delete; - Uniform2ivCommandBufferRequest(uint32_t location, const std::vector &values) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform2ivCommandBufferRequest(uint32_t program, const std::string &location_name, const std::vector &values) + : SetUniformCommandBufferRequest(program, location_name) , values(values) { } Uniform2ivCommandBufferRequest(const Uniform2ivCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , values() { if (clone) @@ -448,14 +451,18 @@ namespace commandbuffers public: TrCommandBufferMessage *serialize() override { - auto message = new TrCommandBufferMessage(type, size, this); + auto message = SetUniformCommandBufferRequest::serialize(); + assert(message != nullptr && "SetUniformCommandBufferRequest::serialize() must not return nullptr"); + if (values.size() > 1 && values.size() % 2 == 0) // Check the value size is 2x message->addVecSegment(values); return message; } void deserialize(TrCommandBufferMessage &message) override { - auto valuesSegment = message.getSegment(0); + SetUniformCommandBufferRequest::deserialize(message); + + auto valuesSegment = message.nextSegment(); if (valuesSegment != nullptr) values = valuesSegment->toVec(); } @@ -463,7 +470,7 @@ namespace commandbuffers { std::stringstream ss; ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << "),"; + << this->locToString() << ", "; ss << "["; for (size_t i = 0; i < values.size(); ++i) @@ -477,26 +484,23 @@ namespace commandbuffers } public: - uint32_t location; std::vector values; }; class Uniform3fCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: Uniform3fCommandBufferRequest() = delete; - Uniform3fCommandBufferRequest(uint32_t location, float v0, float v1, float v2) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform3fCommandBufferRequest(uint32_t program, const std::string &location_name, float v0, float v1, float v2) + : SetUniformCommandBufferRequest(program, location_name) , v0(v0) , v1(v1) , v2(v2) { } Uniform3fCommandBufferRequest(const Uniform3fCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , v0(that.v0) , v1(that.v1) , v2(that.v2) @@ -515,7 +519,6 @@ namespace commandbuffers } public: - uint32_t location; float v0; float v1; float v2; @@ -673,22 +676,20 @@ namespace commandbuffers std::vector values; }; - template - class Uniform4xCommandBufferRequest : public TrCommandBufferRequest + template + class Uniform4xCommandBufferRequest : public SetUniformCommandBufferRequest { public: - Uniform4xCommandBufferRequest(CommandBufferType type, uint32_t location, Tv v0, Tv v1, Tv v2, Tv v3) - : TrCommandBufferRequest(type, sizeof(Tb)) - , location(location) + Uniform4xCommandBufferRequest(uint32_t program, const std::string &location_name, Tv v0, Tv v1, Tv v2, Tv v3) + : SetUniformCommandBufferRequest(program, location_name) , v0(v0) , v1(v1) , v2(v2) , v3(v3) { } - Uniform4xCommandBufferRequest(const Uniform4xCommandBufferRequest &that, bool clone = false) - : TrCommandBufferRequest(that, clone) - , location(that.location) + Uniform4xCommandBufferRequest(const Derived &that, bool clone = false) + : SetUniformCommandBufferRequest(that, clone) , v0(that.v0) , v1(that.v1) , v2(that.v2) @@ -697,19 +698,11 @@ namespace commandbuffers } public: - TrCommandBufferMessage *serialize() override final - { - auto message = new TrCommandBufferMessage(type, size, this); - return message; - } - void deserialize(TrCommandBufferMessage &message) override final - { - } std::string toString(const char *line_prefix) const override { std::stringstream ss; ss << TrCommandBufferRequest::toString(line_prefix) << "(" - << "Loc(" << location << ")," + << this->locToString() << "," << v0 << "," << v1 << "," << v2 << "," @@ -725,19 +718,17 @@ namespace commandbuffers Tv v3; }; - template - class Uniform4xvCommandBufferRequest : public TrCommandBufferRequest + template + class Uniform4xvCommandBufferRequest : public SetUniformCommandBufferRequest { public: - Uniform4xvCommandBufferRequest(CommandBufferType type, uint32_t location, const std::vector &values) - : TrCommandBufferRequest(type, sizeof(Tb)) - , location(location) + Uniform4xvCommandBufferRequest(uint32_t program, const std::string &location_name, const std::vector &values) + : SetUniformCommandBufferRequest(program, location_name) , values(values) { } - Uniform4xvCommandBufferRequest(const Uniform4xvCommandBufferRequest &that, bool clone = false) - : TrCommandBufferRequest(that, clone) - , location(that.location) + Uniform4xvCommandBufferRequest(const Derived &that, bool clone = false) + : SetUniformCommandBufferRequest(that, clone) , values() { if (clone) @@ -747,14 +738,16 @@ namespace commandbuffers public: TrCommandBufferMessage *serialize() override final { - auto message = new TrCommandBufferMessage(type, size, this); + auto message = SetUniformCommandBufferRequest::serialize(); if (values.size() > 3 && values.size() % 4 == 0) // Check the value size is 4x message->addVecSegment(values); return message; } void deserialize(TrCommandBufferMessage &message) override final { - auto valuesSegment = message.getSegment(0); + SetUniformCommandBufferRequest::deserialize(message); + + auto valuesSegment = message.nextSegment(); if (valuesSegment != nullptr) values = valuesSegment->toVec(); } @@ -762,7 +755,7 @@ namespace commandbuffers { std::stringstream ss; ss << TrCommandBufferRequest::toString(line_prefix) << "(" - << "Loc(" << location << "),"; + << this->locToString() << ", "; ss << "["; for (size_t i = 0; i < values.size(); ++i) @@ -781,51 +774,27 @@ namespace commandbuffers }; class Uniform4fCommandBufferRequest final - : public Uniform4xCommandBufferRequest + : public Uniform4xCommandBufferRequest { using Uniform4xCommandBufferRequest::Uniform4xCommandBufferRequest; - - public: - Uniform4fCommandBufferRequest(uint32_t location, float v0, float v1, float v2, float v3) - : Uniform4xCommandBufferRequest(COMMAND_BUFFER_UNIFORM4F_REQ, location, v0, v1, v2, v3) - { - } }; class Uniform4fvCommandBufferRequest final - : public Uniform4xvCommandBufferRequest + : public Uniform4xvCommandBufferRequest { using Uniform4xvCommandBufferRequest::Uniform4xvCommandBufferRequest; - - public: - Uniform4fvCommandBufferRequest(uint32_t location, const std::vector &values) - : Uniform4xvCommandBufferRequest(COMMAND_BUFFER_UNIFORM4FV_REQ, location, values) - { - } }; class Uniform4iCommandBufferRequest final - : public Uniform4xCommandBufferRequest + : public Uniform4xCommandBufferRequest { using Uniform4xCommandBufferRequest::Uniform4xCommandBufferRequest; - - public: - Uniform4iCommandBufferRequest(uint32_t location, int v0, int v1, int v2, int v3) - : Uniform4xCommandBufferRequest(COMMAND_BUFFER_UNIFORM4I_REQ, location, v0, v1, v2, v3) - { - } }; class Uniform4ivCommandBufferRequest final - : public Uniform4xvCommandBufferRequest + : public Uniform4xvCommandBufferRequest { using Uniform4xvCommandBufferRequest::Uniform4xvCommandBufferRequest; - - public: - Uniform4ivCommandBufferRequest(uint32_t location, const std::vector &values) - : Uniform4xvCommandBufferRequest(COMMAND_BUFFER_UNIFORM4IV_REQ, location, values) - { - } }; template diff --git a/src/common/command_buffers/details/vertex_attrib.hpp b/src/common/command_buffers/details/vertex_attrib.hpp index ae7d711cc..7e4941214 100644 --- a/src/common/command_buffers/details/vertex_attrib.hpp +++ b/src/common/command_buffers/details/vertex_attrib.hpp @@ -1,76 +1,162 @@ #pragma once +#include + #include "../shared.hpp" #include "../base.hpp" namespace commandbuffers { - class EnableVertexAttribArrayCommandBufferRequest final - : public TrCommandBufferSimpleRequest + // The base class for all uniform command buffer requests which stores the program and location information. + class SetVertexAttribCommandBufferRequestBase { public: - EnableVertexAttribArrayCommandBufferRequest() = delete; - EnableVertexAttribArrayCommandBufferRequest(uint32_t index) - : TrCommandBufferSimpleRequest() - , index(index) + SetVertexAttribCommandBufferRequestBase(uint32_t program, const std::string &location_name) + : program(program) + , location(0) + , locationAvailable(false) + , locationQueryName(location_name) + { + } + // Create a vertex attrib command buffer request with a program and location index directly. + SetVertexAttribCommandBufferRequestBase(uint32_t program, uint32_t loc) + : program(program) + , location(loc) + , locationAvailable(true) + , locationQueryName("") { } - EnableVertexAttribArrayCommandBufferRequest(const EnableVertexAttribArrayCommandBufferRequest &that, - bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , index(that.index) + SetVertexAttribCommandBufferRequestBase(const SetVertexAttribCommandBufferRequestBase &that, bool clone = false) + : program(that.program) + , location(that.location) + , locationAvailable(that.locationAvailable) { + if (clone) + locationQueryName = that.locationQueryName; } - std::string toString(const char *line_prefix) const override + public: + void setLoc(std::optional index, bool clear_name = false) { - std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ")"; - return ss.str(); + if (index.has_value()) + { + location = index.value_or(0); + locationAvailable = true; + if (clear_name) + locationQueryName.clear(); + } + } + std::string locToString() const + { + std::stringstream loc_ss; + loc_ss << "Loc("; + { + if (locationAvailable) + loc_ss << location; + else + loc_ss << "?"; + } + + if (!locationQueryName.empty()) + loc_ss << ", " << locationQueryName; + loc_ss << ")"; + return loc_ss.str(); } public: - uint32_t index; + uint32_t program; + uint32_t location; + bool locationAvailable; + std::string locationQueryName; }; - class DisableVertexAttribArrayCommandBufferRequest final - : public TrCommandBufferSimpleRequest + template + class SetVertexAttribCommandBufferRequest : public TrCommandBufferSimpleRequest, + public SetVertexAttribCommandBufferRequestBase { public: - DisableVertexAttribArrayCommandBufferRequest() = delete; - DisableVertexAttribArrayCommandBufferRequest(uint32_t index) - : TrCommandBufferSimpleRequest() - , index(index) + SetVertexAttribCommandBufferRequest(uint32_t program, const std::string &location_name) + : TrCommandBufferSimpleRequest() + , SetVertexAttribCommandBufferRequestBase(program, location_name) + { + } + SetVertexAttribCommandBufferRequest(uint32_t program, uint32_t loc) + : TrCommandBufferSimpleRequest() + , SetVertexAttribCommandBufferRequestBase(program, loc) { } - DisableVertexAttribArrayCommandBufferRequest(const DisableVertexAttribArrayCommandBufferRequest &that, - bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , index(that.index) + SetVertexAttribCommandBufferRequest(const Derived &that, bool clone = false) + : TrCommandBufferSimpleRequest(that, clone) + , SetVertexAttribCommandBufferRequestBase(that, clone) { } - std::string toString(const char *line_prefix) const override + public: + virtual TrCommandBufferMessage *serialize() override + { + auto message = new TrCommandBufferMessage(this->type, this->size, this); + if (!this->locationQueryName.empty()) + message->addStringSegment(this->locationQueryName); + return message; + } + virtual void deserialize(TrCommandBufferMessage &message) override + { + auto nameSegment = message.nextSegment(); + if (nameSegment != nullptr) + this->locationQueryName = nameSegment->toString(); + } + virtual std::string toString(const char *line_prefix) const override { std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ")"; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) + << "(" << locToString() << ")"; return ss.str(); } + }; - public: - uint32_t index; + class EnableVertexAttribArrayCommandBufferRequest final + : public SetVertexAttribCommandBufferRequest + { + using SetVertexAttribCommandBufferRequest::SetVertexAttribCommandBufferRequest; + }; + + class DisableVertexAttribArrayCommandBufferRequest final + : public SetVertexAttribCommandBufferRequest + { + using SetVertexAttribCommandBufferRequest::SetVertexAttribCommandBufferRequest; }; class VertexAttribPointerCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetVertexAttribCommandBufferRequest { public: VertexAttribPointerCommandBufferRequest() = delete; - VertexAttribPointerCommandBufferRequest(uint32_t index, uint32_t size, uint32_t type, uint32_t normalized, uint32_t stride, uint32_t offset) - : TrCommandBufferSimpleRequest() - , index(index) + VertexAttribPointerCommandBufferRequest(uint32_t program, + const std::string &location_name, + uint32_t size, + uint32_t type, + uint32_t normalized, + uint32_t stride, + uint32_t offset) + : SetVertexAttribCommandBufferRequest(program, location_name) + , conponentSize(size) + , componentType(type) + , normalized(normalized) + , stride(stride) + , offset(offset) + { + } + VertexAttribPointerCommandBufferRequest(uint32_t program, + uint32_t index, + uint32_t size, + uint32_t type, + uint32_t normalized, + uint32_t stride, + uint32_t offset) + : SetVertexAttribCommandBufferRequest(program, index) , conponentSize(size) , componentType(type) , normalized(normalized) @@ -79,8 +165,7 @@ namespace commandbuffers { } VertexAttribPointerCommandBufferRequest(const VertexAttribPointerCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , index(that.index) + : SetVertexAttribCommandBufferRequest(that, clone) , conponentSize(that.conponentSize) , componentType(that.componentType) , normalized(that.normalized) @@ -92,13 +177,17 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ", " << conponentSize << ", " - << componentType << ", " << normalized << ", " << stride << ", " << offset << ")"; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << this->locToString() << ", " + << conponentSize << ", " + << componentType << ", " + << normalized << ", " + << stride << ", " + << offset << ")"; return ss.str(); } public: - uint32_t index; uint32_t conponentSize; uint32_t componentType; uint32_t normalized; @@ -107,13 +196,31 @@ namespace commandbuffers }; class VertexAttribIPointerCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetVertexAttribCommandBufferRequest { public: VertexAttribIPointerCommandBufferRequest() = delete; - VertexAttribIPointerCommandBufferRequest(uint32_t index, uint32_t size, uint32_t type, uint32_t stride, uint32_t offset) - : TrCommandBufferSimpleRequest() - , index(index) + VertexAttribIPointerCommandBufferRequest(uint32_t program, + const std::string &location_name, + uint32_t size, + uint32_t type, + uint32_t stride, + uint32_t offset) + : SetVertexAttribCommandBufferRequest(program, location_name) + , componentSize(size) + , componentType(type) + , stride(stride) + , offset(offset) + { + } + VertexAttribIPointerCommandBufferRequest(uint32_t program, + uint32_t index, + uint32_t size, + uint32_t type, + uint32_t stride, + uint32_t offset) + : SetVertexAttribCommandBufferRequest(program, index) , componentSize(size) , componentType(type) , stride(stride) @@ -121,8 +228,7 @@ namespace commandbuffers { } VertexAttribIPointerCommandBufferRequest(const VertexAttribIPointerCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , index(that.index) + : SetVertexAttribCommandBufferRequest(that, clone) , componentSize(that.componentSize) , componentType(that.componentType) , stride(that.stride) @@ -133,13 +239,14 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ", " << componentSize << ", " + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << this->locToString() << ", " + << componentSize << ", " << componentType << ", " << stride << ", " << offset << ")"; return ss.str(); } public: - uint32_t index; uint32_t componentSize; uint32_t componentType; uint32_t stride; @@ -147,19 +254,23 @@ namespace commandbuffers }; class VertexAttribDivisorCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetVertexAttribCommandBufferRequest { public: VertexAttribDivisorCommandBufferRequest() = delete; - VertexAttribDivisorCommandBufferRequest(uint32_t index, uint32_t divisor) - : TrCommandBufferSimpleRequest() - , index(index) + VertexAttribDivisorCommandBufferRequest(uint32_t program, const std::string &location_name, uint32_t divisor) + : SetVertexAttribCommandBufferRequest(program, location_name) + , divisor(divisor) + { + } + VertexAttribDivisorCommandBufferRequest(uint32_t program, uint32_t index, uint32_t divisor) + : SetVertexAttribCommandBufferRequest(program, index) , divisor(divisor) { } VertexAttribDivisorCommandBufferRequest(const VertexAttribDivisorCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , index(that.index) + : SetVertexAttribCommandBufferRequest(that, clone) , divisor(that.divisor) { } @@ -167,12 +278,13 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << index << ", " << divisor << ")"; + ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << this->locToString() << ", " + << divisor << ")"; return ss.str(); } public: - uint32_t index; uint32_t divisor; }; } diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index 45cf4d8a9..f2a32d5e3 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -390,6 +390,45 @@ void ContextGLApp::drawElements(GLenum mode, GLsizei count, GLenum type, const v } } + +std::optional ContextGLApp::getAttribLoc(commandbuffers::SetVertexAttribCommandBufferRequestBase *req) const +{ + optional loc = nullopt; + if (req->locationAvailable) + { + loc = req->location; + } + else + { + GLuint program = ObjectManagerRef().FindProgram(req->program); + if (program != 0) [[likely]] + { + loc = glGetAttribLocation(program, req->locationQueryName.c_str()); + if (loc == -1) + loc = nullopt; // If the location is not found, return nullopt + } + } + return loc; +} + +optional ContextGLApp::getUniformLoc(commandbuffers::SetUniformCommandBufferRequestBase *req) const +{ + optional loc = nullopt; + if (req->locationAvailable) + { + loc = req->location; + } + else + { + GLuint program = ObjectManagerRef().FindProgram(req->program); + if (program != 0) [[likely]] + { + loc = glGetUniformLocation(program, req->locationQueryName.c_str()); + } + } + return loc; +} + void ContextGLApp::MarkAsDirty() { m_Dirty = true; diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index 43f7d0350..6daa81830 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "./context_storage.hpp" #include "./framebuffer.hpp" @@ -15,7 +17,7 @@ class ContextGLApp : public ContextGLStorage public: // Create a new context for the content renderer. ContextGLApp(std::string name, std::shared_ptr); - // Create a new context which inherits from another context. And `defaultRenderTarget` is the default framebuffer to + // Create a new context which inherits from another context. And `defaultRenderTarget` is the default framebuffer to // be used in this context. ContextGLApp(std::string name, ContextGLApp *from, std::optional defaultRenderTarget = std::nullopt); @@ -74,6 +76,10 @@ class ContextGLApp : public ContextGLStorage void drawArrays(GLenum mode, GLint first, GLsizei count); void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); +public: // GLES Helpers + std::optional getAttribLoc(commandbuffers::SetVertexAttribCommandBufferRequestBase *) const; + std::optional getUniformLoc(commandbuffers::SetUniformCommandBufferRequestBase *) const; + public: void MarkAsDirty(); bool IsDirty(); @@ -83,7 +89,7 @@ class ContextGLApp : public ContextGLStorage public: renderer::TrContentRenderer &contentRendererChecked() const; - gles::GLObjectManager &ObjectManagerRef() + gles::GLObjectManager &ObjectManagerRef() const { return *m_GLObjectManager; } diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index b8f7e601f..4520f8f58 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -580,15 +580,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface { auto glContext = reqContentRenderer->getContextGL(); auto program = glContext->ObjectManagerRef().FindProgram(req->clientId); + GLint value; glGetProgramiv(program, req->pname, &value); - GetProgramParamCommandBufferResponse res(req, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(DEBUG_TAG, - "[%d] GL::GetProgramParameter(%s) => %d", - options.isDefaultQueue(), - gles::glEnumToString(req->pname).c_str(), - res.value); + PrintDebugInfo(req, to_string(value).c_str(), nullptr, options); + + GetProgramParamCommandBufferResponse res(req, value); reqContentRenderer->sendCommandBufferResponse(res); } TR_OPENGL_FUNC void OnGetProgramInfoLog(GetProgramInfoLogCommandBufferRequest *req, @@ -1418,43 +1416,80 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "enableVertexAttribArray(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + /** * `enableVertexAttribArray` without VAO is not supported in core profile, thus we need to ensure the VAO before calling * `enableVertexAttribArray()`. */ if (backendType == RHIBackendType::OpenGLCore) EnsureVertexArrayObject(reqContentRenderer->getContextGL()); - glEnableVertexAttribArray(req->index); + + glEnableVertexAttribArray(loc.value()); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - PrintDebugInfo(req, nullptr, nullptr, options); + { + PrintDebugInfo(req, to_string(loc.value()).c_str(), nullptr, options); + DEBUG(DEBUG_TAG, " program: %d", reqContentRenderer->getContextGL()->program()); + } } TR_OPENGL_FUNC void OnDisableVertexAttribArray(DisableVertexAttribArrayCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "disableVertexAttribArray(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + /** * `disableVertexAttribArray` without VAO is not supported in core profile, thus we need to ensure the VAO before calling * `disableVertexAttribArray()`. */ if (backendType == RHIBackendType::OpenGLCore) EnsureVertexArrayObject(reqContentRenderer->getContextGL()); - glDisableVertexAttribArray(req->index); + + glDisableVertexAttribArray(loc.value()); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - PrintDebugInfo(req, nullptr, nullptr, options); + { + PrintDebugInfo(req, to_string(loc.value()).c_str(), nullptr, options); + DEBUG(DEBUG_TAG, " program: %d", reqContentRenderer->getContextGL()->program()); + } } TR_OPENGL_FUNC void OnVertexAttribPointer(VertexAttribPointerCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto index = req->index; - auto size = req->conponentSize; - auto type = req->componentType; - auto normalized = req->normalized; - auto stride = req->stride; - auto offset = req->offset; + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "vertexAttribPointer(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } - glVertexAttribPointer(index, size, type, normalized, stride, (const char *)NULL + offset); + GLint size = req->conponentSize; + GLenum type = req->componentType; + GLboolean normalized = req->normalized; + GLsizei stride = req->stride; + uint32_t offset = req->offset; + + glVertexAttribPointer(loc.value(), size, type, normalized, stride, (const char *)NULL + offset); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - PrintDebugInfo(req, nullptr, nullptr, options); + PrintDebugInfo(req, to_string(loc.value()).c_str(), nullptr, options); DEBUG(DEBUG_TAG, " size=%d", size); DEBUG(DEBUG_TAG, " type=%s", gles::glEnumToString(type).c_str()); DEBUG(DEBUG_TAG, " normalized=%s", normalized ? "Yes" : "No"); @@ -1471,13 +1506,22 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto index = req->index; + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "vertexAttribIPointer(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + auto size = req->componentSize; auto type = req->componentType; auto stride = req->stride; auto offset = req->offset; - glVertexAttribIPointer(index, size, type, stride, (const char *)NULL + offset); + glVertexAttribIPointer(loc.value(), size, type, stride, (const char *)NULL + offset); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1485,9 +1529,17 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto index = req->index; - auto divisor = req->divisor; - glVertexAttribDivisor(index, divisor); + optional loc = reqContentRenderer->getContextGL()->getAttribLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "vertexAttribDivisor(): Failed to get location for attrib '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glVertexAttribDivisor(loc.value(), req->divisor); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1508,21 +1560,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - optional loc = nullopt; - if (req->locationAvailable) - { - loc = req->location; - } - else - { - GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); - if (program != 0) [[likely]] - loc = glGetUniformLocation(program, req->locationQueryName.c_str()); - } - + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); if (loc == nullopt) [[unlikely]] { - DEBUG(LOG_TAG_ERROR, "uniform1f: Failed to get location for uniform '%s' in program %d", + DEBUG(LOG_TAG_ERROR, + "uniform1f(): Failed to get location for uniform '%s' in program %d", req->locationQueryName.c_str(), req->program); return; @@ -1553,21 +1595,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface } TR_OPENGL_FUNC void OnUniform1i(Uniform1iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - optional loc = nullopt; - if (req->locationAvailable) - { - loc = req->location; - } - else - { - GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); - if (program != 0) [[likely]] - loc = glGetUniformLocation(program, req->locationQueryName.c_str()); - } - + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); if (loc == nullopt) [[unlikely]] { - DEBUG(LOG_TAG_ERROR, "uniform1f: Failed to get location for uniform '%s' in program %d", + DEBUG(LOG_TAG_ERROR, + "uniform1i(): Failed to get location for uniform '%s' in program %d", req->locationQueryName.c_str(), req->program); return; @@ -1588,41 +1620,85 @@ class RHI_OpenGL : public TrRenderHardwareInterface } TR_OPENGL_FUNC void OnUniform2f(Uniform2fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - glUniform2f(req->location, req->v0, req->v1); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform2f(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glUniform2f(loc.value(), req->v0, req->v1); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform2fv(Uniform2fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - auto count = req->values.size() / 2; - auto value = req->values.data(); - glUniform2fv(loc, count, value); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform2fv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->values.size() / 2; + const GLfloat *value = req->values.data(); + glUniform2fv(loc.value(), count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform2i(Uniform2iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - glUniform2i(req->location, req->v0, req->v1); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform2i(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glUniform2i(loc.value(), req->v0, req->v1); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform2iv(Uniform2ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - auto count = req->values.size() / 2; - auto value = req->values.data(); - glUniform2iv(loc, count, value); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform2iv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->values.size() / 2; + const GLint *value = req->values.data(); + glUniform2iv(loc.value(), count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform3f(Uniform3fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - auto v0 = req->v0; - auto v1 = req->v1; - auto v2 = req->v2; - glUniform3f(loc, v0, v1, v2); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform3f(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glUniform3f(loc.value(), req->v0, req->v1, req->v2); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1656,42 +1732,99 @@ class RHI_OpenGL : public TrRenderHardwareInterface } TR_OPENGL_FUNC void OnUniform4f(Uniform4fCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - auto v0 = TR_OPENGL_GET_NUMBER(req->v0); - auto v1 = TR_OPENGL_GET_NUMBER(req->v1); - auto v2 = TR_OPENGL_GET_NUMBER(req->v2); - auto v3 = TR_OPENGL_GET_NUMBER(req->v3); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform4f(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } - glUniform4f(loc, v0, v1, v2, v3); + glUniform4f(loc.value(), + TR_OPENGL_GET_NUMBER(req->v0), + TR_OPENGL_GET_NUMBER(req->v1), + TR_OPENGL_GET_NUMBER(req->v2), + TR_OPENGL_GET_NUMBER(req->v3)); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform4fv(Uniform4fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - auto count = req->values.size() / 4; - auto value = req->values.data(); - glUniform4fv(loc, count, value); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform4fv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->values.size() / 4; + const GLfloat *value = req->values.data(); + glUniform4fv(loc.value(), count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } - TR_OPENGL_FUNC void OnUniform4i(Uniform4iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnUniform4i(Uniform4iCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { - auto loc = req->location; - auto v0 = req->v0; - auto v1 = req->v1; - auto v2 = req->v2; - auto v3 = req->v3; - glUniform4i(loc, v0, v1, v2, v3); + optional loc = nullopt; + if (req->locationAvailable) + { + loc = req->location; + } + else + { + GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); + if (program != 0) [[likely]] + loc = glGetUniformLocation(program, req->locationQueryName.c_str()); + } + + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform4i(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + glUniform4i(loc.value(), req->v0, req->v1, req->v2, req->v3); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } - TR_OPENGL_FUNC void OnUniform4iv(Uniform4ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + TR_OPENGL_FUNC void OnUniform4iv(Uniform4ivCommandBufferRequest *req, + renderer::TrContentRenderer *reqContentRenderer, + ApiCallOptions &options) { - auto loc = req->location; - auto count = req->values.size() / 4; - auto value = req->values.data(); - glUniform4iv(loc, count, value); + optional loc = nullopt; + if (req->locationAvailable) + { + loc = req->location; + } + else + { + GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); + if (program != 0) [[likely]] + loc = glGetUniformLocation(program, req->locationQueryName.c_str()); + } + + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform4iv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->values.size() / 4; + const GLint *value = req->values.data(); + glUniform4iv(loc.value(), count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1740,9 +1873,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (loc == nullopt) [[unlikely]] { - DEBUG(LOG_TAG_ERROR, "uniformMatrix4fv(): Failed to get location for uniform '%s' in program %d", - req->locationQueryName.c_str(), - req->program); + DEBUG(LOG_TAG_ERROR, "uniformMatrix4fv(): Failed to get location for uniform '%s' in program %d", req->locationQueryName.c_str(), req->program); return; } From cd881d263794520e5c12a62c96d8fcae3f97a5c0 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Mon, 14 Jul 2025 22:03:56 +0800 Subject: [PATCH 14/27] update --- src/client/per_process.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/client/per_process.cpp b/src/client/per_process.cpp index 50f727b5a..bd1037bfd 100644 --- a/src/client/per_process.cpp +++ b/src/client/per_process.cpp @@ -657,6 +657,7 @@ bool TrClientContextPerProcess::sendCommandBufferRequest(TrCommandBufferBase &co TrCommandBufferResponse *TrClientContextPerProcess::recvCommandBufferResponse(int timeout) { + auto before = chrono::steady_clock::now(); // Wait for the async command buffer responses to be processed. if (isAsyncCommandBufferResponseScheduled) { @@ -665,7 +666,13 @@ TrCommandBufferResponse *TrClientContextPerProcess::recvCommandBufferResponse(in { return asyncCommandBufferResponseCallbacks.empty(); }); isAsyncCommandBufferResponseScheduled = false; } - return commandBufferChanReceiver->recvCommandBufferResponse(timeout); + + TrCommandBufferResponse* response = commandBufferChanReceiver->recvCommandBufferResponse(timeout); + auto after = chrono::steady_clock::now(); + auto duration = chrono::duration_cast(after - before).count(); + cerr << "Received command buffer response in " << duration << "ms which blocks the main thread." << endl + << " command buffer: " << response->toString() << endl; + return response; } void TrClientContextPerProcess::recvCommandBufferResponseAsync(AsyncCommandBufferResponseCallback callback) From 78eef15443db47a57ed185112d9f95ca2b5921e9 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Mon, 14 Jul 2025 23:49:57 +0800 Subject: [PATCH 15/27] update --- src/client/graphics/webgl_context.cpp | 198 +++++++++++------- src/client/graphics/webgl_context.hpp | 4 + .../webgl_shader_precision_format.hpp | 20 +- src/client/per_process.cpp | 6 +- .../details/webgl_context_init.hpp | 15 +- src/common/command_buffers/macros.hpp | 4 +- src/renderer/render_api_opengles.cpp | 14 ++ 7 files changed, 173 insertions(+), 88 deletions(-) diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index 9cc398386..dfd57d6ac 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -56,36 +56,56 @@ namespace client_graphics if (id >= commandbuffers::MinimumContextId + commandbuffers::MaxinumContextsCountPerContent) throw runtime_error("Too many contexts created in the content process."); + auto sentAt = chrono::system_clock::now(); auto createReq = CreateWebGLContextRequest(); sendCommandBufferRequestDirectly(createReq, true); - auto sentAt = chrono::system_clock::now(); - auto initCommandBuffer = WebGL1ContextInitCommandBufferRequest(); - sendCommandBufferRequest(initCommandBuffer, true); - - auto resp = recvCommandBufferResponse(COMMAND_BUFFER_WEBGL_CONTEXT_INIT_RES, 3000); - if (resp == nullptr) [[unlikely]] - throw runtime_error("Failed to initialize WebGL context"); - - auto respondAt = chrono::system_clock::now(); - cout << "Received `WebGL1Context` response in " << chrono::duration_cast(respondAt - sentAt).count() << "ms" << endl; - cout << resp->toString(" ") << endl; - - viewport_ = resp->drawingViewport; - maxCombinedTextureImageUnits = resp->maxCombinedTextureImageUnits; - maxCubeMapTextureSize = resp->maxCubeMapTextureSize; - maxFragmentUniformVectors = resp->maxFragmentUniformVectors; - maxRenderbufferSize = resp->maxRenderbufferSize; - maxTextureImageUnits = resp->maxTextureImageUnits; - maxTextureSize = resp->maxTextureSize; - maxVaryingVectors = resp->maxVaryingVectors; - maxVertexAttribs = resp->maxVertexAttribs; - maxVertexTextureImageUnits = resp->maxVertexTextureImageUnits; - maxVertexUniformVectors = resp->maxVertexUniformVectors; - vendor = resp->vendor; - version = resp->version; - renderer = resp->renderer; - delete resp; + static WebGL1ContextInitCommandBufferResponse *initResp = nullptr; + if (initResp == nullptr) + { + auto initReq = WebGL1ContextInitCommandBufferRequest(); + sendCommandBufferRequest(initReq, true); + + initResp = recvCommandBufferResponse(COMMAND_BUFFER_WEBGL_CONTEXT_INIT_RES, + 3000); + if (initResp == nullptr) [[unlikely]] + throw runtime_error("Failed to initialize WebGL context"); + } + + auto initializedAt = chrono::system_clock::now(); + cout << "Initialized a `WebGL1Context` in " + << chrono::duration_cast(initializedAt - sentAt).count() << "ms" << endl; + cout << initResp->toString(" ") << endl; + + viewport_ = initResp->drawingViewport; + maxCombinedTextureImageUnits = initResp->maxCombinedTextureImageUnits; + maxCubeMapTextureSize = initResp->maxCubeMapTextureSize; + maxFragmentUniformVectors = initResp->maxFragmentUniformVectors; + maxRenderbufferSize = initResp->maxRenderbufferSize; + maxTextureImageUnits = initResp->maxTextureImageUnits; + maxTextureSize = initResp->maxTextureSize; + maxVaryingVectors = initResp->maxVaryingVectors; + maxVertexAttribs = initResp->maxVertexAttribs; + maxVertexTextureImageUnits = initResp->maxVertexTextureImageUnits; + maxVertexUniformVectors = initResp->maxVertexUniformVectors; + vendor = initResp->vendor; + version = initResp->version; + renderer = initResp->renderer; + + // Create shader precision formats. + { + for (int i = 0; i < 3; i++) + { + auto vertexFormat = initResp->vertexShaderPrecisionFormats[i]; + vertexShaderPrecisionFormats_[WEBGL_LOW_FLOAT + i] = WebGLShaderPrecisionFormat(vertexFormat[0], + vertexFormat[1], + vertexFormat[2]); + auto fragmentFormat = initResp->fragmentShaderPrecisionFormats[i]; + fragmentShaderPrecisionFormats_[WEBGL_LOW_FLOAT + i] = WebGLShaderPrecisionFormat(fragmentFormat[0], + fragmentFormat[1], + fragmentFormat[2]); + } + } } WebGLContext::~WebGLContext() @@ -848,9 +868,9 @@ namespace client_graphics program->waitForCompleted(); if (program->hasAttribLocation(name)) - return program->getAttribLocation(name); - else - return nullopt; + return program->getAttribLocation(name); + else + return nullopt; } optional WebGLContext::getUniformLocation(shared_ptr program, @@ -1483,6 +1503,24 @@ namespace client_graphics WebGLShaderPrecisionFormat WebGLContext::getShaderPrecisionFormat(int shadertype, int precisiontype) { + if (shadertype != WEBGL_VERTEX_SHADER && shadertype != WEBGL_FRAGMENT_SHADER) + throw runtime_error("Invalid shader type."); + + // Check cache first + if (shadertype == WEBGL_VERTEX_SHADER) + { + auto it = vertexShaderPrecisionFormats_.find(precisiontype); + if (it != vertexShaderPrecisionFormats_.end()) + return it->second; + } + else if (shadertype == WEBGL_FRAGMENT_SHADER) + { + auto it = fragmentShaderPrecisionFormats_.find(precisiontype); + if (it != fragmentShaderPrecisionFormats_.end()) + return it->second; + } + + // Send command to get shader precision format if not found in cache auto req = GetShaderPrecisionFormatCommandBufferRequest(shadertype, precisiontype); sendCommandBufferRequest(req, true); @@ -1507,24 +1545,28 @@ namespace client_graphics if (supportedExtensions_.has_value()) return supportedExtensions_.value(); - auto req = GetExtensionsCommandBufferRequest(); - sendCommandBufferRequest(req, true); + static GetExtensionsCommandBufferResponse *extensionsResp = nullptr; + if (extensionsResp == nullptr) + { + auto req = GetExtensionsCommandBufferRequest(); + sendCommandBufferRequest(req, true); - auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_EXTENSIONS_RES); - if (resp == nullptr) - throw runtime_error("Failed to get supported extensions: timeout."); + extensionsResp = recvCommandBufferResponse(COMMAND_BUFFER_GET_EXTENSIONS_RES); + if (extensionsResp == nullptr) + throw runtime_error("Failed to get supported extensions: timeout."); + } vector extensionsList; - for (size_t i = 0; i < resp->extensions.size(); i++) + for (size_t i = 0; i < extensionsResp->extensions.size(); i++) { // remove GL_ prefix - string extension = resp->extensions[i]; + string extension = extensionsResp->extensions[i]; if (extension.find("GL_") == 0) extensionsList.push_back(extension.substr(3)); else extensionsList.push_back(extension); } - delete resp; + supportedExtensions_ = extensionsList; return supportedExtensions_.value(); } @@ -1592,48 +1634,50 @@ namespace client_graphics WebGL2Context::WebGL2Context(ContextAttributes &attrs) : WebGLContext(attrs, true) { - auto req = WebGL2ContextInitCommandBufferRequest(); - sendCommandBufferRequest(req, true); + static WebGL2ContextInitCommandBufferResponse *initResp = nullptr; + if (initResp == nullptr) + { + auto req = WebGL2ContextInitCommandBufferRequest(); + sendCommandBufferRequest(req, true); - // Wait for the context init response - auto resp = recvCommandBufferResponse(COMMAND_BUFFER_WEBGL2_CONTEXT_INIT_RES); - if (resp == nullptr) - throw runtime_error("Failed to initialize WebGL2 context: timeout."); - - max3DTextureSize = resp->max3DTextureSize; - maxArrayTextureLayers = resp->maxArrayTextureLayers; - maxColorAttachments = resp->maxColorAttachments; - maxCombinedUniformBlocks = resp->maxCombinedUniformBlocks; - maxDrawBuffers = resp->maxDrawBuffers; - maxElementsIndices = resp->maxElementsIndices; - maxElementsVertices = resp->maxElementsVertices; - maxFragmentInputComponents = resp->maxFragmentInputComponents; - maxFragmentUniformBlocks = resp->maxFragmentUniformBlocks; - maxFragmentUniformComponents = resp->maxFragmentUniformComponents; - maxProgramTexelOffset = resp->maxProgramTexelOffset; - maxSamples = resp->maxSamples; - maxTransformFeedbackInterleavedComponents = resp->maxTransformFeedbackInterleavedComponents; - maxTransformFeedbackSeparateAttributes = resp->maxTransformFeedbackSeparateAttributes; - maxTransformFeedbackSeparateComponents = resp->maxTransformFeedbackSeparateComponents; - maxUniformBufferBindings = resp->maxUniformBufferBindings; - maxVaryingComponents = resp->maxVaryingComponents; - maxVertexOutputComponents = resp->maxVertexOutputComponents; - maxVertexUniformBlocks = resp->maxVertexUniformBlocks; - maxVertexUniformComponents = resp->maxVertexUniformComponents; - minProgramTexelOffset = resp->minProgramTexelOffset; - maxClientWaitTimeout = resp->maxClientWaitTimeout; - maxCombinedFragmentUniformComponents = resp->maxCombinedFragmentUniformComponents; - maxCombinedVertexUniformComponents = resp->maxCombinedVertexUniformComponents; - maxElementIndex = resp->maxElementIndex; - maxServerWaitTimeout = resp->maxServerWaitTimeout; - maxUniformBlockSize = resp->maxUniformBlockSize; - maxTextureLODBias = resp->maxTextureLODBias; + // Wait for the context init response + initResp = recvCommandBufferResponse(COMMAND_BUFFER_WEBGL2_CONTEXT_INIT_RES); + if (initResp == nullptr) + throw runtime_error("Failed to initialize WebGL2 context: timeout."); + } - // Extensions - OVR_maxViews = resp->OVR_maxViews; - maxTextureMaxAnisotropy = resp->maxTextureMaxAnisotropy; + max3DTextureSize = initResp->max3DTextureSize; + maxArrayTextureLayers = initResp->maxArrayTextureLayers; + maxColorAttachments = initResp->maxColorAttachments; + maxCombinedUniformBlocks = initResp->maxCombinedUniformBlocks; + maxDrawBuffers = initResp->maxDrawBuffers; + maxElementsIndices = initResp->maxElementsIndices; + maxElementsVertices = initResp->maxElementsVertices; + maxFragmentInputComponents = initResp->maxFragmentInputComponents; + maxFragmentUniformBlocks = initResp->maxFragmentUniformBlocks; + maxFragmentUniformComponents = initResp->maxFragmentUniformComponents; + maxProgramTexelOffset = initResp->maxProgramTexelOffset; + maxSamples = initResp->maxSamples; + maxTransformFeedbackInterleavedComponents = initResp->maxTransformFeedbackInterleavedComponents; + maxTransformFeedbackSeparateAttributes = initResp->maxTransformFeedbackSeparateAttributes; + maxTransformFeedbackSeparateComponents = initResp->maxTransformFeedbackSeparateComponents; + maxUniformBufferBindings = initResp->maxUniformBufferBindings; + maxVaryingComponents = initResp->maxVaryingComponents; + maxVertexOutputComponents = initResp->maxVertexOutputComponents; + maxVertexUniformBlocks = initResp->maxVertexUniformBlocks; + maxVertexUniformComponents = initResp->maxVertexUniformComponents; + minProgramTexelOffset = initResp->minProgramTexelOffset; + maxClientWaitTimeout = initResp->maxClientWaitTimeout; + maxCombinedFragmentUniformComponents = initResp->maxCombinedFragmentUniformComponents; + maxCombinedVertexUniformComponents = initResp->maxCombinedVertexUniformComponents; + maxElementIndex = initResp->maxElementIndex; + maxServerWaitTimeout = initResp->maxServerWaitTimeout; + maxUniformBlockSize = initResp->maxUniformBlockSize; + maxTextureLODBias = initResp->maxTextureLODBias; - delete resp; + // Extensions + OVR_maxViews = initResp->OVR_maxViews; + maxTextureMaxAnisotropy = initResp->maxTextureMaxAnisotropy; } void WebGL2Context::beginQuery(WebGLQueryTarget target, shared_ptr query) diff --git a/src/client/graphics/webgl_context.hpp b/src/client/graphics/webgl_context.hpp index 7ae4526cf..b8da40be0 100644 --- a/src/client/graphics/webgl_context.hpp +++ b/src/client/graphics/webgl_context.hpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include @@ -796,6 +798,8 @@ namespace client_graphics WebGLState clientState_; WebGLError lastError_ = WebGLError::kNoError; std::optional> supportedExtensions_ = std::nullopt; + std::unordered_map vertexShaderPrecisionFormats_; + std::unordered_map fragmentShaderPrecisionFormats_; bool isWebGL2_ = false; bool isContextLost_ = false; bool unpackFlipY_ = false; diff --git a/src/client/graphics/webgl_shader_precision_format.hpp b/src/client/graphics/webgl_shader_precision_format.hpp index 40838c585..603198ae9 100644 --- a/src/client/graphics/webgl_shader_precision_format.hpp +++ b/src/client/graphics/webgl_shader_precision_format.hpp @@ -1,7 +1,10 @@ #pragma once #include -#include "common/command_buffers/details/properties.hpp" +#include +#include +#include + #include "./webgl_object.hpp" namespace client_graphics @@ -9,6 +12,7 @@ namespace client_graphics class WebGLShaderPrecisionFormat { public: + WebGLShaderPrecisionFormat() = default; WebGLShaderPrecisionFormat(int rangeMin, int rangeMax, int precision) : rangeMin(rangeMin) , rangeMax(rangeMax) @@ -22,9 +26,17 @@ namespace client_graphics { } + friend std::ostream &operator<<(std::ostream &os, const WebGLShaderPrecisionFormat &format) + { + os << "WebGLShaderPrecisionFormat(" + << "[" << format.rangeMin << ", " << format.rangeMax << "], " + << format.precision << ")"; + return os; + } + public: - const int rangeMin; - const int rangeMax; - const int precision; + int rangeMin = 0; + int rangeMax = 0; + int precision = 0; }; } diff --git a/src/client/per_process.cpp b/src/client/per_process.cpp index bd1037bfd..7b3d8d6e5 100644 --- a/src/client/per_process.cpp +++ b/src/client/per_process.cpp @@ -667,11 +667,11 @@ TrCommandBufferResponse *TrClientContextPerProcess::recvCommandBufferResponse(in isAsyncCommandBufferResponseScheduled = false; } - TrCommandBufferResponse* response = commandBufferChanReceiver->recvCommandBufferResponse(timeout); + TrCommandBufferResponse *response = commandBufferChanReceiver->recvCommandBufferResponse(timeout); auto after = chrono::steady_clock::now(); auto duration = chrono::duration_cast(after - before).count(); - cerr << "Received command buffer response in " << duration << "ms which blocks the main thread." << endl - << " command buffer: " << response->toString() << endl; + cerr << "Received command buffer response(" << commandTypeToStr(response->type) << ") " + << "in " << duration << "ms which blocks the main thread." << endl; return response; } diff --git a/src/common/command_buffers/details/webgl_context_init.hpp b/src/common/command_buffers/details/webgl_context_init.hpp index 90fcce643..03d764d5e 100644 --- a/src/common/command_buffers/details/webgl_context_init.hpp +++ b/src/common/command_buffers/details/webgl_context_init.hpp @@ -47,6 +47,13 @@ namespace commandbuffers , maxVertexTextureImageUnits(that.maxVertexTextureImageUnits) , maxVertexUniformVectors(that.maxVertexUniformVectors) { + std::memcpy(vertexShaderPrecisionFormats, + that.vertexShaderPrecisionFormats, + sizeof(vertexShaderPrecisionFormats)); + std::memcpy(fragmentShaderPrecisionFormats, + that.fragmentShaderPrecisionFormats, + sizeof(fragmentShaderPrecisionFormats)); + if (clone) { vendor = that.vendor; @@ -73,7 +80,7 @@ namespace commandbuffers version = message.getSegment(1)->toString(); renderer = message.getSegment(2)->toString(); } - std::string toString(const char* line_prefix = " ") const override + std::string toString(const char *line_prefix = " ") const override { std::stringstream ss; ss << line_prefix << "MAX_COMBINED_TEXTURE_IMAGE_UNITS = " << maxCombinedTextureImageUnits << std::endl @@ -105,6 +112,10 @@ namespace commandbuffers string vendor; string version; string renderer; + + // Cache for shader precision formats: GL_HIGH_FLOAT, GL_MEDIUM_FLOAT, GL_LOW_FLOAT. + int vertexShaderPrecisionFormats[3][3]; + int fragmentShaderPrecisionFormats[3][3]; }; class WebGL2ContextInitCommandBufferRequest final @@ -162,7 +173,7 @@ namespace commandbuffers } public: - std::string toString(const char* line_prefix) const override + std::string toString(const char *line_prefix) const override { std::stringstream ss; ss << line_prefix << "GL_MAX_3D_TEXTURE_SIZE = " << max3DTextureSize << std::endl diff --git a/src/common/command_buffers/macros.hpp b/src/common/command_buffers/macros.hpp index 43e2c8100..4c19af4c8 100644 --- a/src/common/command_buffers/macros.hpp +++ b/src/common/command_buffers/macros.hpp @@ -4,7 +4,7 @@ XX(CREATE_WEBGL_CONTEXT, CreateWebGLContextRequest, "GL::CreateContext") \ XX(REMOVE_WEBGL_CONTEXT, RemoveWebGLContextRequest, "GL::RemoveContext") \ XX(WEBGL_CONTEXT_INIT, WebGL1ContextInitCommandBufferRequest, "GL::ContextInit") \ - XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferRequest, "GL::ContextInit") \ + XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferRequest, "GL::Context2Init") \ XX(CREATE_PROGRAM, CreateProgramCommandBufferRequest, "GL::CreateProgram") \ XX(DELETE_PROGRAM, DeleteProgramCommandBufferRequest, "GL::DeleteProgram") \ XX(LINK_PROGRAM, LinkProgramCommandBufferRequest, "GL::LinkProgram") \ @@ -141,7 +141,7 @@ #define TR_COMMAND_BUFFER_RESPONSES_MAP(XX) \ XX(WEBGL_CONTEXT_INIT, WebGL1ContextInitCommandBufferResponse, "GL::ContextInit") \ - XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferResponse, "GL::ContextInit") \ + XX(WEBGL2_CONTEXT_INIT, WebGL2ContextInitCommandBufferResponse, "GL::Context2Init") \ XX(GET_EXTENSIONS, GetExtensionsCommandBufferResponse, "GL::GetExtensions") \ XX(LINK_PROGRAM, LinkProgramCommandBufferResponse, "GL::LinkProgram") \ XX(GET_PROGRAM_PARAM, GetProgramParamCommandBufferResponse, "GL::GetProgramParam") \ diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 4520f8f58..dc43d51ae 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -378,6 +378,20 @@ class RHI_OpenGL : public TrRenderHardwareInterface res.vendor = string((const char *)glGetString(GL_VENDOR)); res.version = string((const char *)glGetString(GL_VERSION)); res.renderer = string((const char *)glGetString(GL_RENDERER)); + + // Cache for shader precision formats. + { + auto &vertexFormats = res.vertexShaderPrecisionFormats; + glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_LOW_FLOAT, &vertexFormats[0][0], &vertexFormats[0][2]); + glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_MEDIUM_FLOAT, &vertexFormats[1][0], &vertexFormats[1][2]); + glGetShaderPrecisionFormat(GL_VERTEX_SHADER, GL_HIGH_FLOAT, &vertexFormats[2][0], &vertexFormats[2][2]); + + auto &fragmentFormats = res.fragmentShaderPrecisionFormats; + glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_LOW_FLOAT, &fragmentFormats[0][0], &fragmentFormats[0][2]); + glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, &fragmentFormats[1][0], &fragmentFormats[1][2]); + glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, &fragmentFormats[2][0], &fragmentFormats[2][2]); + } + if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, &res, options); reqContentRenderer->sendCommandBufferResponse(res); From b9cc4393b3be9332bcd8e240ff88a7903c6a73e1 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Tue, 15 Jul 2025 00:56:52 +0800 Subject: [PATCH 16/27] update --- src/client/graphics/webgl_context.cpp | 52 ++++++++------ src/client/graphics/webgl_context.hpp | 8 ++- src/client/graphics/webgl_program.cpp | 57 +++++++++++++++ src/client/graphics/webgl_program.hpp | 70 +++++++------------ .../command_buffers/details/program.hpp | 2 +- .../command_buffers/webgl_constants.hpp | 28 ++++++++ src/renderer/render_api_opengles.cpp | 2 +- 7 files changed, 150 insertions(+), 69 deletions(-) create mode 100644 src/client/graphics/webgl_program.cpp diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index dfd57d6ac..c21ab0013 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -272,7 +272,11 @@ namespace client_graphics * `WebGLProgram` object directly. */ if (pname == WEBGL_LINK_STATUS) - return static_cast(program->getLinkStatus()); + return static_cast(program->getLinkStatus(false)); + if (pname == WEBGL_ACTIVE_ATTRIBUTES) + return static_cast(program->countActiveAttribs()); + if (pname == WEBGL_ACTIVE_UNIFORMS) + return static_cast(program->countActiveUniforms()); /** * Send a command buffer request and wait for the response if not hit the above conditions. @@ -289,19 +293,27 @@ namespace client_graphics string WebGLContext::getProgramInfoLog(shared_ptr program) { - auto req = GetProgramInfoLogCommandBufferRequest(program->id); - sendCommandBufferRequest(req, true); - - auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_PROGRAM_INFO_LOG_RES); - if (resp != nullptr) + assert(program != nullptr && "Program is not null"); + if (program->isIncomplete()) { - string log(resp->infoLog); - delete resp; - return log; + return ""; } else { - throw runtime_error("Failed to get program info log: timeout."); + auto req = GetProgramInfoLogCommandBufferRequest(program->id); + sendCommandBufferRequest(req, true); + + auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_PROGRAM_INFO_LOG_RES); + if (resp != nullptr) [[likely]] + { + string log(resp->infoLog); + delete resp; + return log; + } + else + { + throw runtime_error("Failed to get program info log: timeout."); + } } } @@ -385,17 +397,17 @@ namespace client_graphics auto req = GetShaderInfoLogCommandBufferRequest(shader->id); sendCommandBufferRequest(req, true); - auto resp = recvCommandBufferResponse(COMMAND_BUFFER_GET_SHADER_INFO_LOG_RES); - if (resp != nullptr) + auto onGetShaderInfoLogResponse = [shader](const GetShaderInfoLogCommandBufferResponse &resp) { - string log(resp->infoLog); - delete resp; - return log; - } - else - { - throw runtime_error("Failed to get shader info log: timeout."); - } + if (!resp.infoLog.empty()) + cerr << "getShaderInfoLog(" << shader->id << "): " << resp.infoLog << endl; + }; + recvResponseAsync(COMMAND_BUFFER_GET_SHADER_INFO_LOG_RES, + onGetShaderInfoLogResponse); + + // Return an empty string directly, and the response will be logged in the async callback. + // This is to avoid blocking the main thread. + return ""; } shared_ptr WebGLContext::createBuffer() diff --git a/src/client/graphics/webgl_context.hpp b/src/client/graphics/webgl_context.hpp index b8da40be0..fafe204fa 100644 --- a/src/client/graphics/webgl_context.hpp +++ b/src/client/graphics/webgl_context.hpp @@ -602,7 +602,13 @@ namespace client_graphics auto response = clientContext_->recvCommandBufferResponse(timeout); if (response == nullptr) [[unlikely]] return nullptr; - assert(response->type == responseType); + if (response->type != responseType) [[unlikely]] + { + std::cerr << "recvCommandBuffer(): " + << "Unexpected response type(" << response->type << "), expected(" << responseType << ")" + << std::endl; + assert(false && "Unexpected response type"); + } return dynamic_cast(response); } diff --git a/src/client/graphics/webgl_program.cpp b/src/client/graphics/webgl_program.cpp new file mode 100644 index 000000000..386319235 --- /dev/null +++ b/src/client/graphics/webgl_program.cpp @@ -0,0 +1,57 @@ +#include "./webgl_program.hpp" + +namespace client_graphics +{ + using namespace std; + + void WebGLProgram::waitForCompleted(int timeout) const + { + std::unique_lock lock(setCompletedMutex_); + setCompletedCv_.wait_for(lock, std::chrono::milliseconds(timeout), [this]() + { return !incomplete_; }); + } + + void WebGLProgram::setCompleted(bool linkStatus) + { + linkStatus_ = linkStatus; + incomplete_ = false; + { + std::unique_lock lock(setCompletedMutex_); + setCompletedCv_.notify_all(); + } + } + + bool WebGLProgram::getLinkStatus(bool sync) const + { + if (sync) + waitForCompleted(); + return linkStatus_; + } + + void WebGLProgram::printInfo() const + { + cout << "Program " << id << " info:" << endl; + cout << "Link status: " << (linkStatus_ ? "true" : "false") << endl; + cout << "Active attributes(" << activeAttribs_.size() << "):" << endl; + for (auto &pair : activeAttribs_) + { + auto activeInfo = pair.second; + cout << " " << pair.first << ": " << activeInfo.name << ", type: " << activeInfo.type << ", size: " << activeInfo.size << endl; + } + + cout << "Active uniforms(" << activeUniforms_.size() << "):" << endl; + for (auto &pair : activeUniforms_) + { + auto activeInfo = pair.second; + cout << " " << pair.first << ": " << activeInfo.name << ", type: " << activeInfo.type << ", size: " << activeInfo.size << endl; + } + + cout << "Attribute locations:" << endl; + for (auto &pair : attribLocations_) + cout << " " << pair.first << ": " << pair.second.index.value_or(-1) << endl; + + cout << "Uniform locations:" << endl; + for (auto &pair : uniformLocations_) + cout << " " << pair.first << ": " << pair.second.index.value_or(-1) << endl; + } +} diff --git a/src/client/graphics/webgl_program.hpp b/src/client/graphics/webgl_program.hpp index 9c7020e05..8a37046b2 100644 --- a/src/client/graphics/webgl_program.hpp +++ b/src/client/graphics/webgl_program.hpp @@ -29,22 +29,9 @@ namespace client_graphics return incomplete_; } // Waits for the program to be completed, it will block until the program response is received from channel peer. - void waitForCompleted(int timeout = 2000) - { - std::unique_lock lock(setCompletedMutex_); - setCompletedCv_.wait_for(lock, std::chrono::milliseconds(timeout), [this]() - { return !incomplete_; }); - } + void waitForCompleted(int timeout = 2000) const; // Calls setCompleted() when the program response is received from channel peer and updates the link status. - void setCompleted(bool linkStatus) - { - linkStatus_ = linkStatus; - incomplete_ = false; - { - std::unique_lock lock(setCompletedMutex_); - setCompletedCv_.notify_all(); - } - } + void setCompleted(bool linkStatus); /** * It sets the link status of the program. * @@ -55,11 +42,19 @@ namespace client_graphics linkStatus_ = linkStatus; } /** - * @returns THe current link status of the program. + * This method gets the current link status of the program. + * + * @param sync If `true`, it will wait for the program to be completed before returning the link status. + * @returns The current link status of the program. + */ + bool getLinkStatus(bool sync = false) const; + /** + * @returns The number of active attributes in the program. */ - bool getLinkStatus() + size_t countActiveAttribs() const { - return linkStatus_; + waitForCompleted(); + return activeAttribs_.size(); } /** * @returns The active attribute information at the given index. @@ -85,6 +80,14 @@ namespace client_graphics { return activeAttribs_.find(index) != activeAttribs_.end(); } + /** + * @returns The number of active uniforms in the program. + */ + size_t countActiveUniforms() const + { + waitForCompleted(); + return activeUniforms_.size(); + } /** * @param index The index of the active uniform. * @returns The active uniform information at the given index. @@ -200,37 +203,12 @@ namespace client_graphics * - Attribute locations * - Uniform locations */ - void printInfo() - { - std::cout << "Program " << id << " info:" << std::endl; - std::cout << "Link status: " << (linkStatus_ ? "true" : "false") << std::endl; - std::cout << "Active attributes:" << std::endl; - for (auto &pair : activeAttribs_) - { - auto activeInfo = pair.second; - std::cout << " " << pair.first << ": " << activeInfo.name << ", type: " << activeInfo.type << ", size: " << activeInfo.size << std::endl; - } - - std::cout << "Active uniforms:" << std::endl; - for (auto &pair : activeUniforms_) - { - auto activeInfo = pair.second; - std::cout << " " << pair.first << ": " << activeInfo.name << ", type: " << activeInfo.type << ", size: " << activeInfo.size << std::endl; - } - - std::cout << "Attribute locations:" << std::endl; - for (auto &pair : attribLocations_) - std::cout << " " << pair.first << ": " << pair.second.index.value_or(-1) << std::endl; - - std::cout << "Uniform locations:" << std::endl; - for (auto &pair : uniformLocations_) - std::cout << " " << pair.first << ": " << pair.second.index.value_or(-1) << std::endl; - } + void printInfo() const; private: std::atomic incomplete_ = true; - std::mutex setCompletedMutex_; - std::condition_variable setCompletedCv_; + mutable std::mutex setCompletedMutex_; + mutable std::condition_variable setCompletedCv_; bool linkStatus_ = false; std::map activeAttribs_; diff --git a/src/common/command_buffers/details/program.hpp b/src/common/command_buffers/details/program.hpp index 94e71eb37..c9397da76 100644 --- a/src/common/command_buffers/details/program.hpp +++ b/src/common/command_buffers/details/program.hpp @@ -443,7 +443,7 @@ namespace commandbuffers std::stringstream ss; ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << clientId << ", " - << WebGLHelper::WebGLEnumToString(pname) << ")"; + << WebGLHelper::WebGLProgramParameterToString(pname) << ")"; return ss.str(); } diff --git a/src/common/command_buffers/webgl_constants.hpp b/src/common/command_buffers/webgl_constants.hpp index f3279e267..a2b30d1b5 100644 --- a/src/common/command_buffers/webgl_constants.hpp +++ b/src/common/command_buffers/webgl_constants.hpp @@ -1350,6 +1350,34 @@ class WebGLHelper ss << "0x" << std::hex << attachment; return ss.str(); } +#undef CASE + } + + // Convert program parameter to string label. + static std::string WebGLProgramParameterToString(int param) + { +#define CASE(x) \ + case x: \ + { \ + return #x; \ + } + + switch (param) + { + CASE(WEBGL_DELETE_STATUS); + CASE(WEBGL_LINK_STATUS); + CASE(WEBGL_VALIDATE_STATUS); + CASE(WEBGL_ATTACHED_SHADERS); + CASE(WEBGL_ACTIVE_ATTRIBUTES); + CASE(WEBGL_ACTIVE_UNIFORMS); + CASE(WEBGL2_TRANSFORM_FEEDBACK_BUFFER_MODE); + CASE(WEBGL2_TRANSFORM_FEEDBACK_VARYINGS); + CASE(WEBGL2_ACTIVE_UNIFORM_BLOCKS); + default: + std::stringstream ss; + ss << "0x" << std::hex << param; + return ss.str(); + } #undef CASE } }; diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index dc43d51ae..4d33937e5 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -482,8 +482,8 @@ class RHI_OpenGL : public TrRenderHardwareInterface return; } + // Create response object LinkProgramCommandBufferResponse res(req, true); - DEBUG(DEBUG_TAG, " GL::LinkProgram(%d) on content#%d", program, reqContentRenderer->getContent()->id); /** * Fetch the locations of the attributes when link successfully. From f1eff33dcac105cd949e6a36aeb9fb29785fb1d4 Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Tue, 15 Jul 2025 01:27:27 +0800 Subject: [PATCH 17/27] fix nits --- src/client/graphics/webgl_context.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index c21ab0013..4a37b63aa 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -879,10 +879,12 @@ namespace client_graphics assert(program != nullptr && "Program is not null"); program->waitForCompleted(); - if (program->hasAttribLocation(name)) - return program->getAttribLocation(name); - else + // Returns `nullopt` if the program is incomplete or not linked. + if (!program->hasAttribLocation(name)) return nullopt; + + auto &location = program->getAttribLocation(name); + return location; } optional WebGLContext::getUniformLocation(shared_ptr program, From 7dc733aab35e5d6fcefb894a5d10c687342d14ef Mon Sep 17 00:00:00 2001 From: Yorkie Liu Date: Tue, 15 Jul 2025 01:31:29 +0800 Subject: [PATCH 18/27] fix lint errors --- src/common/command_buffers/details/metrics.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/command_buffers/details/metrics.hpp b/src/common/command_buffers/details/metrics.hpp index 6a0e14ec6..666526cd9 100644 --- a/src/common/command_buffers/details/metrics.hpp +++ b/src/common/command_buffers/details/metrics.hpp @@ -29,7 +29,7 @@ namespace commandbuffers } public: - inline std::string toString(const char* line_prefix) const override + inline std::string toString(const char *line_prefix) const override { if (category == MetricsCategory::FirstContentfulPaint) return "FCP"; From e582f16fa63f3c53c6179b1a0fb839a02b6ac623 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 15 Jul 2025 14:54:44 +0800 Subject: [PATCH 19/27] fix --- fixtures/html/three-shaders-ocean.html | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/fixtures/html/three-shaders-ocean.html b/fixtures/html/three-shaders-ocean.html index 6fddd617e..97539da05 100644 --- a/fixtures/html/three-shaders-ocean.html +++ b/fixtures/html/three-shaders-ocean.html @@ -54,7 +54,7 @@ // Skybox const sky = new Sky(); - sky.scale.setScalar(10000); + sky.scale.setScalar(100); scene.add(sky); const skyUniforms = sky.material.uniforms; @@ -64,8 +64,8 @@ skyUniforms['mieDirectionalG'].value = 0.8; const parameters = { - elevation: 2, - azimuth: 180 + elevation: 90, + azimuth: 0 }; const pmremGenerator = new THREE.PMREMGenerator(renderer); @@ -80,7 +80,9 @@ sky.material.uniforms['sunPosition'].value.copy(sun); water.material.uniforms['sunDirection'].value.copy(sun).normalize(); - if (renderTarget !== undefined) renderTarget.dispose(); + if (renderTarget !== undefined) { + renderTarget.dispose(); + } sceneEnv.add(sky); renderTarget = pmremGenerator.fromScene(sceneEnv); @@ -90,10 +92,10 @@ updateSun(); - const geometry = new THREE.BoxGeometry(1, 1, 1); + const geometry = new THREE.BoxGeometry(10, 10, 10); const material = new THREE.MeshStandardMaterial({ roughness: 0 }); mesh = new THREE.Mesh(geometry, material); - mesh.position.z = -5; + mesh.position.z = -30; scene.add(mesh); } @@ -119,7 +121,7 @@ function animate() { const time = performance.now() * 0.001; - mesh.position.y = Math.sin(time) * 1; + mesh.position.y = Math.sin(time) * 5; mesh.rotation.x = time * 0.5; mesh.rotation.z = time * 0.51; water.material.uniforms['time'].value += 1.0 / 120.0; From 52b5cd7622f8ae99fed29f3d3ba65d471efdc55c Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 15 Jul 2025 16:10:23 +0800 Subject: [PATCH 20/27] fix nits --- src/client/builtin_scene/instanced_mesh.cpp | 16 ++++++- src/client/builtin_scene/instanced_mesh.hpp | 30 ++++++++++++ src/client/graphics/webgl_context.cpp | 11 ++++- src/client/graphics/webgl_context.hpp | 10 ++++ .../command_buffers/details/draw_calls.hpp | 16 ++++--- src/common/math3d/utils.hpp | 46 +++++++++++++++++++ 6 files changed, 120 insertions(+), 9 deletions(-) diff --git a/src/client/builtin_scene/instanced_mesh.cpp b/src/client/builtin_scene/instanced_mesh.cpp index bb01948a1..329fd0730 100644 --- a/src/client/builtin_scene/instanced_mesh.cpp +++ b/src/client/builtin_scene/instanced_mesh.cpp @@ -107,6 +107,20 @@ namespace builtin_scene } } + bool Instance::skipToDraw() const + { + // Skip if the instance is not enabled. + if (!enabled_) + return true; + + // Skip if the instance is transparent and not own a texture. + if (data_.isTransparent() && !data_.ownTexture()) + return true; + + // Otherwise, the instance is ready to draw. + return false; + } + RenderableInstancesList::RenderableInstancesList(InstanceFilter filter, shared_ptr vao, shared_ptr instanceVbo) @@ -126,7 +140,7 @@ namespace builtin_scene { if (TR_UNLIKELY(instance == nullptr)) continue; - if (!instance->enabled_) + if (instance->skipToDraw()) continue; if (filter == InstanceFilter::kAll) diff --git a/src/client/builtin_scene/instanced_mesh.hpp b/src/client/builtin_scene/instanced_mesh.hpp index bb7d7fd3c..5c15acc6e 100644 --- a/src/client/builtin_scene/instanced_mesh.hpp +++ b/src/client/builtin_scene/instanced_mesh.hpp @@ -1,10 +1,14 @@ #pragma once #include +#include +#include #include #include #include #include + +#include #include #include "./ecs.hpp" @@ -32,6 +36,30 @@ namespace builtin_scene glm::vec2 texUvOffset; /** 22 */ glm::vec2 texUvScale; /** 24 */ uint32_t texLayerIndex; + + friend std::ostream &operator<<(std::ostream &os, const InstanceData &data) + { + os << "InstanceData(" << std::endl + << " transform=" << math3d::to_string(data.transform) << std::endl + << " color=" << math3d::to_string(data.color) << std::endl + << " texUvOffset=" << math3d::to_string(data.texUvOffset) << std::endl + << " texUvScale=" << math3d::to_string(data.texUvScale) << std::endl + << " texLayerIndex=" << data.texLayerIndex << std::endl + << ")"; + return os; + } + + // If the instance is transparent(alpha = 0.0f). + inline bool isTransparent() const + { + return color.a == 0.0f; + } + + // If the instance own texture to draw. + inline bool ownTexture() const + { + return texUvScale.x > 0.0f || texUvScale.y > 0.0f; + } }; class Instance @@ -82,6 +110,8 @@ namespace builtin_scene void removeHolder(std::shared_ptr holder); // Notify the holders that the instance data is updated. void notifyHolders(); + // Returns `true` if the instance should be skipped to draw. + bool skipToDraw() const; private: InstanceData data_; diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index 4a37b63aa..856adb315 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -1363,10 +1363,11 @@ namespace client_graphics sendCommandBufferRequest(req); } - void WebGLContext::colorMask(bool red, bool green, bool blue, bool alpha) + void WebGLContext::colorMask(bool r, bool g, bool b, bool a) { - auto req = ColorMaskCommandBufferRequest(red, green, blue, alpha); + auto req = ColorMaskCommandBufferRequest(r, g, b, a); sendCommandBufferRequest(req); + clientState_.colorMask = {r, g, b, a}; } void WebGLContext::cullFace(int mode) @@ -1640,6 +1641,12 @@ namespace client_graphics if (TR_LIKELY(reported)) return; + if (clientState_.hasNoColorMask()) + { + // If the color mask is not set, we cannot report FCP, the FCP needs to be valid when the color buffer is updated. + return; + } + commandbuffers::PaintingMetricsCommandBufferRequest req(commandbuffers::MetricsCategory::FirstContentfulPaint); sendCommandBufferRequestDirectly(req); reported = true; diff --git a/src/client/graphics/webgl_context.hpp b/src/client/graphics/webgl_context.hpp index fafe204fa..6409e7627 100644 --- a/src/client/graphics/webgl_context.hpp +++ b/src/client/graphics/webgl_context.hpp @@ -246,13 +246,23 @@ namespace client_graphics public: WebGLState() = default; + // Check if the current drawing won't affect the color buffer. + inline bool hasNoColorMask() const + { + return !colorMask[0] && !colorMask[1] && !colorMask[2] && !colorMask[3]; + } + public: + // bindings std::optional> program = std::nullopt; std::optional> vertexArray = std::nullopt; std::optional> vertexBuffer = std::nullopt; std::optional> elementBuffer = std::nullopt; std::optional> framebuffer = std::nullopt; std::optional> renderbuffer = std::nullopt; + + // states + std::array colorMask = {true, true, true, true}; }; /** diff --git a/src/common/command_buffers/details/draw_calls.hpp b/src/common/command_buffers/details/draw_calls.hpp index 017e457b5..c0f60ccbe 100644 --- a/src/common/command_buffers/details/draw_calls.hpp +++ b/src/common/command_buffers/details/draw_calls.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "../shared.hpp" #include "../base.hpp" @@ -106,7 +108,8 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { std::stringstream ss; - ss << "GL::DrawElements(mode=" << mode << ", " + ss << "GL::DrawElements(" + << WebGLHelper::WebGLEnumToString(mode) << ", " << count << ", " << indicesType << ", " << indicesOffset << ")"; @@ -148,11 +151,12 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { std::stringstream ss; - ss << "GL::DrawElementsInstanced(mode=" << mode << ", " - << count << ", " - << indicesType << ", " - << indicesOffset << ", " - << instanceCount << ")"; + ss << "GL::DrawElementsInstanced(" + << WebGLHelper::WebGLEnumToString(mode) << ", " + << "count=" << count << ", " + << "type=" << WebGLHelper::WebGLEnumToString(indicesType) << ", " + << "offset=" << indicesOffset << ", " + << "instances=" << instanceCount << ")"; return ss.str(); } diff --git a/src/common/math3d/utils.hpp b/src/common/math3d/utils.hpp index e1ccae21e..7267d1678 100644 --- a/src/common/math3d/utils.hpp +++ b/src/common/math3d/utils.hpp @@ -1,11 +1,57 @@ #pragma once #include +#include + #include +#include #include +#include namespace math3d { + // Utility functions for converting glm types to string representations: vec2(...) + inline std::string to_string(const glm::vec2 &v) + { + std::stringstream out; + out << "vec2(" << v.x << ", " << v.y << ")"; + return out.str(); + } + + // Utility functions for converting glm types to string representations: vec3(...) + inline std::string to_string(const glm::vec3 &v) + { + std::stringstream out; + out << "vec3(" << v.x << ", " << v.y << ", " << v.z << ")"; + return out.str(); + } + + // Utility functions for converting glm types to string representations: vec4(...) + inline std::string to_string(const glm::vec4 &v) + { + std::stringstream out; + out << "vec4(" << v.r << ", " << v.g << ", " << v.b << ", " << v.a << ")"; + return out.str(); + } + + // Utility functions for converting glm types to string representations: mat4(...) + inline std::string to_string(const glm::mat4 &m) + { + std::stringstream out; + out << "mat4("; + for (int i = 0; i < 4; ++i) + { + out << m[i][0] << ", " + << m[i][1] << ", " + << m[i][2] << ", " + << m[i][3]; + if (i < 3) + out << ", "; + } + out << ")"; + return out.str(); + } + template constexpr typename std::enable_if::is_integer, bool>::type almost_equal(T x, T y, int ulp = 4) From ef0686a19dca398569039a326780f373882eb4f3 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 15 Jul 2025 16:40:00 +0800 Subject: [PATCH 21/27] update --- src/client/builtin_scene/instanced_mesh.cpp | 2 +- src/client/graphics/webgl_context.cpp | 22 +- .../command_buffers/details/uniforms.hpp | 197 +++++++++--------- src/renderer/render_api_opengles.cpp | 181 +++++++++------- 4 files changed, 226 insertions(+), 176 deletions(-) diff --git a/src/client/builtin_scene/instanced_mesh.cpp b/src/client/builtin_scene/instanced_mesh.cpp index 329fd0730..ccdc59a6c 100644 --- a/src/client/builtin_scene/instanced_mesh.cpp +++ b/src/client/builtin_scene/instanced_mesh.cpp @@ -111,7 +111,7 @@ namespace builtin_scene { // Skip if the instance is not enabled. if (!enabled_) - return true; + return true; // Skip if the instance is transparent and not own a texture. if (data_.isTransparent() && !data_.ownTexture()) diff --git a/src/client/graphics/webgl_context.cpp b/src/client/graphics/webgl_context.cpp index 856adb315..49c6ed3af 100644 --- a/src/client/graphics/webgl_context.cpp +++ b/src/client/graphics/webgl_context.cpp @@ -913,7 +913,9 @@ namespace client_graphics void WebGLContext::uniform1fv(WebGLUniformLocation location, const vector value) { - auto req = Uniform1fvCommandBufferRequest(location.index.value_or(0), value); + auto req = Uniform1fvCommandBufferRequest(location.programId, location.name, value); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } @@ -927,7 +929,9 @@ namespace client_graphics void WebGLContext::uniform1iv(WebGLUniformLocation location, const vector value) { - auto req = Uniform1ivCommandBufferRequest(location.index.value_or(0), value); + auto req = Uniform1ivCommandBufferRequest(location.programId, location.name, value); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } @@ -973,19 +977,25 @@ namespace client_graphics void WebGLContext::uniform3fv(WebGLUniformLocation location, const vector value) { - auto req = Uniform3fvCommandBufferRequest(location.index.value_or(0), value); + auto req = Uniform3fvCommandBufferRequest(location.programId, location.name, value); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform3i(WebGLUniformLocation location, int v0, int v1, int v2) { - auto req = Uniform3iCommandBufferRequest(location.index.value_or(0), v0, v1, v2); + auto req = Uniform3iCommandBufferRequest(location.programId, location.name, v0, v1, v2); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } void WebGLContext::uniform3iv(WebGLUniformLocation location, const vector value) { - auto req = Uniform3ivCommandBufferRequest(location.index.value_or(0), value); + auto req = Uniform3ivCommandBufferRequest(location.programId, location.name, value); + if (location.index.has_value()) + req.setLocationIndex(location.index); sendCommandBufferRequest(req); } @@ -2238,7 +2248,7 @@ namespace client_graphics int uniformBlockIndex, uint32_t uniformBlockBinding) { - if (uniformBlockIndex < UINT32_MAX) + if (uniformBlockIndex < UINT32_MAX) [[likely]] { auto commandBuffer = commandbuffers::UniformBlockBindingCommandBufferRequest(program->id, uniformBlockIndex, diff --git a/src/common/command_buffers/details/uniforms.hpp b/src/common/command_buffers/details/uniforms.hpp index 4803971fb..4f9ed34bb 100644 --- a/src/common/command_buffers/details/uniforms.hpp +++ b/src/common/command_buffers/details/uniforms.hpp @@ -188,19 +188,17 @@ namespace commandbuffers }; class Uniform1fvCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: Uniform1fvCommandBufferRequest() = delete; - Uniform1fvCommandBufferRequest(uint32_t location, const std::vector &values) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform1fvCommandBufferRequest(uint32_t program, const std::string &location_name, const std::vector &values) + : SetUniformCommandBufferRequest(program, location_name) , values(values) { } Uniform1fvCommandBufferRequest(const Uniform1fvCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , values() { if (clone) @@ -210,20 +208,37 @@ namespace commandbuffers public: TrCommandBufferMessage *serialize() override { - auto message = new TrCommandBufferMessage(type, size, this); + auto message = SetUniformCommandBufferRequest::serialize(); if (values.size() > 0) message->addVecSegment(values); return message; } void deserialize(TrCommandBufferMessage &message) override { - auto valuesSegment = message.getSegment(0); + SetUniformCommandBufferRequest::deserialize(message); + + auto valuesSegment = message.nextSegment(); if (valuesSegment != nullptr) values = valuesSegment->toVec(); } + std::string toString(const char *line_prefix) const override + { + std::stringstream os; + os << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << this->locToString() << "," + << "["; + + for (size_t i = 0; i < values.size(); ++i) + { + os << values[i]; + if (i < values.size() - 1) + os << ", "; + } + os << "])"; + return os.str(); + } public: - uint32_t location; std::vector values; }; @@ -245,11 +260,11 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { - std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + std::stringstream os; + os << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << this->locToString() << "," << v0 << ")"; - return ss.str(); + return os.str(); } public: @@ -257,19 +272,17 @@ namespace commandbuffers }; class Uniform1ivCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: Uniform1ivCommandBufferRequest() = delete; - Uniform1ivCommandBufferRequest(uint32_t location, const std::vector &values) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform1ivCommandBufferRequest(uint32_t program, const std::string &location_name, const std::vector &values) + : SetUniformCommandBufferRequest(program, location_name) , values(values) { } Uniform1ivCommandBufferRequest(const Uniform1ivCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , values() { if (clone) @@ -279,36 +292,37 @@ namespace commandbuffers public: TrCommandBufferMessage *serialize() override { - auto message = new TrCommandBufferMessage(type, size, this); + auto message = SetUniformCommandBufferRequest::serialize(); if (values.size() > 0) message->addVecSegment(values); return message; } void deserialize(TrCommandBufferMessage &message) override { - auto valuesSegment = message.getSegment(0); + SetUniformCommandBufferRequest::deserialize(message); + + auto valuesSegment = message.nextSegment(); if (valuesSegment != nullptr) values = valuesSegment->toVec(); } std::string toString(const char *line_prefix) const override { - std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << "),"; + std::stringstream os; + os << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << this->locToString() << ", "; - ss << "["; + os << "["; for (size_t i = 0; i < values.size(); ++i) { - ss << values[i]; + os << values[i]; if (i < values.size() - 1) - ss << ", "; + os << ", "; } - ss << "])"; - return ss.str(); + os << "])"; + return os.str(); } public: - uint32_t location; std::vector values; }; @@ -380,19 +394,19 @@ namespace commandbuffers std::string toString(const char *line_prefix) const override { - std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + std::stringstream os; + os << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" << this->locToString() << ", "; - ss << "["; + os << "["; for (size_t i = 0; i < values.size(); ++i) { - ss << values[i]; + os << values[i]; if (i < values.size() - 1) - ss << ", "; + os << ", "; } - ss << "])"; - return ss.str(); + os << "])"; + return os.str(); } public: @@ -525,19 +539,17 @@ namespace commandbuffers }; class Uniform3fvCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: Uniform3fvCommandBufferRequest() = delete; - Uniform3fvCommandBufferRequest(uint32_t location, const std::vector &values) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform3fvCommandBufferRequest(uint32_t program, const std::string &location_name, const std::vector &values) + : SetUniformCommandBufferRequest(program, location_name) , values(values) { } Uniform3fvCommandBufferRequest(const Uniform3fvCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , values() { if (clone) @@ -547,55 +559,54 @@ namespace commandbuffers public: TrCommandBufferMessage *serialize() override { - auto message = new TrCommandBufferMessage(type, size, this); + auto message = SetUniformCommandBufferRequest::serialize(); if (values.size() > 2 && values.size() % 3 == 0) // Check the value size is 3x message->addVecSegment(values); return message; } void deserialize(TrCommandBufferMessage &message) override { - auto valuesSegment = message.getSegment(0); + SetUniformCommandBufferRequest::deserialize(message); + + auto valuesSegment = message.nextSegment(); if (valuesSegment != nullptr) values = valuesSegment->toVec(); } std::string toString(const char *line_prefix) const override { - std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << "),"; + std::stringstream os; + os << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << this->locToString() << ", "; - ss << "["; + os << "["; for (size_t i = 0; i < values.size(); ++i) { - ss << values[i]; + os << values[i]; if (i < values.size() - 1) - ss << ", "; + os << ", "; } - ss << "])"; - return ss.str(); + os << "])"; + return os.str(); } public: - uint32_t location; std::vector values; }; class Uniform3iCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: Uniform3iCommandBufferRequest() = delete; - Uniform3iCommandBufferRequest(uint32_t location, int v0, int v1, int v2) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform3iCommandBufferRequest(uint32_t program, const std::string &location_name, int v0, int v1, int v2) + : SetUniformCommandBufferRequest(program, location_name) , v0(v0) , v1(v1) , v2(v2) { } Uniform3iCommandBufferRequest(const Uniform3iCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that, clone) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , v0(that.v0) , v1(that.v1) , v2(that.v2) @@ -606,34 +617,31 @@ namespace commandbuffers { std::stringstream ss; ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << ")," - << v0 << "," - << v1 << "," + << this->locToString() << "), " + << v0 << ", " + << v1 << ", " << v2 << ")"; return ss.str(); } public: - uint32_t location; int v0; int v1; int v2; }; class Uniform3ivCommandBufferRequest final - : public TrCommandBufferSimpleRequest + : public SetUniformCommandBufferRequest { public: Uniform3ivCommandBufferRequest() = delete; - Uniform3ivCommandBufferRequest(uint32_t location, const std::vector &values) - : TrCommandBufferSimpleRequest() - , location(location) + Uniform3ivCommandBufferRequest(uint32_t program, const std::string &location_name, const std::vector &values) + : SetUniformCommandBufferRequest(program, location_name) , values(values) { } Uniform3ivCommandBufferRequest(const Uniform3ivCommandBufferRequest &that, bool clone = false) - : TrCommandBufferSimpleRequest(that) - , location(that.location) + : SetUniformCommandBufferRequest(that, clone) , values() { if (clone) @@ -643,36 +651,37 @@ namespace commandbuffers public: TrCommandBufferMessage *serialize() override { - auto message = new TrCommandBufferMessage(type, size, this); + auto message = SetUniformCommandBufferRequest::serialize(); if (values.size() > 2 && values.size() % 3 == 0) // Check the value size is 3x message->addVecSegment(values); return message; } void deserialize(TrCommandBufferMessage &message) override { - auto valuesSegment = message.getSegment(0); + SetUniformCommandBufferRequest::deserialize(message); + + auto valuesSegment = message.nextSegment(); if (valuesSegment != nullptr) values = valuesSegment->toVec(); } std::string toString(const char *line_prefix) const override { - std::stringstream ss; - ss << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" - << "Loc(" << location << "),"; + std::stringstream os; + os << TrCommandBufferSimpleRequest::toString(line_prefix) << "(" + << this->locToString() << "), "; - ss << "["; + os << "["; for (size_t i = 0; i < values.size(); ++i) { - ss << values[i]; + os << values[i]; if (i < values.size() - 1) - ss << ", "; + os << ", "; } - ss << "])"; - return ss.str(); + os << "])"; + return os.str(); } public: - uint32_t location; std::vector values; }; @@ -700,18 +709,17 @@ namespace commandbuffers public: std::string toString(const char *line_prefix) const override { - std::stringstream ss; - ss << TrCommandBufferRequest::toString(line_prefix) << "(" + std::stringstream os; + os << TrCommandBufferRequest::toString(line_prefix) << "(" << this->locToString() << "," << v0 << "," << v1 << "," << v2 << "," << v3 << ")"; - return ss.str(); + return os.str(); } public: - uint32_t location; Tv v0; Tv v1; Tv v2; @@ -753,23 +761,22 @@ namespace commandbuffers } std::string toString(const char *line_prefix) const override { - std::stringstream ss; - ss << TrCommandBufferRequest::toString(line_prefix) << "(" + std::stringstream os; + os << TrCommandBufferRequest::toString(line_prefix) << "(" << this->locToString() << ", "; - ss << "["; + os << "["; for (size_t i = 0; i < values.size(); ++i) { - ss << values[i]; + os << values[i]; if (i < values.size() - 1) - ss << ", "; + os << ", "; } - ss << "])"; - return ss.str(); + os << "])"; + return os.str(); } public: - uint32_t location; std::vector values; }; @@ -855,14 +862,14 @@ namespace commandbuffers values_ss << "float[" << values.size() << "], " << "ComputationGraph=" << (isComputationGraph() ? "Placeholder()" : "None"); - std::stringstream ss; - ss << TrCommandBufferRequest::toString(line_prefix) << "(" + std::stringstream os; + os << TrCommandBufferRequest::toString(line_prefix) << "(" << this->locToString() << ", " << "values={" << values_ss.str() << ", " << "count=" << count() << ", " << "transpose=" << (transpose ? "Yes" : "No") << ")"; - return ss.str(); + return os.str(); } public: diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 4d33937e5..48a0636aa 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -1592,20 +1592,22 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto location = req->location; - auto count = req->values.size(); - auto value = req->values.data(); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform1f(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->values.size(); + const GLfloat *value = req->values.data(); - glUniform1fv(location, count, value); + glUniform1fv(loc.value(), count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { PrintDebugInfo(req, nullptr, nullptr, options); - - auto glContext = reqContentRenderer->getContextGL(); - auto contentId = reqContentRenderer->getContent()->id; - DEBUG(DEBUG_TAG, " Content: %d", contentId); - DEBUG(DEBUG_TAG, " Program: %d", glContext->program()); - } } TR_OPENGL_FUNC void OnUniform1i(Uniform1iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { @@ -1625,10 +1627,20 @@ class RHI_OpenGL : public TrRenderHardwareInterface } TR_OPENGL_FUNC void OnUniform1iv(Uniform1ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - auto count = req->values.size(); - auto value = req->values.data(); - glUniform1iv(loc, count, value); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform1iv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->values.size(); + const GLint *value = req->values.data(); + + glUniform1iv(loc.value(), count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1718,29 +1730,59 @@ class RHI_OpenGL : public TrRenderHardwareInterface } TR_OPENGL_FUNC void OnUniform3fv(Uniform3fvCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - auto count = req->values.size() / 3; - auto value = req->values.data(); - glUniform3fv(loc, count, value); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform3fv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->values.size() / 3; + const GLfloat *value = req->values.data(); + + glUniform3fv(loc.value(), count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform3i(Uniform3iCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform3i(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + auto v0 = req->v0; auto v1 = req->v1; auto v2 = req->v2; - glUniform3i(loc, v0, v1, v2); + + glUniform3i(loc.value(), v0, v1, v2); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnUniform3iv(Uniform3ivCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto loc = req->location; - auto count = req->values.size() / 3; - auto value = req->values.data(); - glUniform3iv(loc, count, value); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniform3iv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->values.size() / 3; + const GLint *value = req->values.data(); + + glUniform3iv(loc.value(), count, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1786,18 +1828,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - optional loc = nullopt; - if (req->locationAvailable) - { - loc = req->location; - } - else - { - GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); - if (program != 0) [[likely]] - loc = glGetUniformLocation(program, req->locationQueryName.c_str()); - } - + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); if (loc == nullopt) [[unlikely]] { DEBUG(LOG_TAG_ERROR, @@ -1815,18 +1846,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - optional loc = nullopt; - if (req->locationAvailable) - { - loc = req->location; - } - else - { - GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); - if (program != 0) [[likely]] - loc = glGetUniformLocation(program, req->locationQueryName.c_str()); - } - + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); if (loc == nullopt) [[unlikely]] { DEBUG(LOG_TAG_ERROR, @@ -1847,11 +1867,21 @@ class RHI_OpenGL : public TrRenderHardwareInterface ApiCallOptions &options, xr::DeviceFrame *deviceFrame) { - auto loc = req->location; - auto count = req->count(); - auto transpose = req->transpose; - auto value = req->values.data(); - glUniformMatrix2fv(loc, count, transpose, value); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniformMatrix2fv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->count(); + GLboolean transpose = req->transpose; + const GLfloat *value = req->values.data(); + + glUniformMatrix2fv(loc.value(), count, transpose, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1860,11 +1890,21 @@ class RHI_OpenGL : public TrRenderHardwareInterface ApiCallOptions &options, xr::DeviceFrame *deviceFrame) { - auto loc = req->location; - auto count = req->count(); - auto transpose = req->transpose; - auto value = req->values.data(); - glUniformMatrix3fv(loc, count, transpose, value); + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); + if (loc == nullopt) [[unlikely]] + { + DEBUG(LOG_TAG_ERROR, + "uniformMatrix3fv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); + return; + } + + GLsizei count = req->count(); + GLboolean transpose = req->transpose; + const GLfloat *value = req->values.data(); + + glUniformMatrix3fv(loc.value(), count, transpose, value); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } @@ -1873,26 +1913,19 @@ class RHI_OpenGL : public TrRenderHardwareInterface ApiCallOptions &options, xr::DeviceFrame *deviceFrame) { - optional loc = nullopt; - if (req->locationAvailable) - { - loc = req->location; - } - else - { - GLuint program = reqContentRenderer->getContextGL()->ObjectManagerRef().FindProgram(req->program); - if (program != 0) [[likely]] - loc = glGetUniformLocation(program, req->locationQueryName.c_str()); - } - + optional loc = reqContentRenderer->getContextGL()->getUniformLoc(req); if (loc == nullopt) [[unlikely]] { - DEBUG(LOG_TAG_ERROR, "uniformMatrix4fv(): Failed to get location for uniform '%s' in program %d", req->locationQueryName.c_str(), req->program); + DEBUG(LOG_TAG_ERROR, + "uniformMatrix4fv(): Failed to get location for uniform '%s' in program %d", + req->locationQueryName.c_str(), + req->program); return; } - auto count = req->count(); - auto transpose = req->transpose; + GLsizei count = req->count(); + GLboolean transpose = req->transpose; + auto content = reqContentRenderer->getContent(); if (TR_UNLIKELY(content == nullptr || content->id == -1)) { From bc13d0b3cb341b3ad3f2f045915bae42382521a8 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 15 Jul 2025 20:34:26 +0800 Subject: [PATCH 22/27] update --- src/renderer/gles/context_app.cpp | 22 +++++--- src/renderer/gles/context_app.hpp | 4 ++ src/renderer/gles/context_host.cpp | 62 +++++++++++++--------- src/renderer/gles/context_host.hpp | 1 - src/renderer/gles/context_storage.cpp | 18 +++---- src/renderer/gles/context_storage.hpp | 24 ++++++--- src/renderer/render_api_opengles.cpp | 76 +++++++++++---------------- src/renderer/renderer.cpp | 6 ++- 8 files changed, 115 insertions(+), 98 deletions(-) diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index f2a32d5e3..ba57d73d9 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -146,14 +146,7 @@ void ContextGLApp::onActiveTextureUnitChanged(int active_unit) void ContextGLApp::onTextureBindingChanged(GLenum target, GLuint texture) { - GLint activeUnit; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeUnit); - - auto &binding = m_TextureBindingsWithUnit[activeUnit]; - if (binding == nullptr) - m_TextureBindingsWithUnit[activeUnit] = make_shared(target, texture); - else - binding->reset(target, texture); + m_TextureBindings[m_LastActiveTextureUnit] = GLTextureBinding(target, texture); } void ContextGLApp::RecordProgramOnCreated(GLuint program) @@ -372,6 +365,19 @@ void ContextGLApp::bindFramebuffer(GLenum target, optional id, GLuint onFramebufferChanged(framebuffer); } +void ContextGLApp::activeTexture(GLenum unit) +{ + glActiveTexture(unit); + onActiveTextureUnitChanged(unit); +} + +void ContextGLApp::bindTexture(GLenum target, uint32_t id, GLuint &texture) +{ + texture = ObjectManagerRef().FindTexture(id); + glBindTexture(target, texture); + onTextureBindingChanged(target, texture); +} + void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) { if (shouleExecuteDrawOnCurrent(count)) diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index 6daa81830..9c2ee4651 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -72,6 +72,10 @@ class ContextGLApp : public ContextGLStorage // Framebuffer functions void bindFramebuffer(GLenum target, std::optional id, GLuint &framebuffer); + // Texture functions + void activeTexture(GLenum textureUnit); + void bindTexture(GLenum target, uint32_t id, GLuint &texture); + // Draw functions void drawArrays(GLenum mode, GLint first, GLsizei count); void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); diff --git a/src/renderer/gles/context_host.cpp b/src/renderer/gles/context_host.cpp index 96d7af8c0..a2d4547b4 100644 --- a/src/renderer/gles/context_host.cpp +++ b/src/renderer/gles/context_host.cpp @@ -55,14 +55,47 @@ void ContextGLHost::recordFromHost() glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *)&m_LastActiveTextureUnit); clearTextureBindings(); - for (int i = GL_TEXTURE0; i <= GL_TEXTURE31; i++) + // FIXME(yorkie): currently only record from 0-31 texture units to avoid the performance issue, we can record more + // texture units if needed. + for (int unit = GL_TEXTURE0; unit <= GL_TEXTURE31; unit++) { GLint texture = 0; - glActiveTexture(i); + glActiveTexture(unit); - // TODO: how to support other texture targets? + // Reading the TEXTURE_2D glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture); - m_TextureBindingsWithUnit[i] = make_shared(GL_TEXTURE_2D, texture); + if (texture > 0) + { + m_TextureBindings[unit] = GLTextureBinding(GL_TEXTURE_2D, texture); + continue; + } + + // Reading the TEXTURE_2D_ARRAY + glGetIntegerv(GL_TEXTURE_BINDING_2D_ARRAY, &texture); + if (texture > 0) + { + m_TextureBindings[unit] = GLTextureBinding(GL_TEXTURE_2D_ARRAY, texture); + continue; + } + + // Reading the TEXTURE_3D + glGetIntegerv(GL_TEXTURE_BINDING_3D, &texture); + if (texture > 0) + { + m_TextureBindings[unit] = GLTextureBinding(GL_TEXTURE_3D, texture); + continue; + } + + // Reading the TEXTURE_CUBE_MAP + glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &texture); + if (texture > 0) + { + m_TextureBindings[unit] = GLTextureBinding(GL_TEXTURE_CUBE_MAP, texture); + continue; + } + + // TODO(yorkie): support other texture targets like GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, etc. + m_TextureBindings[unit] = GLTextureBinding(GL_TEXTURE_2D, 0); } glActiveTexture(m_LastActiveTextureUnit); @@ -149,27 +182,6 @@ void ContextGLHost::recordFromHost() DEBUG(LOG_TAG_ERROR, "Occurs an OpenGL error in recording %s context: 0x%04X", name(), error); } -void ContextGLHost::recordTextureBindingFromHost() -{ - auto &binding = m_TextureBindingsWithUnit[m_LastActiveTextureUnit]; - if (binding != nullptr) - return; - - GLuint texture; - GLint beforeActiveUnit; - glGetIntegerv(GL_ACTIVE_TEXTURE, &beforeActiveUnit); - - bool isActiveNotMatched = beforeActiveUnit != m_LastActiveTextureUnit; - if (isActiveNotMatched) - glActiveTexture(m_LastActiveTextureUnit); - - glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&texture); - m_TextureBindingsWithUnit[m_LastActiveTextureUnit] = make_shared(GL_TEXTURE_2D, texture); - - if (isActiveNotMatched) - glActiveTexture(beforeActiveUnit); -} - void ContextGLHost::restore() { ContextGLStorage::restore(); diff --git a/src/renderer/gles/context_host.hpp b/src/renderer/gles/context_host.hpp index 127071a9c..a4927f9ed 100644 --- a/src/renderer/gles/context_host.hpp +++ b/src/renderer/gles/context_host.hpp @@ -21,7 +21,6 @@ class ContextGLHost : public ContextGLStorage public: void recordFromHost(); - void recordTextureBindingFromHost(); void restore(); inline const GLuint currentFramebufferId() const diff --git a/src/renderer/gles/context_storage.cpp b/src/renderer/gles/context_storage.cpp index 7b64a6dbd..164d49c7f 100644 --- a/src/renderer/gles/context_storage.cpp +++ b/src/renderer/gles/context_storage.cpp @@ -253,19 +253,13 @@ void ContextGLStorage::restore() glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferId.value()); bindBuffersError = glGetError(); - for (auto it = m_TextureBindingsWithUnit.begin(); it != m_TextureBindingsWithUnit.end(); it++) + for (auto &it : m_TextureBindings) { - auto unit = it->first; - auto &binding = it->second; - auto target = binding->target(); - auto texture = binding->texture(); - glActiveTexture(unit); - glBindTexture(target, texture); + GLenum unit = it.first; + GLTextureBinding &texture = it.second; + texture.bindTo(unit); } - if (m_LastActiveTextureUnit >= GL_TEXTURE0 && m_LastActiveTextureUnit <= GL_TEXTURE31) - glActiveTexture(m_LastActiveTextureUnit); - else - glActiveTexture(GL_TEXTURE0); + glActiveTexture(m_LastActiveTextureUnit); bindTextureError = glGetError(); #if UNITY_ANDROID || UNITY_WEBGL @@ -337,5 +331,5 @@ void ContextGLStorage::print() void ContextGLStorage::clearTextureBindings() { - m_TextureBindingsWithUnit.clear(); + m_TextureBindings.clear(); } diff --git a/src/renderer/gles/context_storage.hpp b/src/renderer/gles/context_storage.hpp index 266e81edd..47a16f086 100644 --- a/src/renderer/gles/context_storage.hpp +++ b/src/renderer/gles/context_storage.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -33,15 +34,19 @@ class GLErrorGuard std::string name_; }; -class OpenGLTextureBinding +class GLTextureBinding { public: - OpenGLTextureBinding(GLenum target, GLuint texture) + GLTextureBinding() + : target_(GL_TEXTURE_2D) + , texture_(0) + { + } + GLTextureBinding(GLenum target, GLuint texture) : target_(target) , texture_(texture) { } - OpenGLTextureBinding(OpenGLTextureBinding &) = default; inline void reset(GLenum target, GLuint texture) { @@ -57,6 +62,14 @@ class OpenGLTextureBinding return texture_; } + // Bind this texture to the specified texture unit. + // The `unit` should be one of the GL_TEXTURE0, GL_TEXTURE1, ..., GL_TEXTURE31. + inline void bindTo(GLenum unit) + { + glActiveTexture(unit); + glBindTexture(target_, texture_); + } + private: GLenum target_; GLuint texture_; @@ -275,8 +288,7 @@ class ContextGLStorage m_RenderbufferId = from->m_RenderbufferId; m_VertexArrayObjectId = from->m_VertexArrayObjectId; m_LastActiveTextureUnit = from->m_LastActiveTextureUnit; - for (auto it = from->m_TextureBindingsWithUnit.begin(); it != from->m_TextureBindingsWithUnit.end(); it++) - m_TextureBindingsWithUnit[it->first] = std::make_shared(*it->second); + m_TextureBindings = from->m_TextureBindings; } ~ContextGLStorage() { @@ -393,7 +405,7 @@ class ContextGLStorage std::optional m_RenderbufferId; GLint m_VertexArrayObjectId = 0; GLenum m_LastActiveTextureUnit = GL_TEXTURE0; - std::map> m_TextureBindingsWithUnit; + std::unordered_map m_TextureBindings; }; class OpenGLNamesStorage : public std::map diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 48a0636aa..f8a925a63 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -356,6 +356,25 @@ class RHI_OpenGL : public TrRenderHardwareInterface DEBUG(logTag, " Mask=%d", stencilMask); } } + + // Print Texture bindings + { + GLint activatedUnit; + glGetIntegerv(GL_ACTIVE_TEXTURE, &activatedUnit); + DEBUG(logTag, " Active Texture Unit: %d", activatedUnit - GL_TEXTURE0); + + GLint maxTextureUnits; + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + for (int i = 0; i < maxTextureUnits; ++i) + { + GLint textureId; + glActiveTexture(GL_TEXTURE0 + i); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureId); + if (textureId != 0) + DEBUG(logTag, " TEXTURE%d: texture(%d)", i, textureId); + } + glActiveTexture(activatedUnit); // Restore the active texture unit + } } private: @@ -1169,21 +1188,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto &glObjectManager = reqContentRenderer->getContextGL()->ObjectManagerRef(); - auto target = req->target; - auto texture = glObjectManager.FindTexture(req->texture); - GetRenderer()->getContextGL()->recordTextureBindingFromHost(); - glBindTexture(target, texture); - - auto contentGlContext = reqContentRenderer->getContextGL(); - contentGlContext->onTextureBindingChanged(target, texture); + GLuint texture; + reqContentRenderer->getContextGL()->bindTexture(req->target, req->texture, texture); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - PrintDebugInfo(req, to_string(texture).c_str(), nullptr, options); - - GLint activeUnit; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeUnit); - DEBUG(DEBUG_TAG, " active: %d", activeUnit); + stringstream res_ss; + res_ss << "texture(" << texture << ")"; + PrintDebugInfo(req, res_ss.str().c_str(), nullptr, options); } } TR_OPENGL_FUNC void OnTexImage2D(TextureImage2DCommandBufferRequest *req, @@ -1199,7 +1210,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface GLint border = req->border; GLenum format = req->format; GLenum type = req->pixelType; - const GLvoid *pixels = nullptr; + GLvoid *pixels = nullptr; if (req->pixels == nullptr) { @@ -1214,7 +1225,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface const auto &downsampled = transmute::ImageProcessor::GetDownsampledImage(req->pixels, width, height); width = downsampled.width; height = downsampled.height; - pixels = downsampled.pixels.data(); + pixels = (GLvoid *)downsampled.pixels.data(); } else { @@ -1225,10 +1236,8 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { - GLint currentTexture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤tTexture); + PrintDebugInfo(req, nullptr, nullptr, options); - DEBUG(DEBUG_TAG, "[%d] GL::TexImage2D(%s [%d,%d]) => texture(%d)", options.isDefaultQueue(), gles::glEnumToString(target).c_str(), width, height, currentTexture); DEBUG(DEBUG_TAG, " level: %d", level); DEBUG(DEBUG_TAG, " internalformat: %s", gles::glTextureInternalFormatToString(internalformat).c_str()); DEBUG(DEBUG_TAG, " width: %d", width); @@ -1294,12 +1303,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface { glTexParameteri(req->target, req->pname, req->param); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(options.printsCall ? DEBUG_TAG : LOG_TAG_ERROR, - "[%d] GL::TexParameteri(target=%s, pname=%s, param=%d)", - options.isDefaultQueue(), - gles::glEnumToString(req->target).c_str(), - gles::glTextureParameterToString(req->pname).c_str(), - req->param); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnTexParameterf(TextureParameterfCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1307,29 +1311,15 @@ class RHI_OpenGL : public TrRenderHardwareInterface { glTexParameterf(req->target, req->pname, req->param); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - DEBUG(options.printsCall ? DEBUG_TAG : LOG_TAG_ERROR, - "[%d] GL::TexParameterf(target=%s, pname=%s, param=%f)", - options.isDefaultQueue(), - gles::glEnumToString(req->target).c_str(), - gles::glTextureParameterToString(req->pname).c_str(), - req->param); + PrintDebugInfo(req, nullptr, nullptr, options); } TR_OPENGL_FUNC void OnActiveTexture(ActiveTextureCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { - auto textureUnit = req->activeUnit; - glActiveTexture(textureUnit); - reqContentRenderer->getContextGL()->onActiveTextureUnitChanged(textureUnit); + reqContentRenderer->getContextGL()->activeTexture(req->activeUnit); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) - { PrintDebugInfo(req, nullptr, nullptr, options); - - GLint using_program; - glGetIntegerv(GL_CURRENT_PROGRAM, &using_program); - DEBUG(DEBUG_TAG, " program: %d", using_program); - DEBUG(DEBUG_TAG, " id: %d", textureUnit - GL_TEXTURE0); - } } TR_OPENGL_FUNC void OnGenerateMipmap(GenerateMipmapCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, @@ -1798,11 +1788,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface return; } - glUniform4f(loc.value(), - TR_OPENGL_GET_NUMBER(req->v0), - TR_OPENGL_GET_NUMBER(req->v1), - TR_OPENGL_GET_NUMBER(req->v2), - TR_OPENGL_GET_NUMBER(req->v3)); + glUniform4f(loc.value(), req->v0, req->v1, req->v2, req->v3); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) PrintDebugInfo(req, nullptr, nullptr, options); } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 159da6297..676df670d 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -97,7 +97,7 @@ namespace renderer { for (auto contentRenderer : contentRenderers) { - auto content = contentRenderer->getContent(); + shared_ptr content = contentRenderer->getContent(); if (content == nullptr || content->disableRendering) { /** @@ -124,12 +124,16 @@ namespace renderer { if (rhi == nullptr) [[unlikely]] return; // Skip if api is not ready. + + // TODO(yorkie): support the transparents render pass. } void TrRenderer::onBeforeRendering() { if (rhi == nullptr) [[unlikely]] return; // Skip if api is not ready. + + // TODO(yorkie): implement the before rendering logic. } void TrRenderer::onAfterRendering() From 9aaef969e92a1de7d3405a7a518e0be7c931a04b Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 15 Jul 2025 20:45:20 +0800 Subject: [PATCH 23/27] build: fix android errors --- src/client/graphics/webgl_program.hpp | 1 + src/renderer/gles/context_storage.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/client/graphics/webgl_program.hpp b/src/client/graphics/webgl_program.hpp index 8a37046b2..8eee2c9b9 100644 --- a/src/client/graphics/webgl_program.hpp +++ b/src/client/graphics/webgl_program.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include diff --git a/src/renderer/gles/context_storage.hpp b/src/renderer/gles/context_storage.hpp index 47a16f086..7e595f9a6 100644 --- a/src/renderer/gles/context_storage.hpp +++ b/src/renderer/gles/context_storage.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include From 3fa911b2ff6fb887926bcebfbd8c233448b4655b Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Tue, 15 Jul 2025 23:10:07 +0800 Subject: [PATCH 24/27] update --- src/renderer/content_renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/content_renderer.cpp b/src/renderer/content_renderer.cpp index 40252c4af..332b8ede4 100644 --- a/src/renderer/content_renderer.cpp +++ b/src/renderer/content_renderer.cpp @@ -566,7 +566,7 @@ namespace renderer void TrContentRenderer::executeBackupFrame(int viewIndex) { auto &list = stereoFrameForBackup->getCommandBuffers(viewIndex); - if (list.size() > 0) + if (list.size() > 0) [[likely]] { TrBackupGLContextScope contextScopeForBackup(this); constellation->renderer->executeCommandBuffers(list, this, ExecutingPassType::kCachedXRFrame); From 685f3b71f90ac4022449a74cb5184cc1ce52d0a7 Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 16 Jul 2025 17:01:10 +0800 Subject: [PATCH 25/27] update --- src/renderer/gles/context_app.cpp | 11 +---- src/renderer/render_api_opengles.cpp | 70 ++++++++++++---------------- 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index ba57d73d9..e54614aad 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -95,9 +95,6 @@ GLuint ContextGLApp::currentDefaultRenderTarget() const void ContextGLApp::onFrameWillStart(ContextGLHost *host_context) { m_CurrentDefaultRenderTarget = host_context->currentFramebufferId(); - if (!m_FramebufferId.has_value()) - m_FramebufferId = m_CurrentDefaultRenderTarget; - glBindFramebuffer(GL_FRAMEBUFFER, m_CurrentDefaultRenderTarget); glClear(GL_STENCIL_BUFFER_BIT); @@ -527,16 +524,12 @@ renderer::TrContentRenderer &ContextGLApp::contentRendererChecked() const bool ContextGLApp::shouleExecuteDrawOnCurrent(GLsizei count) { assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); - if (!m_FramebufferId.has_value() || m_FramebufferId.value() == 0) [[unlikely]] + if (m_FramebufferId.has_value() && + m_FramebufferId.value() == 0) [[unlikely]] { DEBUG(LOG_TAG_ERROR, "Skip this draw: the framebuffer is not set."); return false; } - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) [[unlikely]] - { - DEBUG(LOG_TAG_ERROR, "Skip this draw: the framebuffer is not complete."); - return false; - } return true; } diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index f8a925a63..4b82a0b25 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -199,13 +199,6 @@ class RHI_OpenGL : public TrRenderHardwareInterface DEBUG(logTag, " Viewport: (%d, %d, %d, %d)", viewport[0], viewport[1], viewport[2], viewport[3]); DEBUG(logTag, " Scissor: (%d, %d, %d, %d)", scissor[0], scissor[1], scissor[2], scissor[3]); } - - auto color0 = GLFramebufferAttachment::FromCurrent(GL_COLOR_ATTACHMENT0); - auto depth = GLFramebufferAttachment::FromCurrent(GL_DEPTH_ATTACHMENT); - if (color0 != nullptr) - color0->print(" Color0"); - if (depth != nullptr) - depth->print(" Depth"); } // Print LINK_STATUS @@ -1970,6 +1963,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface if (matrixToUse == nullptr) [[unlikely]] { + PrintDebugInfo(req, nullptr, nullptr, options); DEBUG(LOG_TAG_ERROR, "UniformMatrix4fv() fails to read the matrix value, placeholderType=%d, deviceFrame=%p", req->computationGraph4values.placeholderId, @@ -2597,12 +2591,13 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectorgetContextGL(); ContextGLApp contextBaseState = ContextGLApp("tmp", contentGlContext); - bool should_copy_to_offscreen_pass = false; - for (auto commandbuffer : list) + bool should_move_to_offscreen_pass = false; + for (auto it = list.begin(); it != list.end();) { + commandbuffers::TrCommandBufferBase *commandbuffer = *it; assert(commandbuffer != nullptr && "command buffer must not be nullptr"); - CommandBufferType commandType = commandbuffer->type; + CommandBufferType commandType = commandbuffer->type; if (commandType == COMMAND_BUFFER_BIND_FRAMEBUFFER_REQ) { auto req = dynamic_cast(commandbuffer); @@ -2613,35 +2608,37 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vectortarget == GL_DRAW_FRAMEBUFFER)) { if (req->isBindToDefault()) // Stop copying commandbuffers into offscreen pass if it is to bind to default. - should_copy_to_offscreen_pass = false; + should_move_to_offscreen_pass = false; else { GLuint framebuffer = contentGlContext->ObjectManagerRef().FindFramebuffer(req->framebuffer); - should_copy_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); - if (should_copy_to_offscreen_pass == true) + should_move_to_offscreen_pass = framebuffer != contentGlContext->currentDefaultRenderTarget(); + if (should_move_to_offscreen_pass == true) content_renderer->resetOffscreenPassGLContext(framebuffer); } } } -#define ADD_COMMAND_BUFFER_HANDLER(commandType, RequestType, handlerName) \ - case COMMAND_BUFFER_##commandType##_REQ: \ - { \ - auto cbRequest = dynamic_cast(commandbuffer); \ - if (cbRequest != nullptr) \ - { \ - if (pass_type == ExecutingPassType::kXRFrame && \ - should_copy_to_offscreen_pass == true) \ - { \ - auto copied_commandbuffer = new RequestType(*cbRequest, true); \ - content_renderer->scheduleCommandBufferAtOffscreenPass(copied_commandbuffer); \ - } \ - else \ - { \ - On##handlerName(cbRequest, content_renderer, callOptions); \ - } \ - } \ - break; \ + // Move the command buffers to offscreen pass if needed + if (pass_type == ExecutingPassType::kXRFrame && should_move_to_offscreen_pass == true) + { + content_renderer->scheduleCommandBufferAtOffscreenPass(commandbuffer); + it = list.erase(it); // Remove this command buffer from the original list + continue; // Skip to the next command buffer + } + + // Move to the next command buffer + it++; + +#define ADD_COMMAND_BUFFER_HANDLER(commandType, RequestType, handlerName) \ + case COMMAND_BUFFER_##commandType##_REQ: \ + { \ + auto cbRequest = dynamic_cast(commandbuffer); \ + if (cbRequest != nullptr) \ + { \ + On##handlerName(cbRequest, content_renderer, callOptions); \ + } \ + break; \ } #define ADD_COMMAND_BUFFER_HANDLER_WITH_DEVICE_FRAME(commandType, RequestType, handlerName) \ @@ -2650,16 +2647,7 @@ bool RHI_OpenGL::ExecuteCommandBuffer(vector(commandbuffer); \ if (cbRequest != nullptr) \ { \ - if (pass_type == ExecutingPassType::kXRFrame && \ - should_copy_to_offscreen_pass == true) \ - { \ - auto copied_commandbuffer = new RequestType(*cbRequest, true); \ - content_renderer->scheduleCommandBufferAtOffscreenPass(copied_commandbuffer); \ - } \ - else \ - { \ - On##handlerName(cbRequest, content_renderer, callOptions, device_frame); \ - } \ + On##handlerName(cbRequest, content_renderer, callOptions, device_frame); \ } \ break; \ } From c97faa9b2767da01f8d27165ba1d3ee20bd3a15c Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 16 Jul 2025 17:33:54 +0800 Subject: [PATCH 26/27] update --- src/renderer/gles/context_host.cpp | 7 ++++++- src/renderer/renderer.hpp | 27 ++++++++++++++++++++++++--- src/runtime/unity_entry.cpp | 12 ++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/renderer/gles/context_host.cpp b/src/renderer/gles/context_host.cpp index a2d4547b4..3c172f066 100644 --- a/src/renderer/gles/context_host.cpp +++ b/src/renderer/gles/context_host.cpp @@ -1,3 +1,5 @@ +#include + #include "./context_host.hpp" #ifndef GL_COMPUTE_SHADER @@ -185,7 +187,10 @@ void ContextGLHost::recordFromHost() void ContextGLHost::restore() { ContextGLStorage::restore(); - glClear(GL_STENCIL_BUFFER_BIT); + + // Clear the host's stencil buffer because it might be written by the content renderers. + if (!renderer::TrRenderer::GetRendererRef().isStencilClearDisabled) [[likely]] + glClear(GL_STENCIL_BUFFER_BIT); } void ContextGLHost::onHostFramebufferChanged() diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index 997bf4627..ea300c154 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -46,10 +46,12 @@ namespace renderer { friend class TrContentRenderer; - private: using ContentRendererReference = std::shared_ptr; using ContentRenderersList = std::vector; + private: + static inline std::shared_ptr Instance_ = nullptr; + public: /** * Create a new renderer with the constellation. @@ -57,9 +59,19 @@ namespace renderer * @param constellation The constellation that the renderer belongs to. * @returns The created `TrRenderer` instance. */ - static inline std::shared_ptr Make(TrConstellation *constellation) + static std::shared_ptr Make(TrConstellation *constellation) { - return std::make_shared(constellation); + assert(Instance_ == nullptr && "Renderer instance is already created."); + Instance_ = std::make_shared(constellation); + return Instance_; + } + /** + * Get the renderer instance. + */ + static inline TrRenderer &GetRendererRef() + { + assert(Instance_ != nullptr && "Renderer instance is not created yet."); + return *Instance_; } public: @@ -77,6 +89,14 @@ namespace renderer { isTracingEnabled = true; } + /** + * Disable the stencil clear, it allows the host not to clear the stencil buffer if the host embedder needs to + * preserve the stencil buffer for some reason. + */ + inline void disableStencilClear() + { + isStencilClearDisabled = true; + } /** * Enable the host context summary. */ @@ -232,6 +252,7 @@ namespace renderer public: bool isTracingEnabled = false; + bool isStencilClearDisabled = false; bool isHostContextSummaryEnabled = false; bool isAppContextSummaryEnabled = false; bool useDoubleWideFramebuffer = false; diff --git a/src/runtime/unity_entry.cpp b/src/runtime/unity_entry.cpp index 95f817daa..a85df6391 100644 --- a/src/runtime/unity_entry.cpp +++ b/src/runtime/unity_entry.cpp @@ -249,12 +249,24 @@ static void OnPlatformSetup(UnityEmbedder *embedder) setenv("JSAR_THREEPIO_API_MODELID", modelidStr, 1); } + // Command setprop jsar.renderer.tracing yes + // Effect: Enable the renderer tracing and print the tracing logs at `TR_GLES`. char enableRendererTracingStr[PROP_VALUE_MAX]; if ( __system_property_get("jsar.renderer.tracing", enableRendererTracingStr) >= 0 && strcmp(enableRendererTracingStr, "yes") == 0) renderer->enableTracing(); + // Command: setprop jsar.renderer.clear_stencil no|disable + // Effect: Disable the stencil clear operation in the renderer. + char disableStencilClearStr[PROP_VALUE_MAX]; + if (__system_property_get("jsar.renderer.clear_stencil", disableStencilClearStr) >= 0) + { + if (strcmp(disableStencilClearStr, "no") == 0 || + strcmp(disableStencilClearStr, "disable")) + renderer->disableStencilClear(); + } + char enablePrintHostContextSummaryStr[PROP_VALUE_MAX]; if ( __system_property_get("jsar.renderer.print_host_context_summary", enablePrintHostContextSummaryStr) >= 0 && From f87211baeedf83a698a47151b58fc74a6fef3bdb Mon Sep 17 00:00:00 2001 From: Yorkie Makoto Date: Wed, 16 Jul 2025 18:33:27 +0800 Subject: [PATCH 27/27] update --- src/renderer/gles/context_app.cpp | 43 +++++++++++++++-- src/renderer/gles/context_app.hpp | 5 +- src/renderer/gles/framebuffer_attachment.cpp | 13 ++++- src/renderer/render_api_opengles.cpp | 50 +++++++++----------- src/runtime/unity_entry.cpp | 2 +- 5 files changed, 77 insertions(+), 36 deletions(-) diff --git a/src/renderer/gles/context_app.cpp b/src/renderer/gles/context_app.cpp index e54614aad..e3564a2c3 100644 --- a/src/renderer/gles/context_app.cpp +++ b/src/renderer/gles/context_app.cpp @@ -377,7 +377,7 @@ void ContextGLApp::bindTexture(GLenum target, uint32_t id, GLuint &texture) void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) { - if (shouleExecuteDrawOnCurrent(count)) + if (shouldExecuteDrawOnCurrent(count)) [[likely]] { glDrawArrays(mode, first, count); onAfterDraw(count); @@ -386,13 +386,48 @@ void ContextGLApp::drawArrays(GLenum mode, GLint first, GLsizei count) void ContextGLApp::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) { - if (shouleExecuteDrawOnCurrent(count)) + if (shouldExecuteDrawOnCurrent(count)) [[likely]] { glDrawElements(mode, count, type, indices); onAfterDraw(count); } } +void ContextGLApp::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) +{ + if (shouldExecuteDrawOnCurrent(count)) [[likely]] + { + glDrawArraysInstanced(mode, first, count, instancecount); + onAfterDraw(count); + } +} + +void ContextGLApp::drawElementsInstanced(GLenum mode, + GLsizei count, + GLenum type, + const GLvoid *indices, + GLsizei instancecount) +{ + if (shouldExecuteDrawOnCurrent(count)) [[likely]] + { + glDrawElementsInstanced(mode, count, type, indices, instancecount); + onAfterDraw(count); + } +} + +void ContextGLApp::drawRangeElements(GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const GLvoid *indices) +{ + if (shouldExecuteDrawOnCurrent(count)) [[likely]] + { + glDrawRangeElements(mode, start, end, count, type, indices); + onAfterDraw(count); + } +} std::optional ContextGLApp::getAttribLoc(commandbuffers::SetVertexAttribCommandBufferRequestBase *req) const { @@ -521,11 +556,11 @@ renderer::TrContentRenderer &ContextGLApp::contentRendererChecked() const return *contentRenderer; } -bool ContextGLApp::shouleExecuteDrawOnCurrent(GLsizei count) +bool ContextGLApp::shouldExecuteDrawOnCurrent(GLsizei count) { assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); if (m_FramebufferId.has_value() && - m_FramebufferId.value() == 0) [[unlikely]] + m_FramebufferId.value() == 0) { DEBUG(LOG_TAG_ERROR, "Skip this draw: the framebuffer is not set."); return false; diff --git a/src/renderer/gles/context_app.hpp b/src/renderer/gles/context_app.hpp index 9c2ee4651..0a330467a 100644 --- a/src/renderer/gles/context_app.hpp +++ b/src/renderer/gles/context_app.hpp @@ -79,6 +79,9 @@ class ContextGLApp : public ContextGLStorage // Draw functions void drawArrays(GLenum mode, GLint first, GLsizei count); void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); + void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + void drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount); + void drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); public: // GLES Helpers std::optional getAttribLoc(commandbuffers::SetVertexAttribCommandBufferRequestBase *) const; @@ -99,7 +102,7 @@ class ContextGLApp : public ContextGLStorage } private: - [[nodiscard]] bool shouleExecuteDrawOnCurrent(GLsizei count); + [[nodiscard]] bool shouldExecuteDrawOnCurrent(GLsizei count); void onAfterDraw(int drawCount); private: diff --git a/src/renderer/gles/framebuffer_attachment.cpp b/src/renderer/gles/framebuffer_attachment.cpp index 198e8fae8..0e84ff3af 100644 --- a/src/renderer/gles/framebuffer_attachment.cpp +++ b/src/renderer/gles/framebuffer_attachment.cpp @@ -99,14 +99,23 @@ unique_ptr GLFramebufferAttachment::FromCurrent(GLenum } GLenum textarget = attachment_object->texture_target_; - glGetIntegerv(textarget, ¤t_texture_binding); + optional texture_binding_name = nullopt; + if (textarget == GL_TEXTURE_2D) + texture_binding_name = GL_TEXTURE_BINDING_2D; + else if (textarget == GL_TEXTURE_2D_ARRAY) + texture_binding_name = GL_TEXTURE_BINDING_2D_ARRAY; + else if (textarget == GL_TEXTURE_2D_MULTISAMPLE) + texture_binding_name = GL_TEXTURE_BINDING_2D_MULTISAMPLE; + assert(texture_binding_name.has_value()); + + glGetIntegerv(texture_binding_name.value(), ¤t_texture_binding); { glBindTexture(textarget, attachment_texture); glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_WIDTH, &attachment_object->width_); glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_HEIGHT, &attachment_object->height_); glGetTexLevelParameteriv(textarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &attachment_object->texture_internal_format_); - glBindTexture(textarget, current_texture_binding); } + glBindTexture(textarget, current_texture_binding); // Clear any errors from the previous call glGetError(); diff --git a/src/renderer/render_api_opengles.cpp b/src/renderer/render_api_opengles.cpp index 4b82a0b25..2e4ea7f33 100644 --- a/src/renderer/render_api_opengles.cpp +++ b/src/renderer/render_api_opengles.cpp @@ -1990,6 +1990,22 @@ class RHI_OpenGL : public TrRenderHardwareInterface } } } + TR_OPENGL_FUNC void OnDrawBuffers(DrawBuffersCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) + { + auto n = req->n; + auto buffers = req->bufs; + glDrawBuffers(n, (const GLenum *)buffers); + if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es2/glDrawBuffers") != GL_NO_ERROR || options.printsCall)) + { + PrintDebugInfo(req, nullptr, nullptr, options); + + GLint bindingFramebuffer; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bindingFramebuffer); + DEBUG(DEBUG_TAG, " framebuffer: %d", bindingFramebuffer); + for (int i = 0; i < n; i++) + DEBUG(DEBUG_TAG, " buffers[%d]: %s", i, gles::glDrawBufferTargetToString(buffers[i]).c_str()); + } + } TR_OPENGL_FUNC void OnDrawArrays(DrawArraysCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) { auto mode = req->mode; @@ -2017,22 +2033,6 @@ class RHI_OpenGL : public TrRenderHardwareInterface DumpDrawCallInfo(DEBUG_TAG, "DrawElements", options.isDefaultQueue(), mode, count, type, indices); } } - TR_OPENGL_FUNC void OnDrawBuffers(DrawBuffersCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) - { - auto n = req->n; - auto buffers = req->bufs; - glDrawBuffers(n, (const GLenum *)buffers); - if (TR_UNLIKELY(CheckError(req, reqContentRenderer, "https://docs.gl/es2/glDrawBuffers") != GL_NO_ERROR || options.printsCall)) - { - PrintDebugInfo(req, nullptr, nullptr, options); - - GLint bindingFramebuffer; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &bindingFramebuffer); - DEBUG(DEBUG_TAG, " framebuffer: %d", bindingFramebuffer); - for (int i = 0; i < n; i++) - DEBUG(DEBUG_TAG, " buffers[%d]: %s", i, gles::glDrawBufferTargetToString(buffers[i]).c_str()); - } - } TR_OPENGL_FUNC void OnDrawArraysInstanced(DrawArraysInstancedCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) @@ -2042,9 +2042,7 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto count = req->count; auto instanceCount = req->instanceCount; - assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); - glDrawArraysInstanced(mode, first, count, instanceCount); - reqContentRenderer->increaseDrawCallsCount(count); + reqContentRenderer->getContextGL()->drawArraysInstanced(mode, first, count, instanceCount); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { PrintDebugInfo(req, nullptr, nullptr, options); @@ -2059,15 +2057,13 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto count = req->count; auto type = req->indicesType; auto indices = reinterpret_cast(req->indicesOffset); - auto instanceCount = req->instanceCount; + auto instancecount = req->instanceCount; - assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); - glDrawElementsInstanced(mode, count, type, indices, instanceCount); - reqContentRenderer->increaseDrawCallsCount(count); + reqContentRenderer->getContextGL()->drawElementsInstanced(mode, count, type, indices, instancecount); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { PrintDebugInfo(req, nullptr, nullptr, options); - DumpDrawCallInfo(DEBUG_TAG, "DrawElementsInstanced", options.isDefaultQueue(), mode, count, type, indices); + DumpDrawCallInfo(DEBUG_TAG, "DrawElementsInstanced", options.isDefaultQueue(), mode, count, 0, nullptr); } } TR_OPENGL_FUNC void OnDrawRangeElements(DrawRangeElementsCommandBufferRequest *req, @@ -2081,13 +2077,11 @@ class RHI_OpenGL : public TrRenderHardwareInterface auto type = req->indicesType; auto indices = reinterpret_cast(req->indicesOffset); - assert(count < WEBGL_MAX_COUNT_PER_DRAWCALL); - glDrawRangeElements(mode, start, end, count, type, indices); - reqContentRenderer->increaseDrawCallsCount(count); + reqContentRenderer->getContextGL()->drawRangeElements(mode, start, end, count, type, indices); if (TR_UNLIKELY(CheckError(req, reqContentRenderer) != GL_NO_ERROR || options.printsCall)) { PrintDebugInfo(req, nullptr, nullptr, options); - DumpDrawCallInfo(DEBUG_TAG, "DrawRangeElements", options.isDefaultQueue(), mode, count, type, indices); + DumpDrawCallInfo(DEBUG_TAG, "DrawRangeElements", options.isDefaultQueue(), mode, count, 0, nullptr); } } TR_OPENGL_FUNC void OnHint(HintCommandBufferRequest *req, renderer::TrContentRenderer *reqContentRenderer, ApiCallOptions &options) diff --git a/src/runtime/unity_entry.cpp b/src/runtime/unity_entry.cpp index a85df6391..c2f7f38c5 100644 --- a/src/runtime/unity_entry.cpp +++ b/src/runtime/unity_entry.cpp @@ -263,7 +263,7 @@ static void OnPlatformSetup(UnityEmbedder *embedder) if (__system_property_get("jsar.renderer.clear_stencil", disableStencilClearStr) >= 0) { if (strcmp(disableStencilClearStr, "no") == 0 || - strcmp(disableStencilClearStr, "disable")) + strcmp(disableStencilClearStr, "disable") == 0) renderer->disableStencilClear(); }