From 81e9db18900720bafcfb10171baab55fa5950001 Mon Sep 17 00:00:00 2001 From: David Steele Date: Fri, 23 Apr 2021 10:36:27 +0100 Subject: [PATCH] Adding Depth/Stencil code Updating command buffer to add new commands to manage depth/stencil mode. Re-instated the test cases that were previously commented output Change-Id: I111cc425488452afe8fa081ae8efb90540cfbc90 --- .../test-graphics-command-buffer.cpp | 64 +++++ .../test-graphics-command-buffer.h | 263 ++++++++++++++++++++- .../test-graphics-controller.cpp | 160 +++++++++++++ automated-tests/src/dali/utc-Dali-Actor.cpp | 26 -- automated-tests/src/dali/utc-Dali-Renderer.cpp | 6 - dali/graphics-api/graphics-command-buffer.h | 31 ++- dali/internal/render/common/render-algorithms.cpp | 215 ++++++++++++----- dali/internal/render/common/render-algorithms.h | 11 +- dali/internal/render/common/render-manager.cpp | 21 +- dali/internal/render/renderers/render-renderer.cpp | 4 +- dali/internal/render/renderers/render-renderer.h | 14 +- dali/internal/update/common/scene-graph-scene.cpp | 37 ++- dali/internal/update/common/scene-graph-scene.h | 11 +- 13 files changed, 725 insertions(+), 138 deletions(-) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp index e34b852..9f86b99 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp @@ -18,6 +18,70 @@ namespace Dali { +std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op) +{ + switch(op) + { + case Graphics::StencilOp::KEEP: + os << "KEEP"; + return os; + case Graphics::StencilOp::ZERO: + os << "ZERO"; + return os; + case Graphics::StencilOp::REPLACE: + os << "REPLACE"; + return os; + case Graphics::StencilOp::INCREMENT_AND_CLAMP: + os << "INCREMENT_AND_CLAMP"; + return os; + case Graphics::StencilOp::DECREMENT_AND_CLAMP: + os << "DECREMENT_AND_CLAMP"; + return os; + case Graphics::StencilOp::INVERT: + os << "INVERT"; + return os; + case Graphics::StencilOp::INCREMENT_AND_WRAP: + os << "INCREMENT_AND_WRAP"; + return os; + case Graphics::StencilOp::DECREMENT_AND_WRAP: + os << "DECREMENT_AND_WRAP"; + return os; + } + return os; +}; + +std::ostream& operator<<(std::ostream& os, Graphics::CompareOp op) +{ + switch(op) + { + case Graphics::CompareOp::NEVER: + os << "NEVER"; + return os; + case Graphics::CompareOp::LESS: + os << "LESS"; + return os; + case Graphics::CompareOp::EQUAL: + os << "EQUAL"; + return os; + case Graphics::CompareOp::LESS_OR_EQUAL: + os << "LESS_OR_EQUAL"; + return os; + case Graphics::CompareOp::GREATER: + os << "GREATER"; + return os; + case Graphics::CompareOp::NOT_EQUAL: + os << "NOT_EQUAL"; + return os; + case Graphics::CompareOp::GREATER_OR_EQUAL: + os << "GREATER_OR_EQUAL"; + return os; + case Graphics::CompareOp::ALWAYS: + os << "ALWAYS"; + return os; + } + return os; +}; + TestGraphicsCommandBuffer::TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction) : mCallStack(callstack), mGlAbstraction(glAbstraction) diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h index a68cb7f..b75a402 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h @@ -54,9 +54,23 @@ enum class CommandType SET_VIEWPORT_TEST = 1 << 13, BEGIN_RENDER_PASS = 1 << 14, END_RENDER_PASS = 1 << 15, - EXECUTE_COMMAND_BUFFERS = 1 << 16 + EXECUTE_COMMAND_BUFFERS = 1 << 16, + SET_COLOR_MASK = 1 << 17, + CLEAR_STENCIL_BUFFER = 1 << 18, + CLEAR_DEPTH_BUFFER = 1 << 19, + SET_STENCIL_TEST_ENABLE = 1 << 20, + SET_STENCIL_WRITE_MASK = 1 << 21, + SET_STENCIL_OP = 1 << 22, + SET_STENCIL_FUNC = 1 << 23, + SET_DEPTH_COMPARE_OP = 1 << 24, + SET_DEPTH_TEST_ENABLE = 1 << 25, + SET_DEPTH_WRITE_ENABLE = 1 << 26, }; +std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op); + +std::ostream& operator<<(std::ostream& os, Graphics::CompareOp op); + using CommandTypeMask = uint32_t; template inline CommandTypeMask operator|(T flags, CommandType bit) @@ -294,6 +308,59 @@ struct Command data.viewportTest.enable = rhs.data.viewportTest.enable; break; } + case CommandType::SET_COLOR_MASK: + { + data.colorMask.enabled = rhs.data.colorMask.enabled; + break; + } + case CommandType::CLEAR_STENCIL_BUFFER: + { + break; + } + case CommandType::CLEAR_DEPTH_BUFFER: + { + break; + } + case CommandType::SET_STENCIL_TEST_ENABLE: + { + data.stencilTest.enabled = rhs.data.stencilTest.enabled; + break; + } + case CommandType::SET_STENCIL_FUNC: + { + data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask; + data.stencilFunc.compareOp = rhs.data.stencilFunc.compareOp; + data.stencilFunc.reference = rhs.data.stencilFunc.reference; + break; + } + case CommandType::SET_STENCIL_WRITE_MASK: + { + data.stencilWriteMask.mask = rhs.data.stencilWriteMask.mask; + break; + } + case CommandType::SET_STENCIL_OP: + { + data.stencilOp.failOp = rhs.data.stencilOp.failOp; + data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp; + data.stencilOp.passOp = rhs.data.stencilOp.passOp; + break; + } + + case CommandType::SET_DEPTH_COMPARE_OP: + { + data.depth.compareOp = rhs.data.depth.compareOp; + break; + } + case CommandType::SET_DEPTH_TEST_ENABLE: + { + data.depth.testEnabled = rhs.data.depth.testEnabled; + break; + } + case CommandType::SET_DEPTH_WRITE_ENABLE: + { + data.depth.writeEnabled = rhs.data.depth.writeEnabled; + break; + } } type = rhs.type; } @@ -394,6 +461,59 @@ struct Command data.viewportTest.enable = rhs.data.viewportTest.enable; break; } + + case CommandType::SET_COLOR_MASK: + { + data.colorMask.enabled = rhs.data.colorMask.enabled; + break; + } + case CommandType::CLEAR_STENCIL_BUFFER: + { + break; + } + case CommandType::CLEAR_DEPTH_BUFFER: + { + break; + } + case CommandType::SET_STENCIL_TEST_ENABLE: + { + data.stencilTest.enabled = rhs.data.stencilTest.enabled; + break; + } + case CommandType::SET_STENCIL_WRITE_MASK: + { + data.stencilWriteMask.mask = rhs.data.stencilWriteMask.mask; + break; + } + case CommandType::SET_STENCIL_OP: + { + data.stencilOp.failOp = rhs.data.stencilOp.failOp; + data.stencilOp.depthFailOp = rhs.data.stencilOp.depthFailOp; + data.stencilOp.passOp = rhs.data.stencilOp.passOp; + break; + } + case CommandType::SET_STENCIL_FUNC: + { + data.stencilFunc.compareMask = rhs.data.stencilFunc.compareMask; + data.stencilFunc.compareOp = rhs.data.stencilFunc.compareOp; + data.stencilFunc.reference = rhs.data.stencilFunc.reference; + break; + } + case CommandType::SET_DEPTH_COMPARE_OP: + { + data.depth.compareOp = rhs.data.depth.compareOp; + break; + } + case CommandType::SET_DEPTH_TEST_ENABLE: + { + data.depth.testEnabled = rhs.data.depth.testEnabled; + break; + } + case CommandType::SET_DEPTH_WRITE_ENABLE: + { + data.depth.writeEnabled = rhs.data.depth.writeEnabled; + break; + } } type = rhs.type; } @@ -480,6 +600,41 @@ struct Command std::vector buffers; } executeCommandBuffers; + struct + { + Graphics::CompareOp compareOp; + bool testEnabled; + bool writeEnabled; + } depth; + + struct + { + Graphics::StencilOp failOp; + Graphics::StencilOp passOp; + Graphics::StencilOp depthFailOp; + } stencilOp; + + struct + { + uint32_t mask; + } stencilWriteMask; + + struct + { + uint32_t compareMask; + Graphics::CompareOp compareOp; + uint32_t reference; + } stencilFunc; + + struct + { + bool enabled; + } stencilTest; + + struct + { + bool enabled; + } colorMask; } data; }; @@ -748,6 +903,112 @@ public: mCommands.back().data.viewportTest.enable = value; } + void SetColorMask(bool enabled) override + { + TraceCallStack::NamedParams params; + params["enabled"] << (enabled ? "T" : "F"); + mCallStack.PushCall("SetColorMask", params.str(), params); + mCommands.emplace_back(); + mCommands.back().type = CommandType::SET_COLOR_MASK; + mCommands.back().data.colorMask.enabled = enabled; + } + + void ClearStencilBuffer() override + { + mCallStack.PushCall("SetStencilMask", ""); + mCommands.emplace_back(); + mCommands.back().type = CommandType::CLEAR_STENCIL_BUFFER; + } + + void SetStencilTestEnable(bool stencilEnable) override + { + TraceCallStack::NamedParams params; + params["enabled"] << (stencilEnable ? "T" : "F"); + mCallStack.PushCall("SetStencilTestEnable", params.str(), params); + mCommands.emplace_back(); + mCommands.back().type = CommandType::SET_STENCIL_TEST_ENABLE; + mCommands.back().data.stencilTest.enabled = stencilEnable; + } + + void SetStencilWriteMask(uint32_t writeMask) override + { + TraceCallStack::NamedParams params; + params["writeMask"] << std::hex << writeMask; + mCallStack.PushCall("SetStencilWriteMask", params.str(), params); + mCommands.emplace_back(); + mCommands.back().type = CommandType::SET_STENCIL_WRITE_MASK; + mCommands.back().data.stencilWriteMask.mask = writeMask; + } + + void SetStencilOp(Graphics::StencilOp failOp, + Graphics::StencilOp passOp, + Graphics::StencilOp depthFailOp) override + { + TraceCallStack::NamedParams params; + params["failOp"] << failOp; + params["passOp"] << passOp; + params["depthFailOp"] << depthFailOp; + mCallStack.PushCall("SetStencilOp", params.str(), params); + mCommands.emplace_back(); + mCommands.back().type = CommandType::SET_STENCIL_OP; + mCommands.back().data.stencilOp.failOp = failOp; + mCommands.back().data.stencilOp.passOp = passOp; + mCommands.back().data.stencilOp.depthFailOp = depthFailOp; + } + + void SetStencilFunc(Graphics::CompareOp compareOp, + uint32_t reference, + uint32_t compareMask) override + { + TraceCallStack::NamedParams params; + params["compareOp"] << compareOp; + params["compareMask"] << std::hex << compareMask; + params["reference"] << std::hex << reference; + mCallStack.PushCall("SetStencilFunc", params.str(), params); + + mCommands.emplace_back(); + mCommands.back().type = CommandType::SET_STENCIL_FUNC; + + mCommands.back().data.stencilFunc.compareOp = compareOp; + mCommands.back().data.stencilFunc.compareMask = compareMask; + mCommands.back().data.stencilFunc.reference = reference; + } + + void SetDepthCompareOp(Graphics::CompareOp compareOp) override + { + TraceCallStack::NamedParams params; + params["compareOp"] << compareOp; + mCallStack.PushCall("SetDepthCompareOp", params.str(), params); + mCommands.emplace_back(); + mCommands.back().type = CommandType::SET_DEPTH_COMPARE_OP; + mCommands.back().data.depth.compareOp = compareOp; + } + + void SetDepthTestEnable(bool depthTestEnable) override + { + TraceCallStack::NamedParams params; + params["enabled"] << (depthTestEnable ? "T" : "F"); + mCallStack.PushCall("SetDepthTestEnable", params.str(), params); + mCommands.emplace_back(); + mCommands.back().type = CommandType::SET_DEPTH_TEST_ENABLE; + mCommands.back().data.depth.testEnabled = depthTestEnable; + } + void SetDepthWriteEnable(bool depthWriteEnable) override + { + TraceCallStack::NamedParams params; + params["enabled"] << (depthWriteEnable ? "T" : "F"); + mCallStack.PushCall("SetDepthWriteEnable", params.str(), params); + mCommands.emplace_back(); + mCommands.back().type = CommandType::SET_DEPTH_WRITE_ENABLE; + mCommands.back().data.depth.writeEnabled = depthWriteEnable; + } + void ClearDepthBuffer() override + { + mCallStack.PushCall("ClearDepthBuffer", ""); + mCommands.emplace_back(); + mCommands.back().type = CommandType::CLEAR_DEPTH_BUFFER; + } + [[nodiscard]] const std::vector& GetCommands() const { return mCommands; diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp index ddcf0f5..a3a0fee 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp @@ -384,6 +384,76 @@ GLenum GetBlendOp(Graphics::BlendOp blendOp) return op; } +struct GLCompareOp +{ + constexpr explicit GLCompareOp(Graphics::CompareOp compareOp) + { + switch(compareOp) + { + case Graphics::CompareOp::NEVER: + op = GL_NEVER; + break; + case Graphics::CompareOp::LESS: + op = GL_LESS; + break; + case Graphics::CompareOp::EQUAL: + op = GL_EQUAL; + break; + case Graphics::CompareOp::LESS_OR_EQUAL: + op = GL_LEQUAL; + break; + case Graphics::CompareOp::GREATER: + op = GL_GREATER; + break; + case Graphics::CompareOp::NOT_EQUAL: + op = GL_NOTEQUAL; + break; + case Graphics::CompareOp::GREATER_OR_EQUAL: + op = GL_GEQUAL; + break; + case Graphics::CompareOp::ALWAYS: + op = GL_ALWAYS; + break; + } + } + GLenum op{GL_LESS}; +}; + +struct GLStencilOp +{ + constexpr explicit GLStencilOp(Graphics::StencilOp stencilOp) + { + switch(stencilOp) + { + case Graphics::StencilOp::KEEP: + op = GL_KEEP; + break; + case Graphics::StencilOp::ZERO: + op = GL_ZERO; + break; + case Graphics::StencilOp::REPLACE: + op = GL_REPLACE; + break; + case Graphics::StencilOp::INCREMENT_AND_CLAMP: + op = GL_INCR; + break; + case Graphics::StencilOp::DECREMENT_AND_CLAMP: + op = GL_DECR; + break; + case Graphics::StencilOp::INVERT: + op = GL_INVERT; + break; + case Graphics::StencilOp::INCREMENT_AND_WRAP: + op = GL_INCR_WRAP; + break; + case Graphics::StencilOp::DECREMENT_AND_WRAP: + op = GL_DECR_WRAP; + break; + } + } + GLenum op{GL_KEEP}; +}; + class TestGraphicsMemory : public Graphics::Memory { public: @@ -602,6 +672,82 @@ void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& com mGl.Viewport(rect.x, rect.y, rect.width, rect.height); break; } + + case CommandType::SET_COLOR_MASK: + { + // Set all channels to the same mask + const bool mask = cmd.data.colorMask.enabled; + mGl.ColorMask(mask, mask, mask, mask); + break; + } + case CommandType::CLEAR_STENCIL_BUFFER: + { + mGl.Clear(GL_STENCIL_BUFFER_BIT); + break; + } + case CommandType::CLEAR_DEPTH_BUFFER: + { + mGl.Clear(GL_DEPTH_BUFFER_BIT); + break; + } + + case CommandType::SET_STENCIL_TEST_ENABLE: + { + if(cmd.data.stencilTest.enabled) + { + mGl.Enable(GL_STENCIL_TEST); + } + else + { + mGl.Disable(GL_STENCIL_TEST); + } + break; + } + + case CommandType::SET_STENCIL_FUNC: + { + mGl.StencilFunc(GLCompareOp(cmd.data.stencilFunc.compareOp).op, + cmd.data.stencilFunc.reference, + cmd.data.stencilFunc.compareMask); + break; + } + + case CommandType::SET_STENCIL_WRITE_MASK: + { + mGl.StencilMask(cmd.data.stencilWriteMask.mask); + break; + } + case CommandType::SET_STENCIL_OP: + { + mGl.StencilOp(GLStencilOp(cmd.data.stencilOp.failOp).op, + GLStencilOp(cmd.data.stencilOp.depthFailOp).op, + GLStencilOp(cmd.data.stencilOp.passOp).op); + break; + } + + case CommandType::SET_DEPTH_COMPARE_OP: + { + mGl.DepthFunc(GLCompareOp(cmd.data.depth.compareOp).op); + break; + } + case CommandType::SET_DEPTH_TEST_ENABLE: + { + if(cmd.data.depth.testEnabled) + { + mGl.Enable(GL_DEPTH_TEST); + } + else + { + mGl.Disable(GL_DEPTH_TEST); + } + break; + } + case CommandType::SET_DEPTH_WRITE_ENABLE: + { + mGl.DepthMask(cmd.data.depth.writeEnabled); + break; + } + case CommandType::EXECUTE_COMMAND_BUFFERS: { // Process secondary command buffers @@ -663,10 +809,24 @@ void TestGraphicsController::ProcessCommandBuffer(TestGraphicsCommandBuffer& com const auto& depthStencil = renderPass->attachments.back(); if(depthStencil.loadOp == Graphics::AttachmentLoadOp::CLEAR) { + mGl.DepthMask(true); + uint32_t depthClearColor = 0u; + if(clearValues.size() == renderPass->attachments.size()) + { + depthClearColor = clearValues.back().depthStencil.depth; + } + mGl.ClearDepthf(depthClearColor); mask |= GL_DEPTH_BUFFER_BIT; } if(depthStencil.stencilLoadOp == Graphics::AttachmentLoadOp::CLEAR) { + uint32_t stencilClearColor = 0u; + if(clearValues.size() == renderPass->attachments.size()) + { + stencilClearColor = clearValues.back().depthStencil.stencil; + } + mGl.ClearStencil(stencilClearColor); + mGl.StencilMask(0xFF); // Clear all the bitplanes (assume 8) mask |= GL_STENCIL_BUFFER_BIT; } } diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index d39bcd7..b3b41e0 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -4237,9 +4237,6 @@ int UtcDaliActorPropertyClippingActor(void) tet_infoline("Testing Actor::Property::ClippingMode: CLIP_CHILDREN actor"); TestApplication application; - // @todo temporary until stencil code has been fixed. -#ifdef TEMPORARY_TEST_REMOVAL - TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace(); TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace(); @@ -4268,9 +4265,6 @@ int UtcDaliActorPropertyClippingActor(void) DALI_TEST_CHECK(stencilTrace.FindMethodAndParamsFromStartIndex("StencilFunc", "514, 1, 0", startIndex)); // 514 is GL_EQUAL, But testing no bit-planes for the first clipping node. DALI_TEST_CHECK(stencilTrace.FindMethodAndParamsFromStartIndex("StencilMask", "1", startIndex)); DALI_TEST_CHECK(stencilTrace.FindMethodAndParamsFromStartIndex("StencilOp", "7680, 7681, 7681", startIndex)); // GL_KEEP, GL_REPLACE, GL_REPLACE -#else - DALI_TEST_CHECK(true); -#endif END_TEST; } @@ -4281,9 +4275,6 @@ int UtcDaliActorPropertyClippingActorEnableThenDisable(void) tet_infoline("Testing Actor::Property::ClippingMode: CLIP_CHILDREN actor enable and then disable"); TestApplication application; - // @todo temporary until stencil code has been fixed. -#ifdef TEMPORARY_TEST_REMOVAL - TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace(); TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace(); @@ -4328,10 +4319,6 @@ int UtcDaliActorPropertyClippingActorEnableThenDisable(void) startIndex = 0u; DALI_TEST_CHECK(stencilTrace.FindMethodAndParamsFromStartIndex("StencilMask", "255", startIndex)); -#else - DALI_TEST_CHECK(true); -#endif - END_TEST; } @@ -4340,9 +4327,6 @@ int UtcDaliActorPropertyClippingNestedChildren(void) // This test checks that a hierarchy of actors are clipped correctly by // writing to and reading from the correct bit-planes of the stencil buffer. tet_infoline("Testing Actor::Property::ClippingMode: CLIP_CHILDREN nested children"); - - // @todo temporary until stencil code has been fixed. -#ifdef TEMPORARY_TEST_REMOVAL TestApplication application; TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); TraceCallStack& stencilTrace = glAbstraction.GetStencilFunctionTrace(); @@ -4414,9 +4398,6 @@ int UtcDaliActorPropertyClippingNestedChildren(void) GenerateTrace(application, enabledDisableTrace, stencilTrace); } } -#else - DALI_TEST_CHECK(true); -#endif END_TEST; } @@ -4425,9 +4406,6 @@ int UtcDaliActorPropertyClippingActorDrawOrder(void) { // This test checks that a hierarchy of actors are drawn in the correct order when clipping is enabled. tet_infoline("Testing Actor::Property::ClippingMode: CLIP_CHILDREN draw order"); - - // @todo temporary until stencil code has been fixed. -#ifdef TEMPORARY_TEST_REMOVAL TestApplication application; TestGlAbstraction& glAbstraction = application.GetGlAbstraction(); TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace(); @@ -4518,10 +4496,6 @@ int UtcDaliActorPropertyClippingActorDrawOrder(void) DALI_TEST_CHECK(enabledDisableTrace.FindMethodAndParamsFromStartIndex("Enable", stencil.str(), startIndex)); DALI_TEST_CHECK(!enabledDisableTrace.FindMethodAndParamsFromStartIndex("Disable", stencil.str(), startIndex)); -#else - DALI_TEST_CHECK(true); -#endif - END_TEST; } diff --git a/automated-tests/src/dali/utc-Dali-Renderer.cpp b/automated-tests/src/dali/utc-Dali-Renderer.cpp index e09b92e..1cff3cd 100644 --- a/automated-tests/src/dali/utc-Dali-Renderer.cpp +++ b/automated-tests/src/dali/utc-Dali-Renderer.cpp @@ -2804,9 +2804,6 @@ int UtcDaliRendererSetRenderModeToUseColorBuffer(void) Renderer renderer = RendererTestFixture(application); - // @todo temporary until stencil code has been fixed. -#ifdef TEMPORARY_TEST_REMOVAL - // Set the RenderMode property to a value that should not allow color buffer writes. // Then check if ColorMask has been called, and that the values are correct. CheckRenderModeColorMask(application, renderer, RenderMode::AUTO, true); @@ -2815,9 +2812,6 @@ int UtcDaliRendererSetRenderModeToUseColorBuffer(void) CheckRenderModeColorMask(application, renderer, RenderMode::STENCIL, false); CheckRenderModeColorMask(application, renderer, RenderMode::COLOR_STENCIL, true); -#else - DALI_TEST_CHECK(true); -#endif END_TEST; } diff --git a/dali/graphics-api/graphics-command-buffer.h b/dali/graphics-api/graphics-command-buffer.h index dd89295..2911679 100644 --- a/dali/graphics-api/graphics-command-buffer.h +++ b/dali/graphics-api/graphics-command-buffer.h @@ -81,8 +81,8 @@ struct ClearValue } color; struct { - float depth; - uint32_t stencil; + float depth; // glClearDepthf + uint32_t stencil; // glClearStencil } depthStencil; }; }; @@ -201,7 +201,7 @@ public: /** * @brief Executes a list of secondary command buffers * - * The secondary command buffers are executed as a part of a primary + * The secondary command buffers will be executed as a part of a primary * command buffer that calls this function. * * @param[in] commandBuffers List of buffers to execute @@ -300,6 +300,31 @@ public: */ virtual void SetViewportEnable(bool value) = 0; + /** + * @brief Sets the color mask for all channels. + */ + virtual void SetColorMask(bool enabled) = 0; + + /** + * @brief Clears the stencil buffer (outside of BeginRenderPass) to the current stencil mask + */ + virtual void ClearStencilBuffer() = 0; + virtual void ClearDepthBuffer() = 0; + + virtual void SetStencilTestEnable(bool stencilEnable) = 0; + virtual void SetStencilWriteMask(uint32_t writeMask) = 0; + virtual void SetStencilFunc(Graphics::CompareOp compareOp, + uint32_t reference, + uint32_t compareMask) = 0; + + virtual void SetStencilOp(Graphics::StencilOp failOp, + Graphics::StencilOp passOp, + Graphics::StencilOp depthFailOp) = 0; + + virtual void SetDepthCompareOp(Graphics::CompareOp compareOp) = 0; + virtual void SetDepthTestEnable(bool depthTestEnable) = 0; + virtual void SetDepthWriteEnable(bool depthWriteEnable) = 0; + protected: CommandBuffer(CommandBuffer&&) = default; CommandBuffer& operator=(CommandBuffer&&) = default; diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index 280ff60..c5adcda 100644 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -39,17 +38,110 @@ namespace Render { namespace { -// Table for fast look-up of Dali::DepthFunction enum to a GL depth function. -// Note: These MUST be in the same order as Dali::DepthFunction enum. -const int DaliDepthToGLDepthTable[] = {GL_NEVER, GL_ALWAYS, GL_LESS, GL_GREATER, GL_EQUAL, GL_NOTEQUAL, GL_LEQUAL, GL_GEQUAL}; +struct GraphicsDepthCompareOp +{ + constexpr explicit GraphicsDepthCompareOp(DepthFunction::Type compareOp) + { + switch(compareOp) + { + case DepthFunction::NEVER: + op = Graphics::CompareOp::NEVER; + break; + case DepthFunction::LESS: + op = Graphics::CompareOp::LESS; + break; + case DepthFunction::EQUAL: + op = Graphics::CompareOp::EQUAL; + break; + case DepthFunction::LESS_EQUAL: + op = Graphics::CompareOp::LESS_OR_EQUAL; + break; + case DepthFunction::GREATER: + op = Graphics::CompareOp::GREATER; + break; + case DepthFunction::NOT_EQUAL: + op = Graphics::CompareOp::NOT_EQUAL; + break; + case DepthFunction::GREATER_EQUAL: + op = Graphics::CompareOp::GREATER_OR_EQUAL; + break; + case DepthFunction::ALWAYS: + op = Graphics::CompareOp::ALWAYS; + break; + } + } + Graphics::CompareOp op{Graphics::CompareOp::NEVER}; +}; -// Table for fast look-up of Dali::StencilFunction enum to a GL stencil function. -// Note: These MUST be in the same order as Dali::StencilFunction enum. -const int DaliStencilFunctionToGL[] = {GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS}; +struct GraphicsStencilCompareOp +{ + constexpr explicit GraphicsStencilCompareOp(StencilFunction::Type compareOp) + { + switch(compareOp) + { + case StencilFunction::NEVER: + op = Graphics::CompareOp::NEVER; + break; + case StencilFunction::LESS: + op = Graphics::CompareOp::LESS; + break; + case StencilFunction::EQUAL: + op = Graphics::CompareOp::EQUAL; + break; + case StencilFunction::LESS_EQUAL: + op = Graphics::CompareOp::LESS_OR_EQUAL; + break; + case StencilFunction::GREATER: + op = Graphics::CompareOp::GREATER; + break; + case StencilFunction::NOT_EQUAL: + op = Graphics::CompareOp::NOT_EQUAL; + break; + case StencilFunction::GREATER_EQUAL: + op = Graphics::CompareOp::GREATER_OR_EQUAL; + break; + case StencilFunction::ALWAYS: + op = Graphics::CompareOp::ALWAYS; + break; + } + } + Graphics::CompareOp op{Graphics::CompareOp::NEVER}; +}; -// Table for fast look-up of Dali::StencilOperation enum to a GL stencil operation. -// Note: These MUST be in the same order as Dali::StencilOperation enum. -const int DaliStencilOperationToGL[] = {GL_ZERO, GL_KEEP, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT, GL_INCR_WRAP, GL_DECR_WRAP}; +struct GraphicsStencilOp +{ + constexpr explicit GraphicsStencilOp(StencilOperation::Type stencilOp) + { + switch(stencilOp) + { + case Dali::StencilOperation::KEEP: + op = Graphics::StencilOp::KEEP; + break; + case Dali::StencilOperation::ZERO: + op = Graphics::StencilOp::ZERO; + break; + case Dali::StencilOperation::REPLACE: + op = Graphics::StencilOp::REPLACE; + break; + case Dali::StencilOperation::INCREMENT: + op = Graphics::StencilOp::INCREMENT_AND_CLAMP; + break; + case Dali::StencilOperation::DECREMENT: + op = Graphics::StencilOp::DECREMENT_AND_CLAMP; + break; + case Dali::StencilOperation::INVERT: + op = Graphics::StencilOp::INVERT; + break; + case Dali::StencilOperation::INCREMENT_WRAP: + op = Graphics::StencilOp::INCREMENT_AND_WRAP; + break; + case Dali::StencilOperation::DECREMENT_WRAP: + op = Graphics::StencilOp::DECREMENT_AND_WRAP; + break; + } + } + Graphics::StencilOp op{Graphics::StencilOp::KEEP}; +}; inline Graphics::Viewport ViewportFromClippingBox(ClippingBox clippingBox, int orientation) { @@ -141,11 +233,11 @@ inline ClippingBox IntersectAABB(const ClippingBox& aabbA, const ClippingBox& aa /** * @brief Set up the stencil and color buffer for automatic clipping (StencilMode::AUTO). * @param[in] item The current RenderItem about to be rendered - * @param[in] context The context - * @param[in/out] lastClippingDepth The stencil depth of the last renderer drawn. - * @param[in/out] lastClippingId The clipping ID of the last renderer drawn. + * @param[in,out] commandBuffer The command buffer to write stencil commands into + * @param[in,out] lastClippingDepth The stencil depth of the last renderer drawn. + * @param[in,out] lastClippingId The clipping ID of the last renderer drawn. */ -inline void SetupStencilClipping(const RenderItem& item, Context& context, uint32_t& lastClippingDepth, uint32_t& lastClippingId) +inline void SetupStencilClipping(const RenderItem& item, Graphics::CommandBuffer& commandBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId) { const Dali::Internal::SceneGraph::Node* node = item.mNode; const uint32_t clippingId = node->GetClippingId(); @@ -154,11 +246,10 @@ inline void SetupStencilClipping(const RenderItem& item, Context& context, uint3 if(clippingId == 0u) { // Exit immediately if there are no clipping actions to perform (EG. we have not yet hit a clipping node). - context.EnableStencilBuffer(false); + commandBuffer.SetStencilTestEnable(false); return; } - - context.EnableStencilBuffer(true); + commandBuffer.SetStencilTestEnable(true); const uint32_t clippingDepth = node->GetClippingDepth(); @@ -175,8 +266,9 @@ inline void SetupStencilClipping(const RenderItem& item, Context& context, uint3 { // We are enabling the stencil-buffer for the first time within this render list. // Clear the buffer at this point. - context.StencilMask(0xff); - context.Clear(GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES); + + commandBuffer.SetStencilWriteMask(0xFF); + commandBuffer.ClearStencilBuffer(); } else if((clippingDepth < lastClippingDepth) || ((clippingDepth == lastClippingDepth) && (clippingId > lastClippingId))) @@ -190,8 +282,8 @@ inline void SetupStencilClipping(const RenderItem& item, Context& context, uint3 // This has the effect of clearing everything except the bit-planes up to (and including) our current depth. const uint32_t stencilClearMask = (currentDepthMask >> 1u) ^ 0xff; - context.StencilMask(stencilClearMask); - context.Clear(GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES); + commandBuffer.SetStencilWriteMask(stencilClearMask); + commandBuffer.ClearStencilBuffer(); } // We keep track of the last clipping Id and depth so we can determine when we are @@ -208,17 +300,19 @@ inline void SetupStencilClipping(const RenderItem& item, Context& context, uint3 // As the mask is made up of contiguous "1" values, we can do this quickly with a bit-shift. const uint32_t testMask = currentDepthMask >> 1u; - context.StencilFunc(GL_EQUAL, currentDepthMask, testMask); // Test against existing stencil bit-planes. All must match up to (but not including) this depth. - context.StencilMask(currentDepthMask); // Write to the new stencil bit-plane (the other previous bit-planes are also written to). - context.StencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); + // Test against existing stencil bit-planes. All must match up to (but not including) this depth. + commandBuffer.SetStencilFunc(Graphics::CompareOp::EQUAL, currentDepthMask, testMask); + // Write to the new stencil bit-plane (the other previous bit-planes are also written to). + commandBuffer.SetStencilWriteMask(currentDepthMask); + commandBuffer.SetStencilOp(Graphics::StencilOp::KEEP, Graphics::StencilOp::REPLACE, Graphics::StencilOp::REPLACE); } else { // We are reading from the stencil buffer. Set up the stencil accordingly // This calculation sets all the bits up to the current depth bit. // This has the effect of testing that the pixel being written to exists in every bit-plane up to the current depth. - context.StencilFunc(GL_EQUAL, currentDepthMask, currentDepthMask); - context.StencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + commandBuffer.SetStencilFunc(Graphics::CompareOp::EQUAL, currentDepthMask, currentDepthMask); + commandBuffer.SetStencilOp(Graphics::StencilOp::KEEP, Graphics::StencilOp::KEEP, Graphics::StencilOp::KEEP); } } @@ -228,11 +322,11 @@ inline void SetupStencilClipping(const RenderItem& item, Context& context, uint3 * - If AUTO is selected for reading, the decision will be based on the Layer Behavior. * - If AUTO is selected for writing, the decision will be based on the items opacity. * @param[in] item The RenderItem to set up the depth buffer for. - * @param[in] context The context used to execute GL commands. + * @param[in,out] secondaryCommandBuffer The secondary command buffer to write depth commands to * @param[in] depthTestEnabled True if depth testing has been enabled. * @param[in/out] firstDepthBufferUse Initialize to true on the first call, this method will set it to false afterwards. */ -inline void SetupDepthBuffer(const RenderItem& item, Context& context, bool depthTestEnabled, bool& firstDepthBufferUse) +inline void SetupDepthBuffer(const RenderItem& item, Graphics::CommandBuffer& commandBuffer, bool depthTestEnabled, bool& firstDepthBufferUse) { // Set up whether or not to write to the depth buffer. const DepthWriteMode::Type depthWriteMode = item.mRenderer->GetDepthWriteMode(); @@ -242,6 +336,7 @@ inline void SetupDepthBuffer(const RenderItem& item, Context& context, bool dept // Set up whether or not to read from (test) the depth buffer. const DepthTestMode::Type depthTestMode = item.mRenderer->GetDepthTestMode(); + // Most common mode (AUTO) is tested first. const bool enableDepthTest = ((depthTestMode == DepthTestMode::AUTO) && depthTestEnabled) || (depthTestMode == DepthTestMode::ON); @@ -250,10 +345,10 @@ inline void SetupDepthBuffer(const RenderItem& item, Context& context, bool dept if(enableDepthWrite || enableDepthTest) { // The depth buffer must be enabled if either reading or writing. - context.EnableDepthBuffer(true); + commandBuffer.SetDepthTestEnable(true); - // Look-up the GL depth function from the Dali::DepthFunction enum, and set it. - context.DepthFunc(DaliDepthToGLDepthTable[item.mRenderer->GetDepthFunction()]); + // Look-up the depth function from the Dali::DepthFunction enum, and set it. + commandBuffer.SetDepthCompareOp(GraphicsDepthCompareOp(item.mRenderer->GetDepthFunction()).op); // If this is the first use of the depth buffer this RenderTask, perform a clear. // Note: We could do this at the beginning of the RenderTask and rely on the @@ -265,17 +360,18 @@ inline void SetupDepthBuffer(const RenderItem& item, Context& context, bool dept firstDepthBufferUse = false; // Note: The buffer will only be cleared if written to since a previous clear. - context.DepthMask(true); - context.Clear(GL_DEPTH_BUFFER_BIT, Context::CHECK_CACHED_VALUES); + commandBuffer.SetDepthWriteEnable(true); + commandBuffer.ClearDepthBuffer(); } // Set up the depth mask based on our depth write setting. - context.DepthMask(enableDepthWrite); + //context.DepthMask(enableDepthWrite); + commandBuffer.SetDepthWriteEnable(enableDepthWrite); } else { // The depth buffer is not being used by this renderer, so we must disable it to stop it being tested. - context.EnableDepthBuffer(false); + commandBuffer.SetDepthTestEnable(false); } } @@ -287,13 +383,11 @@ inline void SetupDepthBuffer(const RenderItem& item, Context& context, bool dept * As the clips are hierarchical, this RenderItems AABB is clipped against the current "active" scissor bounds via an intersection operation. * @param[in] item The current RenderItem about to be rendered * @param[in,out] commandBuffer The command buffer to write into - * @param[in] context The context * @param[in] instruction The render-instruction to process. */ inline void RenderAlgorithms::SetupScissorClipping( const RenderItem& item, Graphics::CommandBuffer& commandBuffer, - Context& context, const RenderInstruction& instruction) { // Get the number of child scissors in the stack (do not include layer or root box). @@ -363,8 +457,7 @@ inline void RenderAlgorithms::SetupScissorClipping( { useScissorBox.y = (instruction.mFrameBuffer->GetHeight() - useScissorBox.height) - useScissorBox.y; } - Graphics::Rect2D scissorBox = { - useScissorBox.x, useScissorBox.y, uint32_t(useScissorBox.width), uint32_t(useScissorBox.height)}; + Graphics::Rect2D scissorBox = {useScissorBox.x, useScissorBox.y, uint32_t(useScissorBox.width), uint32_t(useScissorBox.height)}; commandBuffer.SetScissor(scissorBox); } } @@ -372,7 +465,6 @@ inline void RenderAlgorithms::SetupScissorClipping( inline void RenderAlgorithms::SetupClipping(const RenderItem& item, Graphics::CommandBuffer& commandBuffer, - Context& context, bool& usedStencilBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId, @@ -393,17 +485,17 @@ inline void RenderAlgorithms::SetupClipping(const RenderItem& case RenderMode::AUTO: { // Turn the color buffer on as we always want to render this renderer, regardless of clipping hierarchy. - context.ColorMask(true); + commandBuffer.SetColorMask(true); // The automatic clipping feature will manage the scissor and stencil functions, only if stencil buffer is available for the latter. // As both scissor and stencil clips can be nested, we may be simultaneously traversing up the scissor tree, requiring a scissor to be un-done. Whilst simultaneously adding a new stencil clip. // We process both based on our current and old clipping depths for each mode. // Both methods with return rapidly if there is nothing to be done for that type of clipping. - SetupScissorClipping(item, commandBuffer, context, instruction); + SetupScissorClipping(item, commandBuffer, instruction); if(stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE) { - SetupStencilClipping(item, context, lastClippingDepth, lastClippingId); + SetupStencilClipping(item, commandBuffer, lastClippingDepth, lastClippingId); } break; } @@ -416,11 +508,11 @@ inline void RenderAlgorithms::SetupClipping(const RenderItem& // The stencil buffer will not be used at all, but we only need to disable it if it's available. if(stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE) { - context.EnableStencilBuffer(false); + commandBuffer.SetStencilTestEnable(false); } // Setup the color buffer based on the RenderMode. - context.ColorMask(renderMode == RenderMode::COLOR); + commandBuffer.SetColorMask(renderMode == RenderMode::COLOR); break; } @@ -432,26 +524,26 @@ inline void RenderAlgorithms::SetupClipping(const RenderItem& // We are using the low-level Renderer Stencil API. // The stencil buffer must be enabled for every renderer with stencil mode on, as renderers in between can disable it. // Note: As the command state is cached, it is only sent when needed. - context.EnableStencilBuffer(true); + commandBuffer.SetStencilTestEnable(true); // Setup the color buffer based on the RenderMode. - context.ColorMask(renderMode == RenderMode::COLOR_STENCIL); + commandBuffer.SetColorMask(renderMode == RenderMode::COLOR_STENCIL); // If this is the first use of the stencil buffer within this RenderList, clear it (this avoids unnecessary clears). if(!usedStencilBuffer) { - context.Clear(GL_STENCIL_BUFFER_BIT, Context::CHECK_CACHED_VALUES); + commandBuffer.ClearStencilBuffer(); usedStencilBuffer = true; } - // Setup the stencil buffer based on the renderers properties. - context.StencilFunc(DaliStencilFunctionToGL[renderer->GetStencilFunction()], - renderer->GetStencilFunctionReference(), - renderer->GetStencilFunctionMask()); - context.StencilOp(DaliStencilOperationToGL[renderer->GetStencilOperationOnFail()], - DaliStencilOperationToGL[renderer->GetStencilOperationOnZFail()], - DaliStencilOperationToGL[renderer->GetStencilOperationOnZPass()]); - context.StencilMask(renderer->GetStencilMask()); + // Setup the stencil buffer based on the renderer's properties. + commandBuffer.SetStencilOp(GraphicsStencilOp(renderer->GetStencilOperationOnFail()).op, + GraphicsStencilOp(renderer->GetStencilOperationOnZPass()).op, + GraphicsStencilOp(renderer->GetStencilOperationOnZFail()).op); + commandBuffer.SetStencilFunc(GraphicsStencilCompareOp(renderer->GetStencilFunction()).op, + renderer->GetStencilFunctionReference(), + renderer->GetStencilFunctionMask()); + commandBuffer.SetStencilWriteMask(renderer->GetStencilMask()); } break; } @@ -459,7 +551,6 @@ inline void RenderAlgorithms::SetupClipping(const RenderItem& } inline void RenderAlgorithms::ProcessRenderList(const RenderList& renderList, - Context& context, BufferIndex bufferIndex, const Matrix& viewMatrix, const Matrix& projectionMatrix, @@ -547,18 +638,18 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& // Set up clipping based on both the Renderer and Actor APIs. // The Renderer API will be used if specified. If AUTO, the Actors automatic clipping feature will be used. - SetupClipping(item, secondaryCommandBuffer, context, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction); + SetupClipping(item, secondaryCommandBuffer, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction); if(DALI_LIKELY(item.mRenderer)) { // Set up the depth buffer based on per-renderer flags if depth buffer is available // If the per renderer flags are set to "ON" or "OFF", they will always override any Layer depth mode or // draw-mode state, such as Overlays. - // If the flags are set to "AUTO", the behavior then depends on the type of renderer. Overlay Renderers will always - // disable depth testing and writing. Color Renderers will enable them if the Layer does. + // If the flags are set to "AUTO", the behavior then depends on the type of renderer. Overlay Renderers will + // always disable depth testing and writing. Color Renderers will enable them if the Layer does. if(depthBufferAvailable == Integration::DepthBufferAvailable::TRUE) { - SetupDepthBuffer(item, context, autoDepthTestMode, firstDepthBufferUse); + SetupDepthBuffer(item, secondaryCommandBuffer, autoDepthTestMode, firstDepthBufferUse); } // Depending on whether the renderer has draw commands attached or not the rendering process will @@ -612,7 +703,6 @@ void RenderAlgorithms::SubmitCommandBuffer() } void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& instruction, - Context& context, BufferIndex bufferIndex, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, @@ -643,7 +733,6 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& if(renderList && !renderList->IsEmpty()) { ProcessRenderList(*renderList, - context, bufferIndex, *viewMatrix, *projectionMatrix, diff --git a/dali/internal/render/common/render-algorithms.h b/dali/internal/render/common/render-algorithms.h index 90b7146..cc76d49 100644 --- a/dali/internal/render/common/render-algorithms.h +++ b/dali/internal/render/common/render-algorithms.h @@ -27,8 +27,6 @@ namespace Dali { namespace Internal { -class Context; - namespace SceneGraph { class RenderInstruction; @@ -53,7 +51,6 @@ public: /** * Process a render-instruction. * @param[in] instruction The render-instruction to process. - * @param[in] context The GL context. * @param[in] bufferIndex The current render buffer index (previous update buffer) * @param[in] depthBufferAvailable Whether the depth buffer is available * @param[in] stencilBufferAvailable Whether the stencil buffer is available @@ -63,7 +60,6 @@ public: * @param[in] orientation The surface orientation */ void ProcessRenderInstruction(const SceneGraph::RenderInstruction& instruction, - Context& context, BufferIndex bufferIndex, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, @@ -114,19 +110,17 @@ private: * - Disable scissor clipping completely if it is not needed * @param[in] item The current RenderItem (about to be rendered) * @param[in] commandBuffer The command buffer to write into - * @param[in] context The current Context + * @param[in] instruction The render-instruction to process. */ inline void SetupScissorClipping( const Dali::Internal::SceneGraph::RenderItem& item, Graphics::CommandBuffer& commandBuffer, - Context& context, const Dali::Internal::SceneGraph::RenderInstruction& instruction); /** * @brief Set up the clipping based on the specified clipping settings. * @param[in] item The current RenderItem (about to be rendered) - * @param[in] context The context * @param[in,out] commandBuffer The command buffer to write commands to * @param[in/out] usedStencilBuffer True if the stencil buffer has been used so far within this RenderList. Used by StencilMode::ON. * @param[in/out] lastClippingDepth The stencil depth of the last renderer drawn. Used by the clipping feature. @@ -136,7 +130,6 @@ private: */ inline void SetupClipping(const Dali::Internal::SceneGraph::RenderItem& item, Graphics::CommandBuffer& commandBuffer, - Context& context, bool& usedStencilBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId, @@ -146,7 +139,6 @@ private: /** * @brief Process a render-list. * @param[in] renderList The render-list to process. - * @param[in] context The GL context. * @param[in] buffer The current render buffer index (previous update buffer) * @param[in] viewMatrix The view matrix from the appropriate camera. * @param[in] projectionMatrix The projection matrix from the appropriate camera. @@ -158,7 +150,6 @@ private: * @param[in] orientation The Scene's surface orientation */ inline void ProcessRenderList(const Dali::Internal::SceneGraph::RenderList& renderList, - Context& context, BufferIndex bufferIndex, const Matrix& viewMatrix, const Matrix& projectionMatrix, diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 28b29e7..188ed7e 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -249,7 +249,7 @@ void RenderManager::SetShaderSaver(ShaderSaver& upstream) void RenderManager::AddRenderer(OwnerPointer& renderer) { // Initialize the renderer as we are now in render thread - renderer->Initialize(mImpl->context, mImpl->graphicsController, mImpl->programController, mImpl->shaderCache, *(mImpl->uniformBufferManager.get())); + renderer->Initialize(mImpl->graphicsController, mImpl->programController, mImpl->shaderCache, *(mImpl->uniformBufferManager.get())); mImpl->rendererContainer.PushBack(renderer.Release()); } @@ -341,7 +341,7 @@ void RenderManager::RemoveFrameBuffer(Render::FrameBuffer* frameBuffer) void RenderManager::InitializeScene(SceneGraph::Scene* scene) { - scene->Initialize(*mImpl->CreateSceneContext(), mImpl->graphicsController); + scene->Initialize(*mImpl->CreateSceneContext(), mImpl->graphicsController, mImpl->depthBufferAvailable, mImpl->stencilBufferAvailable); mImpl->sceneContainer.push_back(scene); } @@ -359,7 +359,7 @@ void RenderManager::UninitializeScene(SceneGraph::Scene* scene) void RenderManager::SurfaceReplaced(SceneGraph::Scene* scene) { Context* newContext = mImpl->ReplaceSceneContext(scene->GetContext()); - scene->Initialize(*newContext, mImpl->graphicsController); + scene->Initialize(*newContext, mImpl->graphicsController, mImpl->depthBufferAvailable, mImpl->stencilBufferAvailable); } void RenderManager::AttachColorTextureToFrameBuffer(Render::FrameBuffer* frameBuffer, Render::Texture* texture, uint32_t mipmapLevel, uint32_t layer) @@ -815,6 +815,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: Rect surfaceRect = sceneObject->GetSurfaceRect(); int32_t surfaceOrientation = sceneObject->GetSurfaceOrientation(); + // @todo Should these be part of scene? Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable; Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable; @@ -865,7 +866,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: mImpl->programController.ClearCurrentProgram(); } } - else + else // no framebuffer { if(mImpl->currentContext->IsSurfacelessContextSupported()) { @@ -893,6 +894,17 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: currentClearValues = clearValues; + // @todo SceneObject should already have the depth clear / stencil clear in the clearValues array. + // if the window has a depth/stencil buffer. + if((depthBufferAvailable == Integration::DepthBufferAvailable::TRUE || + stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE) && + (currentClearValues.size() <= 1)) + { + currentClearValues.emplace_back(); + currentClearValues.back().depthStencil.depth = 0; + currentClearValues.back().depthStencil.stencil = 0; + } + auto loadOp = instruction.mIsClearColorSet ? Graphics::AttachmentLoadOp::CLEAR : Graphics::AttachmentLoadOp::LOAD; currentRenderTarget = sceneObject->GetSurfaceRenderTarget(); @@ -1002,7 +1014,6 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: mImpl->renderAlgorithms.ProcessRenderInstruction( instruction, - *mImpl->currentContext, mImpl->renderBufferIndex, depthBufferAvailable, stencilBufferAvailable, diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 03a8d98..ec314d2 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -243,7 +243,6 @@ Renderer::Renderer(SceneGraph::RenderDataProvider* dataProvider, StencilParameters& stencilParameters) : mGraphicsController(nullptr), mRenderDataProvider(dataProvider), - mContext(nullptr), mGeometry(geometry), mProgramCache(nullptr), mUniformIndexMap(), @@ -270,9 +269,8 @@ Renderer::Renderer(SceneGraph::RenderDataProvider* dataProvider, mBlendingOptions.SetBlendColor(blendColor); } -void Renderer::Initialize(Context& context, Graphics::Controller& graphicsController, ProgramCache& programCache, Render::ShaderCache& shaderCache, Render::UniformBufferManager& uniformBufferManager) +void Renderer::Initialize(Graphics::Controller& graphicsController, ProgramCache& programCache, Render::ShaderCache& shaderCache, Render::UniformBufferManager& uniformBufferManager) { - mContext = &context; mGraphicsController = &graphicsController; mProgramCache = &programCache; mShaderCache = &shaderCache; diff --git a/dali/internal/render/renderers/render-renderer.h b/dali/internal/render/renderers/render-renderer.h index 05e1971..01a4001 100644 --- a/dali/internal/render/renderers/render-renderer.h +++ b/dali/internal/render/renderers/render-renderer.h @@ -41,7 +41,6 @@ namespace Dali { namespace Internal { -class Context; class Texture; class ProgramCache; @@ -162,14 +161,12 @@ public: /** * Second-phase construction. * This is called when the renderer is inside render thread - * @param[in] context Context used by the renderer (To be removed) * @param[in] graphicsController The graphics controller to use * @param[in] programCache Cache of program objects * @param[in] shaderCache Cache of shaders * @param[in] uniformBufferManager Uniform buffer manager */ - void Initialize(Context& context, - Graphics::Controller& graphicsController, + void Initialize(Graphics::Controller& graphicsController, ProgramCache& programCache, Render::ShaderCache& shaderCache, Render::UniformBufferManager& uniformBufferManager); @@ -366,7 +363,7 @@ public: * @param[in] boundTextures The textures bound for rendering * @param[in] instruction. for use case like reflection where CullFace needs to be adjusted * - * @return True if the content has been rendered, false if skipped. + * @return True if commands have been added to the command buffer */ bool Render(Graphics::CommandBuffer& commandBuffer, BufferIndex bufferIndex, @@ -445,13 +442,6 @@ private: Renderer& operator=(const Renderer& rhs); /** - * Sets blending options - * @param context to use - * @param blend Wheter blending should be enabled or not - */ - void SetBlending(Context& context, bool blend); - - /** * Builds a uniform map based on the index of the cached location in the Program. * @param[in] bufferIndex The index of the previous update buffer. * @param[in] node The node using the renderer diff --git a/dali/internal/update/common/scene-graph-scene.cpp b/dali/internal/update/common/scene-graph-scene.cpp index e6f7fa1..3526f5d 100644 --- a/dali/internal/update/common/scene-graph-scene.cpp +++ b/dali/internal/update/common/scene-graph-scene.cpp @@ -18,6 +18,7 @@ #include // INTERNAL INCLUDES +#include #include #include @@ -44,7 +45,7 @@ Scene::~Scene() mFramePresentedCallbacks.clear(); } -void Scene::Initialize(Context& context, Graphics::Controller& graphicsController) +void Scene::Initialize(Context& context, Graphics::Controller& graphicsController, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable) { mContext = &context; @@ -53,21 +54,47 @@ void Scene::Initialize(Context& context, Graphics::Controller& graphicsControlle // Default behaviour for color attachments is to CLEAR and STORE mClearValues.clear(); + mClearValues.emplace_back(); + + // Assume single color attachment Graphics::AttachmentDescription desc{}; desc.SetLoadOp(Graphics::AttachmentLoadOp::CLEAR); desc.SetStoreOp(Graphics::AttachmentStoreOp::STORE); attachmentDescriptions.push_back(desc); - mClearValues.emplace_back(); + + if(depthBufferAvailable == Integration::DepthBufferAvailable::TRUE || + stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE) + { + // Depth + desc.SetLoadOp(Graphics::AttachmentLoadOp::CLEAR); + desc.SetStoreOp(Graphics::AttachmentStoreOp::STORE); + + // Stencil + desc.SetStencilLoadOp(Graphics::AttachmentLoadOp::CLEAR); + desc.SetStencilStoreOp(Graphics::AttachmentStoreOp::STORE); + attachmentDescriptions.push_back(desc); + + mClearValues.emplace_back(); + mClearValues.back().depthStencil.depth = 0; + mClearValues.back().depthStencil.stencil = 0; + } Graphics::RenderPassCreateInfo rpInfo{}; rpInfo.SetAttachments(attachmentDescriptions); // Add default render pass (loadOp = clear) - mRenderPass = graphicsController.CreateRenderPass(rpInfo, nullptr); + mRenderPass = graphicsController.CreateRenderPass(rpInfo, nullptr); // Warning: Shallow ptr - desc.SetLoadOp( Graphics::AttachmentLoadOp::LOAD ); + desc.SetLoadOp(Graphics::AttachmentLoadOp::LOAD); attachmentDescriptions[0] = desc; - mRenderPassNoClear = graphicsController.CreateRenderPass(rpInfo, nullptr); + if(attachmentDescriptions.size() > 1) + { + desc.SetLoadOp(Graphics::AttachmentLoadOp::LOAD); + desc.SetStencilLoadOp(Graphics::AttachmentLoadOp::LOAD); + attachmentDescriptions.back() = desc; + } + + mRenderPassNoClear = graphicsController.CreateRenderPass(rpInfo, nullptr); // Warning: Shallow ptr } Context* Scene::GetContext() diff --git a/dali/internal/update/common/scene-graph-scene.h b/dali/internal/update/common/scene-graph-scene.h index 04411ae..e580490 100644 --- a/dali/internal/update/common/scene-graph-scene.h +++ b/dali/internal/update/common/scene-graph-scene.h @@ -19,6 +19,7 @@ // INTERNAL INCLUDES #include +#include #include #include #include @@ -53,8 +54,10 @@ public: * Creates a scene object in the GPU. * @param[in] context The GL context * @param[in] graphicsController The graphics controller + * @param[in] depthBufferAvailable True if there is a depth buffer + * @param[in] stencilBufferAvailable True if there is a stencil buffer */ - void Initialize(Context& context, Graphics::Controller& graphicsController); + void Initialize(Context& context, Graphics::Controller& graphicsController, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable); /** * Gets the context holding the GL state of rendering for the scene @@ -233,9 +236,9 @@ private: * The default render pass (most likely to be used) is the load = CLEAR * and store = STORE for color attachment. */ - Graphics::UniquePtr mRenderPass{nullptr}; ///< The render pass created to render the surface - Graphics::UniquePtr mRenderPassNoClear{nullptr}; ///< The render pass created to render the surface without clearing color - Graphics::RenderTarget* mRenderTarget{nullptr}; ///< This is created in the event thread when surface is created/resized/replaced + Graphics::UniquePtr mRenderPass{nullptr}; ///< The render pass created to render the surface + Graphics::UniquePtr mRenderPassNoClear{nullptr}; ///< The render pass created to render the surface without clearing color + Graphics::RenderTarget* mRenderTarget{nullptr}; ///< This is created in the event thread when surface is created/resized/replaced // clear colors std::vector mClearValues{}; -- 2.7.4