uint64_t timeToSleepUntil = 0;
int extraFramesDropped = 0;
+ const unsigned int renderToFboInterval = mEnvironmentOptions.GetRenderToFboInterval();
+ const bool renderToFboEnabled = 0u != renderToFboInterval;
+ unsigned int frameCount = 0u;
+
while( UpdateRenderReady( useElapsedTime, updateRequired, timeToSleepUntil ) )
{
LOG_UPDATE_RENDER_TRACE;
// RESIZE SURFACE
//////////////////////////////
+ const bool isRenderingToFbo = renderToFboEnabled && ( ( 0u == frameCount ) || ( 0u != frameCount % renderToFboInterval ) );
+ ++frameCount;
+
// The resizing will be applied in the next loop
bool surfaceResized = ShouldSurfaceBeResized();
if( DALI_UNLIKELY( surfaceResized ) )
Integration::UpdateStatus updateStatus;
AddPerformanceMarker( PerformanceInterface::UPDATE_START );
- mCore.Update( frameDelta, currentTime, nextFrameTime, updateStatus );
+ mCore.Update( frameDelta,
+ currentTime,
+ nextFrameTime,
+ updateStatus,
+ renderToFboEnabled,
+ isRenderingToFbo );
AddPerformanceMarker( PerformanceInterface::UPDATE_END );
unsigned int keepUpdatingStatus = updateStatus.KeepUpdating();
if( renderStatus.NeedsPostRender() )
{
- mRenderHelper.PostRender();
+ mRenderHelper.PostRender( isRenderingToFbo );
}
// Trigger event thread to request Update/Render thread to sleep if update not required
}
}
- // Sleep until at least the the default frame duration has elapsed. This will return immediately if the specified end-time has already passed.
- TimeService::SleepUntil( timeToSleepUntil );
+ // Render to FBO is intended to measure fps above 60 so sleep is not wanted.
+ if( 0u == renderToFboInterval )
+ {
+ // Sleep until at least the the default frame duration has elapsed. This will return immediately if the specified end-time has already passed.
+ TimeService::SleepUntil( timeToSleepUntil );
+ }
}
// Inform core of context destruction & shutdown EGL
mPanMinimumDistance(-1),
mPanMinimumEvents(-1),
mGlesCallTime( 0 ),
- mWindowWidth( 0 ),
- mWindowHeight( 0 ),
+ mWindowWidth( 0u ),
+ mWindowHeight( 0u ),
mThreadingMode( ThreadingMode::COMBINED_UPDATE_RENDER ),
- mRenderRefreshRate( 1 ),
+ mRenderRefreshRate( 1u ),
mGlesCallAccumulate( false ),
mMultiSamplingLevel( DEFAULT_MULTI_SAMPLING_LEVEL ),
mMaxTextureSize( 0 ),
mIndicatorVisibleMode( -1 ),
+ mRenderToFboInterval( 0u ),
mLogFunction( NULL )
{
ParseEnvironmentOptions();
return mIndicatorVisibleMode;
}
+unsigned int EnvironmentOptions::GetRenderToFboInterval() const
+{
+ return mRenderToFboInterval;
+}
+
bool EnvironmentOptions::PerformanceServerRequired() const
{
return ( ( GetPerformanceStatsLoggingOptions() > 0) ||
mIndicatorVisibleMode = indicatorVisibleMode;
}
}
+
+ mRenderToFboInterval = GetIntegerEnvironmentVariable( DALI_RENDER_TO_FBO, 0u );
}
} // Adaptor
-#ifndef __DALI_INTERNAL_ADAPTOR_ENVIRONMENT_OPTIONS_H__
-#define __DALI_INTERNAL_ADAPTOR_ENVIRONMENT_OPTIONS_H__
+#ifndef DALI_INTERNAL_ADAPTOR_ENVIRONMENT_OPTIONS_H
+#define DALI_INTERNAL_ADAPTOR_ENVIRONMENT_OPTIONS_H
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
*/
int GetIndicatorVisibleMode() const;
+ /**
+ * @brief Retrieves the interval of frames to be rendered into the Frame Buffer Object and the Frame Buffer.
+ *
+ * @return The number of frames that are going to be rendered into the Frame Buffer Object but the last one which is going to be rendered into the Frame Buffer.
+ */
+ unsigned int GetRenderToFboInterval() const;
+
private: // Internal
/**
int mMultiSamplingLevel; ///< The number of samples required in multisample buffers
unsigned int mMaxTextureSize; ///< The maximum texture size that GL can handle
int mIndicatorVisibleMode; ///< Indicator visible mode
+ unsigned int mRenderToFboInterval; ///< The number of frames that are going to be rendered into the Frame Buffer Object but the last one which is going to be rendered into the Frame Buffer.
Dali::Integration::Log::LogFunction mLogFunction;
} // Internal
} // Dali
-#endif // __DALI_INTERNAL_ADAPTOR_ENVIRONMENT_OPTIONS_H__
+#endif // DALI_INTERNAL_ADAPTOR_ENVIRONMENT_OPTIONS_H
-#ifndef __DALI_INTERNAL_ADAPTOR_ENVIRONMENT_VARIABLES_H__
-#define __DALI_INTERNAL_ADAPTOR_ENVIRONMENT_VARIABLES_H__
+#ifndef DALI_INTERNAL_ADAPTOR_ENVIRONMENT_VARIABLES_H
+#define DALI_INTERNAL_ADAPTOR_ENVIRONMENT_VARIABLES_H
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
#define DALI_ENV_INDICATOR_VISIBLE_MODE "DALI_INDICATOR_VISIBLE_MODE"
+#define DALI_RENDER_TO_FBO "DALI_RENDER_TO_FBO"
+
} // namespace Adaptor
} // namespace Internal
} // namespace Dali
-#endif // __DALI_INTERNAL_ADAPTOR_ENVIRONMENT_VARIABLES_H__
+#endif // DALI_INTERNAL_ADAPTOR_ENVIRONMENT_VARIABLES_H
return true;
}
-void RenderHelper::PostRender()
+void RenderHelper::PostRender( bool renderToFbo )
{
// Inform the gl implementation that rendering has finished before informing the surface
mGLES.PostRender();
- if( mSurface )
+ if( renderToFbo )
+ {
+ mGLES.Flush();
+ mGLES.Finish();
+ }
+ else
{
- // Inform the surface that rendering this frame has finished.
- mSurface->PostRender( *mEGL, mGLES, mDisplayConnection, mSurfaceReplaced, mSurfaceResized );
+ if( mSurface )
+ {
+ // Inform the surface that rendering this frame has finished.
+ mSurface->PostRender( *mEGL, mGLES, mDisplayConnection, mSurfaceReplaced, mSurfaceResized );
+ }
}
mSurfaceReplaced = false;
mSurfaceResized = false;
-#ifndef __DALI_INTERNAL_RENDER_HELPER_H__
-#define __DALI_INTERNAL_RENDER_HELPER_H__
+#ifndef DALI_INTERNAL_RENDER_HELPER_H
+#define DALI_INTERNAL_RENDER_HELPER_H
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
* Called after core has rendered the scene
*
* @note Called from render thread
+ *
+ * @param[in] renderToFbo Whether to render to a Frame Buffer Object.
*/
- void PostRender();
+ void PostRender( bool renderToFbo );
private:
} // namespace Dali
-#endif // __DALI_INTERNAL_RENDER_HELPER_H__
+#endif // DALI_INTERNAL_RENDER_HELPER_H
EglSyncImplementation* eglSyncImpl = mEglFactory->GetSyncImplementation();
- mCore = Integration::Core::New( *this, *mPlatformAbstraction, *mGLES, *eglSyncImpl, *mGestureManager, dataRetentionPolicy );
+ mCore = Integration::Core::New( *this,
+ *mPlatformAbstraction,
+ *mGLES,
+ *eglSyncImpl,
+ *mGestureManager,
+ dataRetentionPolicy ,
+ 0u != mEnvironmentOptions->GetRenderToFboInterval() );
const unsigned int timeInterval = mEnvironmentOptions->GetObjectProfilerInterval();
if( 0u < timeInterval )
// We always need the first update!
mStatus.keepUpdating = Integration::KeepUpdating::STAGE_KEEP_RENDERING;
- mCore = Dali::Integration::Core::New(
- mRenderController,
- mPlatformAbstraction,
- mGlAbstraction,
- mGlSyncAbstraction,
- mGestureManager,
- mDataRetentionPolicy);
+ mCore = Dali::Integration::Core::New( mRenderController,
+ mPlatformAbstraction,
+ mGlAbstraction,
+ mGlSyncAbstraction,
+ mGestureManager,
+ mDataRetentionPolicy,
+ false );
mCore->ContextCreated();
mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight );
unsigned int nextVSyncTime = mLastVSyncTime + intervalMilliseconds;
float elapsedSeconds = intervalMilliseconds / 1e3f;
- mCore->Update( elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus );
+ mCore->Update( elapsedSeconds, mLastVSyncTime, nextVSyncTime, mStatus, false, false );
GetRenderController().Initialize();