[4.0] Add ability to change rendering behavior 14/193014/1
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 23 Aug 2018 10:36:06 +0000 (11:36 +0100)
committerHeeyong Song <heeyong.song@samsung.com>
Wed, 14 Nov 2018 01:01:23 +0000 (10:01 +0900)
Change-Id: Ia3c8445069a5fe6044aec8edb2a5ecfa2216b915

automated-tests/src/dali/utc-Dali-Stage.cpp
dali/devel-api/common/stage-devel.cpp
dali/devel-api/common/stage-devel.h
dali/internal/common/type-abstraction-enums.h
dali/internal/event/common/stage-impl.cpp
dali/internal/event/common/stage-impl.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h

index 4dabb87..c517c0b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
@@ -1670,3 +1670,46 @@ int UtcDaliStageOperatorAssign(void)
 
   END_TEST;
 }
+
+int UtcDaliStageRenderingBehavior(void)
+{
+  TestApplication application;
+  Stage stage = Stage::GetCurrent();
+
+  tet_infoline( "Check default rendering behavior is only if required" );
+  DALI_TEST_CHECK( DevelStage::GetRenderingBehavior( stage ) == DevelStage::Rendering::IF_REQUIRED );
+
+  tet_infoline( "No update required with an empty application" );
+  application.SendNotification();
+  DALI_TEST_CHECK( application.UpdateOnly() == false );
+  application.RenderOnly();
+
+  tet_infoline( "Change to continuous rendering, further updates should be required" );
+  DevelStage::SetRenderingBehavior( stage, DevelStage::Rendering::CONTINUOUSLY );
+
+  DALI_TEST_CHECK( DevelStage::GetRenderingBehavior( stage ) == DevelStage::Rendering::CONTINUOUSLY );
+
+  application.SendNotification();
+  DALI_TEST_CHECK( application.UpdateOnly() == true );
+  application.RenderOnly();
+
+  application.SendNotification();
+  DALI_TEST_CHECK( application.UpdateOnly() == true );
+  application.RenderOnly();
+
+  tet_infoline( "Change to rendering only if required, further updates should NOT be required" );
+  DevelStage::SetRenderingBehavior( stage, DevelStage::Rendering::IF_REQUIRED );
+
+  DALI_TEST_CHECK( DevelStage::GetRenderingBehavior( stage ) == DevelStage::Rendering::IF_REQUIRED );
+
+  application.SendNotification();
+  DALI_TEST_CHECK( application.UpdateOnly() == false );
+  application.RenderOnly();
+
+  tet_infoline( "The next update is not required so TestApplication should print a warning" );
+  application.SendNotification();
+  DALI_TEST_CHECK( application.UpdateOnly() == false );
+  application.RenderOnly();
+
+  END_TEST;
+}
index d68a5a0..e4c23ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
@@ -30,6 +30,16 @@ KeyEventGeneratedSignalType& KeyEventGeneratedSignal( Dali::Stage stage )
   return GetImplementation( stage ).KeyEventGeneratedSignal();
 }
 
+void SetRenderingBehavior( Dali::Stage stage, Rendering renderingBehavior )
+{
+  GetImplementation( stage ).SetRenderingBehavior( renderingBehavior );
+}
+
+Rendering GetRenderingBehavior( Dali::Stage stage )
+{
+  return GetImplementation( stage ).GetRenderingBehavior();
+}
+
 } // namespace DevelStage
 
 } // namespace Dali
index f54e411..9d0adcf 100644 (file)
@@ -27,6 +27,15 @@ namespace Dali
 namespace DevelStage
 {
 
+/**
+ * @brief The DALi rendering behavior.
+ */
+enum class Rendering
+{
+  IF_REQUIRED,  ///< Default. Will only render if required to do so.
+  CONTINUOUSLY, ///< Will render continuously.
+};
+
 typedef Signal< bool (const KeyEvent&) > KeyEventGeneratedSignalType;      ///< Stage key event generated signal type
 
 /**
@@ -37,6 +46,25 @@ typedef Signal< bool (const KeyEvent&) > KeyEventGeneratedSignalType;      ///<
  */
 DALI_IMPORT_API KeyEventGeneratedSignalType& KeyEventGeneratedSignal( Dali::Stage stage );
 
+/**
+ * @brief Gives the user the ability to set the rendering behavior of DALi.
+ *
+ * @param[in] stage The stage
+ * @param[in] renderingBehavior The rendering behavior required.
+ *
+ * @note By default, DALi uses Rendering::IF_REQUIRED.
+ * @see Rendering
+ */
+DALI_IMPORT_API void SetRenderingBehavior( Dali::Stage stage, Rendering renderingBehavior );
+
+/**
+ * @brief Retrieves the rendering behavior of DALi.
+ *
+ * @param[in] stage The stage
+ * @return The rendering behavior of DALi.
+ */
+DALI_IMPORT_API Rendering GetRenderingBehavior( Dali::Stage stage );
+
 } // namespace DevelStage
 
 } // namespace Dali
index a788e60..87a8e62 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_TYPE_ABSTRACTION_ENUMS_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/public-api/rendering/renderer.h>
+#include <dali/devel-api/common/stage-devel.h>
 #include <dali/internal/common/type-abstraction.h>
 
 namespace Dali
@@ -36,6 +37,7 @@ template <> struct ParameterType< Dali::DepthFunction::Type >    : public BasicT
 template <> struct ParameterType< Dali::RenderMode::Type >       : public BasicType< Dali::RenderMode::Type > {};
 template <> struct ParameterType< Dali::StencilFunction::Type >  : public BasicType< Dali::StencilFunction::Type > {};
 template <> struct ParameterType< Dali::StencilOperation::Type > : public BasicType< Dali::StencilOperation::Type > {};
