Render to Frame Buffer Object. 76/155576/11
authorVictor Cebollada <v.cebollada@samsung.com>
Thu, 12 Oct 2017 15:32:21 +0000 (16:32 +0100)
committerVictor Cebollada <v.cebollada@samsung.com>
Wed, 1 Nov 2017 09:38:13 +0000 (09:38 +0000)
* A new feature has been added to dali-core/dali-adaptor to
  measure the performance above 60 fps avoiding the vsync.

  It renders the frames into a Frame Buffer Object. However,
  is possible to render into the default Frame Buffer every
  certain number of frames.

* Usage: $ DALI_FPS_TRACKING=1 DALI_RENDER_TO_FBO=30 path_to_DALi_app

  Will render into the Frame Buffer Object 29 frames of 30, the 30th
  will be rendered into the Frame Buffer. Will show as well the FPS.

Change-Id: I37b3ae6efaf9e618f9cf34583c75db4187327044
Signed-off-by: Victor Cebollada <v.cebollada@samsung.com>
16 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-application.cpp
dali/integration-api/core.cpp
dali/integration-api/core.h
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/event/common/stage-impl.cpp
dali/internal/event/common/stage-impl.h
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-instruction.cpp
dali/internal/render/common/render-instruction.h
dali/internal/render/common/render-manager.cpp
dali/internal/update/manager/render-task-processor.cpp
dali/internal/update/manager/render-task-processor.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h
dali/internal/update/render-tasks/scene-graph-render-task.h

index 66366765eae5bf8502888b596ebfb3a4c7970179..54a69bbb65a715936918f277c8c30013489aab86 100644 (file)
@@ -62,13 +62,13 @@ void TestApplication::Initialize()
   // 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 );
@@ -171,7 +171,7 @@ void TestApplication::DoUpdate( unsigned int intervalMilliseconds, const char* l
   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();
 
index 0c6ef9bb3e6b3514bcc21051ee3b61d3cc0a09d0..dbe71ecf1a475e68639a0b72372ef7d92beb53a5 100644 (file)
@@ -30,11 +30,22 @@ namespace Dali
 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;
 }
@@ -99,9 +110,9 @@ unsigned int Core::GetMaximumUpdateCount() const
   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 )
index 2e41509aed745f1290c13e8a2d61c88dd625bb42..6d4471526e8da95fa367039b6b306c99365c6979 100644 (file)
@@ -216,14 +216,16 @@ public:
    * @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.
@@ -339,8 +341,15 @@ public:
    * @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.
index aa6eb19e8a775d7895194f1760378352bb117a07..873dbf543c1abda60ec950482ecd112729e4bc88 100644 (file)
@@ -78,9 +78,13 @@ using Integration::Event;
 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)
@@ -121,7 +125,7 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
   // 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 );
@@ -204,7 +208,7 @@ void Core::SetDpi( unsigned int dpiHorizontal, unsigned int dpiVertical )
   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
@@ -214,7 +218,9 @@ void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds,
   // 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();
index 49d7b3339381bb42d96e602cf00becb5e54d340d..2a73f5af4eca8e92c70d6bd24e37aa32b9d815c9 100644 (file)
@@ -79,7 +79,8 @@ public:
         Integration::GlAbstraction& glAbstraction,
         Integration::GlSyncAbstraction& glSyncAbstraction,
         Integration::GestureManager& gestureManager,
-        ResourcePolicy::DataRetention dataRetentionPolicy );
+        ResourcePolicy::DataRetention dataRetentionPolicy,
+        bool renderToFboEnabled );
 
   /**
    * Destructor
@@ -129,7 +130,7 @@ public:
   /**
    * @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()
index 9e10b2e02fc40663320dde55c32d134f13a92619..b54e34f36199a850dfb5c0ddb501552bff943b8f 100644 (file)
@@ -39,6 +39,7 @@
 #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;
 
@@ -95,8 +96,9 @@ StagePtr Stage::New( AnimationPlaylist& playlist,
   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
@@ -230,13 +232,23 @@ void Stage::SurfaceResized( float width, float height )
     // 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 );
+    }
   }
 }
 
@@ -712,7 +724,8 @@ Stage::Stage( AnimationPlaylist& playlist,
   mTopMargin( 0 ),
   mSystemOverlay( NULL ),
   mDepthTreeDirty( false ),
-  mForceNextUpdate( false )
+  mForceNextUpdate( false ),
+  mRenderToFbo( false )
 {
 }
 
index 7ff94ba31b53188865a1740ed74eeedd8c41aef6..c8b04b84812315d0757eba57e7f8b0346e7c6974 100644 (file)
@@ -1,5 +1,5 @@
-#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.
@@ -87,8 +87,9 @@ public:
 
   /**
    * Initialize the stage.
+   * @param[in] renderToFbo Whether to render into a Frame Buffer Object.
    */
