// 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();
namespace Integration
{
-Core* Core::New(RenderController& renderController, PlatformAbstraction& platformAbstraction,
- GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction, GestureManager& gestureManager, ResourcePolicy::DataRetention policy )
+Core* Core::New( RenderController& renderController,
+ PlatformAbstraction& platformAbstraction,
+ GlAbstraction& glAbstraction,
+ GlSyncAbstraction& glSyncAbstraction,
+ GestureManager& gestureManager,
+ ResourcePolicy::DataRetention policy,
+ bool renderToFboEnabled )
{
Core* instance = new Core;
- instance->mImpl = new Internal::Core( renderController, platformAbstraction, glAbstraction, glSyncAbstraction, gestureManager, policy );
+ instance->mImpl = new Internal::Core( renderController,
+ platformAbstraction,
+ glAbstraction,
+ glSyncAbstraction,
+ gestureManager,
+ policy,
+ renderToFboEnabled );
return instance;
}
return mImpl->GetMaximumUpdateCount();
}
-void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, UpdateStatus& status )
+ void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo )
{
- mImpl->Update( elapsedSeconds, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds, status );
+ mImpl->Update( elapsedSeconds, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds, status, renderToFboEnabled, isRenderingToFbo );
}
void Core::Render( RenderStatus& status )
* @param[in] policy The data retention policy. This depends on application setting
* and platform support. Dali should honour this policy when deciding to discard
* intermediate resource data.
+ * @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled.
* @return A newly allocated Core.
*/
- static Core* New(RenderController& renderController,
- PlatformAbstraction& platformAbstraction,
- GlAbstraction& glAbstraction,
- GlSyncAbstraction& glSyncAbstraction,
- GestureManager& gestureManager,
- ResourcePolicy::DataRetention policy);
+ static Core* New( RenderController& renderController,
+ PlatformAbstraction& platformAbstraction,
+ GlAbstraction& glAbstraction,
+ GlSyncAbstraction& glSyncAbstraction,
+ GestureManager& gestureManager,
+ ResourcePolicy::DataRetention policy,
+ bool renderToFboEnabled );
/**
* Non-virtual destructor. Core is not intended as a base class.
* @param[in] nextVSyncTimeMilliseconds The time of the next predicted VSync in milliseconds
* @param[out] status showing whether further updates are required. This also shows
* whether a Notification event should be sent, regardless of whether the multi-threading is used.
- */
- void Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, UpdateStatus& status );
+ * @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled.
+ * @param[in] isRenderingToFbo Whether this frame is being rendered into the Frame Buffer Object.
+ */
+ void Update( float elapsedSeconds,
+ unsigned int lastVSyncTimeMilliseconds,
+ unsigned int nextVSyncTimeMilliseconds,
+ UpdateStatus& status,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo );
/**
* Render the next frame. This method should be preceded by a call up Update.
using Integration::UpdateStatus;
using Integration::RenderStatus;
-Core::Core( RenderController& renderController, PlatformAbstraction& platform,
- GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction,
- GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy)
+Core::Core( RenderController& renderController,
+ PlatformAbstraction& platform,
+ GlAbstraction& glAbstraction,
+ GlSyncAbstraction& glSyncAbstraction,
+ GestureManager& gestureManager,
+ ResourcePolicy::DataRetention dataRetentionPolicy,
+ bool renderToFboEnabled )
: mRenderController( renderController ),
mPlatform(platform),
mProcessingEvent(false)
// This must be called after stage is created but before stage initialization
mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) );
- mStage->Initialize();
+ mStage->Initialize( renderToFboEnabled );
mGestureEventProcessor = new GestureEventProcessor( *mStage, *mUpdateManager, gestureManager, mRenderController );
mEventProcessor = new EventProcessor( *mStage, *mNotificationManager, *mGestureEventProcessor );
mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
}
-void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status )
+void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo )
{
// set the time delta so adaptor can easily print FPS with a release build with 0 as
// it is cached by frametime
// Use the estimated time diff till we render as the elapsed time.
status.keepUpdating = mUpdateManager->Update( elapsedSeconds,
lastVSyncTimeMilliseconds,
- nextVSyncTimeMilliseconds );
+ nextVSyncTimeMilliseconds,
+ renderToFboEnabled,
+ isRenderingToFbo );
// Check the Notification Manager message queue to set needsNotification
status.needsNotification = mNotificationManager->MessagesToProcess();
Integration::GlAbstraction& glAbstraction,
Integration::GlSyncAbstraction& glSyncAbstraction,
Integration::GestureManager& gestureManager,
- ResourcePolicy::DataRetention dataRetentionPolicy );
+ ResourcePolicy::DataRetention dataRetentionPolicy,
+ bool renderToFboEnabled );
/**
* Destructor
/**
* @copydoc Dali::Integration::Core::Update()
*/
- void Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status );
+ void Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo );
/**
* @copydoc Dali::Integration::Core::Render()
#include <dali/public-api/events/touch-data.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/public-api/rendering/frame-buffer.h>
using Dali::Internal::SceneGraph::Node;
return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager, renderController ) );
}
-void Stage::Initialize()
+void Stage::Initialize( bool renderToFbo )
{
+ mRenderToFbo = renderToFbo;
mObjectRegistry = ObjectRegistry::New();
// Create the ordered list of layers
// if single render task to screen then set its viewport parameters
if( 1 == mRenderTaskList->GetTaskCount() )
{
- Dali::RenderTask mDefaultRenderTask = mRenderTaskList->GetTask( 0u );
+ Dali::RenderTask defaultRenderTask = mRenderTaskList->GetTask( 0u );
- if(!mDefaultRenderTask.GetTargetFrameBuffer())
+ if(!defaultRenderTask.GetTargetFrameBuffer())
{
- mDefaultRenderTask.SetViewport( Viewport(0, 0, width, height) );
+ defaultRenderTask.SetViewport( Viewport(0, 0, width, height) );
}
}
+
+ if( mRenderToFbo )
+ {
+ Dali::FrameBuffer frameBuffer = Dali::FrameBuffer::New( width, height, Dali::FrameBuffer::Attachment::NONE );
+ Dali::Texture texture = Dali::Texture::New( Dali::TextureType::TEXTURE_2D, Dali::Pixel::RGB888, width, height );
+ frameBuffer.AttachColorTexture( texture );
+
+ Dali::RenderTask defaultRenderTask = mRenderTaskList->GetTask( 0u );
+ defaultRenderTask.SetFrameBuffer( frameBuffer );
+ }
}
}
mTopMargin( 0 ),
mSystemOverlay( NULL ),
mDepthTreeDirty( false ),
- mForceNextUpdate( false )
+ mForceNextUpdate( false ),
+ mRenderToFbo( false )
{
}
-#ifndef __DALI_INTERNAL_STAGE_H__
-#define __DALI_INTERNAL_STAGE_H__
+#ifndef DALI_INTERNAL_STAGE_H
+#define DALI_INTERNAL_STAGE_H
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
/**
* Initialize the stage.
+ * @param[in] renderToFbo Whether to render into a Frame Buffer Object.
*/
- void Initialize();
+ void Initialize( bool renderToFbo );
/**
* Uninitialize the stage.
Integration::SystemOverlay* mSystemOverlay; ///< SystemOverlay stage access
- bool mDepthTreeDirty; ///< True if the depth tree needs recalculating
- bool mForceNextUpdate; ///< True if the next rendering is really required.
-
// The key event signal
Dali::Stage::KeyEventSignalType mKeyEventSignal;
Dali::DevelStage::KeyEventGeneratedSignalType mKeyEventGeneratedSignal;
Dali::Stage::ContextStatusSignal mContextRegainedSignal;
Dali::Stage::SceneCreatedSignalType mSceneCreatedSignal;
+
+ bool mDepthTreeDirty:1; ///< True if the depth tree needs recalculating
+ bool mForceNextUpdate:1; ///< True if the next rendering is really required.
+ bool mRenderToFbo:1; ///< Whether to render to a Frame Buffer Object.
};
} // namespace Internal
} // namespace Dali
-#endif // __DALI_INTERNAL_STAGE_H__
+#endif // DALI_INTERNAL_STAGE_H
}
}
-inline void RenderAlgorithms::ProcessRenderList(
- const RenderList& renderList,
- Context& context,
- BufferIndex bufferIndex,
- const Matrix& viewMatrix,
- const Matrix& projectionMatrix )
+inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList,
+ Context& context,
+ BufferIndex bufferIndex,
+ const Matrix& viewMatrix,
+ const Matrix& projectionMatrix )
{
DALI_PRINT_RENDER_LIST( renderList );
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
mClearColor(),
mIsViewportSet( false ),
mIsClearColorSet( false ),
+ mIgnoreRenderToFbo( false ),
mFrameBuffer( 0 ),
mCamera( 0 ),
mNextFreeRenderList( 0 )
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H
+#define DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Vector4 mClearColor; ///< Optional color to clear with
bool mIsViewportSet:1; ///< Flag to determine whether the viewport is set
bool mIsClearColorSet:1; ///< Flag to determine whether the clearColor is set
+ bool mIgnoreRenderToFbo:1; ///< Whether to ignore the render to FBO option (used to measure the performance above 60 fps)
Render::FrameBuffer* mFrameBuffer;
} // namespace Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H
instructions(),
renderAlgorithms(),
backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
- frameCount( 0 ),
+ frameCount( 0u ),
renderBufferIndex( SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX ),
defaultSurfaceRect(),
rendererContainer(),
DALI_ASSERT_DEBUG( mImpl->context.IsGlContextCreated() );
// Increment the frame count at the beginning of each frame
- ++(mImpl->frameCount);
+ ++mImpl->frameCount;
// Process messages queued during previous update
mImpl->renderQueue.ProcessMessages( mImpl->renderBufferIndex );
status.SetNeedsPostRender( true );
// switch rendering to adaptor provided (default) buffer
- mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, 0 );
+ mImpl->context.BindFramebuffer( GL_FRAMEBUFFER, 0u );
mImpl->context.Viewport( mImpl->defaultSurfaceRect.x,
mImpl->defaultSurfaceRect.y,
clearColor = Dali::RenderTask::DEFAULT_CLEAR_COLOR;
}
- if( instruction.mFrameBuffer != 0 )
+ if( !instruction.mIgnoreRenderToFbo && ( instruction.mFrameBuffer != 0 ) )
{
instruction.mFrameBuffer->Bind( mImpl->context );
if ( instruction.mIsViewportSet )
}
}
-
/**
* Process the list of render-tasks; the output is a series of render instructions.
* @note When ProcessRenderTasks is called, the layers should already the transparent/opaque renderers which are ready to render.
* @param[in] sortedLayers The layers containing lists of opaque / transparent renderables.
* @param[out] instructions The instructions for rendering the next frame.
* @param[in] renderInstructionProcessor An instance of the RenderInstructionProcessor used to sort and handle the renderers for each layer.
+ * @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled (used to measure FPS above 60)
+ * @param[in] isRenderingToFbo Whether this frame is being rendered into the Frame Buffer Object (used to measure FPS above 60)
* @param[in] processOffscreen Whether the offscreen render tasks are the ones processed. Otherwise it processes the onscreen tasks.
*/
void ProcessTasks( BufferIndex updateBufferIndex,
SortedLayerPointers& sortedLayers,
RenderInstructionContainer& instructions,
RenderInstructionProcessor& renderInstructionProcessor,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo,
bool processOffscreen )
{
uint32_t clippingId = 0u;
bool hasClippingNodes = false;
+ bool isFirstRenderTask = true;
for( RenderTaskList::RenderTaskContainer::Iterator iter = taskContainer.Begin(), endIter = taskContainer.End(); endIter != iter; ++iter )
{
RenderTask& renderTask = **iter;
- const bool hasFrameBuffer = renderTask.GetFrameBuffer() != 0;
+ const bool hasFrameBuffer = NULL != renderTask.GetFrameBuffer();
+ const bool isDefaultRenderTask = isFirstRenderTask;
+ isFirstRenderTask = false;
- if( ( !processOffscreen && hasFrameBuffer ) ||
- ( processOffscreen && !hasFrameBuffer ) ||
+ if( ( !renderToFboEnabled && ( ( !processOffscreen && hasFrameBuffer ) ||
+ ( processOffscreen && !hasFrameBuffer ) ) ) ||
+ ( renderToFboEnabled && ( ( processOffscreen && !hasFrameBuffer ) ||
+ ( isDefaultRenderTask && processOffscreen ) ||
+ ( !isDefaultRenderTask && !processOffscreen && hasFrameBuffer ) ) ) ||
!renderTask.ReadyToRender( updateBufferIndex ) )
{
// Skip to next task.
continue;
}
+ const unsigned int currentNumberOfInstructions = instructions.Count( updateBufferIndex );
+
if( renderTask.IsRenderRequired() )
{
for( size_t i = 0u, layerCount = sortedLayers.size(); i < layerCount; ++i )
hasClippingNodes,
instructions );
}
+
+ if( !processOffscreen && isDefaultRenderTask && renderToFboEnabled && !isRenderingToFbo && hasFrameBuffer )
+ {
+ // Traverse the instructions of the default render task and mark them to be rendered into the frame buffer.
+ for( unsigned int index = currentNumberOfInstructions, count = instructions.Count( updateBufferIndex ); index < count; ++index )
+ {
+ RenderInstruction& instruction = instructions.At( updateBufferIndex, index );
+ instruction.mIgnoreRenderToFbo = true;
+ }
+ }
}
}
RenderTaskList& renderTasks,
Layer& rootNode,
SortedLayerPointers& sortedLayers,
- RenderInstructionContainer& instructions )
+ RenderInstructionContainer& instructions,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo )
{
RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks();
sortedLayers,
instructions,
mRenderInstructionProcessor,
+ renderToFboEnabled,
+ isRenderingToFbo,
true );
+
DALI_LOG_INFO( gRenderTaskLogFilter, Debug::General, "RenderTaskProcessor::Process() Onscreen\n" );
// Now that the off screen renders are done we can process on screen render tasks.
sortedLayers,
instructions,
mRenderInstructionProcessor,
+ renderToFboEnabled,
+ isRenderingToFbo,
false );
}
#define DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_PROCESSOR_H
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* Process the list of render-tasks; the output is a series of render instructions.
* @note When ProcessRenderTasks is called, the layers should already the transparent/opaque renderers which are ready to render.
* If there is only one default render-task, then no further processing is required.
- * @param[in] updateBufferIndex The current update buffer index.
- * @param[in] renderTasks The list of render-tasks.
- * @param[in] rootNode The root node of the scene-graph.
- * @param[in] sortedLayers The layers containing lists of opaque / transparent renderables.
- * @param[out] instructions The instructions for rendering the next frame.
+ * @param[in] updateBufferIndex The current update buffer index.
+ * @param[in] renderTasks The list of render-tasks.
+ * @param[in] rootNode The root node of the scene-graph.
+ * @param[in] sortedLayers The layers containing lists of opaque / transparent renderables.
+ * @param[out] instructions The instructions for rendering the next frame.
+ * @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled (used to measure FPS above 60)
+ * @param[in] isRenderingToFbo Whether this frame is being rendered into the Frame Buffer Object (used to measure FPS above 60)
*/
void Process( BufferIndex updateBufferIndex,
RenderTaskList& renderTasks,
Layer& rootNode,
SortedLayerPointers& sortedLayers,
- RenderInstructionContainer& instructions );
+ RenderInstructionContainer& instructions,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo );
private:
unsigned int UpdateManager::Update( float elapsedSeconds,
unsigned int lastVSyncTimeMilliseconds,
- unsigned int nextVSyncTimeMilliseconds )
+ unsigned int nextVSyncTimeMilliseconds,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo )
{
const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
if ( NULL != mImpl->root )
{
mImpl->renderTaskProcessor.Process( bufferIndex,
- mImpl->taskList,
- *mImpl->root,
- mImpl->sortedLayers,
- mImpl->renderInstructions );
+ mImpl->taskList,
+ *mImpl->root,
+ mImpl->sortedLayers,
+ mImpl->renderInstructions,
+ renderToFboEnabled,
+ isRenderingToFbo );
// Process the system-level RenderTasks last
if ( NULL != mImpl->systemLevelRoot )
{
mImpl->renderTaskProcessor.Process( bufferIndex,
- mImpl->systemLevelTaskList,
- *mImpl->systemLevelRoot,
- mImpl->systemLevelSortedLayers,
- mImpl->renderInstructions );
+ mImpl->systemLevelTaskList,
+ *mImpl->systemLevelRoot,
+ mImpl->systemLevelSortedLayers,
+ mImpl->renderInstructions,
+ renderToFboEnabled,
+ isRenderingToFbo );
}
}
}
* @param[in] elapsedSeconds The elapsed time that should be applied to animations.
* @param[in] lastVSyncTimeMilliseconds The last time, in milliseconds, that we had a VSync.
* @param[in] nextVSyncTimeMilliseconds The estimated time, in milliseconds, of the next VSync.
+ * @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled.
+ * @param[in] isRenderingToFbo Whether this frame is being rendered into the Frame Buffer Object.
* @return True if further updates are required e.g. during animations.
*/
- unsigned int Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds );
+ unsigned int Update( float elapsedSeconds,
+ unsigned int lastVSyncTimeMilliseconds,
+ unsigned int nextVSyncTimeMilliseconds,
+ bool renderToFboEnabled,
+ bool isRenderingToFbo );
/**
* Set the background color i.e. the glClear color used at the beginning of each frame.
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H__
+#ifndef DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H
+#define DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
/**
* Set the frame-buffer used as a render target.
- * @param[in] resourceId The resource ID of the frame-buffer, or zero if not rendering off-screen.
- * @param[in] isNativeFBO if this render task is targeting a native FBO
- */
- void SetFrameBufferId( unsigned int resourceId, bool isNativeFBO );
-
- /**
- * Retrieve the resource ID of the frame-buffer.
- * @return The resource ID, or zero if not rendering off-screen.
- */
- unsigned int GetFrameBufferId() const;
-
- /**
- * Set the frame-buffer used as a render target.
* @param[in] frameBuffer The framebuffer
*/
void SetFrameBuffer( Render::FrameBuffer* frameBuffer );
} // namespace Dali
-#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H