+template <> struct ParameterType< Dali::DevelStage::Rendering >  : public BasicType< Dali::DevelStage::Rendering > {};
 
 } //namespace Internal
 
index 0ae2eaf..e2f65e4 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
@@ -624,6 +624,22 @@ void Stage::KeepRendering( float durationSeconds )
   KeepRenderingMessage( mUpdateManager, durationSeconds );
 }
 
+void Stage::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
+{
+  if( mRenderingBehavior != renderingBehavior )
+  {
+    // Send message to change the rendering behavior
+    SetRenderingBehaviorMessage( mUpdateManager, renderingBehavior );
+
+    mRenderingBehavior = renderingBehavior;
+  }
+}
+
+DevelStage::Rendering Stage::GetRenderingBehavior() const
+{
+  return mRenderingBehavior;
+}
+
 bool Stage::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
 {
   bool connected( true );
@@ -804,6 +820,7 @@ Stage::Stage( AnimationPlaylist& playlist,
   mStereoBase( DEFAULT_STEREO_BASE ),
   mTopMargin( 0 ),
   mSystemOverlay( NULL ),
+  mRenderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
   mDepthTreeDirty( false ),
   mForceNextUpdate( false ),
   mRenderToFbo( false )
index 35db048..e1c2409 100755 (executable)
@@ -2,7 +2,7 @@
 #define DALI_INTERNAL_STAGE_H
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 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.
@@ -314,6 +314,16 @@ public:
   void KeepRendering( float durationSeconds );
 
   /**
+   * @copydoc Dali::DevelStage::SetRenderingBehavior()
+   */
+  void SetRenderingBehavior( DevelStage::Rendering renderingBehavior );
+
+  /**
+   * @copydoc Dali::DevelStage::GetRenderingBehavior()
+   */
+  DevelStage::Rendering GetRenderingBehavior() const;
+
+  /**
    * Used by the EventProcessor to emit key event signals.
    * @param[in] event The key event.
    */
@@ -553,6 +563,8 @@ private:
 
   Dali::Stage::SceneCreatedSignalType mSceneCreatedSignal;
 
+  DevelStage::Rendering mRenderingBehavior; ///< The rendering behavior
+
   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.
index 1722334..49a28a4 100644 (file)
@@ -198,6 +198,7 @@ struct UpdateManager::Impl
     keepRenderingSeconds( 0.0f ),
     nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
     frameCounter( 0 ),
+    renderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
     animationFinishedDuringUpdate( false ),
     previousUpdateScene( false ),
     renderTaskWaiting( false ),
@@ -303,6 +304,8 @@ struct UpdateManager::Impl
   int                                  nodeDirtyFlags;                ///< cumulative node dirty flags from previous frame
   int                                  frameCounter;                  ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
 
+  DevelStage::Rendering                renderingBehavior;             ///< Set via DevelStage::SetRenderingBehavior
+
   bool                                 animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
   bool                                 previousUpdateScene;           ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
   bool                                 renderTaskWaiting;             ///< A REFRESH_ONCE render task is waiting to be rendered
@@ -970,13 +973,15 @@ unsigned int UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
 
   unsigned int keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
 
+  // If the rendering behavior is set to continuously render, then continue to render.
   // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
   // Keep updating until no messages are received and no animations are running.
   // If an animation has just finished, update at least once more for Discard end-actions.
   // No need to check for renderQueue as there is always a render after update and if that
   // render needs another update it will tell the adaptor to call update again
 
-  if ( mImpl->keepRenderingSeconds > 0.0f )
+  if ( ( mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY ) ||
+       ( mImpl->keepRenderingSeconds > 0.0f ) )
   {
     keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
   }
@@ -1024,6 +1029,11 @@ void UpdateManager::KeepRendering( float durationSeconds )
   mImpl->keepRenderingSeconds = std::max( mImpl->keepRenderingSeconds, durationSeconds );
 }
 
+void UpdateManager::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
+{
+  mImpl->renderingBehavior = renderingBehavior;
+}
+
 void UpdateManager::SetLayerDepths( const SortedLayerPointers& layers, bool systemLevel )
 {
   if ( !systemLevel )
index 8e381fc..705eecf 100644 (file)
@@ -22,6 +22,8 @@
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/common/dali-common.h>
 
+#include <dali/devel-api/common/stage-devel.h>
+
 #include <dali/internal/common/message.h>
 #include <dali/internal/common/type-abstraction-enums.h>
 #include <dali/internal/common/shader-saver.h>
@@ -585,6 +587,11 @@ public:
   void KeepRendering( float durationSeconds );
 
   /**
+   * @copydoc Dali::DevelStage::SetRenderingBehavior()
+   */
+  void SetRenderingBehavior( DevelStage::Rendering renderingBehavior );
+
+  /**
    * Sets the depths of all layers.
    * @param layers The layers in depth order.
    * @param[in] systemLevel True if using the system-level overlay.
@@ -958,6 +965,17 @@ inline void KeepRenderingMessage( UpdateManager& manager, float durationSeconds
   new (slot) LocalType( &manager, &UpdateManager::KeepRendering, durationSeconds );
 }
 
+inline void SetRenderingBehaviorMessage( UpdateManager& manager, DevelStage::Rendering renderingBehavior )
+{
+  typedef MessageValue1< UpdateManager, DevelStage::Rendering > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = manager.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) LocalType( &manager, &UpdateManager::SetRenderingBehavior, renderingBehavior );
+}
+
 /**
  * Create a message for setting the depth of a layer
  * @param[in] manager The update manager