From c6d3ffa4ba3ef2c25915d9369e9157cc2bca3b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jhonny=20Go=CC=88ransson?= Date: Thu, 21 Nov 2024 14:24:36 +0100 Subject: [PATCH] Add a debug function to disable blitting --- defold-rive/include/defold/renderer.h | 8 +- defold-rive/src/comp_rive.cpp | 42 ++++--- defold-rive/src/comp_rive.h | 1 + defold-rive/src/private/renderer_context.h | 2 +- .../src/private/renderer_context_metal.mm | 5 +- .../src/private/renderer_context_opengl.cpp | 106 ++++++++++-------- defold-rive/src/private/renderer_private.cpp | 13 ++- defold-rive/src/script_rive.cpp | 15 +++ 8 files changed, 125 insertions(+), 67 deletions(-) diff --git a/defold-rive/include/defold/renderer.h b/defold-rive/include/defold/renderer.h index a4517d5..5ee6395 100644 --- a/defold-rive/include/defold/renderer.h +++ b/defold-rive/include/defold/renderer.h @@ -35,6 +35,12 @@ namespace dmRive typedef void* HRenderContext; typedef struct ShaderResources ShaderResources; + struct RenderBeginParams + { + bool m_DoFinalBlit = true; + uint8_t m_BackbufferSamples = 0; + }; + HRenderContext NewRenderContext(); void DeleteRenderContext(HRenderContext context); rive::rcp CreateRiveRenderImage(HRenderContext context, void* bytes, uint32_t byte_count); @@ -43,7 +49,7 @@ namespace dmRive rive::Mat2D GetViewTransform(HRenderContext context, dmRender::HRenderContext render_context); rive::Mat2D GetViewProjectionTransform(HRenderContext context, dmRender::HRenderContext render_context); void GetDimensions(HRenderContext context, uint32_t* width, uint32_t* height); - void RenderBegin(HRenderContext context, dmResource::HFactory factory); + void RenderBegin(HRenderContext context, dmResource::HFactory factory, const RenderBeginParams& params); void RenderEnd(HRenderContext context); dmResource::Result LoadShaders(dmResource::HFactory factory, ShaderResources** resources); void ReleaseShaders(dmResource::HFactory factory, ShaderResources** resources); diff --git a/defold-rive/src/comp_rive.cpp b/defold-rive/src/comp_rive.cpp index db7ae9a..9eb35f4 100644 --- a/defold-rive/src/comp_rive.cpp +++ b/defold-rive/src/comp_rive.cpp @@ -114,6 +114,7 @@ namespace dmRive static float g_DisplayFactor = 0.0f; static float g_OriginalWindowWidth = 0.0f; static float g_OriginalWindowHeight = 0.0f; + static RenderBeginParams g_RenderBeginParams; static void ResourceReloadedCallback(const dmResource::ResourceReloadedParams* params); static void DestroyComponent(struct RiveWorld* world, uint32_t index); @@ -448,18 +449,21 @@ namespace dmRive { RenderEnd(world->m_RiveRenderContext); - // Do our own resolve here - dmRender::RenderObject& ro = *world->m_RenderObjects.End(); - world->m_RenderObjects.SetSize(world->m_RenderObjects.Size()+1); - ro.Init(); - ro.m_Material = GetBlitToBackBufferMaterial(world->m_RiveRenderContext, render_context); - ro.m_VertexDeclaration = dmRender::GetVertexDeclaration(ro.m_Material); - ro.m_VertexBuffer = world->m_BlitToBackbufferVertexBuffer; - ro.m_PrimitiveType = dmGraphics::PRIMITIVE_TRIANGLES; - ro.m_VertexStart = 0; - ro.m_VertexCount = 6; - ro.m_Textures[0] = GetBackingTexture(world->m_RiveRenderContext); - dmRender::AddToRender(render_context, &ro); + if (g_RenderBeginParams.m_DoFinalBlit) + { + // Do our own resolve here + dmRender::RenderObject& ro = *world->m_RenderObjects.End(); + world->m_RenderObjects.SetSize(world->m_RenderObjects.Size()+1); + ro.Init(); + ro.m_Material = GetBlitToBackBufferMaterial(world->m_RiveRenderContext, render_context); + ro.m_VertexDeclaration = dmRender::GetVertexDeclaration(ro.m_Material); + ro.m_VertexBuffer = world->m_BlitToBackbufferVertexBuffer; + ro.m_PrimitiveType = dmGraphics::PRIMITIVE_TRIANGLES; + ro.m_VertexStart = 0; + ro.m_VertexCount = 6; + ro.m_Textures[0] = GetBackingTexture(world->m_RiveRenderContext); + dmRender::AddToRender(render_context, &ro); + } } } @@ -503,7 +507,7 @@ namespace dmRive dmRive::RiveSceneData* data = (dmRive::RiveSceneData*) scene_res->m_Scene; world->m_RiveRenderContext = data->m_RiveRenderContext; - RenderBegin(world->m_RiveRenderContext, world->m_Ctx->m_Factory); + RenderBegin(world->m_RiveRenderContext, world->m_Ctx->m_Factory, g_RenderBeginParams); uint32_t width, height; GetDimensions(world->m_RiveRenderContext, &width, &height); @@ -1359,6 +1363,9 @@ namespace dmRive rivectx->m_RenderContext = *(dmRender::HRenderContext*)ctx->m_Contexts.Get(dmHashString64("render")); rivectx->m_MaxInstanceCount = dmConfigFile::GetInt(ctx->m_Config, "rive.max_instance_count", 128); + g_RenderBeginParams.m_DoFinalBlit = true; + g_RenderBeginParams.m_BackbufferSamples = dmConfigFile::GetInt(ctx->m_Config, "display.samples", 0); + g_OriginalWindowWidth = dmGraphics::GetWidth(rivectx->m_GraphicsContext); g_OriginalWindowHeight = dmGraphics::GetHeight(rivectx->m_GraphicsContext); g_DisplayFactor = dmGraphics::GetDisplayScaleFactor(rivectx->m_GraphicsContext); @@ -1727,6 +1734,15 @@ namespace dmRive } return text_run_value->text().c_str(); } + + void CompRiveDebugSetBlitMode(bool value) + { + #if defined (DM_PLATFORM_MACOS) || defined (DM_PLATFORM_IOS) + dmLogWarning("Changing the blit mode is not supported on this platform."); + #else + g_RenderBeginParams.m_DoFinalBlit = value; + #endif + } } DM_DECLARE_COMPONENT_TYPE(ComponentTypeRive, "rivemodelc", dmRive::ComponentTypeCreate, dmRive::ComponentTypeDestroy); diff --git a/defold-rive/src/comp_rive.h b/defold-rive/src/comp_rive.h index 0ce707f..1d90703 100644 --- a/defold-rive/src/comp_rive.h +++ b/defold-rive/src/comp_rive.h @@ -120,6 +120,7 @@ namespace dmRive StateMachineInputData::Result CompRiveSetStateMachineInput(RiveComponent* component, const char* input_name, const char* nested_artboard_path, const StateMachineInputData& data); float CompRiveGetDisplayScaleFactor(); + void CompRiveDebugSetBlitMode(bool value); // bool CompRiveSetIKTargetInstance(RiveComponent* component, dmhash_t constraint_id, float mix, dmhash_t instance_id); // bool CompRiveSetIKTargetPosition(RiveComponent* component, dmhash_t constraint_id, float mix, Vectormath::Aos::Point3 position); diff --git a/defold-rive/src/private/renderer_context.h b/defold-rive/src/private/renderer_context.h index 0b6bec4..7885e3f 100644 --- a/defold-rive/src/private/renderer_context.h +++ b/defold-rive/src/private/renderer_context.h @@ -14,7 +14,7 @@ namespace dmRive virtual ~IDefoldRiveRenderer() {} virtual rive::Factory* Factory() = 0; virtual rive::Renderer* MakeRenderer() = 0; - virtual void OnSizeChanged(uint32_t width, uint32_t height, uint32_t sample_count) = 0; + virtual void OnSizeChanged(uint32_t width, uint32_t height, uint32_t sample_count, bool do_final_blit) = 0; virtual void BeginFrame(const rive::gpu::RenderContext::FrameDescriptor& frameDescriptor) = 0; virtual void Flush() = 0; virtual void SetRenderTargetTexture(dmGraphics::HTexture texture) = 0; diff --git a/defold-rive/src/private/renderer_context_metal.mm b/defold-rive/src/private/renderer_context_metal.mm index 2ba10cf..109ffca 100644 --- a/defold-rive/src/private/renderer_context_metal.mm +++ b/defold-rive/src/private/renderer_context_metal.mm @@ -52,8 +52,11 @@ void Flush() override [flushCommandBuffer commit]; } - void OnSizeChanged(uint32_t width, uint32_t height, uint32_t sample_count) override + void OnSizeChanged(uint32_t width, uint32_t height, uint32_t sample_count, bool do_final_blit) override { + // For now we can only output the result if we blit it to the backbuffer via an extra DC + assert(do_final_blit); + auto renderContextImpl = m_RenderContext->static_impl_cast(); m_RenderTarget = renderContextImpl->makeRenderTarget(MTLPixelFormatBGRA8Unorm, width, height); diff --git a/defold-rive/src/private/renderer_context_opengl.cpp b/defold-rive/src/private/renderer_context_opengl.cpp index 69d7e6a..5568dfd 100644 --- a/defold-rive/src/private/renderer_context_opengl.cpp +++ b/defold-rive/src/private/renderer_context_opengl.cpp @@ -140,8 +140,65 @@ namespace dmRive m_DefoldPipelineState.m_WriteColorMask & (1<<0)); } - void OnSizeChanged(uint32_t width, uint32_t height, uint32_t sample_count) override + void OnSizeChanged(uint32_t width, uint32_t height, uint32_t sample_count, bool do_final_blit) override { + uint32_t fbo_id = GetFrameBufferId(width, height, do_final_blit); + uint32_t fbo_samples = do_final_blit ? 0 : sample_count; + + dmLogInfo("OnSizeChanged %d %d %d %d", width, height, fbo_id, fbo_samples); + + m_RenderTarget = rive::make_rcp(width, height, fbo_id, fbo_samples); + OpenGLCheckError("OnSizeChanged After"); + + glViewport(0, 0, width, height); + } + + void SetGraphicsContext(dmGraphics::HContext graphics_context) override + { + m_GraphicsContext = graphics_context; + } + + void SetRenderTargetTexture(dmGraphics::HTexture texture) override + { + + } + + dmGraphics::HTexture GetBackingTexture() override + { + return dmGraphics::GetRenderTargetTexture(m_DefoldRenderTarget, dmGraphics::BUFFER_TYPE_COLOR0_BIT); + } + + rive::rcp MakeImageTexture(uint32_t width, + uint32_t height, + uint32_t mipLevelCount, + const uint8_t imageDataRGBA[]) override + { + if (mipLevelCount < 1) + mipLevelCount = 1; + + auto renderContextImpl = m_RenderContext->static_impl_cast(); + auto texture = renderContextImpl->makeImageTexture(width, height, mipLevelCount, imageDataRGBA); + OpenGLCheckError("MakeImageTexture After"); + return texture; + } + + private: + + void SetDefoldGraphicsState(dmGraphics::State state, bool flag) + { + if (flag) + dmGraphics::EnableState(m_GraphicsContext, state); + else + dmGraphics::DisableState(m_GraphicsContext, state); + } + + uint32_t GetFrameBufferId(uint32_t width, uint32_t height, bool do_final_blit) + { + // Use framebuffer for the final blit + if (!do_final_blit) + return 0; + + // Otherwise, use an intermediate framebuffer for the final blit if (!m_DefoldRenderTarget) { dmGraphics::RenderTargetCreationParams params = {}; @@ -195,53 +252,8 @@ namespace dmRive { dmGraphics::SetRenderTargetSize(m_DefoldRenderTarget, width, height); } - assert(m_DefoldRenderTarget); - uint32_t id = dmGraphics::OpenGLGetRenderTargetId(m_GraphicsContext, m_DefoldRenderTarget); - - m_RenderTarget = rive::make_rcp(width, height, id, sample_count); - OpenGLCheckError("OnSizeChanged After"); - - glViewport(0, 0, width, height); - } - - void SetGraphicsContext(dmGraphics::HContext graphics_context) override - { - m_GraphicsContext = graphics_context; - } - - void SetRenderTargetTexture(dmGraphics::HTexture texture) override - { - - } - - dmGraphics::HTexture GetBackingTexture() override - { - return dmGraphics::GetRenderTargetTexture(m_DefoldRenderTarget, dmGraphics::BUFFER_TYPE_COLOR0_BIT); - } - - rive::rcp MakeImageTexture(uint32_t width, - uint32_t height, - uint32_t mipLevelCount, - const uint8_t imageDataRGBA[]) override - { - if (mipLevelCount < 1) - mipLevelCount = 1; - - auto renderContextImpl = m_RenderContext->static_impl_cast(); - auto texture = renderContextImpl->makeImageTexture(width, height, mipLevelCount, imageDataRGBA); - OpenGLCheckError("MakeImageTexture After"); - return texture; - } - - private: - - void SetDefoldGraphicsState(dmGraphics::State state, bool flag) - { - if (flag) - dmGraphics::EnableState(m_GraphicsContext, state); - else - dmGraphics::DisableState(m_GraphicsContext, state); + return dmGraphics::OpenGLGetRenderTargetId(m_GraphicsContext, m_DefoldRenderTarget); } std::unique_ptr m_RenderContext; diff --git a/defold-rive/src/private/renderer_private.cpp b/defold-rive/src/private/renderer_private.cpp index 46b82b0..39cf1f4 100644 --- a/defold-rive/src/private/renderer_private.cpp +++ b/defold-rive/src/private/renderer_private.cpp @@ -58,6 +58,7 @@ namespace dmRive uint32_t m_LastWidth; uint32_t m_LastHeight; + uint8_t m_LastDoFinalBlit : 1; uint8_t m_FrameBegin : 1; }; @@ -157,7 +158,7 @@ namespace dmRive return renderer->m_RenderContext->GetBackingTexture(); } - void RenderBegin(HRenderContext context, dmResource::HFactory factory) + void RenderBegin(HRenderContext context, dmResource::HFactory factory, const RenderBeginParams& params) { DefoldRiveRenderer* renderer = (DefoldRiveRenderer*) context; @@ -177,24 +178,28 @@ namespace dmRive uint32_t width = dmGraphics::GetWindowWidth(renderer->m_GraphicsContext); uint32_t height = dmGraphics::GetWindowHeight(renderer->m_GraphicsContext); - if (width != renderer->m_LastWidth || height != renderer->m_LastHeight) + if (width != renderer->m_LastWidth || height != renderer->m_LastHeight || renderer->m_LastDoFinalBlit != params.m_DoFinalBlit) { dmLogInfo("Change size to %d, %d", width, height); - renderer->m_RenderContext->OnSizeChanged(width, height, 0); + renderer->m_RenderContext->OnSizeChanged(width, height, params.m_BackbufferSamples, params.m_DoFinalBlit); renderer->m_LastWidth = width; renderer->m_LastHeight = height; + renderer->m_LastDoFinalBlit = params.m_DoFinalBlit; } + int samples = (int) params.m_DoFinalBlit ? 0 : params.m_BackbufferSamples; + #if defined(DM_PLATFORM_MACOS) || defined(DM_PLATFORM_IOS) dmGraphics::HTexture swap_chain_texture = dmGraphics::VulkanGetActiveSwapChainTexture(renderer->m_GraphicsContext); renderer->m_RenderContext->SetRenderTargetTexture(swap_chain_texture); + samples = 0; #endif renderer->m_RenderContext->BeginFrame({ .renderTargetWidth = width, .renderTargetHeight = height, .clearColor = 0x00000000, - .msaaSampleCount = 0, + .msaaSampleCount = samples, // .disableRasterOrdering = s_forceAtomicMode, // .wireframe = s_wireframe, // .fillsDisabled = s_disableFill, diff --git a/defold-rive/src/script_rive.cpp b/defold-rive/src/script_rive.cpp index 66f8471..9850b29 100644 --- a/defold-rive/src/script_rive.cpp +++ b/defold-rive/src/script_rive.cpp @@ -412,6 +412,20 @@ namespace dmRive return 1; } + // This is an "all bets are off" mode. + static int RiveComp_DebugSetBlitMode(lua_State* L) + { + DM_LUA_STACK_CHECK(L, 0); + + if (!lua_isboolean(L, 1)) + { + return DM_LUA_ERROR("The first argument must be a boolean."); + } + bool value = lua_toboolean(L, 1); + CompRiveDebugSetBlitMode(value); + return 0; + } + static const luaL_reg RIVE_FUNCTIONS[] = { {"play_anim", RiveComp_PlayAnim}, @@ -426,6 +440,7 @@ namespace dmRive {"get_projection_matrix", RiveComp_GetProjectionMatrix}, {"get_state_machine_input", RiveComp_GetStateMachineInput}, {"set_state_machine_input", RiveComp_SetStateMachineInput}, + {"debug_set_blit_mode", RiveComp_DebugSetBlitMode}, {0, 0} };