4be76bd1d2f869d88a3a41a03321fda781a1b634
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / common / object-profiler.cpp
1 /*
2  * Copyright (c) 20217 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/system/common/object-profiler.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <dali/integration-api/profiling.h>
24 #include <dali/public-api/object/base-object.h>
25 #include <dali/public-api/object/ref-object.h>
26 #include <dali/public-api/object/type-registry.h>
27 #include <stdlib.h>
28
29 using std::string;
30 using namespace Dali::Integration::Profiling;
31
32 namespace Dali
33 {
34 namespace Internal
35 {
36 namespace Adaptor
37 {
38 ObjectProfiler::ObjectProfiler(Dali::ObjectRegistry objectRegistry, uint32_t timeInterval)
39 : mObjectRegistry(objectRegistry)
40 {
41   // This class must be created after the Stage; this means it doesn't count the initial objects
42   // that are created by the stage (base layer, default camera actor)
43
44   mTimer = Dali::Timer::New(timeInterval * 1000);
45   mTimer.TickSignal().Connect(this, &ObjectProfiler::OnTimeout);
46   mTimer.Start();
47
48   mObjectRegistry.ObjectCreatedSignal().Connect(this, &ObjectProfiler::OnObjectCreated);
49   mObjectRegistry.ObjectDestroyedSignal().Connect(this, &ObjectProfiler::OnObjectDestroyed);
50 }
51
52 ObjectProfiler::~ObjectProfiler()
53 {
54 }
55
56 void ObjectProfiler::DisplayInstanceCounts()
57 {
58   for(auto&& element : mInstanceCountContainer)
59   {
60     std::size_t memorySize = GetMemorySize(element.first, element.second);
61     if(memorySize > 0)
62     {
63       LogMessage(Debug::DebugInfo, "%-30s: % 4d  Memory MemorySize: ~% 6.1f kB\n", element.first.c_str(), element.second, memorySize / 1024.0f);
64     }
65     else
66     {
67       LogMessage(Debug::DebugInfo, "%-30s: % 4d\n", element.first.c_str(), element.second);
68     }
69   }
70   LogMessage(Debug::DebugInfo, "\n");
71 }
72
73 bool ObjectProfiler::OnTimeout()
74 {
75   DisplayInstanceCounts();
76   return true;
77 }
78
79 void ObjectProfiler::OnObjectCreated(BaseHandle handle)
80 {
81   string theType = handle.GetTypeName();
82   if(theType.empty())
83   {
84     DALI_LOG_ERROR("Object created from an unregistered type\n");
85     theType = "<Unregistered>";
86   }
87
88   mInstanceTypes.push_back(InstanceTypePair(&handle.GetBaseObject(), theType));
89
90   bool found = false;
91   for(auto&& element : mInstanceCountContainer)
92   {
93     if(element.first == theType)
94     {
95       element.second++;
96       found = true;
97     }
98   }
99   if(!found)
100   {
101     InstanceCountPair instanceCount(theType, 1);
102     mInstanceCountContainer.emplace_back(instanceCount);
103   }
104 }
105
106 void ObjectProfiler::OnObjectDestroyed(const Dali::RefObject* object)
107 {
108   const BaseObject* baseObject = static_cast<const BaseObject*>(object);
109
110   const auto end = mInstanceTypes.end();
111   for(auto iter = mInstanceTypes.begin(); iter != end; ++iter)
112   {
113     if(iter->first == baseObject)
114     {
115       const auto& theType = iter->second;
116       if(!theType.empty())
117       {
118         auto&& countIter = std::find_if(mInstanceCountContainer.begin(),
119                                         mInstanceCountContainer.end(),
120                                         [theType](const InstanceCountPair& instance) { return instance.first == theType; });
121         if(countIter != mInstanceCountContainer.end())
122         {
123           (*countIter).second--;
124         }
125       }
126       mInstanceTypes.erase(iter);
127       return;
128     }
129   }
130 }
131
132 std::size_t ObjectProfiler::GetMemorySize(const std::string& name, uint32_t count)
133 {
134   struct MemoryMemorySize
135   {
136     std::string name;
137     std::size_t memorySize;
138   };
139   MemoryMemorySize memoryMemorySizes[] =
140     {
141       {"Animation", ANIMATION_MEMORY_SIZE},
142       {"Constraint", CONSTRAINT_MEMORY_SIZE},
143       {"Actor", ACTOR_MEMORY_SIZE},
144       {"Layer", LAYER_MEMORY_SIZE},
145       {"CameraActor", CAMERA_ACTOR_MEMORY_SIZE},
146       {"Renderer", RENDERER_MEMORY_SIZE},
147       {"Geometry", GEOMETRY_MEMORY_SIZE},
148       {"PropertyBuffer", PROPERTY_BUFFER_MEMORY_SIZE},
149       {"TextureSet", TEXTURE_SET_MEMORY_SIZE},
150       {"Sampler", SAMPLER_MEMORY_SIZE},
151       {"Shader", SHADER_MEMORY_SIZE},
152     };
153
154   for(size_t i = 0; i < sizeof(memoryMemorySizes) / sizeof(MemoryMemorySize); i++)
155   {
156     if(memoryMemorySizes[i].name.compare(name) == 0)
157     {
158       return count * memoryMemorySizes[i].memorySize;
159     }
160   }
161   return 0;
162 }
163
164 } // namespace Adaptor
165 } // namespace Internal
166 } // namespace Dali