9903b79cb7f2d34e5d9c1df3faddc9bc54367756
[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/actors/image-actor.h>
26 #include <dali/public-api/common/stage.h>
27 #include <dali/public-api/object/ref-object.h>
28 #include <dali/public-api/object/base-object.h>
29 #include <dali/public-api/object/type-registry.h>
30
31 using std::string;
32 using namespace Dali::Integration::Profiling;
33
34 namespace Dali
35 {
36 namespace Internal
37 {
38 namespace Adaptor
39 {
40
41 ObjectProfiler::ObjectProfiler( unsigned int timeInterval )
42 {
43   // This class must be created after the Stage; this means it doesn't count the initial objects
44   // that are created by the stage (base layer, default camera actor)
45   mObjectRegistry = Dali::Stage::GetCurrent().GetObjectRegistry();
46
47   mTimer = Dali::Timer::New( timeInterval * 1000 );
48   mTimer.TickSignal().Connect( this, &ObjectProfiler::OnTimeout );
49   mTimer.Start();
50
51   mObjectRegistry.ObjectCreatedSignal().Connect( this, &ObjectProfiler::OnObjectCreated );
52   mObjectRegistry.ObjectDestroyedSignal().Connect( this, &ObjectProfiler::OnObjectDestroyed );
53 }
54
55 ObjectProfiler::~ObjectProfiler()
56 {
57 }
58
59 void ObjectProfiler::DisplayInstanceCounts()
60 {
61   InstanceCountMapIterator iter = mInstanceCountMap.begin();
62   InstanceCountMapIterator end = mInstanceCountMap.end();
63
64   for( ; iter != end; iter++ )
65   {
66     int memorySize = GetMemorySize(iter->first, iter->second);
67     if( memorySize > 0 )
68     {
69       LogMessage( Debug::DebugInfo, "%-30s: % 4d  Memory MemorySize: ~% 6.1f kB\n",
70                   iter->first.c_str(), iter->second, memorySize / 1024.0f );
71     }
72     else
73     {
74       LogMessage( Debug::DebugInfo, "%-30s: % 4d\n",
75                   iter->first.c_str(), iter->second );
76     }
77   }
78   LogMessage(Debug::DebugInfo, "\n");
79
80   int quadCount = 0;
81
82   // Count number of quads:
83
84   for( InstanceTypes::iterator iter = mInstanceTypes.begin(), end = mInstanceTypes.end(); iter != end; ++iter )
85   {
86     if( iter->second.compare("ImageActor") == 0 )
87     {
88       BaseHandle handle(iter->first);
89       Dali::ImageActor imageActor = Dali::ImageActor::DownCast(handle);
90       if( imageActor )
91       {
92         if( imageActor.GetStyle() == Dali::ImageActor::STYLE_QUAD )
93         {
94           quadCount++;
95         }
96       }
97     }
98   }
99
100   LogMessage(Debug::DebugInfo, "Number of image actors using Quad style: %d\n", quadCount);
101 }
102
103 bool ObjectProfiler::OnTimeout()
104 {
105   DisplayInstanceCounts();
106   return true;
107 }
108
109 void ObjectProfiler::OnObjectCreated(BaseHandle handle)
110 {
111   string theType = handle.GetTypeName();
112   if( theType.empty() )
113   {
114     DALI_LOG_ERROR("Object created from an unregistered type\n");
115     theType = "<Unregistered>";
116   }
117
118   mInstanceTypes.push_back(InstanceTypePair(&handle.GetBaseObject(), theType));
119
120   InstanceCountMapIterator iter = mInstanceCountMap.find(theType);
121   if( iter == mInstanceCountMap.end() )
122   {
123     InstanceCountPair instanceCount(theType, 1);
124     mInstanceCountMap.insert(instanceCount);
125   }
126   else
127   {
128     iter->second++;
129   }
130 }
131
132 void ObjectProfiler::OnObjectDestroyed(const Dali::RefObject* object)
133 {
134   const BaseObject* baseObject = static_cast<const BaseObject*>(object);
135
136   InstanceTypes::iterator end = mInstanceTypes.end();
137   for( InstanceTypes::iterator iter = mInstanceTypes.begin(); iter != end; iter++)
138   {
139     if( iter->first == baseObject )
140     {
141       const std::string& theType = iter->second;
142       if( !theType.empty() )
143       {
144         InstanceCountMapIterator countIter = mInstanceCountMap.find(theType);
145         if( countIter != mInstanceCountMap.end() )
146         {
147           countIter->second--;
148         }
149       }
150       mInstanceTypes.erase( iter );
151       break;
152     }
153   }
154 }
155
156 int ObjectProfiler::GetMemorySize(const std::string& name, int count)
157 {
158   struct MemoryMemorySize
159   {
160     std::string name;
161     int memorySize;
162   };
163   MemoryMemorySize memoryMemorySizes[] =
164     {
165       { "Animation", ANIMATION_MEMORY_SIZE },
166       { "Constraint", CONSTRAINT_MEMORY_SIZE },
167       { "Actor", ACTOR_MEMORY_SIZE },
168       { "Layer", LAYER_MEMORY_SIZE },
169       { "CameraActor", CAMERA_ACTOR_MEMORY_SIZE },
170       { "ImageActor", IMAGE_ACTOR_MEMORY_SIZE },
171       { "Image", IMAGE_MEMORY_SIZE },
172       { "Renderer", RENDERER_MEMORY_SIZE },
173       { "Geometry", GEOMETRY_MEMORY_SIZE },
174       { "PropertyBuffer", PROPERTY_BUFFER_MEMORY_SIZE },
175       { "Material", MATERIAL_MEMORY_SIZE },
176       { "Sampler", SAMPLER_MEMORY_SIZE },
177       { "Shader", SHADER_MEMORY_SIZE },
178     };
179
180   for( size_t i=0; i<sizeof(memoryMemorySizes)/sizeof(MemoryMemorySize); i++ )
181   {
182     if( memoryMemorySizes[i].name.compare(name) == 0 )
183     {
184       return count * memoryMemorySizes[i].memorySize;
185     }
186   }
187   return 0;
188 }
189
190 } // Adaptor
191 } // Internal
192 } // Dali