-  void Initialize();
+  void Initialize( bool renderToFbo );
 
   /**
    * Uninitialize the stage.
@@ -525,9 +526,6 @@ private:
 
   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;
@@ -546,6 +544,10 @@ private:
   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
@@ -572,4 +574,4 @@ inline const Internal::Stage& GetImplementation(const Dali::Stage& stage)
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_STAGE_H__
+#endif // DALI_INTERNAL_STAGE_H
index 1fb3a889822eff4a932975655bd2f0aed37e7da5..7c5063fd07daa915bca67fc258fdb109f9073566 100644 (file)
@@ -367,12 +367,11 @@ inline void RenderAlgorithms::SetupClipping( const RenderItem& item, Context& co
   }
 }
 
-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 );
 
index a5f52020486c2604ac61338477bb79a0626709b8..4eb7a401a67ba6b33b32f5a55b13d38c712d35cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -37,6 +37,7 @@ RenderInstruction::RenderInstruction()
   mClearColor(),
   mIsViewportSet( false ),
   mIsClearColorSet( false ),
+  mIgnoreRenderToFbo( false ),
   mFrameBuffer( 0 ),
   mCamera( 0 ),
   mNextFreeRenderList( 0 )
index dc613fa3105decabd217471634a2409b185314c5..3157f85edf3b52f6b7c8531863e54f13f8da83c2 100644 (file)
@@ -1,8 +1,8 @@
-#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.
@@ -139,6 +139,7 @@ public: // Data
   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;
 
@@ -156,4 +157,4 @@ private: // Data
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_H
index f19c956a9d1f9b3e5c7d020025d3c4b5fc5625ef..a4ddb84b508530114a681ce2af4e9099cd9573cc 100644 (file)
@@ -61,7 +61,7 @@ struct RenderManager::Impl
     instructions(),
     renderAlgorithms(),
     backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
-    frameCount( 0 ),
+    frameCount( 0u ),
     renderBufferIndex( SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX ),
     defaultSurfaceRect(),
     rendererContainer(),
@@ -394,7 +394,7 @@ void RenderManager::Render( Integration::RenderStatus& status )
   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 );
@@ -409,7 +409,7 @@ void RenderManager::Render( Integration::RenderStatus& status )
     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,
@@ -483,7 +483,7 @@ void RenderManager::DoRender( RenderInstruction& instruction )
     clearColor = Dali::RenderTask::DEFAULT_CLEAR_COLOR;
   }
 
-  if( instruction.mFrameBuffer != 0 )
+  if( !instruction.mIgnoreRenderToFbo && ( instruction.mFrameBuffer != 0 ) )
   {
     instruction.mFrameBuffer->Bind( mImpl->context );
     if ( instruction.mIsViewportSet )
index c5b7e3183823f4ce6a563ecd6206cfffc9ab4b5c..31422ca46a632b6dd1db1da5da8e117c3b11f897 100644 (file)
@@ -189,7 +189,6 @@ void AddRenderablesForTask( BufferIndex updateBufferIndex,
   }
 }
 
-
 /**
  * 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.
@@ -200,6 +199,8 @@ void AddRenderablesForTask( BufferIndex updateBufferIndex,
  * @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,
@@ -208,19 +209,27 @@ 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.
@@ -243,6 +252,8 @@ void ProcessTasks( BufferIndex updateBufferIndex,
       continue;
     }
 
+    const unsigned int currentNumberOfInstructions = instructions.Count( updateBufferIndex );
+
     if( renderTask.IsRenderRequired() )
     {
       for( size_t i = 0u, layerCount = sortedLayers.size(); i < layerCount; ++i )
@@ -267,6 +278,16 @@ void ProcessTasks( BufferIndex updateBufferIndex,
                                           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;
+      }
+    }
   }
 }
 
@@ -284,7 +305,9 @@ void RenderTaskProcessor::Process( BufferIndex updateBufferIndex,
                                    RenderTaskList& renderTasks,
                                    Layer& rootNode,
                                    SortedLayerPointers& sortedLayers,
-                                   RenderInstructionContainer& instructions )
+                                   RenderInstructionContainer& instructions,
+                                   bool renderToFboEnabled,
+                                   bool isRenderingToFbo )
 {
   RenderTaskList::RenderTaskContainer& taskContainer = renderTasks.GetTasks();
 
@@ -310,7 +333,10 @@ void RenderTaskProcessor::Process( BufferIndex updateBufferIndex,
                 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.
@@ -322,6 +348,8 @@ void RenderTaskProcessor::Process( BufferIndex updateBufferIndex,
                 sortedLayers,
                 instructions,
                 mRenderInstructionProcessor,
+                renderToFboEnabled,
+                isRenderingToFbo,
                 false );
 }
 
index 2b69406d0dc33ce2e8ae6fe60c8a230e403db92e..5d2bdbb0cf91c3a5068966f7efd726d51f2b198c 100644 (file)
@@ -2,7 +2,7 @@
 #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.
@@ -54,17 +54,21 @@ public:
    * 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:
 
index 897573bd2ae43f56b7c8c354d23177e81d853dd1..c509ec6ad03058ed98db2a66820146c1f3a3241d 100644 (file)
@@ -806,7 +806,9 @@ void UpdateManager::UpdateNodes( BufferIndex bufferIndex )
 
 unsigned int UpdateManager::Update( float elapsedSeconds,
                                     unsigned int lastVSyncTimeMilliseconds,
-                                    unsigned int nextVSyncTimeMilliseconds )
+                                    unsigned int nextVSyncTimeMilliseconds,
+                                    bool renderToFboEnabled,
+                                    bool isRenderingToFbo )
 {
   const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
 
@@ -895,19 +897,23 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
       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 );
         }
       }
     }
index 602a04bf946332eef926880c378d44f7e60f3b44..d603eb61f302d29d880f7073a4ab804674590dff 100644 (file)
@@ -549,9 +549,15 @@ public:
    * @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.
index 99ed6c192a35ae96f8c1ebf054d16c97b24682ec..0797dd3de108d595b5cb79970b287fe087dcb3b3 100644 (file)
@@ -1,5 +1,5 @@
-#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.
@@ -108,19 +108,6 @@ public:
    */
   void SetCamera( Node* cameraNode, Camera* camera );
 
-  /**
-   * 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
@@ -528,4 +515,4 @@ inline void BakeViewportSizeMessage( EventThreadServices& eventThreadServices, c
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H__
+#endif // DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_H