[dali_1.9.21] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / system / common / object-profiler.cpp
1 /*
2  * Copyright (c) 20207 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 <stdlib.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/integration-api/profiling.h>
25 #include <dali/public-api/object/ref-object.h>
26 #include <dali/public-api/object/base-object.h>
27 #include <dali/public-api/object/type-registry.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
39 ObjectProfiler::ObjectProfiler( Dali::ObjectRegistry objectRegistry, uint32_t timeInterval )
40 : mObjectRegistry( objectRegistry )
41 {
42   // This class must be created after the Stage; this means it doesn't count the initial objects
43   // that are created by the stage (base layer, default camera actor)
44
45   mTimer = Dali::Timer::New( timeInterval * 1000 );
46   mTimer.TickSignal().Connect( this, &ObjectProfiler::OnTimeout );
47   mTimer.Start();
48
49   mObjectRegistry.ObjectCreatedSignal().Connect( this, &ObjectProfiler::OnObjectCreated );
50   mObjectRegistry.ObjectDestroyedSignal().Connect( this, &ObjectProfiler::OnObjectDestroyed );
51 }
52
53 ObjectProfiler::~ObjectProfiler()
54 {
55 }
56
57 void ObjectProfiler::DisplayInstanceCounts()
58 {
59   for( auto&& element : mInstanceCountContainer )
60   {
61     std::size_t memorySize = GetMemorySize( element.first, element.second );
62     if( memorySize > 0 )
63     {
64       LogMessage( Debug::DebugInfo, "%-30s: % 4d  Memory MemorySize: ~% 6.1f kB\n",
65                   element.first.c_str(), element.second, memorySize / 1024.0f );
66     }
67     else
68     {
69       LogMessage( Debug::DebugInfo, "%-30s: % 4d\n",
70                   element.first.c_str(), element.second );
71     }
72   }
73   LogMessage(Debug::DebugInfo, "\n");
74 }
75
76 bool ObjectProfiler::OnTimeout()
77 {
78   DisplayInstanceCounts();
79   return true;
80 }
81
82 void ObjectProfiler::OnObjectCreated(BaseHandle handle)
83 {
84   string theType = handle.GetTypeName();
85   if( theType.empty() )
86   {
87     DALI_LOG_ERROR("Object created from an unregistered type\n");
88     theType = "<Unregistered>";
89   }
90
91   mInstanceTypes.push_back(InstanceTypePair(&handle.GetBaseObject(), theType));
92
93   bool found = false;
94   for( auto&& element : mInstanceCountContainer )
95   {
96     if( element.first == theType )
97     {
98       element.second++;
99       found = true;
100     }
101   }
102   if( !found )
103   {
104     InstanceCountPair instanceCount( theType, 1 );
105     mInstanceCountContainer.emplace_back( instanceCount );
106   }
107 }
108
109 void ObjectProfiler::OnObjectDestroyed(const Dali::RefObject* object)
110 {
111   const BaseObject* baseObject = static_cast<const BaseObject*>(object);
112
113   const auto end = mInstanceTypes.end();
114   for( auto iter = mInstanceTypes.begin(); iter != end; ++iter )
115   {
116     if( iter->first == baseObject )
117     {
118       const auto& theType = iter->second;
119       if( !theType.empty() )
120       {
121         auto&& countIter = std::find_if( mInstanceCountContainer.begin(),
122                                          mInstanceCountContainer.end(),
123                                          [theType] ( const InstanceCountPair& instance )
124                                                    { return instance.first == theType; } );
125         if( countIter != mInstanceCountContainer.end() )
126         {
127           (*countIter).second--;
128         }
129       }
130       mInstanceTypes.erase( iter );
131       return;
132     }
133   }
134 }
135
136 std::size_t ObjectProfiler::GetMemorySize( const std::string& name, uint32_t count )
137 {
138   struct MemoryMemorySize
139   {
140     std::string name;
141     std::size_t memorySize;
142   };
143   MemoryMemorySize memoryMemorySizes[] =
144     {
145       { "Animation", ANIMATION_MEMORY_SIZE },
146       { "Constraint", CONSTRAINT_MEMORY_SIZE },
147       { "Actor", ACTOR_MEMORY_SIZE },
148       { "Layer", LAYER_MEMORY_SIZE },
149       { "CameraActor", CAMERA_ACTOR_MEMORY_SIZE },
150       { "Renderer", RENDERER_MEMORY_SIZE },
151       { "Geometry", GEOMETRY_MEMORY_SIZE },
152       { "PropertyBuffer", PROPERTY_BUFFER_MEMORY_SIZE },
153       { "TextureSet", TEXTURE_SET_MEMORY_SIZE },
154       { "Sampler", SAMPLER_MEMORY_SIZE },
155       { "Shader", SHADER_MEMORY_SIZE },
156     };
157
158   for( size_t i=0; i<sizeof(memoryMemorySizes)/sizeof(MemoryMemorySize); i++ )
159   {
160     if( memoryMemorySizes[i].name.compare(name) == 0 )
161     {
162       return count * memoryMemorySizes[i].memorySize;
163     }
164   }
165   return 0;
166 }
167
168 } // Adaptor
169 } // Internal
170 } // Dali