From: Adeel Kazmi Date: Thu, 23 Aug 2018 10:36:06 +0000 (+0100) Subject: [4.0] Add ability to change rendering behavior X-Git-Tag: accepted/tizen/4.0/unified/20190104.230757~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F14%2F193014%2F1;p=platform%2Fcore%2Fuifw%2Fdali-core.git [4.0] Add ability to change rendering behavior Change-Id: Ia3c8445069a5fe6044aec8edb2a5ecfa2216b915 --- diff --git a/automated-tests/src/dali/utc-Dali-Stage.cpp b/automated-tests/src/dali/utc-Dali-Stage.cpp index 4dabb87..c517c0b 100644 --- a/automated-tests/src/dali/utc-Dali-Stage.cpp +++ b/automated-tests/src/dali/utc-Dali-Stage.cpp @@ -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; +} diff --git a/dali/devel-api/common/stage-devel.cpp b/dali/devel-api/common/stage-devel.cpp index d68a5a0..e4c23ad 100644 --- a/dali/devel-api/common/stage-devel.cpp +++ b/dali/devel-api/common/stage-devel.cpp @@ -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 diff --git a/dali/devel-api/common/stage-devel.h b/dali/devel-api/common/stage-devel.h index f54e411..9d0adcf 100644 --- a/dali/devel-api/common/stage-devel.h +++ b/dali/devel-api/common/stage-devel.h @@ -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 diff --git a/dali/internal/common/type-abstraction-enums.h b/dali/internal/common/type-abstraction-enums.h index a788e60..87a8e62 100644 --- a/dali/internal/common/type-abstraction-enums.h +++ b/dali/internal/common/type-abstraction-enums.h @@ -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 +#include #include 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 diff --git a/dali/internal/event/common/stage-impl.cpp b/dali/internal/event/common/stage-impl.cpp index 0ae2eaf..e2f65e4 100755 --- a/dali/internal/event/common/stage-impl.cpp +++ b/dali/internal/event/common/stage-impl.cpp @@ -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 ) diff --git a/dali/internal/event/common/stage-impl.h b/dali/internal/event/common/stage-impl.h index 35db048..e1c2409 100755 --- a/dali/internal/event/common/stage-impl.h +++ b/dali/internal/event/common/stage-impl.h @@ -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. diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 1722334..49a28a4 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -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 ) diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 8e381fc..705eecf 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -22,6 +22,8 @@ #include #include +#include + #include #include #include @@ -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