X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Frender%2Fcommon%2Frender-algorithms.cpp;h=efcb5757f868aa28439d2b0344ca926dc407d534;hb=refs%2Fchanges%2F13%2F263213%2F14;hp=7ab6f375e953fa1b51762437ca26cb6c72d79b83;hpb=e55a2190173c771eca34729d740ef38f3876063a;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index 7ab6f37..efcb575 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,32 +345,32 @@ 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 - // context cache to ignore the clear if not required, but, we would have to enable - // the depth buffer to do so, which could be a redundant enable. + // graphics implementation to ignore the clear if not required, but, we would + // have to enable the depth buffer to do so, which could be a redundant enable. if(DALI_UNLIKELY(firstDepthBufferUse)) { // This is the first time the depth buffer is being written to or read. 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); + 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); } } @@ -286,10 +381,15 @@ inline void SetupDepthBuffer(const RenderItem& item, Context& context, bool dept * A stack of scissor clips at each depth of clipping is maintained, so it can be applied and unapplied. * 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] context The context + * @param[in,out] commandBuffer The command buffer to write into * @param[in] instruction The render-instruction to process. + * @param[in] orientation The Scene's surface orientation. */ -inline void RenderAlgorithms::SetupScissorClipping(const RenderItem& item, Context& context, const RenderInstruction& instruction) +inline void RenderAlgorithms::SetupScissorClipping( + const RenderItem& item, + Graphics::CommandBuffer& commandBuffer, + const RenderInstruction& instruction, + int orientation) { // Get the number of child scissors in the stack (do not include layer or root box). size_t childStackDepth = mScissorStack.size() - 1u; @@ -329,7 +429,7 @@ inline void RenderAlgorithms::SetupScissorClipping(const RenderItem& item, Conte // This is a clipping node. We generate the AABB for this node and intersect it with the previous intersection further up the tree. // Get the AABB bounding box for the current render item. - const ClippingBox scissorBox(item.CalculateViewportSpaceAABB(item.mSize, mViewportRectangle.width, mViewportRectangle.height)); + const ClippingBox scissorBox(RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, item.mSize, mViewportRectangle.width, mViewportRectangle.height)); // Get the AABB for the parent item that we must intersect with. const ClippingBox& parentBox(mScissorStack.back()); @@ -341,10 +441,13 @@ inline void RenderAlgorithms::SetupScissorClipping(const RenderItem& item, Conte // The scissor test is enabled if we have any children on the stack, OR, if there are none but it is a user specified layer scissor box. // IE. It is not enabled if we are at the top of the stack and the layer does not have a specified clipping box. - const bool scissorEnabled = (mScissorStack.size() > 0u) || mHasLayerScissor; + const bool scissorEnabled = (!mScissorStack.empty()) || mHasLayerScissor; // Enable the scissor test based on the above calculation - context.SetScissorTest(scissorEnabled); + if(scissorEnabled) + { + commandBuffer.SetScissorTestEnable(scissorEnabled); + } // If scissor is enabled, we use the calculated screen-space coordinates (now in the stack). if(scissorEnabled) @@ -355,18 +458,21 @@ inline void RenderAlgorithms::SetupScissorClipping(const RenderItem& item, Conte { useScissorBox.y = (instruction.mFrameBuffer->GetHeight() - useScissorBox.height) - useScissorBox.y; } - context.Scissor(useScissorBox.x, useScissorBox.y, useScissorBox.width, useScissorBox.height); + + Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0); + commandBuffer.SetScissor(Rect2DFromClippingBox(useScissorBox, orientation, graphicsViewport)); } } } inline void RenderAlgorithms::SetupClipping(const RenderItem& item, - Context& context, + Graphics::CommandBuffer& commandBuffer, bool& usedStencilBuffer, uint32_t& lastClippingDepth, uint32_t& lastClippingId, Integration::StencilBufferAvailable stencilBufferAvailable, - const RenderInstruction& instruction) + const RenderInstruction& instruction, + int orientation) { RenderMode::Type renderMode = RenderMode::AUTO; const Renderer* renderer = item.mRenderer; @@ -382,17 +488,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, context, instruction); + SetupScissorClipping(item, commandBuffer, instruction, orientation); if(stencilBufferAvailable == Integration::StencilBufferAvailable::TRUE) { - SetupStencilClipping(item, context, lastClippingDepth, lastClippingId); + SetupStencilClipping(item, commandBuffer, lastClippingDepth, lastClippingId); } break; } @@ -405,11 +511,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; } @@ -421,26 +527,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; } @@ -448,7 +554,6 @@ inline void RenderAlgorithms::SetupClipping(const RenderItem& } inline void RenderAlgorithms::ProcessRenderList(const RenderList& renderList, - Context& context, BufferIndex bufferIndex, const Matrix& viewMatrix, const Matrix& projectionMatrix, @@ -474,7 +579,12 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& bool firstDepthBufferUse(true); mViewportRectangle = viewport; - mGraphicsCommandBuffer->SetViewport(ViewportFromClippingBox(mViewportRectangle, orientation)); + + auto* mutableRenderList = const_cast(&renderList); + auto& secondaryCommandBuffer = mutableRenderList->GetCommandBuffer(mGraphicsController); + secondaryCommandBuffer.Reset(); + + secondaryCommandBuffer.SetViewport(ViewportFromClippingBox(mViewportRectangle, orientation)); mHasLayerScissor = false; // Setup Scissor testing (for both viewport and per-node scissor) @@ -485,34 +595,28 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& if(!rootClippingRect.IsEmpty()) { Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0); - mGraphicsCommandBuffer->SetScissorTestEnable(true); - mGraphicsCommandBuffer->SetScissor(Rect2DFromRect(rootClippingRect, orientation, graphicsViewport)); + secondaryCommandBuffer.SetScissorTestEnable(true); + secondaryCommandBuffer.SetScissor(Rect2DFromRect(rootClippingRect, orientation, graphicsViewport)); mScissorStack.push_back(rootClippingRect); } // We are not performing a layer clip and no clipping rect set. Add the viewport as the root scissor rectangle. else if(!renderList.IsClipping()) { - mGraphicsCommandBuffer->SetScissorTestEnable(false); + secondaryCommandBuffer.SetScissorTestEnable(false); mScissorStack.push_back(mViewportRectangle); } if(renderList.IsClipping()) { Graphics::Viewport graphicsViewport = ViewportFromClippingBox(mViewportRectangle, 0); - mGraphicsCommandBuffer->SetScissorTestEnable(true); + secondaryCommandBuffer.SetScissorTestEnable(true); const ClippingBox& layerScissorBox = renderList.GetClippingBox(); - mGraphicsCommandBuffer->SetScissor(Rect2DFromClippingBox(layerScissorBox, orientation, graphicsViewport)); + secondaryCommandBuffer.SetScissor(Rect2DFromClippingBox(layerScissorBox, orientation, graphicsViewport)); mScissorStack.push_back(layerScissorBox); mHasLayerScissor = true; } - // Submit scissor/viewport - //Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH}; - //submitInfo.cmdBuffer.push_back(mGraphicsCommandBuffer.get()); - //mGraphicsController.SubmitCommandBuffers(submitInfo); - - mGraphicsRenderItemCommandBuffers.clear(); - // Loop through all RenderList in the RenderList, set up any prerequisites to render them, then perform the render. + // Loop through all RenderItems in the RenderList, set up any prerequisites to render them, then perform the render. for(uint32_t index = 0u; index < count; ++index) { const RenderItem& item = renderList.GetItem(index); @@ -521,7 +625,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& bool skip = true; if(!rootClippingRect.IsEmpty()) { - auto rect = item.CalculateViewportSpaceAABB(item.mUpdateSize, mViewportRectangle.width, mViewportRectangle.height); + auto rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, item.mUpdateSize, mViewportRectangle.width, mViewportRectangle.height); if(rect.Intersect(rootClippingRect)) { @@ -537,20 +641,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, context, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction); - - + SetupClipping(item, secondaryCommandBuffer, usedStencilBuffer, lastClippingDepth, lastClippingId, stencilBufferAvailable, instruction, orientation); 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 @@ -563,21 +665,12 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& auto const MAX_QUEUE = item.mRenderer->GetDrawCommands().empty() ? 1 : DevelRenderer::RENDER_QUEUE_MAX; for(auto queue = 0u; queue < MAX_QUEUE; ++queue) { - // Render the item. If rendered, add its command buffer into the list - if( item.mRenderer->Render(context, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque, boundTextures, instruction, queue) ) - { - mGraphicsRenderItemCommandBuffers.emplace_back( item.mRenderer->GetGraphicsCommandBuffer() ); - } + // Render the item. It will write into the command buffer everything it has to render + item.mRenderer->Render(secondaryCommandBuffer, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix, viewMatrix, projectionMatrix, item.mSize, !item.mIsOpaque, boundTextures, instruction, queue); } } } } - - // Execute command buffers - if(!mGraphicsRenderItemCommandBuffers.empty()) - { - mGraphicsCommandBuffer->ExecuteCommandBuffers( std::move(mGraphicsRenderItemCommandBuffers) ); - } } RenderAlgorithms::RenderAlgorithms(Graphics::Controller& graphicsController) @@ -594,29 +687,25 @@ void RenderAlgorithms::ResetCommandBuffer() { mGraphicsCommandBuffer = mGraphicsController.CreateCommandBuffer( Graphics::CommandBufferCreateInfo() - .SetLevel(Graphics::CommandBufferLevel::SECONDARY), + .SetLevel(Graphics::CommandBufferLevel::PRIMARY), nullptr); } else { mGraphicsCommandBuffer->Reset(); } - - // Reset list of secondary buffers to submit - mGraphicsRenderItemCommandBuffers.clear(); } void RenderAlgorithms::SubmitCommandBuffer() { // Submit main command buffer Graphics::SubmitInfo submitInfo; - submitInfo.cmdBuffer.push_back( mGraphicsCommandBuffer.get() ); + submitInfo.cmdBuffer.push_back(mGraphicsCommandBuffer.get()); submitInfo.flags = 0 | Graphics::SubmitFlagBits::FLUSH; - mGraphicsController.SubmitCommandBuffers( submitInfo ); + mGraphicsController.SubmitCommandBuffers(submitInfo); } void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& instruction, - Context& context, BufferIndex bufferIndex, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, @@ -635,7 +724,8 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& if(viewMatrix && projectionMatrix) { - const RenderListContainer::SizeType count = instruction.RenderListCount(); + std::vector buffers; + const RenderListContainer::SizeType count = instruction.RenderListCount(); // Iterate through each render list in order. If a pair of render lists // are marked as interleaved, then process them together. @@ -646,7 +736,6 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& if(renderList && !renderList->IsEmpty()) { ProcessRenderList(*renderList, - context, bufferIndex, *viewMatrix, *projectionMatrix, @@ -657,8 +746,19 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& viewport, rootClippingRect, orientation); + + // Execute command buffer + auto* commandBuffer = renderList->GetCommandBuffer(); + if(commandBuffer) + { + buffers.push_back(commandBuffer); + } } } + if(!buffers.empty()) + { + mGraphicsCommandBuffer->ExecuteCommandBuffers(std::move(buffers)); + } } }