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)
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<typename T>
inline CommandTypeMask operator|(T flags, CommandType bit)
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;
}
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;
}
std::vector<const TestGraphicsCommandBuffer*> 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;
};
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<Command>& GetCommands() const
{
return mCommands;
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:
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
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;
}
}
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();
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;
}
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();
startIndex = 0u;
DALI_TEST_CHECK(stencilTrace.FindMethodAndParamsFromStartIndex("StencilMask", "255", startIndex));
-#else
- DALI_TEST_CHECK(true);
-#endif
-
END_TEST;
}
// 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();
GenerateTrace(application, enabledDisableTrace, stencilTrace);
}
}
-#else
- DALI_TEST_CHECK(true);
-#endif
END_TEST;
}
{
// 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();
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;
}
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);
CheckRenderModeColorMask(application, renderer, RenderMode::STENCIL, false);
CheckRenderModeColorMask(application, renderer, RenderMode::COLOR_STENCIL, true);
-#else
- DALI_TEST_CHECK(true);
-#endif
END_TEST;
}
} color;
struct
{
- float depth;
- uint32_t stencil;
+ float depth; // glClearDepthf
+ uint32_t stencil; // glClearStencil
} depthStencil;
};
};
/**
* @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
*/
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;
#include <dali/internal/render/common/render-debug.h>
#include <dali/internal/render/common/render-instruction.h>
#include <dali/internal/render/common/render-list.h>
-#include <dali/internal/render/gl-resources/context.h>
#include <dali/internal/render/renderers/render-renderer.h>
#include <dali/internal/update/nodes/scene-graph-layer.h>
{
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)
{
/**
* @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();
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();
{
// 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)))
// 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
// 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);
}
}
* - 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();
// 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);
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
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);
}
}
* 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).
{
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);
}
}
inline void RenderAlgorithms::SetupClipping(const RenderItem& item,
Graphics::CommandBuffer& commandBuffer,
- Context& context,
bool& usedStencilBuffer,
uint32_t& lastClippingDepth,
uint32_t& lastClippingId,
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;
}
// 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;
}
// 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;
}
}
inline void RenderAlgorithms::ProcessRenderList(const RenderList& renderList,
- Context& context,
BufferIndex bufferIndex,
const Matrix& viewMatrix,
const Matrix& projectionMatrix,
// 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
}
void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& instruction,
- Context& context,
BufferIndex bufferIndex,
Integration::DepthBufferAvailable depthBufferAvailable,
Integration::StencilBufferAvailable stencilBufferAvailable,
if(renderList && !renderList->IsEmpty())
{
ProcessRenderList(*renderList,
- context,
bufferIndex,
*viewMatrix,
*projectionMatrix,
{
namespace Internal
{
-class Context;
-
namespace SceneGraph
{
class RenderInstruction;
/**
* 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
* @param[in] orientation The surface orientation
*/
void ProcessRenderInstruction(const SceneGraph::RenderInstruction& instruction,
- Context& context,
BufferIndex bufferIndex,
Integration::DepthBufferAvailable depthBufferAvailable,
Integration::StencilBufferAvailable stencilBufferAvailable,
* - 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.
*/
inline void SetupClipping(const Dali::Internal::SceneGraph::RenderItem& item,
Graphics::CommandBuffer& commandBuffer,
- Context& context,
bool& usedStencilBuffer,
uint32_t& lastClippingDepth,
uint32_t& lastClippingId,
/**
* @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.
* @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,
void RenderManager::AddRenderer(OwnerPointer<Render::Renderer>& 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());
}
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);
}
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)
Rect<int32_t> 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;
mImpl->programController.ClearCurrentProgram();
}
}
- else
+ else // no framebuffer
{
if(mImpl->currentContext->IsSurfacelessContextSupported())
{
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();
mImpl->renderAlgorithms.ProcessRenderInstruction(
instruction,
- *mImpl->currentContext,
mImpl->renderBufferIndex,
depthBufferAvailable,
stencilBufferAvailable,
StencilParameters& stencilParameters)
: mGraphicsController(nullptr),
mRenderDataProvider(dataProvider),
- mContext(nullptr),
mGeometry(geometry),
mProgramCache(nullptr),
mUniformIndexMap(),
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;
{
namespace Internal
{
-class Context;
class Texture;
class ProgramCache;
/**
* 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);
* @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,
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
#include <dali/internal/update/common/scene-graph-scene.h>
// INTERNAL INCLUDES
+#include <dali/integration-api/core-enumerations.h>
#include <dali/internal/render/gl-resources/context.h>
#include <dali/internal/update/render-tasks/scene-graph-render-task-list.h>
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;
// 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()
// INTERNAL INCLUDES
#include <dali/graphics-api/graphics-controller.h>
+#include <dali/integration-api/core.h>
#include <dali/integration-api/scene.h>
#include <dali/internal/common/message.h>
#include <dali/internal/event/common/event-thread-services.h>
* 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
* The default render pass (most likely to be used) is the load = CLEAR
* and store = STORE for color attachment.
*/
- Graphics::UniquePtr<Graphics::RenderPass> mRenderPass{nullptr}; ///< The render pass created to render the surface
- Graphics::UniquePtr<Graphics::RenderPass> 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<Graphics::RenderPass> mRenderPass{nullptr}; ///< The render pass created to render the surface
+ Graphics::UniquePtr<Graphics::RenderPass> 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<Graphics::ClearValue> mClearValues{};