From d006650fc8288342f3666e063d71b4c2256c63e8 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Wed, 17 Jan 2024 14:07:53 +0900 Subject: [PATCH] [Tizen] Add trace marker for some CORE Update cases - Log for each UpdateManager / RenderManager operations - Log for message queue size and count - Log for FrameUpdateCallback interface Change-Id: I73c7970b03fecc26b6534ff4b00578e7ce3189ae Signed-off-by: Eunki, Hong --- dali/internal/render/common/render-algorithms.cpp | 18 ++++- dali/internal/render/common/render-manager.cpp | 60 ++++++++++++++-- dali/internal/render/queue/render-queue.cpp | 15 +++- .../update/animation/scene-graph-animation.cpp | 6 +- .../update/manager/frame-callback-processor.cpp | 52 +++++++++++++- .../update/manager/render-task-processor.cpp | 7 +- dali/internal/update/manager/resetter-container.h | 11 ++- .../update/manager/scene-graph-traveler.cpp | 16 ++++- dali/internal/update/manager/transform-manager.cpp | 21 ++++-- dali/internal/update/manager/update-algorithms.cpp | 13 +++- dali/internal/update/manager/update-manager.cpp | 83 ++++++++++++++++++++-- .../internal/update/queue/update-message-queue.cpp | 26 ++++++- 12 files changed, 299 insertions(+), 29 deletions(-) diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp index 9c00289..4e872f5 100644 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ #include // INTERNAL INCLUDES +#include #include #include #include @@ -390,6 +391,8 @@ inline void SetupDepthBuffer(const RenderItem& item, Graphics::CommandBuffer& co } } +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); } // Unnamed namespace /** @@ -645,6 +648,11 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& // Prepare Render::Renderer Render for this secondary command buffer. Renderer::PrepareCommandBuffer(); + uint32_t renderCallCount = 0u; + + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_LIST_PROCESS", [&](std::ostringstream& oss) { + oss << "[" << count << "]"; + }); // 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) { @@ -697,10 +705,14 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList& { // 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, queue); + ++renderCallCount; } } } } + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_LIST_PROCESS", [&](std::ostringstream& oss) { + oss << "[renderCallCount:" << renderCallCount << "]"; + }); } RenderAlgorithms::RenderAlgorithms(Graphics::Controller& graphicsController) @@ -744,6 +756,9 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& int orientation, const Uint16Pair& sceneSize) { + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_INSTRUCTION_PROCESS", [&](std::ostringstream& oss) { + oss << "[" << instruction.RenderListCount() << "]"; + }); DALI_PRINT_RENDER_INSTRUCTION(instruction, bufferIndex); const Matrix* viewMatrix = instruction.GetViewMatrix(bufferIndex); @@ -790,6 +805,7 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction& mGraphicsCommandBuffer->ExecuteCommandBuffers(std::move(buffers)); } } + DALI_TRACE_END(gTraceFilter, "DALI_RENDER_INSTRUCTION_PROCESS"); } } // namespace Render diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index 2844fe3..e974e62 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ // INTERNAL INCLUDES #include #include +#include #include #include @@ -127,6 +128,9 @@ inline void AlignDamagedRect(Rect& rect) rect.width = ((right + 16) / 16) * 16 - rect.x; rect.height = ((bottom + 16) / 16) * 16 - rect.y; } + +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); } // namespace /** @@ -481,6 +485,8 @@ void RenderManager::RemoveRenderTracker(Render::RenderTracker* renderTracker) void RenderManager::PreRender(Integration::RenderStatus& status, bool forceClear) { + DALI_TRACE_BEGIN(gTraceFilter, "DALI_RENDER_PRE_RENDER"); + DALI_PRINT_RENDER_START(mImpl->renderBufferIndex); DALI_LOG_INFO(gLogFilter, Debug::Verbose, "\n\nNewFrame %d\n", mImpl->frameCount); @@ -525,6 +531,10 @@ void RenderManager::PreRender(Integration::RenderStatus& status, bool forceClear */ mImpl->commandBufferSubmitted = false; + + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_PRE_RENDER", [&](std::ostringstream& oss) { + oss << "[" << totalInstructionCount << "]"; + }); } void RenderManager::PreRender(Integration::Scene& scene, std::vector>& damagedRects) @@ -597,6 +607,12 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& return; } + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_DIRTY_RECT", [&](std::ostringstream& oss) { + oss << "[" << itemsDirtyRects.size() << "]"; + }); + + uint32_t renderItemCount = 0u; + // Mark previous dirty rects in the std::unordered_map. for(auto& dirtyRectPair : itemsDirtyRects) { @@ -671,6 +687,8 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& if(!renderList->IsEmpty()) { const std::size_t listCount = renderList->Count(); + renderItemCount += listCount; + for(uint32_t listIndex = 0u; listIndex < listCount; ++listIndex) { RenderItem& item = renderList->GetItem(listIndex); @@ -785,6 +803,11 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& { damagedRectCleaner.SetCleanOnReturn(false); } + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_DIRTY_RECT", [&](std::ostringstream& oss) { + oss << "[" << itemsDirtyRects.size() << ","; + oss << "itemCount:" << renderItemCount << ","; + oss << "damagedRects:" << damagedRects.size() << "]"; + }); } void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::Scene& scene, bool renderToFbo) @@ -834,6 +857,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: clippingRect = Rect(); } + DALI_TRACE_BEGIN(gTraceFilter, "DALI_RENDER_UBO"); // Prefetch programs before we start rendering so reflection is // ready, and we can pull exact size of UBO needed (no need to resize during drawing) auto totalSizeCPU = 0u; @@ -903,6 +927,10 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: DALI_LOG_INFO(gLogFilter, Debug::Verbose, "GPU buffer: nil\n"); } #endif + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_UBO", [&](std::ostringstream& oss) { + oss << "[cpuMemory:" << totalSizeCPU << ","; + oss << "gpuMemory:" << totalSizeGPU << "]"; + }); for(uint32_t i = 0; i < instructionCount; ++i) { @@ -1104,6 +1132,10 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: mainCommandBuffer->EndRenderPass(syncObject); } + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_FINISHED", [&](std::ostringstream& oss) { + oss << "[" << targetstoPresent.size() << "]"; + }); + // Flush UBOs mImpl->uniformBufferManager->Flush(sceneObject, renderToFbo); mImpl->renderAlgorithms.SubmitCommandBuffer(); @@ -1120,6 +1152,8 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration:: rt = target; } } + + DALI_TRACE_END(gTraceFilter, "DALI_RENDER_FINISHED"); } void RenderManager::PostRender() @@ -1136,17 +1170,31 @@ void RenderManager::PostRender() } // Notify RenderGeometries that rendering has finished - for(auto&& iter : mImpl->geometryContainer) + if(mImpl->geometryContainer.Count() > 0u) { - iter->OnRenderFinished(); + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_GEOMETRY_RENDER_FINISHED", [&](std::ostringstream& oss) { + oss << "[" << mImpl->geometryContainer.Count() << "]"; + }); + for(auto&& iter : mImpl->geometryContainer) + { + iter->OnRenderFinished(); + } + DALI_TRACE_END(gTraceFilter, "DALI_GEOMETRY_RENDER_FINISHED"); } // Notify updated RenderTexture that rendering has finished - for(auto&& iter : mImpl->updatedTextures) + if(mImpl->updatedTextures.Count() > 0u) { - iter->OnRenderFinished(); + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_TEXTURE_UPDATED", [&](std::ostringstream& oss) { + oss << "[" << mImpl->updatedTextures.Count() << "]"; + }); + for(auto&& iter : mImpl->updatedTextures) + { + iter->OnRenderFinished(); + } + mImpl->updatedTextures.Clear(); + DALI_TRACE_END(gTraceFilter, "DALI_TEXTURE_UPDATED"); } - mImpl->updatedTextures.Clear(); // Remove discarded textures after OnRenderFinished called mImpl->textureDiscardQueue.Clear(); diff --git a/dali/internal/render/queue/render-queue.cpp b/dali/internal/render/queue/render-queue.cpp index ca582ba..f42ee9f 100644 --- a/dali/internal/render/queue/render-queue.cpp +++ b/dali/internal/render/queue/render-queue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,11 @@ // CLASS HEADER #include +// EXTERNAL INCLUDES +#include + // INTERNAL INCLUDES +#include #include namespace Dali @@ -30,6 +34,8 @@ namespace // unnamed namespace static const std::size_t INITIAL_BUFFER_SIZE = 32768; static const std::size_t MAX_BUFFER_SIZE = 32768; +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); } // unnamed namespace namespace SceneGraph @@ -80,15 +86,19 @@ uint32_t* RenderQueue::ReserveMessageSlot(BufferIndex updateBufferIndex, std::si void RenderQueue::ProcessMessages(BufferIndex bufferIndex) { + DALI_TRACE_BEGIN(gTraceFilter, "DALI_RENDER_MESSAGE_QUEUE_PROCESS"); std::size_t capacity = container0->GetCapacity() + container1->GetCapacity(); mCapacity = capacity; // write is atomic. + uint32_t messageCount = 0u; + MessageBuffer* container = GetCurrentContainer(bufferIndex); for(MessageBuffer::Iterator iter = container->Begin(); iter.IsValid(); iter.Next()) { MessageBase* message = reinterpret_cast(iter.Get()); + ++messageCount; message->Process(bufferIndex); // Call virtual destructor explictly; since delete will not be called after placement new @@ -98,6 +108,9 @@ void RenderQueue::ProcessMessages(BufferIndex bufferIndex) container->Reset(); LimitBufferCapacity(bufferIndex); + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDER_MESSAGE_QUEUE_PROCESS", [&](std::ostringstream& oss) { + oss << "[" << messageCount << "]"; + }); } MessageBuffer* RenderQueue::GetCurrentContainer(BufferIndex bufferIndex) diff --git a/dali/internal/update/animation/scene-graph-animation.cpp b/dali/internal/update/animation/scene-graph-animation.cpp index 75551c6..78657f9 100644 --- a/dali/internal/update/animation/scene-graph-animation.cpp +++ b/dali/internal/update/animation/scene-graph-animation.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include // fmod // INTERNAL INCLUDES +#include #include #include #include @@ -53,6 +54,9 @@ bool CompareAnimatorEndTimes(const Dali::Internal::SceneGraph::AnimatorBase* lhs return ((lhs->GetIntervalDelay() + lhs->GetDuration()) < (rhs->GetIntervalDelay() + rhs->GetDuration())); } +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); + } // unnamed namespace namespace Dali diff --git a/dali/internal/update/manager/frame-callback-processor.cpp b/dali/internal/update/manager/frame-callback-processor.cpp index e6d2617..82b2bc5 100644 --- a/dali/internal/update/manager/frame-callback-processor.cpp +++ b/dali/internal/update/manager/frame-callback-processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,11 @@ // EXTERNAL INCLUDES #include +#ifdef TRACE_ENABLED +#include +#include +#endif + // INTERNAL INCLUDES #include #include @@ -30,6 +35,18 @@ namespace { DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false); + +#ifdef TRACE_ENABLED +uint64_t GetNanoSeconds() +{ + // Get the time of a monotonic clock since its epoch. + auto epoch = std::chrono::steady_clock::now().time_since_epoch(); + + auto duration = std::chrono::duration_cast(epoch); + + return static_cast(duration.count()); +} +#endif } // namespace namespace Dali @@ -83,7 +100,9 @@ bool FrameCallbackProcessor::Update(BufferIndex bufferIndex, float elapsedSecond if(mNodeHierarchyChanged) { - DALI_LOG_DEBUG_INFO("Node hierarchy changed. Update traveler map\n"); + DALI_LOG_DEBUG_INFO("Node hierarchy changed. Update traveler map [%zu]\n", mTravelerMap.size()); + uint32_t removedCount = 0u; + uint32_t cacheClearedCount = 0u; // Clear node traveler for(auto iter = mTravelerMap.begin(); iter != mTravelerMap.end();) { @@ -92,16 +111,19 @@ bool FrameCallbackProcessor::Update(BufferIndex bufferIndex, float elapsedSecond if(iter->second->IsInvalidated() || iter->second->ReferenceCount() == 1u) { iter = mTravelerMap.erase(iter); + ++removedCount; } else { if(iter->first->IsDescendentHierarchyChanged()) { iter->second->NodeHierarchyChanged(); + ++cacheClearedCount; } ++iter; } } + DALI_LOG_DEBUG_INFO("Update traveler map Finished [%zu] removed:%zu, updated:%zu\n", mTravelerMap.size(), removedCount, cacheClearedCount); } if(!mFrameCallbacks.empty()) @@ -110,17 +132,41 @@ bool FrameCallbackProcessor::Update(BufferIndex bufferIndex, float elapsedSecond oss << "[" << mFrameCallbacks.size() << "]"; }); +#ifdef TRACE_ENABLED + std::vector> frameCallbackTimeChecker; + + uint32_t frameIndex = 0u; +#endif + // If any of the FrameCallback::Update calls returns false, then they are no longer required & can be removed. auto iter = std::remove_if( mFrameCallbacks.begin(), mFrameCallbacks.end(), [&](OwnerPointer& frameCallback) { +#ifdef TRACE_ENABLED + uint64_t start = GetNanoSeconds(); +#endif FrameCallback::RequestFlags requests = frameCallback->Update(bufferIndex, elapsedSeconds, mNodeHierarchyChanged); +#ifdef TRACE_ENABLED + uint64_t end = GetNanoSeconds(); + frameCallbackTimeChecker.emplace_back(end - start, ++frameIndex); +#endif keepRendering |= (requests & FrameCallback::KEEP_RENDERING); return (requests & FrameCallback::CONTINUE_CALLING) == 0; }); mFrameCallbacks.erase(iter, mFrameCallbacks.end()); DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_FRAME_CALLBACK_UPDATE", [&](std::ostringstream& oss) { - oss << "[" << mFrameCallbacks.size() << "]"; + oss << "[" << mFrameCallbacks.size() << ","; + + std::sort(frameCallbackTimeChecker.rbegin(), frameCallbackTimeChecker.rend()); + auto topCount = std::min(5u, static_cast(frameCallbackTimeChecker.size())); + + oss << "top" << topCount << "["; + for(auto i = 0u; i < topCount; ++i) + { + oss << "(" << static_cast(frameCallbackTimeChecker[i].first) / 1000000.0f << "ms,"; + oss << frameCallbackTimeChecker[i].second << ")"; + } + oss << "]"; }); } diff --git a/dali/internal/update/manager/render-task-processor.cpp b/dali/internal/update/manager/render-task-processor.cpp index c1460e2..d2d9298 100644 --- a/dali/internal/update/manager/render-task-processor.cpp +++ b/dali/internal/update/manager/render-task-processor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include #include #include #include @@ -42,6 +43,9 @@ namespace SceneGraph { namespace // Unnamed namespace { +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); + // Return false if the node or it's parents are exclusive to another render-task. bool CheckExclusivity(const Node& node, const RenderTask& task) { @@ -214,6 +218,7 @@ void ProcessTasks(BufferIndex updateBufferIndex, bool isRenderingToFbo, bool processOffscreen) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_TASK_PROCESS"); uint32_t clippingId = 0u; bool hasClippingNodes = false; diff --git a/dali/internal/update/manager/resetter-container.h b/dali/internal/update/manager/resetter-container.h index 9c042b1..2a88d88 100644 --- a/dali/internal/update/manager/resetter-container.h +++ b/dali/internal/update/manager/resetter-container.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_UPDATE_RESETTER_CONTAINER_H /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ namespace Dali::Internal::SceneGraph { - /** * Template class to manage node/property resetters */ @@ -76,6 +75,14 @@ public: } /** + * @return The number of resetter contained. + */ + size_t Count() const + { + return mContainer.size(); + } + + /** * @return an iterator to the start of the container */ Iterator Begin() diff --git a/dali/internal/update/manager/scene-graph-traveler.cpp b/dali/internal/update/manager/scene-graph-traveler.cpp index 30bf0f3..1fb90ee 100644 --- a/dali/internal/update/manager/scene-graph-traveler.cpp +++ b/dali/internal/update/manager/scene-graph-traveler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,15 @@ #include // INTERNAL INCLUDES +#include #include +namespace +{ +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); +} // namespace + namespace Dali { namespace Internal @@ -54,6 +61,9 @@ SceneGraph::Node* SceneGraphTraveler::FindNode(uint32_t id) } else { + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_SCENE_GRAPH_TRAVELER", [&](std::ostringstream& oss) { + oss << "[" << mTravledNodeMap.size() << "]"; + }); while(!FullSearched()) { SceneGraph::Node& currentNode = GetCurrentNode(); @@ -68,6 +78,10 @@ SceneGraph::Node* SceneGraphTraveler::FindNode(uint32_t id) break; } } + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_SCENE_GRAPH_TRAVELER", [&](std::ostringstream& oss) { + oss << "[" << mTravledNodeMap.size() << ","; + oss << "found:" << (node == nullptr ? 0 : 1) << "]"; + }); } return node; diff --git a/dali/internal/update/manager/transform-manager.cpp b/dali/internal/update/manager/transform-manager.cpp index b92b13d..32789de 100644 --- a/dali/internal/update/manager/transform-manager.cpp +++ b/dali/internal/update/manager/transform-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ #include #include +#include namespace Dali { @@ -77,6 +78,8 @@ inline void CalculateCenterPosition( } } +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); } // unnamed namespace TransformManager::TransformManager() @@ -225,6 +228,7 @@ void TransformManager::ResetToBaseValue() { if(mComponentCount) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_TRANSFORM_RESET_TO_BASE"); memcpy(&mTxComponentAnimatable[0], &mTxComponentAnimatableBaseValue[0], sizeof(TransformComponentAnimatable) * mComponentCount); memcpy(&mSize[0], &mSizeBase[0], sizeof(Vector3) * mComponentCount); memset(&mLocalMatrixDirty[0], false, sizeof(bool) * mComponentCount); @@ -235,8 +239,13 @@ bool TransformManager::Update() { bool componentsChanged = false; + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_TRANSFORM_UPDATE", [&](std::ostringstream& oss) { + oss << "[" << mComponentCount << "]"; + }); + if(mReorder) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_TRANSFORM_REORDER"); //If some transform component has change its parent or has been removed since last update //we need to reorder the vectors ReorderComponents(); @@ -281,15 +290,15 @@ bool TransformManager::Update() // Compute intermediate Local information CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, mSize[i], half, topLeft); Vector3 intermediateLocalPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex]; - Matrix intermediateLocalMatrix; + Matrix intermediateLocalMatrix; intermediateLocalMatrix.SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, intermediateLocalPosition); // Compute intermediate world information Matrix intermediateWorldMatrix; MatrixUtils::MultiplyTransformMatrix(intermediateWorldMatrix, intermediateLocalMatrix, mWorld[parentIndex]); - Vector3 intermediateWorldPosition, intermediateWorldScale; - Quaternion intermediateWorldOrientation; + Vector3 intermediateWorldPosition, intermediateWorldScale; + Quaternion intermediateWorldOrientation; intermediateWorldMatrix.GetTransformComponents(intermediateWorldPosition, intermediateWorldOrientation, intermediateWorldScale); // Compute final world information @@ -357,6 +366,10 @@ bool TransformManager::Update() mComponentDirty[i] = false; } + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_TRANSFORM_UPDATE", [&](std::ostringstream& oss) { + oss << "[componentsChanged:" << componentsChanged << "]"; + }); + return componentsChanged; } diff --git a/dali/internal/update/manager/update-algorithms.cpp b/dali/internal/update/manager/update-algorithms.cpp index 0cfd6dd..6870965 100644 --- a/dali/internal/update/manager/update-algorithms.cpp +++ b/dali/internal/update/manager/update-algorithms.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,13 @@ #include #include +#include + +namespace +{ +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); +} // namespace namespace Dali { @@ -161,6 +168,8 @@ NodePropertyFlags UpdateNodeTree(Layer& rootNode, return NodePropertyFlags::NOTHING; } + DALI_TRACE_BEGIN(gTraceFilter, "DALI_UPDATE_NODE_TREE"); + // If the root node was not previously visible BufferIndex previousBuffer = updateBufferIndex ? 0u : 1u; if(DALI_UNLIKELY(!rootNode.IsVisible(previousBuffer))) // almost never ever true @@ -191,6 +200,8 @@ NodePropertyFlags UpdateNodeTree(Layer& rootNode, updated); } + DALI_TRACE_END(gTraceFilter, "DALI_UPDATE_NODE_TREE"); + return cumulativeDirtyFlags; } diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 8cc38a4..1fdc932 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include #include @@ -74,6 +75,12 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPD } // unnamed namespace #endif +namespace +{ +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); +} // namespace + using namespace Dali::Integration; using Dali::Internal::Update::MessageQueue; @@ -761,14 +768,41 @@ void UpdateManager::ResetProperties(BufferIndex bufferIndex) // Clear the "animations finished" flag; This should be set if any (previously playing) animation is stopped mImpl->animationFinishedDuringUpdate = false; - // Reset node properties - mImpl->nodeResetters.ResetToBaseValues(bufferIndex); + if(mImpl->nodeResetters.Count() > 0u) + { + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_NODE_RESETTER", [&](std::ostringstream& oss) { + oss << "[" << mImpl->nodeResetters.Count() << "]"; + }); + // Reset node properties + mImpl->nodeResetters.ResetToBaseValues(bufferIndex); + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_NODE_RESETTER", [&](std::ostringstream& oss) { + oss << "[" << mImpl->nodeResetters.Count() << "]"; + }); + } - // Reset renderer properties - mImpl->rendererResetters.ResetToBaseValues(bufferIndex); + if(mImpl->rendererResetters.Count() > 0u) + { + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDERER_RESETTER", [&](std::ostringstream& oss) { + oss << "[" << mImpl->rendererResetters.Count() << "]"; + }); + // Reset renderer properties + mImpl->rendererResetters.ResetToBaseValues(bufferIndex); + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_RENDERER_RESETTER", [&](std::ostringstream& oss) { + oss << "[" << mImpl->rendererResetters.Count() << "]"; + }); + } - // Reset all animating / constrained properties - mImpl->propertyResetters.ResetToBaseValues(bufferIndex); + if(mImpl->propertyResetters.Count() > 0u) + { + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_PROPERTY_RESETTER", [&](std::ostringstream& oss) { + oss << "[" << mImpl->propertyResetters.Count() << "]"; + }); + // Reset all animating / constrained properties + mImpl->propertyResetters.ResetToBaseValues(bufferIndex); + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_PROPERTY_RESETTER", [&](std::ostringstream& oss) { + oss << "[" << mImpl->propertyResetters.Count() << "]"; + }); + } // Clear all root nodes dirty flags for(auto& scene : mImpl->scenes) @@ -777,6 +811,9 @@ void UpdateManager::ResetProperties(BufferIndex bufferIndex) root->ResetDirtyFlags(bufferIndex); } + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_UPDATE_NODE_RESET", [&](std::ostringstream& oss) { + oss << "[" << mImpl->nodes.Count() << "]"; + }); // Clear node dirty flags Vector::Iterator iter = mImpl->nodes.Begin() + 1; Vector::Iterator endIter = mImpl->nodes.End(); @@ -784,6 +821,7 @@ void UpdateManager::ResetProperties(BufferIndex bufferIndex) { (*iter)->ResetDirtyFlags(bufferIndex); } + DALI_TRACE_END(gTraceFilter, "DALI_UPDATE_NODE_RESET"); } bool UpdateManager::ProcessGestures(BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds) @@ -807,6 +845,10 @@ bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds) auto&& iter = mImpl->animations.Begin(); + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_ANIMATION_ANIMATE", [&](std::ostringstream& oss) { + oss << "[" << mImpl->animations.Count() << "]"; + }); + while(iter != mImpl->animations.End()) { Animation* animation = *iter; @@ -848,11 +890,16 @@ bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds) mImpl->notificationManager.QueueNotification(&mImpl->animationPlaylist, std::move(mImpl->notifyRequiredAnimations)); } + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_ANIMATION_ANIMATE", [&](std::ostringstream& oss) { + oss << "[" << mImpl->animations.Count() << "]"; + }); + return animationActive; } void UpdateManager::ConstrainCustomObjects(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_CONSTRAINT_CUSTOM_OBJECTS"); // Constrain custom objects (in construction order) for(auto&& object : mImpl->customObjects) { @@ -866,6 +913,7 @@ void UpdateManager::ConstrainCustomObjects(PropertyOwnerContainer& postPropertyO void UpdateManager::ConstrainRenderTasks(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_CONSTRAINT_RENDER_TASK"); // Constrain render-tasks for(auto&& scene : mImpl->scenes) { @@ -886,6 +934,7 @@ void UpdateManager::ConstrainRenderTasks(PropertyOwnerContainer& postPropertyOwn void UpdateManager::ConstrainShaders(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_CONSTRAINT_SHADER"); // constrain shaders... (in construction order) for(auto&& shader : mImpl->shaders) { @@ -899,6 +948,7 @@ void UpdateManager::ConstrainShaders(PropertyOwnerContainer& postPropertyOwners, void UpdateManager::ProcessPropertyNotifications(BufferIndex bufferIndex) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_PROPERTY_NOTIFICATION"); for(auto&& notification : mImpl->propertyNotifications) { bool valid = notification->Check(bufferIndex); @@ -936,6 +986,7 @@ void UpdateManager::ForwardCompiledShadersToEventThread() void UpdateManager::UpdateRenderers(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_RENDERER"); for(const auto& rendererKey : mImpl->renderers) { // Apply constraints @@ -952,6 +1003,7 @@ void UpdateManager::UpdateRenderers(PropertyOwnerContainer& postPropertyOwners, void UpdateManager::UpdateNodes(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_NODES"); mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING; for(auto&& scene : mImpl->scenes) @@ -970,6 +1022,7 @@ void UpdateManager::UpdateNodes(PropertyOwnerContainer& postPropertyOwners, Buff void UpdateManager::UpdateLayers(BufferIndex bufferIndex) { + DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_LAYER"); for(auto&& scene : mImpl->scenes) { if(scene && scene->root) @@ -997,7 +1050,9 @@ uint32_t UpdateManager::Update(float elapsedSeconds, bool isAnimationRunning = IsAnimationRunning(); // Process Touches & Gestures + DALI_TRACE_BEGIN(gTraceFilter, "DALI_UPDATE_GESTURE"); const bool gestureUpdated = ProcessGestures(bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds); + DALI_TRACE_END(gTraceFilter, "DALI_UPDATE_GESTURE"); bool updateScene = // The scene-graph requires an update if.. (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || // ..nodes were dirty in previous frame OR @@ -1034,6 +1089,15 @@ uint32_t UpdateManager::Update(float elapsedSeconds, // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes if(updateScene || mImpl->previousUpdateScene) { + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_UPDATE_INTERNAL", [&](std::ostringstream& oss) { + oss << "[node:" << mImpl->nodes.Size() << ","; + oss << "custom:" << mImpl->customObjects.Size() << ","; + oss << "animations:" << mImpl->animations.Size() << ","; + oss << "renderers:" << mImpl->renderers.Size() << ","; + oss << "textureSets:" << mImpl->textureSets.Size() << ","; + oss << "shaders:" << mImpl->shaders.Size() << "]"; + }); + // Animate bool animationActive = Animate(bufferIndex, elapsedSeconds); @@ -1100,6 +1164,8 @@ uint32_t UpdateManager::Update(float elapsedSeconds, // reset the update buffer index and make sure there is enough room in the instruction container if(mImpl->renderersAdded) { + DALI_TRACE_BEGIN(gTraceFilter, "DALI_UPDATE_TASK_PROCESS"); + // Calculate how many render tasks we have in total std::size_t numberOfRenderTasks = 0; for(auto&& scene : mImpl->scenes) @@ -1155,7 +1221,10 @@ uint32_t UpdateManager::Update(float elapsedSeconds, } DALI_LOG_INFO(gLogFilter, Debug::General, "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", numberOfRenderTasks, numberOfRenderInstructions); + DALI_TRACE_END(gTraceFilter, "DALI_UPDATE_TASK_PROCESS"); } + + DALI_TRACE_END(gTraceFilter, "DALI_UPDATE_INTERNAL"); } if(!uploadOnly) diff --git a/dali/internal/update/queue/update-message-queue.cpp b/dali/internal/update/queue/update-message-queue.cpp index cb35cc2..9446c35 100644 --- a/dali/internal/update/queue/update-message-queue.cpp +++ b/dali/internal/update/queue/update-message-queue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * Copyright (c) 2024 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,13 @@ // CLASS HEADER #include +// EXTERNAL INCLUDES +#include + // INTERNAL INCLUDES #include #include +#include #include #include #include @@ -49,6 +53,9 @@ using MessageBufferIter = MessageBufferQueue::iterator; using MessageQueueMutex = Dali::Mutex; +// TODO : The name of trace marker name is from VD specific. We might need to change it future. +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_COMBINED, false); + } // unnamed namespace namespace Update @@ -210,6 +217,9 @@ bool MessageQueue::FlushQueue() { // queueMutex must be locked whilst accessing processQueue or recycleQueue MessageQueueMutex::ScopedLock lock(mImpl->queueMutex); + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_MESSAGE_QUEUE_FLUSH", [&](std::ostringstream& oss) { + oss << "[capacity:" << mImpl->currentMessageBuffer->GetCapacity() << "]"; + }); mImpl->processQueue.push_back(mImpl->currentMessageBuffer); mImpl->currentMessageBuffer = nullptr; @@ -237,6 +247,7 @@ bool MessageQueue::FlushQueue() mImpl->sceneUpdate |= 2; mImpl->sceneUpdateFlag = false; } + DALI_TRACE_END(gTraceFilter, "DALI_MESSAGE_QUEUE_FLUSH"); } return messagesToProcess; @@ -260,12 +271,19 @@ bool MessageQueue::ProcessMessages(BufferIndex updateBufferIndex) copiedProcessQueue = std::move(mImpl->processQueue); // Move message queue } + DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_UPDATE_MESSAGE_QUEUE_PROCESS", [&](std::ostringstream& oss) { + oss << "[queueCount:" << copiedProcessQueue.size() << "]"; + }); + + uint32_t messageCount = 0u; + for(auto&& buffer : copiedProcessQueue) { for(MessageBuffer::Iterator bufferIter = buffer->Begin(); bufferIter.IsValid(); bufferIter.Next()) { MessageBase* message = reinterpret_cast(bufferIter.Get()); + ++messageCount; message->Process(updateBufferIndex); // Call virtual destructor explictly; since delete will not be called after placement new @@ -280,6 +298,12 @@ bool MessageQueue::ProcessMessages(BufferIndex updateBufferIndex) mImpl->recycleQueue.insert(mImpl->recycleQueue.end(), std::make_move_iterator(copiedProcessQueue.begin()), std::make_move_iterator(copiedProcessQueue.end())); + + // Note trace end inside of mutex, since we need to check recycleQueue size correct. + DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_UPDATE_MESSAGE_QUEUE_PROCESS", [&](std::ostringstream& oss) { + oss << "[messageCount:" << messageCount << ","; + oss << "recycleQueueCount:" << mImpl->recycleQueue.size() << "]"; + }); } PERF_MONITOR_END(PerformanceMonitor::PROCESS_MESSAGES); -- 2.7.4