1984304723da36963c26c07d4cbf71e68f2f1b40
[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  mSystemTrace( adaptorServices.GetSystemTraceInterface() ),
42  mNetworkServer( adaptorServices, environmentOptions ),
43  mStatContextManager( *this ),
44  mStatisticsLogBitmask( 0 ),
45  mNetworkControlEnabled( mEnvironmentOptions.GetNetworkControlMode()),
46  mLoggingEnabled( false ),
47  mLogFunctionInstalled( false )
48 {
49   SetLogging( mEnvironmentOptions.GetPerformanceStatsLoggingOptions(),
50               mEnvironmentOptions.GetPerformanceTimeStampOutput(),
51               mEnvironmentOptions.GetPerformanceStatsLoggingFrequency());
52
53   if( mNetworkControlEnabled )
54   {
55     mLoggingEnabled  = true;
56     mNetworkServer.Start();
57   }
58 }
59
60 PerformanceServer::~PerformanceServer()
61 {
62   if( mNetworkControlEnabled )
63   {
64     mNetworkServer.Stop();
65   }
66
67   if( mLogFunctionInstalled )
68   {
69     mEnvironmentOptions.UnInstallLogFunction();
70   }
71 }
72
73 void PerformanceServer::SetLogging( unsigned int statisticsLogOptions,
74                                     unsigned int timeStampOutput,
75                                     unsigned int logFrequency )
76 {
77   mStatisticsLogBitmask = statisticsLogOptions;
78   mPerformanceOutputBitmask = timeStampOutput;
79
80   mStatContextManager.SetLoggingLevel( mStatisticsLogBitmask, logFrequency);
81
82   if( ( mStatisticsLogBitmask == 0) && ( mPerformanceOutputBitmask == 0 ))
83   {
84     mLoggingEnabled = false;
85   }
86   else
87   {
88     mLoggingEnabled = true;
89   }
90 }
91
92 void PerformanceServer::SetLoggingFrequency( unsigned int logFrequency, ContextId contextId )
93 {
94   mStatContextManager.SetLoggingFrequency( logFrequency, contextId );
95 }
96
97 void PerformanceServer::EnableLogging( bool enable, ContextId contextId )
98 {
99   mStatContextManager.EnableLogging( enable, contextId );
100 }
101
102 PerformanceInterface::ContextId PerformanceServer::AddContext( const char* name )
103 {
104   // for adding custom contexts
105   return mStatContextManager.AddContext( name, PerformanceMarker::CUSTOM_EVENTS );
106 }
107
108 void PerformanceServer::RemoveContext( ContextId contextId )
109 {
110   mStatContextManager.RemoveContext( contextId );
111 }
112
113 void PerformanceServer::AddMarker( MarkerType markerType, ContextId contextId )
114 {
115   // called only for custom markers
116
117   if( !mLoggingEnabled )
118   {
119     return;
120   }
121
122   // This is only called from main event thread, but may overlap with internal AddMarker calls
123   // from other threads ( update, render etc).
124   boost::mutex::scoped_lock sharedDatalock( mDataMutex );
125
126   // Get the time stamp
127   unsigned int seconds = 0;
128   unsigned int microseconds = 0;
129   mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
130
131   // Create a marker
132   PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ) );
133
134   // get the marker description for this context, e.g SIZE_NEGOTIATION_START
135   const char* const description = mStatContextManager.GetMarkerDescription( markerType, contextId );
136
137   // log it
138   LogMarker( marker, description );
139
140   // Add custom marker to statistics context manager
141   mStatContextManager.AddCustomMarker( marker, contextId );
142
143 }
144
145 void PerformanceServer::AddMarker( MarkerType markerType )
146 {
147   // called only for internal markers
148
149   if( !mLoggingEnabled )
150   {
151     return;
152   }
153
154   // AddMarker can be called from multiple threads, to avoid problems
155   // with updating contexts and the kernel trace, lock here.
156   boost::mutex::scoped_lock sharedDatalock( mDataMutex );
157
158   if( markerType == VSYNC )
159   {
160     // make sure log function is installed, note this will be called only from v-sync thread
161     // if the v-sync thread has already installed one, it won't make any difference.
162     if( ! mLogFunctionInstalled )
163     {
164       mEnvironmentOptions.InstallLogFunction();
165       mLogFunctionInstalled = true;
166     }
167   }
168
169   // Get the time
170   unsigned int seconds = 0;
171   unsigned int microseconds = 0;
172   mPlatformAbstraction.GetTimeMicroseconds( seconds, microseconds );
173
174   // Create a marker
175   PerformanceMarker marker( markerType, FrameTimeStamp( 0, seconds, microseconds ) );
176
177   // log it
178   LogMarker(marker, marker.GetName() );
179
180   // Add internal marker to statistics context manager
181   mStatContextManager.AddInternalMarker( marker );
182
183 }
184
185 void PerformanceServer::LogContextStatistics( const char* const text )
186 {
187   Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo, text );
188 }
189
190 void PerformanceServer::LogMarker( const PerformanceMarker& marker, const char* const description )
191 {
192   // log to the network ( this is thread safe)
193   if( mNetworkControlEnabled )
194   {
195     mNetworkServer.TransmitMarker( marker, description );
196   }
197
198   // log to kernel trace
199   if( mPerformanceOutputBitmask & OUTPUT_KERNEL_TRACE )
200   {
201     // description will be something like UPDATE_START or UPDATE_END
202     mKernelTrace.Trace( marker, description );
203   }
204
205   // log to system trace
206   if( mPerformanceOutputBitmask & OUTPUT_SYSTEM_TRACE )
207   {
208     mSystemTrace.Trace( marker, description );
209   }
210
211   // log to Dali log
212   if ( mPerformanceOutputBitmask & OUTPUT_DALI_LOG )
213   {
214     Integration::Log::LogMessage( Dali::Integration::Log::DebugInfo,
215                                     "%d.%06d (seconds), %s\n",
216                                     marker.GetTimeStamp().seconds,
217                                     marker.GetTimeStamp().microseconds,
218                                     description);
219   }
220 }
221
222
223 } // namespace Internal
224
225 } // namespace Adaptor
226
227 } // namespace Dali