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