79cf21405669326b5d92aef659c7a57b1c6d85a1
[platform/core/uifw/dali-adaptor.git] / adaptors / base / performance-logging / performance-server.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 "performance-server.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/platform-abstraction.h>
23
24 // INTERNAL INCLUDES
25 #include <base/environment-options.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 namespace Adaptor
34 {
35
36 PerformanceServer::PerformanceServer( AdaptorInternalServices& adaptorServices,
37                                       const EnvironmentOptions& environmentOptions)
38 :mPlatformAbstraction( adaptorServices.GetPlatformAbstractionInterface() ),
39  mEnvironmentOptions( environmentOptions ),
40  mKernelTrace( adaptorServices.GetKernelTraceInterface() ),
41  mStatContextManager( *this ),
42  mStatisticsLogBitmask( 0 ),
43  mLoggingEnabled( false ),
44  mLogFunctionInstalled( false )
45 {
46   SetLogging( mEnvironmentOptions.GetPerformanceStatsLoggingOptions(),
47               mEnvironmentOptions.GetPerformanceTimeStampOutput(),
48               mEnvironmentOptions.GetPerformanceStatsLoggingFrequency());
49 }
50
51 PerformanceServer::~PerformanceServer()
52 {
53   if( mLogFunctionInstalled )
54   {
55     mEnvironmentOptions.UnInstallLogFunction();
56   }
57 }
58
59 void PerformanceServer::SetLogging( unsigned int statisticsLogOptions,
60                                     unsigned int timeStampOutput,
61                                     unsigned int logFrequency )
62 {
63   if( ( statisticsLogOptions == 0) && ( timeStampOutput == 0 ))
64   {
65     mLoggingEnabled = false;
66     return;
67   }
68
69   mStatisticsLogBitmask = statisticsLogOptions;
70   mPerformanceOutputBitmask = timeStampOutput;
71
72   mStatContextManager.SetLoggingLevel( mStatisticsLogBitmask, logFrequency);
73
74   mLoggingEnabled = true;
75 }
76
77 void PerformanceServer::SetLoggingFrequency( unsigned int logFrequency, ContextId contextId )
78 {
79   mStatContextManager.SetLoggingFrequency( logFrequency, contextId );
80 }
81
82 void PerformanceServer::EnableLogging( bool enable, ContextId contextId )
83 {
84   mStatContextManager.EnableLogging( enable, contextId );
85 }
86
87 PerformanceInterface::ContextId PerformanceServer::AddContext( const char* name )
88 {
89   // for adding custom contexts
90   return mStatContextManager.AddContext( name, PerformanceMarker::CUSTOM_EVENTS );
91 }
92
93 void PerformanceServer::RemoveContext( ContextId contextId )
94 {
95   mStatContextManager.RemoveContext( contextId );
96 }
97
98 void PerformanceServer::AddMarker( MarkerType markerType, ContextId contextId )
99 {
100   // called only for custom markers
101
102   if( !mLoggingEnabled )
103   {
104     return;
105   }
106
107   // This is only called from main event thread, but may overlap with internal AddMarker calls
108   // from other threads ( update, render etc).
109   boost::mutex::scoped_lock sharedDatalock( mDataMutex );
110
111   // Get the time stamp
112   unsigned int seconds = 0;
113   unsigned int microseconds = 0;
114   mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
115
116   // Create a marker
117   PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ) );
118
119   // get the marker description for this context, e.g SIZE_NEGOTIATION_START
120   const char* const description = mStatContextManager.GetMarkerDescription( markerType, contextId );
121
122   // log it
123   LogMarker( marker, description );
124
125   // Add custom marker to statistics context manager
126   mStatContextManager.AddCustomMarker( marker, contextId );
127
128 }
129
130 void PerformanceServer::AddMarker( MarkerType markerType )
131 {
132   // called only for internal markers
133
134   if( !mLoggingEnabled )
135   {
136     return;
137   }
138
139   // AddMarker can be called from multiple threads, to avoid problems
140   // with updating contexts and the kernel trace, lock here.
141   boost::mutex::scoped_lock sharedDatalock( mDataMutex );
142
143   if( markerType == VSYNC )
144   {
145     // make sure log function is installed, note this will be called only from v-sync thread
146     // if the v-sync thread has already installed one, it won't make any difference.
147     if( ! mLogFunctionInstalled )
148     {
149       mEnvironmentOptions.InstallLogFunction();
150       mLogFunctionInstalled = true;
151     }
152   }
153
154   // Get the time
155   unsigned int seconds = 0;
156   unsigned int microseconds = 0;
157   mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
158
159   // Create a marker
160   PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ) );
161
162   // log it
163   LogMarker(marker, marker.GetName() );
164
165   // Add internal marker to statistics context manager
166   mStatContextManager.AddInternalMarker( marker );
167
168 }
169
170 void PerformanceServer::LogContextStatistics( const char* const text )
171 {
172   Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, text );
173 }
174
175 void PerformanceServer::LogMarker( const PerformanceMarker& marker, const char* const description )
176 {
177
178
179
180   // log to kernel trace
181   if( mPerformanceOutputBitmask & OUTPUT_KERNEL_TRACE )
182   {
183     // name will be something like UPDATE_START or UPDATE_END
184     mKernelTrace.Trace( description );
185   }
186
187   // log to Dali log
188   if ( mPerformanceOutputBitmask & OUTPUT_DALI_LOG )
189   {
190     Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo,
191                                     "%d.%06d (seconds), %s\n",
192                                     marker.GetTimeStamp().seconds,
193                                     marker.GetTimeStamp().microseconds,
194                                     description);
195   }
196 }
197
198
199 } // namespace Internal
200
201 } // namespace Adaptor
202
203 } // namespace Dali