#include <base/interfaces/trigger-event-interface.h>
#include <base/interfaces/performance-interface.h>
#include <base/interfaces/vsync-monitor-interface.h>
+#include <base/interfaces/kernel-trace-interface.h>
#include <internal/common/render-surface-impl.h> // @todo move to base/interfaces
*/
virtual PerformanceInterface* GetPerformanceInterface() = 0;
+ /**
+ * @return kernel trace interface
+ */
+ virtual KernelTraceInterface& GetKernelTraceInterface() = 0;
protected:
--- /dev/null
+#ifndef __DALI_INTERNAL_BASE_KERNEL_TRACE_INTERFACE_H__
+#define __DALI_INTERNAL_BASE_KERNEL_TRACE_INTERFACE_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <string>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+/**
+ * Abstract Kernel Tracing Interface.
+ * Used to log trace messages to the kernel.
+ * E.g. On Linux this will use ftrace
+ *
+ */
+class KernelTraceInterface
+{
+
+public:
+
+ /**
+ * Write a trace message
+ * @param traceMessage trace message
+ */
+ virtual void Trace( const std::string& traceMessage ) = 0;
+
+protected:
+
+ /**
+ * Constructor
+ */
+ KernelTraceInterface()
+ {
+ }
+
+ /**
+ * virtual destructor
+ */
+ virtual ~KernelTraceInterface()
+ {
+ }
+
+ // Undefined copy constructor.
+ KernelTraceInterface( const KernelTraceInterface& );
+
+ // Undefined assignment operator.
+ KernelTraceInterface& operator=( const KernelTraceInterface& );
+};
+
+} // namespace Internal
+
+} // namespace Adaptor
+
+} // namespace Dali
+
+#endif
*/
enum LogLevel
{
- DISABLED = 0,
- LOG_UPDATE_RENDER = 1 << 0, ///< Bit 0, log update and render times
- LOG_EVENT_PROCESS = 1 << 1, ///< Bit 1, log event process times
+ DISABLED = 0,
+ LOG_UPDATE_RENDER = 1 << 0, ///< Bit 0, log update and render times
+ LOG_EVENT_PROCESS = 1 << 1, ///< Bit 1, log event process times
+ LOG_EVENTS_TO_KERNEL = 1 << 2, ///< Bit 2, log all events to kernel trace
};
/**
{
PerformanceInterface* PerformanceInterfaceFactory::CreateInterface(
- Integration::PlatformAbstraction& platformAbstraction,
+ AdaptorInternalServices& adaptorServices,
const LogOptions& logOptions )
{
- return new PerformanceServer( platformAbstraction, logOptions );
+ return new PerformanceServer( adaptorServices, logOptions );
}
//
// INTERNAL INCLUDES
-#include <base/interfaces/performance-interface.h>
-#include <dali/integration-api/platform-abstraction.h>
+#include <base/interfaces/adaptor-internal-services.h>
#include <dali/integration-api/debug.h>
#include <base/log-options.h>
/**
* Create a new concrete implementation of the performance interface.
- * @param platformAbstraction platform abstraction
+ * @param adaptorServices adaptor internal services
* @param logOptions log options
* @return pointer to a new performance interface
*/
- static PerformanceInterface* CreateInterface( Integration::PlatformAbstraction& platformAbstraction,
+ static PerformanceInterface* CreateInterface( AdaptorInternalServices& adaptorServices,
const LogOptions& logOptions );
};
namespace Adaptor
{
+namespace
+{
+
+struct NamePair
+{
+ PerformanceMarker::MarkerType type;
+ const char* name;
+};
+
+const NamePair MarkerLookup[] =
+{
+ { PerformanceMarker::V_SYNC , "V_SYNC" },
+ { PerformanceMarker::UPDATE_START , "UPDATE_START" },
+ { PerformanceMarker::UPDATE_END , "UPDATE_END" },
+ { PerformanceMarker::RENDER_START , "RENDER_START" },
+ { PerformanceMarker::RENDER_END , "RENDER_END" },
+ { PerformanceMarker::SWAP_START , "SWAP_START" },
+ { PerformanceMarker::SWAP_END , "SWAP_END" },
+ { PerformanceMarker::PROCESS_EVENTS_START, "PROCESS_EVENT_START" },
+ { PerformanceMarker::PROCESS_EVENTS_END, "PROCESS_EVENT_END" },
+ { PerformanceMarker::PAUSED , "PAUSED" },
+ { PerformanceMarker::RESUME , "RESUMED" }
+};
+}
PerformanceMarker::PerformanceMarker( MarkerType type )
:mType(type)
{
{
}
+const char* PerformanceMarker::GetName( ) const
+{
+ return MarkerLookup[ mType ].name;
+}
+
unsigned int PerformanceMarker::MicrosecondDiff( const PerformanceMarker& start,const PerformanceMarker& end )
{
return FrameTimeStamp::MicrosecondDiff( start.mTimeStamp, end.mTimeStamp );
public:
/**
- * enum for difference performance markers
+ * enum for difference performance markers.
+ * Please modify the name lookup table in performance-marker.cpp
+ * file if adding new markers.
*/
enum MarkerType
{
- V_SYNC , ///< V-Sync
+ V_SYNC = 0, ///< V-Sync
UPDATE_START , ///< Update start
UPDATE_END , ///< Update end
RENDER_START , ///< Render start
return mType;
}
+ /**
+ * @return the name of the marker
+ */
+ const char* GetName() const;
+
/**
* @param start the start marker
* @param end the end marker
}
-PerformanceServer::PerformanceServer( Integration::PlatformAbstraction& platformAbstraction,
+PerformanceServer::PerformanceServer( AdaptorInternalServices& adaptorServices,
const LogOptions& logOptions)
:mLoggingEnabled( false),
mLogFunctionInstalled( false ),
mLogFrequencyMicroseconds( 0),
- mPlatformAbstraction( platformAbstraction ),
- mLogOptions(logOptions)
+ mPlatformAbstraction( adaptorServices.GetPlatformAbstractionInterface() ),
+ mLogOptions(logOptions),
+ mKernelTrace( adaptorServices.GetKernelTraceInterface() )
{
SetLogging( mLogOptions.GetPerformanceLoggingLevel(), mLogOptions.GetFrameRateLoggingFrequency());
}
// store the marker
mMarkers.PushBack( marker );
+ if( mLogLevel & LOG_EVENTS_TO_KERNEL )
+ {
+ mKernelTrace.Trace(marker.GetName());
+ }
+
// only log on the v-sync thread, so we have less impact on update/render
if( marker.GetType() != PerformanceMarker::V_SYNC )
{
//
// INTERNAL INCLUDES
-#include <base/interfaces/performance-interface.h>
#include <base/performance-logging/frame-time-stats.h>
#include <dali/public-api/common/dali-vector.h>
-#include <dali/integration-api/platform-abstraction.h>
+#include <base/interfaces/adaptor-internal-services.h>
// EXTERNAL INCLUDES
#include <boost/thread/mutex.hpp>
/**
* Constructor
- * @param platformAbstraction platform abstraction
+ * @param adaptorServices adaptor internal services
* @param logOptions log options
*/
- PerformanceServer( Integration::PlatformAbstraction& platformAbstraction,
+ PerformanceServer( AdaptorInternalServices& adaptorServices,
const LogOptions& logOptions );
/**
MarkerVector mMarkers; ///< vector of markers
boost::mutex mDataMutex; ///< mutex
const LogOptions& mLogOptions; ///< log options
+ KernelTraceInterface& mKernelTrace; ///< kernel trace interface
};
if( mLogOptions.GetPerformanceLoggingLevel() > 0 )
{
- mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *mPlatformAbstraction, mLogOptions );
+ mPerformanceInterface = PerformanceInterfaceFactory::CreateInterface( *this, mLogOptions );
}
mCallbackManager = CallbackManager::New();
return mVSyncMonitor;
}
+KernelTraceInterface& Adaptor::GetKernelTraceInterface()
+{
+ return mKernelTracer;
+}
+
PerformanceInterface* Adaptor::GetPerformanceInterface()
{
return mPerformanceInterface;
#include <internal/common/drag-and-drop-detector-impl.h>
#include <internal/common/damage-observer.h>
#include <internal/common/window-visibility-observer.h>
+#include <internal/common/kernel-trace.h>
namespace Dali
{
*/
void NotifyLanguageChanged();
-public: //BaseAdaptorInterfaces
+public: //AdaptorInternalServices
/**
- * @copydoc Dali::Internal::Adaptor::BaseAdaptorInterface::GetPlatformAbstractionInterface()
+ * @copydoc Dali::Internal::Adaptor::AdaptorInternalServices::GetPlatformAbstractionInterface()
*/
virtual Dali::Integration::PlatformAbstraction& GetPlatformAbstractionInterface();
/**
- * @copydoc Dali::Internal::Adaptor::BaseAdaptorInterface::GetGlesInterface()
+ * @copydoc Dali::Internal::Adaptor::AdaptorInternalServices::GetGlesInterface()
*/
virtual Dali::Integration::GlAbstraction& GetGlesInterface();
/**
- * @copydoc Dali::Internal::Adaptor::BaseAdaptorInterface::GetEGLFactoryInterface()
+ * @copydoc Dali::Internal::Adaptor::AdaptorInternalServices::GetEGLFactoryInterface()
*/
virtual EglFactoryInterface& GetEGLFactoryInterface() const;
/**
- * @copydoc Dali::Internal::Adaptor::BaseAdaptorInterface::GetTriggerEventInterface()
+ * @copydoc Dali::Internal::Adaptor::AdaptorInternalServices::GetTriggerEventInterface()
*/
virtual TriggerEventInterface& GetTriggerEventInterface();
/**
- * @copydoc Dali::Internal::Adaptor::BaseAdaptorInterface::GetRenderSurfaceInterface()
+ * @copydoc Dali::Internal::Adaptor::AdaptorInternalServices::GetRenderSurfaceInterface()
*/
virtual RenderSurface* GetRenderSurfaceInterface();
/**
- * @copydoc Dali::Internal::Adaptor::BaseAdaptorInterface::GetVSyncMonitorInterface()
+ * @copydoc Dali::Internal::Adaptor::AdaptorInternalServices::GetVSyncMonitorInterface()
*/
virtual VSyncMonitorInterface* GetVSyncMonitorInterface();
/**
- * @copydoc Dali::Internal::Adaptor::BaseAdaptorInterface::GetPerformanceInterface()
+ * @copydoc Dali::Internal::Adaptor::AdaptorInternalServices::GetPerformanceInterface()
*/
virtual PerformanceInterface* GetPerformanceInterface();
+ /**
+ * copydoc Dali::Internal::Adaptor::AdaptorInternalServices::GetKernelTraceInterface()
+ */
+ virtual KernelTraceInterface& GetKernelTraceInterface();
+
public: // Signals
/**
DeviceLayout mBaseLayout; ///< The base layout of the application
LogOptions mLogOptions; ///< log options
PerformanceInterface* mPerformanceInterface; ///< Performance interface
+ KernelTrace mKernelTracer;
public:
inline static Adaptor& GetImplementation(Dali::Adaptor& adaptor) {return *adaptor.mImpl;}
};
$(tizen_adaptor_internal_src_dir)/imf-manager-impl.cpp \
$(tizen_adaptor_internal_src_dir)/indicator-impl.cpp \
$(tizen_adaptor_internal_src_dir)/indicator-buffer.cpp \
+ $(tizen_adaptor_internal_src_dir)/kernel-trace.cpp \
$(tizen_adaptor_internal_src_dir)/key-impl.cpp \
$(tizen_adaptor_internal_src_dir)/locale-utils.cpp \
$(tizen_adaptor_internal_src_dir)/native-bitmap-buffer-impl.cpp \
--- /dev/null
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// CLASS HEADER
+#include "kernel-trace.h"
+
+// INTERNAL HEADERS
+#include <dali/integration-api/debug.h>
+
+// EXTERNAL HEADERS
+#include <fcntl.h>
+#include <stdio.h>
+
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+namespace
+{
+const char* TRACE_MARKER_FILE = "/sys/kernel/debug/tracing/trace_marker";
+const char* SPI_PREFIX = "SPI_EV_DALI_"; ///< prefix to let the SPI tool know it should read the trace
+}// un-named name space
+
+KernelTrace::KernelTrace()
+: mFileDescriptor( 0 ),
+ mLoggedError( false )
+{
+}
+
+KernelTrace::~KernelTrace()
+{
+ if( mFileDescriptor )
+ {
+ close( mFileDescriptor );
+ }
+}
+
+// If this function doesn't appear to work, you can test manually on the device.
+// $ cd /sys/kernel/debug/tracing
+//
+// If the folder doesn't exist then the kernel needs to be re-built with ftrace enabled
+// If it does exist, then you can continue to test ftrace is working:
+//
+// $ echo 1 > tracing_enabled
+// $ echo "test" > trace_marker
+// $ cat trace
+// should print out test message
+// If the message did not get added to the trace, then check you have write permissions to the trace_marker file.
+//
+//
+void KernelTrace::Trace( const std::string& traceMessage )
+{
+ // Open the trace_marker file
+ if( mFileDescriptor == 0 )
+ {
+ mFileDescriptor = open( TRACE_MARKER_FILE , O_WRONLY);
+ if( mFileDescriptor == -1 )
+ {
+ // we want to keep trying to open it, so it will start working if someone fixes
+ // the permissions on the trace marker
+ mFileDescriptor = 0;
+
+ // first time we fail to open the file, log an error
+ if( !mLoggedError )
+ {
+ mLoggedError = true;
+ DALI_LOG_ERROR("Failed to open /sys/kernel/debug/tracing/trace_marker for writing please check file permissions.");
+ }
+
+ }
+ }
+
+ if( mFileDescriptor > 0 )
+ {
+ std::string msg( SPI_PREFIX );
+ msg+=traceMessage;
+
+ int ret = write( mFileDescriptor, msg.c_str(), msg.length() );
+ // if it failed then close the file description and try again next time we trace
+ if( ret < 0 )
+ {
+ close( mFileDescriptor );
+ mFileDescriptor = 0;
+ }
+ }
+}
+
+} // namespace Internal
+
+} // namespace Adaptor
+
+} // namespace Dali
+
--- /dev/null
+#ifndef __DALI_INTERNAL_ADAPTOR_KERNEL_TRACE_H__
+#define __DALI_INTERNAL_ADAPTOR_KERNEL_TRACE_H__
+
+//
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <base/interfaces/kernel-trace-interface.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace Adaptor
+{
+
+/**
+ * Concrete Kernel Tracing Interface.
+ * Used to log trace messages to the kernel using ftrace.
+ *
+ */
+class KernelTrace : public KernelTraceInterface
+{
+public:
+
+ /**
+ * Constructor
+ */
+ KernelTrace();
+
+ /**
+ * Destructor
+ */
+ virtual ~KernelTrace();
+
+ /**
+ * @copydoc KernelTracerInterface::KernelTrace()
+ */
+ virtual void Trace( const std::string& traceMessage );
+
+private:
+
+ int mFileDescriptor;
+ bool mLoggedError:1;
+
+};
+
+} // namespace Internal
+
+} // namespace Adaptor
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_ADAPTOR_KERNEL_TRACE_H__