/*
- * 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.
#include <dali/internal/render/common/render-algorithms.h>
// INTERNAL INCLUDES
+#include <dali/integration-api/trace.h>
#include <dali/internal/render/common/render-debug.h>
#include <dali/internal/render/common/render-instruction.h>
#include <dali/internal/render/common/render-list.h>
}
}
+// 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
/**
// 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)
{
{
// 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)
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);
mGraphicsCommandBuffer->ExecuteCommandBuffers(std::move(buffers));
}
}
+ DALI_TRACE_END(gTraceFilter, "DALI_RENDER_INSTRUCTION_PROCESS");
}
} // namespace Render
/*
- * 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.
// INTERNAL INCLUDES
#include <dali/devel-api/threading/thread-pool.h>
#include <dali/integration-api/core.h>
+#include <dali/integration-api/trace.h>
#include <dali/internal/common/ordered-set.h>
#include <dali/internal/event/common/scene-impl.h>
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
/**
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);
*/
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<Rect<int>>& damagedRects)
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)
{
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);
{
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)
clippingRect = Rect<int>();
}
+ 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;
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)
{
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();
rt = target;
}
}
+
+ DALI_TRACE_END(gTraceFilter, "DALI_RENDER_FINISHED");
}
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();
/*
- * 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.
// CLASS HEADER
#include <dali/internal/render/queue/render-queue.h>
+// EXTERNAL INCLUDES
+#include <sstream>
+
// INTERNAL INCLUDES
+#include <dali/integration-api/trace.h>
#include <dali/internal/common/message.h>
namespace Dali
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
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<MessageBase*>(iter.Get());
+ ++messageCount;
message->Process(bufferIndex);
// Call virtual destructor explictly; since delete will not be called after placement new
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)
/*
- * 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.
#include <cmath> // fmod
// INTERNAL INCLUDES
+#include <dali/integration-api/trace.h>
#include <dali/internal/common/memory-pool-object-allocator.h>
#include <dali/internal/render/common/performance-monitor.h>
#include <dali/public-api/math/math-utils.h>
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
/*
- * 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.
// EXTERNAL INCLUDES
#include <algorithm>
+#ifdef TRACE_ENABLED
+#include <chrono>
+#include <cmath>
+#endif
+
// INTERNAL INCLUDES
#include <dali/devel-api/update/frame-callback-interface.h>
#include <dali/devel-api/update/update-proxy.h>
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<std::chrono::nanoseconds>(epoch);
+
+ return static_cast<uint64_t>(duration.count());
+}
+#endif
} // namespace
namespace Dali
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();)
{
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())
oss << "[" << mFrameCallbacks.size() << "]";
});
+#ifdef TRACE_ENABLED
+ std::vector<std::pair<uint64_t, uint32_t>> 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>& 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<uint32_t>(frameCallbackTimeChecker.size()));
+
+ oss << "top" << topCount << "[";
+ for(auto i = 0u; i < topCount; ++i)
+ {
+ oss << "(" << static_cast<float>(frameCallbackTimeChecker[i].first) / 1000000.0f << "ms,";
+ oss << frameCallbackTimeChecker[i].second << ")";
+ }
+ oss << "]";
});
}
/*
- * 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.
// INTERNAL INCLUDES
#include <dali/integration-api/debug.h>
+#include <dali/integration-api/trace.h>
#include <dali/internal/render/common/render-instruction-container.h>
#include <dali/internal/render/common/render-instruction.h>
#include <dali/internal/render/common/render-item.h>
{
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)
{
bool isRenderingToFbo,
bool processOffscreen)
{
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_TASK_PROCESS");
uint32_t clippingId = 0u;
bool hasClippingNodes = false;
#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.
namespace Dali::Internal::SceneGraph
{
-
/**
* Template class to manage node/property resetters
*/
}
/**
+ * @return The number of resetter contained.
+ */
+ size_t Count() const
+ {
+ return mContainer.size();
+ }
+
+ /**
* @return an iterator to the start of the container
*/
Iterator Begin()
/*
- * 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.
#include <dali/internal/update/manager/scene-graph-traveler.h>
// INTERNAL INCLUDES
+#include <dali/integration-api/trace.h>
#include <dali/internal/update/nodes/node.h>
+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
}
else
{
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_SCENE_GRAPH_TRAVELER", [&](std::ostringstream& oss) {
+ oss << "[" << mTravledNodeMap.size() << "]";
+ });
while(!FullSearched())
{
SceneGraph::Node& currentNode = GetCurrentNode();
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;
/*
- * 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.
#include <dali/public-api/common/constants.h>
#include <dali/integration-api/debug.h>
+#include <dali/integration-api/trace.h>
namespace Dali
{
}
}
+// 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()
{
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);
{
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();
// 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
mComponentDirty[i] = false;
}
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_TRANSFORM_UPDATE", [&](std::ostringstream& oss) {
+ oss << "[componentsChanged:" << componentsChanged << "]";
+ });
+
return componentsChanged;
}
/*
- * 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.
#include <dali/public-api/math/vector3.h>
#include <dali/integration-api/debug.h>
+#include <dali/integration-api/trace.h>
+
+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
{
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
updated);
}
+ DALI_TRACE_END(gTraceFilter, "DALI_UPDATE_NODE_TREE");
+
return cumulativeDirtyFlags;
}
/*
- * 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.
// INTERNAL INCLUDES
#include <dali/integration-api/core.h>
+#include <dali/integration-api/trace.h>
#include <dali/internal/common/owner-key-container.h>
} // 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;
// 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)
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<Node*>::Iterator iter = mImpl->nodes.Begin() + 1;
Vector<Node*>::Iterator endIter = mImpl->nodes.End();
{
(*iter)->ResetDirtyFlags(bufferIndex);
}
+ DALI_TRACE_END(gTraceFilter, "DALI_UPDATE_NODE_RESET");
}
bool UpdateManager::ProcessGestures(BufferIndex bufferIndex, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds)
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;
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)
{
void UpdateManager::ConstrainRenderTasks(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex)
{
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_CONSTRAINT_RENDER_TASK");
// Constrain render-tasks
for(auto&& scene : mImpl->scenes)
{
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)
{
void UpdateManager::ProcessPropertyNotifications(BufferIndex bufferIndex)
{
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_PROPERTY_NOTIFICATION");
for(auto&& notification : mImpl->propertyNotifications)
{
bool valid = notification->Check(bufferIndex);
void UpdateManager::UpdateRenderers(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex)
{
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_RENDERER");
for(const auto& rendererKey : mImpl->renderers)
{
// Apply constraints
void UpdateManager::UpdateNodes(PropertyOwnerContainer& postPropertyOwners, BufferIndex bufferIndex)
{
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_NODES");
mImpl->nodeDirtyFlags = NodePropertyFlags::NOTHING;
for(auto&& scene : mImpl->scenes)
void UpdateManager::UpdateLayers(BufferIndex bufferIndex)
{
+ DALI_TRACE_SCOPE(gTraceFilter, "DALI_UPDATE_LAYER");
for(auto&& scene : mImpl->scenes)
{
if(scene && scene->root)
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
// 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);
// 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)
}
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)
/*
- * 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.
// CLASS HEADER
#include <dali/internal/update/queue/update-message-queue.h>
+// EXTERNAL INCLUDES
+#include <sstream>
+
// INTERNAL INCLUDES
#include <dali/devel-api/threading/mutex.h>
#include <dali/integration-api/render-controller.h>
+#include <dali/integration-api/trace.h>
#include <dali/internal/common/message-buffer.h>
#include <dali/internal/common/message.h>
#include <dali/internal/render/common/performance-monitor.h>
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
{
// 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;
mImpl->sceneUpdate |= 2;
mImpl->sceneUpdateFlag = false;
}
+ DALI_TRACE_END(gTraceFilter, "DALI_MESSAGE_QUEUE_FLUSH");
}
return messagesToProcess;
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<MessageBase*>(bufferIter.Get());
+ ++messageCount;
message->Process(updateBufferIndex);
// Call virtual destructor explictly; since delete will not be called after placement new
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);