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