From: David Steele Date: Thu, 19 Sep 2024 09:23:09 +0000 (+0100) Subject: Added clip transform matrix to the Graphics Controller X-Git-Tag: dali_2.3.43~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d79988ac10bca05da9ad2a422681bb1ca69a0a3b;p=platform%2Fcore%2Fuifw%2Fdali-core.git Added clip transform matrix to the Graphics Controller For GL, this matrix should not be used, so doesn't affect render time. For Vulkan, this will change to Vulkan clip space, so adds another matrix multiply. (Consider moving the projection matrix setup to graphics controller...) Moved the viewport/scissor setting to the secondary command buffer. (It's not an issue for GL, but is for Vulkan) Also ensured that the viewport near/far clip values are set. Change-Id: I4c1842fad5766d9be769fe9dce79386f84b5459a --- 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 f0bc4d6d5..114879fb4 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 @@ -1505,4 +1505,22 @@ Graphics::UniquePtr TestGraphicsController::ReleaseTextureFro return texture; } +bool TestGraphicsController::HasClipMatrix() const +{ + return true; +} + +const Matrix& TestGraphicsController::GetClipMatrix() const +{ + // This matrix transforms from GL -> Vulkan clip space + constexpr float VULKAN_CLIP_MATRIX_DATA[] = { + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 1.0f}; + static const Matrix VULKAN_CLIP_MATRIX(VULKAN_CLIP_MATRIX_DATA); + static const Matrix IDENTITY = Matrix::IDENTITY; + + // For now, return IDENTITY to stay in GL clip space. + // @todo Add test toggle + return IDENTITY; +} + } // namespace Dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h index e21c30400..2b0a9b97a 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h @@ -422,6 +422,9 @@ public: // ResourceId relative API. */ Graphics::UniquePtr ReleaseTextureFromResourceId(uint32_t resourceId) override; + bool HasClipMatrix() const override; + const Matrix& GetClipMatrix() const override; + public: // Test Functions void SetAutoAttrCreation(bool v) { @@ -499,14 +502,14 @@ public: // Test Functions uint32_t elementStrideInBytes) { TestGraphicsReflection::TestUniformInfo info; - info.name = std::move(name); - info.type = type; - info.uniformClass = Graphics::UniformClass::UNIFORM; - info.numElements = elementCount; - info.locations = {0}; - info.bufferIndex = 0; // this will update when AddCustomUniformBlock called - - auto retval= GetUniformBufferArrayStrideAndTypeSize(info, elementStrideInBytes); + info.name = std::move(name); + info.type = type; + info.uniformClass = Graphics::UniformClass::UNIFORM; + info.numElements = elementCount; + info.locations = {0}; + info.bufferIndex = 0; // this will update when AddCustomUniformBlock called + + auto retval = GetUniformBufferArrayStrideAndTypeSize(info, elementStrideInBytes); info.elementStride = std::max(retval.first, retval.second); info.offsets = {blockInfo.size}; blockInfo.size += (elementCount == 0 ? 1 : elementCount) * std::max(retval.first, retval.second); @@ -567,4 +570,4 @@ public: } // namespace Dali -#endif //TEST_GRAPHICS_CONTROLLER_H +#endif // TEST_GRAPHICS_CONTROLLER_H diff --git a/dali/graphics-api/graphics-controller.h b/dali/graphics-api/graphics-controller.h index 466edfa82..19009339b 100644 --- a/dali/graphics-api/graphics-controller.h +++ b/dali/graphics-api/graphics-controller.h @@ -412,6 +412,20 @@ public: // ResourceId relative API. */ virtual UniquePtr ReleaseTextureFromResourceId(uint32_t resourceId) = 0; + /** + * @brief Determine if the backend needs to multiply the projection matrix by a clip matrix + * + * @return TRUE if the graphics backend requires an alternative clip matrix + */ + virtual bool HasClipMatrix() const = 0; + + /** + * @brief Get the alternative clipping matrix. + * + * @return the clipping matrix + */ + virtual const Matrix& GetClipMatrix() const = 0; + protected: /** * Creates controller diff --git a/dali/graphics-api/graphics-types.h b/dali/graphics-api/graphics-types.h index 77800058b..dab4ab641 100644 --- a/dali/graphics-api/graphics-types.h +++ b/dali/graphics-api/graphics-types.h @@ -80,7 +80,7 @@ struct Viewport float width = 0.0f; float height = 0.0f; float minDepth = 0.0f; - float maxDepth = 0.0f; + float maxDepth = 1.0f; }; /** diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index fd56538e7..7f067c177 100644 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -40,6 +40,7 @@ namespace Render { namespace { + struct GraphicsDepthCompareOp { constexpr explicit GraphicsDepthCompareOp(DepthFunction::Type compareOp) @@ -147,7 +148,7 @@ struct GraphicsStencilOp inline Graphics::Viewport ViewportFromClippingBox(const Uint16Pair& sceneSize, ClippingBox clippingBox, int orientation) { - Graphics::Viewport viewport{static_cast(clippingBox.x), static_cast(clippingBox.y), static_cast(clippingBox.width), static_cast(clippingBox.height), 0.0f, 0.0f}; + Graphics::Viewport viewport{static_cast(clippingBox.x), static_cast(clippingBox.y), static_cast(clippingBox.width), static_cast(clippingBox.height), 0.0f, 1.0f}; if(orientation == 90 || orientation == 270) { @@ -169,6 +170,8 @@ inline Graphics::Viewport ViewportFromClippingBox(const Uint16Pair& sceneSize, C viewport.x = sceneSize.GetX() - (clippingBox.x + clippingBox.width); viewport.y = sceneSize.GetY() - (clippingBox.y + clippingBox.height); } + viewport.minDepth = 0; + viewport.maxDepth = 1; return viewport; } @@ -630,9 +633,9 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& // Add root clipping rect (set manually for Render function by partial update for example) // on the bottom of the stack + Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0); if(!rootClippingRect.IsEmpty()) { - Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0); secondaryCommandBuffer.SetScissorTestEnable(true); secondaryCommandBuffer.SetScissor(Rect2DFromRect(rootClippingRect, orientation, graphicsViewport)); mScissorStack.push_back(rootClippingRect); @@ -641,12 +644,13 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& else if(!renderList.IsClipping()) { secondaryCommandBuffer.SetScissorTestEnable(false); + //@todo Vk requires a scissor to be set, as we have turned on dynamic state scissor in the pipelines. + secondaryCommandBuffer.SetScissor(Rect2DFromClippingBox(mViewportRectangle, orientation, graphicsViewport)); mScissorStack.push_back(mViewportRectangle); } if(renderList.IsClipping()) { - Graphics::Viewport graphicsViewport = ViewportFromClippingBox(sceneSize, mViewportRectangle, 0); secondaryCommandBuffer.SetScissorTestEnable(true); const ClippingBox& layerScissorBox = renderList.GetClippingBox(); secondaryCommandBuffer.SetScissor(Rect2DFromClippingBox(layerScissorBox, orientation, graphicsViewport)); @@ -657,6 +661,13 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& // Prepare Render::Renderer Render for this secondary command buffer. Renderer::PrepareCommandBuffer(); + // Modify by the clip matrix if necessary (transforms from GL clip space to alternative clip space) + Matrix clippedProjectionMatrix(projectionMatrix); + if(mGraphicsController.HasClipMatrix()) + { + Matrix::Multiply(clippedProjectionMatrix, projectionMatrix, mGraphicsController.GetClipMatrix()); + } + // 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) { @@ -708,7 +719,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& for(auto queue = 0u; queue < MAX_QUEUE; ++queue) { // 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.mScale, item.mSize, !item.mIsOpaque, instruction, renderTarget, queue); + item.mRenderer->Render(secondaryCommandBuffer, bufferIndex, *item.mNode, item.mModelMatrix, item.mModelViewMatrix, viewMatrix, clippedProjectionMatrix, item.mScale, item.mSize, !item.mIsOpaque, instruction, renderTarget, queue); } } } diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 5b32fd802..5aff37e3d 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -1257,10 +1257,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: scissorArea, currentClearValues); - mainCommandBuffer->SetViewport({float(viewportRect.x), - float(viewportRect.y), - float(viewportRect.width), - float(viewportRect.height)}); + // Note, don't set the viewport/scissor on the primary command buffer. mImpl->renderAlgorithms.ProcessRenderInstruction( instruction, @@ -1288,7 +1285,8 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: if(targetsToPresent.size() > 0u) { - DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_FINISHED", [&](std::ostringstream& oss) { oss << "[" << targetsToPresent.size() << "]"; }); + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_FINISHED", [&](std::ostringstream& oss) + { oss << "[" << targetsToPresent.size() << "]"; }); } // Flush UBOs