7d86bf05af88b255e711fab9bc98a10bda754729
[platform/core/uifw/dali-adaptor.git] / adaptors / common / object-profiler.cpp
1 /*
2  * Copyright (c) 2014 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 "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/common/stage.h>
26 #include <dali/public-api/object/ref-object.h>
27 #include <dali/public-api/object/base-object.h>
28 #include <dali/public-api/object/type-registry.h>
29
30 using std::string;
31 using namespace Dali::Integration::Profiling;
32
33 namespace Dali
34 {
35 namespace Internal
36 {
37 namespace Adaptor
38 {
39
40 ObjectProfiler::ObjectProfiler( unsigned int timeInterval )
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   mObjectRegistry = Dali::Stage::GetCurrent().GetObjectRegistry();
45
46   mTimer = Dali::Timer::New( timeInterval * 1000 );
47   mTimer.TickSignal().Connect( this, &ObjectProfiler::OnTimeout );
48   mTimer.Start();
49
50   mObjectRegistry.ObjectCreatedSignal().Connect( this, &ObjectProfiler::OnObjectCreated );
51   mObjectRegistry.ObjectDestroyedSignal().Connect( this, &ObjectProfiler::OnObjectDestroyed );
52 }
53
54 ObjectProfiler::~ObjectProfiler()
55 {
56 }
57
58 void ObjectProfiler::DisplayInstanceCounts()
59 {
60   InstanceCountMapIterator iter = mInstanceCountMap.begin();
61   InstanceCountMapIterator end = mInstanceCountMap.end();
62
63   for( ; iter != end; iter++ )
64   {
65     int memorySize = GetMemorySize(iter->first, iter->second);
66     if( memorySize > 0 )
67     {
68       LogMessage( Debug::DebugInfo, "%-30s: % 4d  Memory MemorySize: ~% 6.1f kB\n",
69                   iter->first.c_str(), iter->second, memorySize / 1024.0f );
70     }
71     else
72     {
73       LogMessage( Debug::DebugInfo, "%-30s: % 4d\n",
74                   iter->first.c_str(), iter->second );
75     }
76   }
77   LogMessage(Debug::DebugInfo, "\n");
78 }
79
80 bool ObjectProfiler::OnTimeout()
81 {
82   DisplayInstanceCounts();
83   return true;
84 }
85
86 void ObjectProfiler::OnObjectCreated(BaseHandle handle)
87 {
88   string theType = handle.GetTypeName();
89   if( theType.empty() )
90   {
91     DALI_LOG_ERROR("Object created from an unregistered type\n");
92     theType = "<Unregistered>";
93   }
94
95   mInstanceTypes.push_back(InstanceTypePair(&handle.GetBaseObject(), theType));
96
97   InstanceCountMapIterator iter = mInstanceCountMap.find(theType);
98   if( iter == mInstanceCountMap.end() )
99   {
100     InstanceCountPair instanceCount(theType, 1);
101     mInstanceCountMap.insert(instanceCount);
102   }
103   else
104   {
105     iter->second++;
106   }
107 }
108
109 void ObjectProfiler::OnObjectDestroyed(const Dali::RefObject* object)
110 {
111   const BaseObject* baseObject = static_cast<const BaseObject*>(object);
112
113   InstanceTypes::iterator end = mInstanceTypes.end();
114   for( InstanceTypes::iterator iter = mInstanceTypes.begin(); iter != end; iter++)
115   {
116     if( iter->first == baseObject )
117     {
118       const std::string& theType = iter->second;
119       if( !theType.empty() )
120       {
121         InstanceCountMapIterator countIter = mInstanceCountMap.find(theType);
122         if( countIter != mInstanceCountMap.end() )
123         {
124           countIter->second--;
125         }
126       }
127       mInstanceTypes.erase( iter );
128       break;
129     }
130   }
131 }
132
133 int ObjectProfiler::GetMemorySize(const std::string& name, int count)
134 {
135   struct MemoryMemorySize
136   {
137     std::string name;
138     int memorySize;
139   };
140   MemoryMemorySize memoryMemorySizes[] =
141     {
142       { "Animation", ANIMATION_MEMORY_SIZE },
143       { "Constraint", CONSTRAINT_MEMORY_SIZE },
144       { "Actor", ACTOR_MEMORY_SIZE },
145       { "Layer", LAYER_MEMORY_SIZE },
146       { "CameraActor", CAMERA_ACTOR_MEMORY_SIZE },
147       { "Image", IMAGE_MEMORY_SIZE },
148       { "Renderer", RENDERER_MEMORY_SIZE },
149       { "Geometry", GEOMETRY_MEMORY_SIZE },
150       { "PropertyBuffer", PROPERTY_BUFFER_MEMORY_SIZE },
151       { "TextureSet", TEXTURE_SET_MEMORY_SIZE },
152       { "Sampler", SAMPLER_MEMORY_SIZE },
153       { "Shader", SHADER_MEMORY_SIZE },
154     };
155
156   for( size_t i=0; i<sizeof(memoryMemorySizes)/sizeof(MemoryMemorySize); i++ )
157   {
158     if( memoryMemorySizes[i].name.compare(name) == 0 )
159     {
160       return count * memoryMemorySizes[i].memorySize;
161     }
162   }
163   return 0;
164 }
165
166 } // Adaptor
167 } // Internal
168 } // Dali