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