From 4fad7c0fbcdc7c359a852db081dc5db15a9b4db8 Mon Sep 17 00:00:00 2001 From: Jiyun Yang Date: Mon, 14 Oct 2019 15:18:09 +0900 Subject: [PATCH] [Tizen] Implement partial update This reverts commit 52d6f9b02130f5e824ebebc919cecbc487605cac. --- .../test-application.cpp | 3 +- .../test-render-surface.cpp | 9 + .../test-render-surface.h | 10 + automated-tests/src/dali/utc-Dali-Actor.cpp | 31 +++ dali/devel-api/actors/actor-devel.h | 9 + dali/integration-api/core-enumerations.h | 9 + dali/integration-api/core.cpp | 6 +- dali/integration-api/core.h | 4 +- dali/integration-api/render-surface.h | 18 ++ dali/internal/common/core-impl.cpp | 5 +- dali/internal/common/core-impl.h | 3 +- dali/internal/event/actors/actor-impl.cpp | 27 +++ dali/internal/event/actors/actor-impl.h | 12 ++ dali/internal/event/common/scene-impl.cpp | 4 + .../event/rendering/frame-buffer-impl.cpp | 9 + .../event/rendering/frame-buffer-impl.h | 6 + .../render/common/render-algorithms.cpp | 15 +- .../render/common/render-algorithms.h | 8 +- dali/internal/render/common/render-item.cpp | 21 +- dali/internal/render/common/render-item.h | 5 +- dali/internal/render/common/render-list.h | 22 +- .../internal/render/common/render-manager.cpp | 198 ++++++++++++++++-- dali/internal/render/common/render-manager.h | 3 +- .../renderers/render-surface-frame-buffer.cpp | 30 ++- .../renderers/render-surface-frame-buffer.h | 32 +++ .../update/animation/scene-graph-animator.h | 5 + .../update/common/property-owner-messages.h | 2 + .../internal/update/common/property-owner.cpp | 9 + dali/internal/update/common/property-owner.h | 13 ++ .../manager/render-instruction-processor.cpp | 46 +++- .../update/manager/transform-manager.cpp | 99 ++++++++- .../update/manager/transform-manager.h | 20 ++ .../update/manager/update-manager.cpp | 2 + .../internal/update/nodes/node-declarations.h | 0 dali/internal/update/nodes/node-messages.h | 4 + dali/internal/update/nodes/node.cpp | 41 ++++ dali/internal/update/nodes/node.h | 40 ++++ .../update/nodes/scene-graph-layer.cpp | 5 + .../update/rendering/scene-graph-renderer.cpp | 53 ++++- .../update/rendering/scene-graph-renderer.h | 13 ++ 40 files changed, 808 insertions(+), 43 deletions(-) mode change 100644 => 100755 automated-tests/src/dali/dali-test-suite-utils/test-application.cpp mode change 100644 => 100755 automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp mode change 100644 => 100755 automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h mode change 100644 => 100755 automated-tests/src/dali/utc-Dali-Actor.cpp mode change 100644 => 100755 dali/devel-api/actors/actor-devel.h mode change 100644 => 100755 dali/integration-api/core-enumerations.h mode change 100644 => 100755 dali/integration-api/core.cpp mode change 100644 => 100755 dali/integration-api/core.h mode change 100644 => 100755 dali/integration-api/render-surface.h mode change 100644 => 100755 dali/internal/common/core-impl.cpp mode change 100644 => 100755 dali/internal/common/core-impl.h mode change 100644 => 100755 dali/internal/event/actors/actor-impl.cpp mode change 100644 => 100755 dali/internal/event/common/scene-impl.cpp mode change 100644 => 100755 dali/internal/event/rendering/frame-buffer-impl.cpp mode change 100644 => 100755 dali/internal/event/rendering/frame-buffer-impl.h mode change 100644 => 100755 dali/internal/render/common/render-algorithms.cpp mode change 100644 => 100755 dali/internal/render/common/render-algorithms.h mode change 100644 => 100755 dali/internal/render/common/render-item.cpp mode change 100644 => 100755 dali/internal/render/common/render-item.h mode change 100644 => 100755 dali/internal/render/common/render-list.h mode change 100644 => 100755 dali/internal/render/common/render-manager.cpp mode change 100644 => 100755 dali/internal/render/common/render-manager.h mode change 100644 => 100755 dali/internal/render/renderers/render-surface-frame-buffer.cpp mode change 100644 => 100755 dali/internal/render/renderers/render-surface-frame-buffer.h mode change 100644 => 100755 dali/internal/update/animation/scene-graph-animator.h mode change 100644 => 100755 dali/internal/update/common/property-owner-messages.h mode change 100644 => 100755 dali/internal/update/common/property-owner.cpp mode change 100644 => 100755 dali/internal/update/common/property-owner.h mode change 100644 => 100755 dali/internal/update/manager/render-instruction-processor.cpp mode change 100644 => 100755 dali/internal/update/manager/transform-manager.cpp mode change 100644 => 100755 dali/internal/update/manager/transform-manager.h mode change 100644 => 100755 dali/internal/update/manager/update-manager.cpp mode change 100644 => 100755 dali/internal/update/nodes/node-declarations.h mode change 100644 => 100755 dali/internal/update/nodes/node-messages.h mode change 100644 => 100755 dali/internal/update/rendering/scene-graph-renderer.cpp diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp old mode 100644 new mode 100755 index 44b49645b..34566e6aa --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp @@ -63,7 +63,8 @@ void TestApplication::CreateCore() mDataRetentionPolicy, Integration::RenderToFrameBuffer::FALSE, Integration::DepthBufferAvailable::TRUE, - Integration::StencilBufferAvailable::TRUE ); + Integration::StencilBufferAvailable::TRUE, + Integration::PartialUpdateAvailable::FALSE ); mCore->ContextCreated(); diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp old mode 100644 new mode 100755 index 066b37e9a..73ad9c846 --- a/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.cpp @@ -117,4 +117,13 @@ Vector4 TestRenderSurface::GetBackgroundColor() return mBackgroundColor; } +void TestRenderSurface::SetDamagedRect( const Dali::DamagedRect& damagedRect, Dali::DamagedRect& mergedRect ) +{ +} + +int32_t TestRenderSurface::GetBufferAge() +{ + return 0; +} + } // Namespace dali diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h b/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h old mode 100644 new mode 100755 index be38d000a..128f890aa --- a/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h +++ b/automated-tests/src/dali/dali-test-suite-utils/test-render-surface.h @@ -137,6 +137,16 @@ public: */ virtual Vector4 GetBackgroundColor(); + /** + * @copydoc Dali::Integration::RenderSurface::SetDamagedRect + */ + virtual void SetDamagedRect( const Dali::DamagedRect& damagedRect, Dali::DamagedRect& mergedRect ); + + /** + * @copydoc Dali::Integration::RenderSurface::GetBufferAge + */ + virtual int32_t GetBufferAge(); + private: /** diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp old mode 100644 new mode 100755 index 12cbecd6a..7ced69b25 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -3284,6 +3284,7 @@ const PropertyStringIndex PROPERTY_TABLE[] = { "inheritPosition", Actor::Property::INHERIT_POSITION, Property::BOOLEAN }, { "clippingMode", Actor::Property::CLIPPING_MODE, Property::STRING }, { "opacity", DevelActor::Property::OPACITY, Property::FLOAT }, + { "updateSizeHint", DevelActor::Property::UPDATE_SIZE_HINT, Property::VECTOR2 }, }; const unsigned int PROPERTY_TABLE_COUNT = sizeof( PROPERTY_TABLE ) / sizeof( PROPERTY_TABLE[0] ); } // unnamed namespace @@ -7196,6 +7197,36 @@ int utcDaliActorCulled(void) END_TEST; } +int UtcDaliActorUpdateSizeHint(void) +{ + TestApplication application; + + Actor actor = Actor::New(); + Vector3 vector(100.0f, 100.0f, 0.0f); + + DALI_TEST_CHECK(vector != actor.GetCurrentSize()); + + actor.SetSize(vector.x, vector.y); + + + Vector2 updateSizeHint = Vector2(150.f, 150.f); + actor.SetProperty(Dali::DevelActor::Property::UPDATE_SIZE_HINT, updateSizeHint); + + // Flush the queue and render once + application.SendNotification(); + application.Render(); + + + Vector2 currentSizeHint = actor.GetProperty( Dali::DevelActor::Property::UPDATE_SIZE_HINT ).Get< Vector2 >(); + DALI_TEST_EQUALS( currentSizeHint, updateSizeHint, Math::MACHINE_EPSILON_0, TEST_LOCATION ); + + // Flush the queue and render once + application.SendNotification(); + application.Render(); + + END_TEST; +} + int utcDaliEnsureRenderWhenRemovingLastRenderableActor(void) { TestApplication application; diff --git a/dali/devel-api/actors/actor-devel.h b/dali/devel-api/actors/actor-devel.h old mode 100644 new mode 100755 index ff521def7..915ac2d7a --- a/dali/devel-api/actors/actor-devel.h +++ b/dali/devel-api/actors/actor-devel.h @@ -128,6 +128,15 @@ enum Type * @note True means that the actor is out of the view frustum. */ CULLED = INHERIT_LAYOUT_DIRECTION + 5, + + /** + * @brief Sets the update size hint of the actor. + * @details Name "updateSizeHint", type Property::VECTOR2. + * @note When this value is set, the update area is determined by this value when a partial update. + * By default, render item size is used for partial update. + * It is scaled but not animated. + */ + UPDATE_SIZE_HINT = INHERIT_LAYOUT_DIRECTION + 6, }; } // namespace Property diff --git a/dali/integration-api/core-enumerations.h b/dali/integration-api/core-enumerations.h old mode 100644 new mode 100755 index 24299f42a..92ab03790 --- a/dali/integration-api/core-enumerations.h +++ b/dali/integration-api/core-enumerations.h @@ -56,6 +56,15 @@ enum class StencilBufferAvailable TRUE }; +/** + * @brief Enumerations to specify whether the partial update is available. + */ +enum class PartialUpdateAvailable +{ + FALSE = 0, + TRUE +}; + } // namespace Integration } // namespace Dali diff --git a/dali/integration-api/core.cpp b/dali/integration-api/core.cpp old mode 100644 new mode 100755 index d154574bb..8c8f09b78 --- a/dali/integration-api/core.cpp +++ b/dali/integration-api/core.cpp @@ -43,7 +43,8 @@ Core* Core::New( RenderController& renderController, ResourcePolicy::DataRetention policy, RenderToFrameBuffer renderToFboEnabled, DepthBufferAvailable depthBufferAvailable, - StencilBufferAvailable stencilBufferAvailable ) + StencilBufferAvailable stencilBufferAvailable, + PartialUpdateAvailable partialUpdateAvailable ) { Core* instance = new Core; instance->mImpl = new Internal::Core( renderController, @@ -54,7 +55,8 @@ Core* Core::New( RenderController& renderController, policy, renderToFboEnabled, depthBufferAvailable, - stencilBufferAvailable ); + stencilBufferAvailable, + partialUpdateAvailable ); return instance; } diff --git a/dali/integration-api/core.h b/dali/integration-api/core.h old mode 100644 new mode 100755 index e7644af1d..493d68414 --- a/dali/integration-api/core.h +++ b/dali/integration-api/core.h @@ -232,6 +232,7 @@ public: * @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled. * @param[in] depthBufferAvailable Whether the depth buffer is available * @param[in] stencilBufferAvailable Whether the stencil buffer is available + * @param[in] partialUpdateAvailble whether the partial update is available * @return A newly allocated Core. */ static Core* New( RenderController& renderController, @@ -242,7 +243,8 @@ public: ResourcePolicy::DataRetention policy, RenderToFrameBuffer renderToFboEnabled, DepthBufferAvailable depthBufferAvailable, - StencilBufferAvailable stencilBufferAvailable ); + StencilBufferAvailable stencilBufferAvailable, + PartialUpdateAvailable partialUpdateAvailable ); /** * Non-virtual destructor. Core is not intended as a base class. diff --git a/dali/integration-api/render-surface.h b/dali/integration-api/render-surface.h old mode 100644 new mode 100755 index b0a3b373f..bb36f602f --- a/dali/integration-api/render-surface.h +++ b/dali/integration-api/render-surface.h @@ -48,6 +48,12 @@ class GraphicsInterface; */ typedef Dali::Rect PositionSize; +/** + * @brief The Rect of partial updated area + */ +typedef Dali::Rect DamagedRect; + + namespace Integration { @@ -189,6 +195,18 @@ public: */ virtual Integration::StencilBufferAvailable GetStencilBufferRequired() = 0; + /** + * @brief Sets currentframe updated/damaged rects + * @return The Rect of partial updated area + */ + virtual void SetDamagedRect( const DamagedRect& damagedRect, DamagedRect& mergedRect ) = 0; + + /** + * @brief Gets buffer age + * @return current buffer age + */ + virtual int32_t GetBufferAge() = 0; + private: /** diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp old mode 100644 new mode 100755 index b78b515a3..636a35582 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -89,7 +89,8 @@ Core::Core( RenderController& renderController, ResourcePolicy::DataRetention dataRetentionPolicy, Integration::RenderToFrameBuffer renderToFboEnabled, Integration::DepthBufferAvailable depthBufferAvailable, - Integration::StencilBufferAvailable stencilBufferAvailable ) + Integration::StencilBufferAvailable stencilBufferAvailable, + Integration::PartialUpdateAvailable partialUpdateAvailable ) : mRenderController( renderController ), mPlatform(platform), mProcessingEvent(false), @@ -109,7 +110,7 @@ Core::Core( RenderController& renderController, mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor(); - mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, glContextHelperAbstraction, depthBufferAvailable, stencilBufferAvailable ); + mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, glContextHelperAbstraction, depthBufferAvailable, stencilBufferAvailable, partialUpdateAvailable ); RenderQueue& renderQueue = mRenderManager->GetRenderQueue(); diff --git a/dali/internal/common/core-impl.h b/dali/internal/common/core-impl.h old mode 100644 new mode 100755 index 4f137a5ce..094f37735 --- a/dali/internal/common/core-impl.h +++ b/dali/internal/common/core-impl.h @@ -88,7 +88,8 @@ public: ResourcePolicy::DataRetention dataRetentionPolicy, Integration::RenderToFrameBuffer renderToFboEnabled, Integration::DepthBufferAvailable depthBufferAvailable, - Integration::StencilBufferAvailable stencilBufferAvailable ); + Integration::StencilBufferAvailable stencilBufferAvailable, + Integration::PartialUpdateAvailable partialUpdateAvailable ); /** * Destructor diff --git a/dali/internal/event/actors/actor-impl.cpp b/dali/internal/event/actors/actor-impl.cpp old mode 100644 new mode 100755 index 44a9e89fc..e62346407 --- a/dali/internal/event/actors/actor-impl.cpp +++ b/dali/internal/event/actors/actor-impl.cpp @@ -214,6 +214,7 @@ DALI_PROPERTY( "opacity", FLOAT, true, true, true, Dali: DALI_PROPERTY( "screenPosition", VECTOR2, false, false, false, Dali::DevelActor::Property::SCREEN_POSITION ) DALI_PROPERTY( "positionUsesAnchorPoint", BOOLEAN, true, false, false, Dali::DevelActor::Property::POSITION_USES_ANCHOR_POINT ) DALI_PROPERTY( "culled", BOOLEAN, false, false, true, Dali::DevelActor::Property::CULLED ) +DALI_PROPERTY( "updateSizeHint", VECTOR2, true, false, true, Dali::DevelActor::Property::UPDATE_SIZE_HINT ) DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties ) // Signals @@ -2718,6 +2719,12 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr break; } + case Dali::DevelActor::Property::UPDATE_SIZE_HINT: + { + SetUpdateSizeHint( property.Get< Vector2 >() ); + break; + } + default: { // this can happen in the case of a non-animatable default property so just do nothing @@ -3976,6 +3983,12 @@ bool Actor::GetCurrentPropertyValue( Property::Index index, Property::Value& val break; } + case Dali::DevelActor::Property::UPDATE_SIZE_HINT: + { + value = GetUpdateSizeHint(); + break; + } + default: { // Must be an event-side only property @@ -4725,6 +4738,20 @@ float Actor::GetMaximumSize( Dimension::Type dimension ) const return FLT_MAX; // Default } +void Actor::SetUpdateSizeHint( const Vector2& updateSizeHint ) +{ + // node is being used in a separate thread; queue a message to set the value & base value + SceneGraph::NodeTransformPropertyMessage::Send( GetEventThreadServices(), &GetNode(), &GetNode().mUpdateSizeHint, &SceneGraph::TransformManagerPropertyHandler::Bake, Vector3(updateSizeHint.width, updateSizeHint.height, 0.f ) ); +} + +Vector2 Actor::GetUpdateSizeHint() const +{ + // node is being used in a separate thread; copy the value from the previous update + Vector3 updateSizeHint = Vector3::ZERO; + GetNode().GetUpdateSizeHint( GetEventThreadServices().GetEventBufferIndex(), updateSizeHint ); + return Vector2( updateSizeHint.width, updateSizeHint.height ); +} + Object* Actor::GetParentObject() const { return mParent; diff --git a/dali/internal/event/actors/actor-impl.h b/dali/internal/event/actors/actor-impl.h index 92e6ab85d..950dc6c99 100755 --- a/dali/internal/event/actors/actor-impl.h +++ b/dali/internal/event/actors/actor-impl.h @@ -1228,6 +1228,18 @@ public: */ float GetMaximumSize( Dimension::Type dimension ) const; + /** + * @brief Sets the update size hint of an actor for partial update. + * @param [in] updateSizeHint The new updateSizeHint. + */ + void SetUpdateSizeHint( const Vector2& updateSizeHint ); + + /** + * @brief Return the update size hint of actor + * @return Return the update size hint + */ + Vector2 GetUpdateSizeHint() const; + /** * @copydoc Dali::Actor::AddRenderer() */ diff --git a/dali/internal/event/common/scene-impl.cpp b/dali/internal/event/common/scene-impl.cpp old mode 100644 new mode 100755 index 917f76a2b..82f519604 --- a/dali/internal/event/common/scene-impl.cpp +++ b/dali/internal/event/common/scene-impl.cpp @@ -149,6 +149,10 @@ void Scene::Add(Actor& actor) void Scene::Remove(Actor& actor) { mRootLayer->Remove( actor ); + if( mSurface ) + { + mRenderTaskList->GetTask( 0u )->GetFrameBuffer()->SetPartialUpdateEnabled( false ); + } } Size Scene::GetSize() const diff --git a/dali/internal/event/rendering/frame-buffer-impl.cpp b/dali/internal/event/rendering/frame-buffer-impl.cpp old mode 100644 new mode 100755 index 33afe3556..fe94b5ba3 --- a/dali/internal/event/rendering/frame-buffer-impl.cpp +++ b/dali/internal/event/rendering/frame-buffer-impl.cpp @@ -134,6 +134,15 @@ void FrameBuffer::MarkSurfaceAsInvalid() } } +void FrameBuffer::SetPartialUpdateEnabled( bool value ) +{ + if( mRenderObject->IsSurfaceBacked() ) + { + SetFrameBufferPartialUpdateMessage( mEventThreadServices.GetUpdateManager(), static_cast( mRenderObject ), value ); + } +} + + FrameBuffer::~FrameBuffer() { if( EventThreadServices::IsCoreRunning() && mRenderObject ) diff --git a/dali/internal/event/rendering/frame-buffer-impl.h b/dali/internal/event/rendering/frame-buffer-impl.h old mode 100644 new mode 100755 index 8484948f9..7428ad147 --- a/dali/internal/event/rendering/frame-buffer-impl.h +++ b/dali/internal/event/rendering/frame-buffer-impl.h @@ -114,6 +114,12 @@ public: */ void MarkSurfaceAsInvalid(); + /** + * @brief Sets whether to enable partial update. + * @param[in] value whether partial update or not + */ + void SetPartialUpdateEnabled( bool value ); + private: // implementation /** diff --git a/dali/internal/render/common/render-algorithms.cpp b/dali/internal/render/common/render-algorithms.cpp old mode 100644 new mode 100755 index a8d2162aa..610496d82 --- a/dali/internal/render/common/render-algorithms.cpp +++ b/dali/internal/render/common/render-algorithms.cpp @@ -415,7 +415,8 @@ inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList, Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, Vector& boundTextures, - int orientation ) + int orientation, + Dali::ClippingBox& scissorBox ) { DALI_PRINT_RENDER_LIST( renderList ); @@ -474,6 +475,12 @@ inline void RenderAlgorithms::ProcessRenderList( const RenderList& renderList, mScissorStack.push_back( layerScissorBox ); mHasLayerScissor = true; } + else if ( !scissorBox.IsEmpty() ) + { + context.SetScissorTest( true ); + context.Scissor( scissorBox.x, scissorBox.y, scissorBox.width, scissorBox.height ); + mScissorStack.push_back( scissorBox ); + } else { // We are not performing a layer clip. Add the viewport as the root scissor rectangle. @@ -522,7 +529,8 @@ void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instru Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, Vector& boundTextures, - int orientation ) + int orientation, + Dali::ClippingBox& scissorBox ) { DALI_PRINT_RENDER_INSTRUCTION( instruction, bufferIndex ); @@ -552,7 +560,8 @@ void RenderAlgorithms::ProcessRenderInstruction( const RenderInstruction& instru depthBufferAvailable, stencilBufferAvailable, boundTextures, - orientation ); + orientation, + scissorBox ); } } } diff --git a/dali/internal/render/common/render-algorithms.h b/dali/internal/render/common/render-algorithms.h old mode 100644 new mode 100755 index 98c219bf5..bb5e066ba --- a/dali/internal/render/common/render-algorithms.h +++ b/dali/internal/render/common/render-algorithms.h @@ -59,6 +59,7 @@ class RenderAlgorithms * @param[in] depthBufferAvailable Whether the depth buffer is available * @param[in] stencilBufferAvailable Whether the stencil buffer is available * @param[in] boundTextures The textures bound for rendering + * @param[in] scissorBox The damaged rect for partial update */ void ProcessRenderInstruction( const SceneGraph::RenderInstruction& instruction, Context& context, @@ -66,7 +67,8 @@ class RenderAlgorithms Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, Vector& boundTextures, - int orientation); + int orientation, + Dali::ClippingBox& scissorBox ); private: @@ -118,6 +120,7 @@ class RenderAlgorithms * @param[in] depthBufferAvailable Whether the depth buffer is available * @param[in] stencilBufferAvailable Whether the stencil buffer is available * @param[in] boundTextures The textures bound for rendering + * @param[in] scissorBox The damaged rect for partial update */ inline void ProcessRenderList( const Dali::Internal::SceneGraph::RenderList& renderList, Context& context, @@ -127,7 +130,8 @@ class RenderAlgorithms Integration::DepthBufferAvailable depthBufferAvailable, Integration::StencilBufferAvailable stencilBufferAvailable, Vector& boundTextures, - int orientation ); + int orientation, + Dali::ClippingBox& scissorBox ); // Prevent copying: RenderAlgorithms( RenderAlgorithms& rhs ); diff --git a/dali/internal/render/common/render-item.cpp b/dali/internal/render/common/render-item.cpp old mode 100644 new mode 100755 index d47f808ab..e5620366c --- a/dali/internal/render/common/render-item.cpp +++ b/dali/internal/render/common/render-item.cpp @@ -46,11 +46,13 @@ RenderItem::RenderItem() : mModelMatrix( false ), mModelViewMatrix( false ), mSize(), + mUpdateSizeHint(), mRenderer( NULL ), mNode( NULL ), mTextureSet( NULL ), mDepthIndex( 0 ), - mIsOpaque( true ) + mIsOpaque( true ), + mPartialUpdateEnabled( false ) { } @@ -59,11 +61,22 @@ RenderItem::~RenderItem() } -ClippingBox RenderItem::CalculateViewportSpaceAABB( const int viewportWidth, const int viewportHeight ) const +ClippingBox RenderItem::CalculateViewportSpaceAABB( const int viewportWidth, const int viewportHeight, const bool useUpdateSizeHint ) const { // Calculate extent vector of the AABB: - const float halfActorX = mSize.x * 0.5f; - const float halfActorY = mSize.y * 0.5f; + float halfActorX; + float halfActorY; + if( useUpdateSizeHint ) + { + halfActorX = mUpdateSizeHint.x * 0.5f; + halfActorY = mUpdateSizeHint.y * 0.5f; + } + else + { + halfActorX = mSize.x * 0.5f; + halfActorY = mSize.y * 0.5f; + } + // To transform the actor bounds to screen-space, We do a fast, 2D version of a matrix multiply optimized for 2D quads. // This reduces float multiplications from 64 (16 * 4) to 12 (4 * 3). diff --git a/dali/internal/render/common/render-item.h b/dali/internal/render/common/render-item.h old mode 100644 new mode 100755 index 7dbd3fb0e..96a6130eb --- a/dali/internal/render/common/render-item.h +++ b/dali/internal/render/common/render-item.h @@ -65,9 +65,10 @@ struct RenderItem * * @param[in] viewportWidth The width of the viewport to calculate for * @param[in] viewportHeight The height of the viewport to calculate for + * @param[in] useUpdateSizeHint Set to true if you want to use update size hint instead of item size * @return The AABB coordinates in viewport-space (x, y, width, height) */ - ClippingBox CalculateViewportSpaceAABB( const int viewportWidth, const int viewportHeight ) const; + ClippingBox CalculateViewportSpaceAABB( const int viewportWidth, const int viewportHeight, const bool useUpdateSizeHint = false ) const; /** * Overriden delete operator. @@ -79,11 +80,13 @@ struct RenderItem Matrix mModelMatrix; Matrix mModelViewMatrix; Vector3 mSize; + Vector3 mUpdateSizeHint; Render::Renderer* mRenderer; Node* mNode; const void* mTextureSet; //< Used for sorting only int mDepthIndex; bool mIsOpaque:1; + bool mPartialUpdateEnabled:1; private: diff --git a/dali/internal/render/common/render-list.h b/dali/internal/render/common/render-list.h old mode 100644 new mode 100755 index 41af19f47..90925eb89 --- a/dali/internal/render/common/render-list.h +++ b/dali/internal/render/common/render-list.h @@ -63,7 +63,8 @@ public: : mNextFree( 0 ), mClippingBox( NULL ), mSourceLayer( NULL ), - mHasColorRenderItems( false ) + mHasColorRenderItems( false ), + mPartialUpdateEnabled( false ) { } @@ -258,6 +259,24 @@ public: return mHasColorRenderItems; } + /** + * Enable/Disable Partial update dirty flag + * @param[in] true to mark dirty else false + */ + void SetPartialUpdateEnabled( bool value ) + { + mPartialUpdateEnabled = value; + } + + /** + * Get Partial update dirty flag + * @return true if dirty else false + */ + bool IsPartialUpdateEnabled() const + { + return mPartialUpdateEnabled; + } + private: /* @@ -272,6 +291,7 @@ private: ClippingBox* mClippingBox; ///< The clipping box, in window coordinates, when clipping is enabled Layer* mSourceLayer; ///< The originating layer where the renderers are from bool mHasColorRenderItems : 1; ///< True if list contains color render items + bool mPartialUpdateEnabled : 1; //< True if partial update is needed. }; diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp old mode 100644 new mode 100755 index 431bd0ac4..fbad2b303 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -62,6 +62,37 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_REN } // unnamed namespace #endif +namespace +{ +const float partialUpdateRatio = 0.8f; // If the partial update area exceeds 80%, change to full update. + +/** + * @brief Find the intersection of two AABB rectangles. + * This is a logical AND operation. IE. The intersection is the area overlapped by both rectangles. + * @param[in] aabbA Rectangle A + * @param[in] aabbB Rectangle B + * @return The intersection of rectangle A & B (result is a rectangle) + */ +inline ClippingBox IntersectAABB( const ClippingBox& aabbA, const ClippingBox& aabbB ) +{ + ClippingBox intersectionBox; + + // First calculate the largest starting positions in X and Y. + intersectionBox.x = std::max( aabbA.x, aabbB.x ); + intersectionBox.y = std::max( aabbA.y, aabbB.y ); + + // Now calculate the smallest ending positions, and take the largest starting + // positions from the result, to get the width and height respectively. + // If the two boxes do not intersect at all, then we need a 0 width and height clipping area. + // We use max here to clamp both width and height to >= 0 for this use-case. + intersectionBox.width = std::max( std::min( aabbA.x + aabbA.width, aabbB.x + aabbB.width ) - intersectionBox.x, 0 ); + intersectionBox.height = std::max( std::min( aabbA.y + aabbA.height, aabbB.y + aabbB.height ) - intersectionBox.y, 0 ); + + return intersectionBox; +} + +} + /** * Structure to contain internal data */ @@ -71,7 +102,8 @@ struct RenderManager::Impl Integration::GlSyncAbstraction& glSyncAbstraction, Integration::GlContextHelperAbstraction& glContextHelperAbstraction, Integration::DepthBufferAvailable depthBufferAvailableParam, - Integration::StencilBufferAvailable stencilBufferAvailableParam ) + Integration::StencilBufferAvailable stencilBufferAvailableParam, + Integration::PartialUpdateAvailable partialUpdateAvailableParam ) : context( glAbstraction, &surfaceContextContainer ), currentContext( &context ), glAbstraction( glAbstraction ), @@ -92,6 +124,7 @@ struct RenderManager::Impl programController( glAbstraction ), depthBufferAvailable( depthBufferAvailableParam ), stencilBufferAvailable( stencilBufferAvailableParam ), + partialUpdateAvailable( partialUpdateAvailableParam ), defaultSurfaceOrientation( 0 ) { // Create thread pool with just one thread ( there may be a need to create more threads in the future ). @@ -171,6 +204,7 @@ struct RenderManager::Impl Integration::DepthBufferAvailable depthBufferAvailable; ///< Whether the depth buffer is available Integration::StencilBufferAvailable stencilBufferAvailable; ///< Whether the stencil buffer is available + Integration::PartialUpdateAvailable partialUpdateAvailable; ///< Whether the partial update is available std::unique_ptr threadPool; ///< The thread pool Vector boundTextures; ///< The textures bound for rendering @@ -183,14 +217,16 @@ RenderManager* RenderManager::New( Integration::GlAbstraction& glAbstraction, Integration::GlSyncAbstraction& glSyncAbstraction, Integration::GlContextHelperAbstraction& glContextHelperAbstraction, Integration::DepthBufferAvailable depthBufferAvailable, - Integration::StencilBufferAvailable stencilBufferAvailable ) + Integration::StencilBufferAvailable stencilBufferAvailable, + Integration::PartialUpdateAvailable partialUpdateAvailable ) { RenderManager* manager = new RenderManager; manager->mImpl = new Impl( glAbstraction, glSyncAbstraction, glContextHelperAbstraction, depthBufferAvailable, - stencilBufferAvailable ); + stencilBufferAvailable, + partialUpdateAvailable ); return manager; } @@ -598,10 +634,87 @@ void RenderManager::Render( Integration::RenderStatus& status, bool forceClear, DALI_PRINT_RENDER_END(); } +bool GetDamagedRect( Rect &viewportRect, RenderInstruction& instruction, Rect &damagedRect ) +{ + // merge bounding + int dx1 = viewportRect.width, dx2 = 0, dy1 = viewportRect.height, dy2 = 0; + int checkWidth = static_cast( static_cast( viewportRect.width ) * partialUpdateRatio ); + int checkHeight = static_cast( static_cast( viewportRect.height ) * partialUpdateRatio ); + Rect screenRect; + + bool isPartialUpdate = false; + + const RenderListContainer::SizeType renderListCount = instruction.RenderListCount(); + // Iterate through each render list. + + for( RenderListContainer::SizeType index = 0; index < renderListCount; ++index ) + { + const RenderList* renderList = instruction.GetRenderList( index ); + + if( renderList && !renderList->IsEmpty() && renderList->IsPartialUpdateEnabled() ) + { + const std::size_t itemCount = renderList->Count(); + for( uint32_t itemIndex = 0u; itemIndex < itemCount; ++itemIndex ) + { + const RenderItem& item = renderList->GetItem( itemIndex ); + + if( item.mPartialUpdateEnabled ) + { + isPartialUpdate = true; + + screenRect = item.CalculateViewportSpaceAABB( viewportRect.width, viewportRect.height, true ); + + dx1 = std::min( screenRect.x, dx1 ); + dx2 = std::max( screenRect.x + screenRect.width, dx2); + dy1 = std::min( screenRect.y, dy1 ); + dy2 = std::max( screenRect.y + screenRect.height, dy2 ); + + if( ( dx2 - dx1 ) > checkWidth && ( dy2 - dy1 ) > checkHeight ) + { + return false; + } + } + } + } + } + + if( isPartialUpdate ) + { + if( dx1 < 0.0f ) + { + dx1 = 0.0f; + } + if( dy1 < 0.0f ) + { + dy1 = 0.0f; + } + if( dx2 > viewportRect.width ) + { + dx2 = viewportRect.width; + } + if( dy2 > viewportRect.height ) + { + dy2 = viewportRect.height; + } + + damagedRect.x = dx1; + damagedRect.y = dy1; + damagedRect.width = dx2 - dx1; + damagedRect.height = dy2 - dy1; + } + + return isPartialUpdate; +} + void RenderManager::DoRender( RenderInstruction& instruction ) { Rect viewportRect; Vector4 clearColor; + bool isPartialUpdate = false; + Dali::DamagedRect damagedRect; + Dali::DamagedRect mergedRect; + Dali::ClippingBox scissorBox; + Dali::ClippingBox intersectRect; if ( instruction.mIsClearColorSet ) { @@ -617,6 +730,7 @@ void RenderManager::DoRender( RenderInstruction& instruction ) Vector4 backgroundColor = mImpl->backgroundColor; Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable; Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable; + Integration::PartialUpdateAvailable partialUpdateAvailable = mImpl->partialUpdateAvailable; Render::SurfaceFrameBuffer* surfaceFrameBuffer = nullptr; if ( instruction.mFrameBuffer != 0 ) @@ -682,25 +796,64 @@ void RenderManager::DoRender( RenderInstruction& instruction ) mImpl->currentContext->BindFramebuffer( GL_FRAMEBUFFER, 0u ); } + + if( surfaceFrameBuffer && + partialUpdateAvailable == Integration::PartialUpdateAvailable::TRUE ) + { + const RenderListContainer::SizeType renderListCount = instruction.RenderListCount(); + // Iterate through each render list. + if( surfaceFrameBuffer->IsPartialUpdateEnabled() ) + { + isPartialUpdate = GetDamagedRect( surfaceRect, instruction, damagedRect ) ; + } + + if( !isPartialUpdate ) + { + damagedRect = surfaceRect; + } + + surfaceFrameBuffer->SetDamagedRect( damagedRect, mergedRect ); + + if( mergedRect.IsEmpty() ) + { + isPartialUpdate = false; + } + else + { + scissorBox.x = mergedRect.x; + scissorBox.y = mergedRect.y; + scissorBox.width = mergedRect.width; + scissorBox.height = mergedRect.height; + } + } + if ( surfaceFrameBuffer ) { - mImpl->currentContext->Viewport( surfaceRect.x, - surfaceRect.y, - surfaceRect.width, - surfaceRect.height ); + mImpl->currentContext->Viewport( surfaceRect.x, + surfaceRect.y, + surfaceRect.width, + surfaceRect.height ); + - mImpl->currentContext->ClearColor( backgroundColor.r, - backgroundColor.g, - backgroundColor.b, - backgroundColor.a ); + mImpl->currentContext->ClearColor( backgroundColor.r, + backgroundColor.g, + backgroundColor.b, + backgroundColor.a ); } // Clear the entire color, depth and stencil buffers for the default framebuffer, if required. // It is important to clear all 3 buffers when they are being used, for performance on deferred renderers // e.g. previously when the depth & stencil buffers were NOT cleared, it caused the DDK to exceed a "vertex count limit", // and then stall. That problem is only noticeable when rendering a large number of vertices per frame. - - mImpl->currentContext->SetScissorTest( false ); + if( isPartialUpdate ) + { + mImpl->currentContext->SetScissorTest( true ); + mImpl->currentContext->Scissor( scissorBox.x, scissorBox.y, scissorBox.width, scissorBox.height ); + } + else + { + mImpl->currentContext->SetScissorTest( false ); + } GLbitfield clearMask = GL_COLOR_BUFFER_BIT; @@ -721,6 +874,12 @@ void RenderManager::DoRender( RenderInstruction& instruction ) mImpl->currentContext->Clear( clearMask, Context::FORCE_CLEAR ); + if( isPartialUpdate ) + { + mImpl->currentContext->SetScissorTest( false ); + } + + if( !instruction.mIgnoreRenderToFbo && ( instruction.mFrameBuffer != 0 ) ) { if ( instruction.mFrameBuffer->IsSurfaceBacked() ) // Surface rendering @@ -792,7 +951,15 @@ void RenderManager::DoRender( RenderInstruction& instruction ) // Clear the viewport area only mImpl->currentContext->SetScissorTest( true ); - mImpl->currentContext->Scissor( viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height ); + if( isPartialUpdate ) + { + intersectRect = IntersectAABB( scissorBox, viewportRect ); + mImpl->currentContext->Scissor( intersectRect.x, intersectRect.y, intersectRect.width, intersectRect.height ); + } + else + { + mImpl->currentContext->Scissor( viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height ); + } mImpl->currentContext->ColorMask( true ); mImpl->currentContext->Clear( GL_COLOR_BUFFER_BIT , Context::CHECK_CACHED_VALUES ); mImpl->currentContext->SetScissorTest( false ); @@ -808,7 +975,8 @@ void RenderManager::DoRender( RenderInstruction& instruction ) depthBufferAvailable, stencilBufferAvailable, mImpl->boundTextures, - surfaceOrientation ); + surfaceOrientation, + scissorBox ); // Synchronise the FBO/Texture access when there are multiple contexts if ( mImpl->currentContext->IsSurfacelessContextSupported() ) diff --git a/dali/internal/render/common/render-manager.h b/dali/internal/render/common/render-manager.h old mode 100644 new mode 100755 index 74215920b..16aac975e --- a/dali/internal/render/common/render-manager.h +++ b/dali/internal/render/common/render-manager.h @@ -83,7 +83,8 @@ public: Integration::GlSyncAbstraction& glSyncAbstraction, Integration::GlContextHelperAbstraction& glContextHelperAbstraction, Integration::DepthBufferAvailable depthBufferAvailable, - Integration::StencilBufferAvailable stencilBufferAvailable ); + Integration::StencilBufferAvailable stencilBufferAvailable, + Integration::PartialUpdateAvailable partialUpdateAvailable ); /** * Non-virtual destructor; not intended as a base class diff --git a/dali/internal/render/renderers/render-surface-frame-buffer.cpp b/dali/internal/render/renderers/render-surface-frame-buffer.cpp old mode 100644 new mode 100755 index 7154ff698..05248ce3d --- a/dali/internal/render/renderers/render-surface-frame-buffer.cpp +++ b/dali/internal/render/renderers/render-surface-frame-buffer.cpp @@ -35,7 +35,9 @@ SurfaceFrameBuffer::SurfaceFrameBuffer( Integration::RenderSurface* surface ) mHeight( mSurface->GetPositionSize().height ), mBackgroundColor( 0.f, 0.f, 0.f, 1.f ), mSizeChanged( false ), - mIsSurfaceInvalid( false ) + mBackgroundColorChanged( false ), + mIsSurfaceInvalid( false ), + mPartialUpdateEnabled( true ) { } @@ -104,6 +106,16 @@ void SurfaceFrameBuffer::PostRender() } mSizeChanged = false; + mBackgroundColorChanged = false; + mPartialUpdateEnabled = true; +} + +void SurfaceFrameBuffer::SetDamagedRect( const Dali::DamagedRect& damagedRect, Dali::DamagedRect& mergedRect ) +{ + if ( IsSurfaceValid() ) + { + mSurface->SetDamagedRect( damagedRect, mergedRect ); + } } Context* SurfaceFrameBuffer::GetContext() @@ -134,6 +146,7 @@ void SurfaceFrameBuffer::SetSize( uint32_t width, uint32_t height ) void SurfaceFrameBuffer::SetBackgroundColor( const Vector4& color ) { mBackgroundColor = color; + mBackgroundColorChanged = true; } bool SurfaceFrameBuffer::IsSurfaceValid() const @@ -141,6 +154,21 @@ bool SurfaceFrameBuffer::IsSurfaceValid() const return mSurface && !mIsSurfaceInvalid; } +bool SurfaceFrameBuffer::IsPartialUpdateEnabled() const +{ + bool ret = false; + if ( IsSurfaceValid() ) + { + ret = mSurface->GetBufferAge() && ( mPartialUpdateEnabled && !( mSizeChanged || mBackgroundColorChanged ) ); + } + return ret; +} + +void SurfaceFrameBuffer::SetPartialUpdateEnabled( bool value ) +{ + mPartialUpdateEnabled = value; +} + } //Render } //Internal diff --git a/dali/internal/render/renderers/render-surface-frame-buffer.h b/dali/internal/render/renderers/render-surface-frame-buffer.h old mode 100644 new mode 100755 index edd667d33..6749e8745 --- a/dali/internal/render/renderers/render-surface-frame-buffer.h +++ b/dali/internal/render/renderers/render-surface-frame-buffer.h @@ -135,6 +135,25 @@ public: */ Vector4 GetBackgroundColor(); + /** + * @brief Sets currentframe damaged rects + * @param[in] Sets currentframe damaged rects + * @param[out] return merged rect + */ + void SetDamagedRect( const Dali::DamagedRect& damagedRect, Dali::DamagedRect& mergedRect ); + + /** + * @brief Gets whether partial update is required for partial update + * @return whether partial update or not + */ + bool IsPartialUpdateEnabled() const; + + /** + * @brief Sets whether partial update is required for partial update + * @param[in] value whether partial update or not + */ + void SetPartialUpdateEnabled( bool value ); + private: Integration::RenderSurface* mSurface; ///< The render surface @@ -144,7 +163,9 @@ private: uint32_t mHeight; Vector4 mBackgroundColor; bool mSizeChanged; + bool mBackgroundColorChanged; std::atomic mIsSurfaceInvalid; ///< This is set only from the event thread and read only from the render thread + bool mPartialUpdateEnabled; ///< This value is whether partial update is required }; // Messages for FrameBuffer @@ -170,6 +191,17 @@ inline void SetFrameBufferBackgroundColorMessage( SceneGraph::UpdateManager& upd new (slot) LocalType( surfaceFrameBuffer, &SurfaceFrameBuffer::SetBackgroundColor, color ); } +inline void SetFrameBufferPartialUpdateMessage( SceneGraph::UpdateManager& updateManager, SurfaceFrameBuffer* surfaceFrameBuffer, bool value ) +{ + typedef MessageValue1< SurfaceFrameBuffer, bool > LocalType; + + // Reserve some memory inside the message queue + uint32_t* slot = updateManager.ReserveMessageSlot( sizeof( LocalType ) ); + + // Construct message in the message queue memory; note that delete should not be called on the return value + new (slot) LocalType( surfaceFrameBuffer, &SurfaceFrameBuffer::SetPartialUpdateEnabled, value ); +} + } // namespace Render } // namespace Internal diff --git a/dali/internal/update/animation/scene-graph-animator.h b/dali/internal/update/animation/scene-graph-animator.h old mode 100644 new mode 100755 index 0b3ff50e1..cbf0842ad --- a/dali/internal/update/animation/scene-graph-animator.h +++ b/dali/internal/update/animation/scene-graph-animator.h @@ -519,6 +519,11 @@ public: progress = SetProgress( progress ); } + if( mPropertyOwner ) + { + mPropertyOwner->SetPropertyDirty( true ); + } + float alpha = ApplyAlphaFunction( progress ); // PropertyType specific part diff --git a/dali/internal/update/common/property-owner-messages.h b/dali/internal/update/common/property-owner-messages.h old mode 100644 new mode 100755 index 1e3129928..8668e4ead --- a/dali/internal/update/common/property-owner-messages.h +++ b/dali/internal/update/common/property-owner-messages.h @@ -108,6 +108,7 @@ public: */ virtual void Process( BufferIndex updateBufferIndex ) { + mSceneObject->SetPropertyDirty( true ); (mProperty->*mMemberFunction)( updateBufferIndex, mParam ); } @@ -187,6 +188,7 @@ public: */ virtual void Process( BufferIndex updateBufferIndex ) { + mSceneObject->SetPropertyDirty( true ); (mProperty->*mMemberFunction)( updateBufferIndex, mParam ); } diff --git a/dali/internal/update/common/property-owner.cpp b/dali/internal/update/common/property-owner.cpp old mode 100644 new mode 100755 index fb655e3db..b094a437f --- a/dali/internal/update/common/property-owner.cpp +++ b/dali/internal/update/common/property-owner.cpp @@ -143,6 +143,7 @@ void PropertyOwner::RemoveConstraint( ConstraintBase* constraint ) } PropertyOwner::PropertyOwner() +:mPropertyDirty( false ) { } @@ -171,7 +172,15 @@ void PropertyOwner::RemoveUniformMapObserver( UniformMap::Observer& observer ) mUniformMaps.RemoveObserver( observer ); } +void PropertyOwner::SetPropertyDirty( bool value ) +{ + mPropertyDirty = value; +} +bool PropertyOwner::IsPropertyDirty() const +{ + return mPropertyDirty; +} } // namespace SceneGraph diff --git a/dali/internal/update/common/property-owner.h b/dali/internal/update/common/property-owner.h old mode 100644 new mode 100755 index 843a19b16..637d82b6a --- a/dali/internal/update/common/property-owner.h +++ b/dali/internal/update/common/property-owner.h @@ -206,6 +206,18 @@ public: */ void RemoveUniformMapObserver( UniformMap::Observer& observer ); + /** + * Set whether property has changed to run following a render. + * @param[in] value Set to true if the property has changed + */ + virtual void SetPropertyDirty( bool value ); + + /** + * Query the property status following rendering of a frame. + * @return True if the property has changed + */ + virtual bool IsPropertyDirty() const; + protected: @@ -226,6 +238,7 @@ protected: OwnedPropertyContainer mCustomProperties; ///< Properties provided with InstallCustomProperty() UniformMap mUniformMaps; ///< Container of owned uniform maps + bool mPropertyDirty:1; ///< Required for marking it dirty in case of partial update. private: diff --git a/dali/internal/update/manager/render-instruction-processor.cpp b/dali/internal/update/manager/render-instruction-processor.cpp old mode 100644 new mode 100755 index 204a472f3..9bed5131c --- a/dali/internal/update/manager/render-instruction-processor.cpp +++ b/dali/internal/update/manager/render-instruction-processor.cpp @@ -33,6 +33,7 @@ #include #include #include +#include namespace { @@ -161,8 +162,8 @@ inline void AddRendererToRenderList( BufferIndex updateBufferIndex, { bool inside( true ); Node* node = renderable.mNode; - - if( cull && renderable.mRenderer && !renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) ) + bool geomertryModified = false; + if( cull && renderable.mRenderer && !( geomertryModified = renderable.mRenderer->GetShader().HintEnabled( Dali::Shader::Hint::MODIFIES_GEOMETRY ) ) ) { const Vector4& boundingSphere = node->GetBoundingSphere(); inside = ( boundingSphere.w > Math::MACHINE_EPSILON_1000 ) && @@ -180,17 +181,27 @@ inline void AddRendererToRenderList( BufferIndex updateBufferIndex, item.mNode = renderable.mNode; item.mIsOpaque = ( opacityType == Renderer::OPAQUE ); item.mDepthIndex = 0; + item.mPartialUpdateEnabled = false; - if(!isLayer3d) + if( !isLayer3d ) { item.mDepthIndex = renderable.mNode->GetDepthIndex(); } + if( isLayer3d || geomertryModified ) + { + renderList.SetPartialUpdateEnabled( false ); + } if( DALI_LIKELY( renderable.mRenderer ) ) { item.mRenderer = &renderable.mRenderer->GetRenderer(); item.mTextureSet = renderable.mRenderer->GetTextures(); item.mDepthIndex += renderable.mRenderer->GetDepthIndex(); + + if( FaceCullingMode::NONE != renderable.mRenderer->GetFaceCullingMode() ) + { + renderList.SetPartialUpdateEnabled( false ); + } } else { @@ -201,13 +212,28 @@ inline void AddRendererToRenderList( BufferIndex updateBufferIndex, node->GetWorldMatrixAndSize( item.mModelMatrix, item.mSize ); Matrix::Multiply( item.mModelViewMatrix, item.mModelMatrix, viewMatrix ); - } - node->SetCulled( updateBufferIndex, false ); + if( DALI_LIKELY( item.mRenderer ) && renderList.IsPartialUpdateEnabled() ) + { + if( node->IsPropertyDirty() || node->IsComponentChanged() ) + { + item.mPartialUpdateEnabled = true; + + item.mUpdateSizeHint = item.mSize; + Vector3 updateSizeHint = Vector3::ZERO; + node->GetUpdateSizeHint( updateBufferIndex, updateSizeHint ); + if( updateSizeHint != Vector3::ZERO ) + { + item.mUpdateSizeHint = updateSizeHint; + } + } + } + } + node->SetCulled( updateBufferIndex, false ); } else { - node->SetCulled( updateBufferIndex, true ); + node->SetCulled( updateBufferIndex, true ); } } @@ -434,6 +460,10 @@ void RenderInstructionProcessor::Prepare( BufferIndex updateBufferIndex, if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) ) { renderList->SetHasColorRenderItems( true ); + if( !isLayer3D ) + { + renderList->SetPartialUpdateEnabled( true ); + } AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, @@ -456,6 +486,10 @@ void RenderInstructionProcessor::Prepare( BufferIndex updateBufferIndex, if( !SetupRenderList( renderables, layer, instruction, tryReuseRenderList, &renderList ) ) { renderList->SetHasColorRenderItems( false ); + if( !isLayer3D ) + { + renderList->SetPartialUpdateEnabled( true ); + } AddRenderersToRenderList( updateBufferIndex, *renderList, renderables, diff --git a/dali/internal/update/manager/transform-manager.cpp b/dali/internal/update/manager/transform-manager.cpp old mode 100644 new mode 100755 index c2cc4bbd5..01804625a --- a/dali/internal/update/manager/transform-manager.cpp +++ b/dali/internal/update/manager/transform-manager.cpp @@ -106,6 +106,10 @@ TransformId TransformManager::CreateTransform() mSizeBase.PushBack(Vector3(0.0f,0.0f,0.0f)); mComponentDirty.PushBack(false); mLocalMatrixDirty.PushBack(false); + mComponentChanged.PushBack(false); + mPrevWorld.PushBack(Matrix::IDENTITY); + mUpdateSizeHint.PushBack(Vector3(0.0f,0.0f,0.0f)); + mUpdateSizeHintBase.PushBack(Vector3(0.0f,0.0f,0.0f)); } else { @@ -123,6 +127,10 @@ TransformId TransformManager::CreateTransform() mSizeBase[mComponentCount] = Vector3(0.0f,0.0f,0.0f); mComponentDirty[mComponentCount] = false; mLocalMatrixDirty[mComponentCount] = false; + mComponentChanged[mComponentCount] = false; + mPrevWorld[mComponentCount].SetIdentity(); + mUpdateSizeHint[mComponentCount] = Vector3(0.0f,0.0f,0.0f); + mUpdateSizeHintBase[mComponentCount] = Vector3(0.0f,0.0f,0.0f); } mComponentCount++; @@ -146,6 +154,10 @@ void TransformManager::RemoveTransform(TransformId id) mComponentDirty[index] = mComponentDirty[mComponentCount]; mLocalMatrixDirty[index] = mLocalMatrixDirty[mComponentCount]; mBoundingSpheres[index] = mBoundingSpheres[mComponentCount]; + mComponentChanged[index] = mComponentChanged[mComponentCount]; + mPrevWorld[index] = mPrevWorld[mComponentCount]; + mUpdateSizeHint[index] = mUpdateSizeHint[mComponentCount]; + mUpdateSizeHintBase[index] = mUpdateSizeHintBase[mComponentCount]; TransformId lastItemId = mComponentId[mComponentCount]; mIds[ lastItemId ] = index; @@ -215,7 +227,6 @@ void TransformManager::SetInheritOrientation( TransformId id, bool inherit ) { mInheritanceMode[ index ] &= ~INHERIT_ORIENTATION; } - mComponentDirty[index] = true; } @@ -226,6 +237,7 @@ void TransformManager::ResetToBaseValue() memcpy( &mTxComponentAnimatable[0], &mTxComponentAnimatableBaseValue[0], sizeof(TransformComponentAnimatable)*mComponentCount ); memcpy( &mSize[0], &mSizeBase[0], sizeof(Vector3)*mComponentCount ); memset( &mLocalMatrixDirty[0], false, sizeof(bool)*mComponentCount ); + memcpy( &mUpdateSizeHint[0], &mUpdateSizeHintBase[0], sizeof(Vector3)*mComponentCount ); } } @@ -246,6 +258,8 @@ void TransformManager::Update() const Vector3 topLeft( 0.0f, 0.0f, 0.5f ); for( unsigned int i(0); i mSize; ///< Size of the components Vector< TransformId > mParent; ///< Parent of the components Vector< Matrix > mWorld; ///< Local to world transform of the components + Vector< Matrix > mPrevWorld; ///< Local to world transform of the components in last frame Vector< Matrix > mLocal; ///< Local to parent space transform of the components Vector< Vector4 > mBoundingSpheres; ///< Bounding spheres. xyz is the center and w is the radius Vector< TransformComponentAnimatable > mTxComponentAnimatableBaseValue; ///< Base values for the animatable part of the components @@ -390,6 +407,9 @@ private: Vector< bool > mComponentDirty; ///< 1u if some of the parts of the component has changed in this frame, 0 otherwise Vector< bool > mLocalMatrixDirty; ///< 1u if the local matrix has been updated in this frame, 0 otherwise Vector< SOrderItem > mOrderedComponents; ///< Used to reorder components when hierarchy changes + Vector< bool> mComponentChanged; ///< Component is changed or not + Vector< Vector3 > mUpdateSizeHint; ///< BoundingBox of the components + Vector< Vector3 > mUpdateSizeHintBase; ///< Base value for the boundingBox of the components bool mReorder; ///< Flag to determine if the components have to reordered in the next Update }; diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp old mode 100644 new mode 100755 index 571e8b34b..b2390ab20 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -426,6 +426,8 @@ void UpdateManager::ConnectNode( Node* parent, Node* node ) parent->ConnectChild( node ); + parent->SetPropertyDirty( true ); + // Inform the frame-callback-processor, if set, about the node-hierarchy changing if( mImpl->frameCallbackProcessor ) { diff --git a/dali/internal/update/nodes/node-declarations.h b/dali/internal/update/nodes/node-declarations.h old mode 100644 new mode 100755 diff --git a/dali/internal/update/nodes/node-messages.h b/dali/internal/update/nodes/node-messages.h old mode 100644 new mode 100755 index 3fdb2e26e..a005dd348 --- a/dali/internal/update/nodes/node-messages.h +++ b/dali/internal/update/nodes/node-messages.h @@ -105,6 +105,7 @@ public: */ virtual void Process( BufferIndex updateBufferIndex ) { + mNode->SetPropertyDirty( true ); (mProperty->*mMemberFunction)( updateBufferIndex, mParam ); } @@ -186,6 +187,7 @@ public: */ virtual void Process( BufferIndex updateBufferIndex ) { + mNode->SetPropertyDirty( true ); (mProperty->*mMemberFunction)( updateBufferIndex, mParam ); } @@ -265,6 +267,7 @@ public: */ virtual void Process( BufferIndex updateBufferIndex ) { + mNode->SetPropertyDirty( true ); (mProperty->*mMemberFunction)( updateBufferIndex, mParam ); } @@ -344,6 +347,7 @@ public: */ virtual void Process( BufferIndex updateBufferIndex ) { + mNode->SetPropertyDirty( true ); (mProperty->*mMemberFunction)( updateBufferIndex, mParam ); } diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index d80d7c45f..5fbb64d43 100755 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -87,6 +87,7 @@ Node::Node() mPosition( TRANSFORM_PROPERTY_POSITION ), // Zero initialized by default mOrientation(), // Initialized to identity by default mScale( TRANSFORM_PROPERTY_SCALE ), + mUpdateSizeHint( TRANSFORM_PROPERTY_UPDATE_SIZE_HINT ), mVisible( true ), mCulled( false ), mColor( Color::WHITE ), @@ -114,6 +115,7 @@ Node::Node() { mUniformMapChanged[0] = 0u; mUniformMapChanged[1] = 0u; + mPropertyDirty = true; #ifdef DEBUG_ENABLED gNodeCount++; @@ -153,6 +155,7 @@ void Node::CreateTransform( SceneGraph::TransformManager* transformManager ) //Initialize all the animatable properties mPosition.Initialize( transformManager, mTransformId ); mScale.Initialize( transformManager, mTransformId ); + mUpdateSizeHint.Initialize( transformManager, mTransformId ); mOrientation.Initialize( transformManager, mTransformId ); mSize.Initialize( transformManager, mTransformId ); mParentOrigin.Initialize( transformManager, mTransformId ); @@ -283,15 +286,23 @@ void Node::AddRenderer( Renderer* renderer ) } mRenderer.PushBack( renderer ); + SetPropertyDirty( true ); } + void Node::RemoveRenderer( const Renderer* renderer ) { + Node *parent = mIsRoot ? NULL : GetParent(); RendererContainer::SizeType rendererCount( mRenderer.Size() ); for( RendererContainer::SizeType i = 0; i < rendererCount; ++i ) { if( mRenderer[i] == renderer ) { + if( parent != NULL ) + { + parent->mPropertyDirty = true; + } + SetPropertyDirty( true ); mRenderer.Erase( mRenderer.Begin()+i); return; } @@ -331,6 +342,9 @@ NodePropertyFlags Node::GetInheritedDirtyFlags( NodePropertyFlags parentFlags ) void Node::ResetDirtyFlags( BufferIndex updateBufferIndex ) { mDirtyFlags = NodePropertyFlags::NOTHING; + + SetPropertyDirty( false ); + } void Node::SetParent( Node& parentNode ) @@ -373,6 +387,33 @@ void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex ) } } +void Node::SetPropertyDirty( bool value ) +{ + mPropertyDirty = value; + + const NodeIter endIter = mChildren.End(); + for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter ) + { + Node* current = *iter; + current->SetPropertyDirty( value ); + } +} + +bool Node::IsPropertyDirty() const +{ + if( !mPropertyDirty ) + { + for( auto&& existingRenderer : mRenderer ) + { + if( existingRenderer->IsDirty() ) + { + return true; + } + } + } + return mPropertyDirty; +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index 5cd607379..e349e1064 100755 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -182,6 +182,7 @@ public: */ void SetClippingMode( const ClippingMode::Type clippingMode ) { + SetPropertyDirty( true ); mClippingMode = clippingMode; } @@ -313,6 +314,7 @@ public: */ void SetDirtyFlag( NodePropertyFlags flag ) { + SetPropertyDirty( true ); mDirtyFlags |= flag; } @@ -321,6 +323,7 @@ public: */ void SetAllDirtyFlags() { + SetPropertyDirty( true ); mDirtyFlags = NodePropertyFlags::ALL; } @@ -684,6 +687,7 @@ public: */ void SetDrawMode( const DrawMode::Type& drawMode ) { + SetPropertyDirty( true ); mDrawMode = drawMode; } @@ -720,6 +724,7 @@ public: */ void SetDepthIndex( uint32_t depthIndex ) { + SetPropertyDirty( true ); mDepthIndex = depthIndex; } @@ -765,6 +770,40 @@ public: return mCulled[bufferIndex]; } + /** + * @Is component changed + * @Return true if component is changed else false + */ + bool IsComponentChanged() const + { + return (mTransformId != INVALID_TRANSFORM_ID) && + (mTransformManager->IsComponentChanged( mTransformId )); + } + + /** + * Retrieve the update size hint of the node + * @return A vector3 describing the update size hint + */ + void GetUpdateSizeHint( BufferIndex bufferIndex, Vector3& updateSizeHint ) const + { + if( mTransformId != INVALID_TRANSFORM_ID ) + { + mTransformManager->GetUpdateSizeHint( mTransformId, updateSizeHint ); + } + } + + /** + * Set whether partial update needs to run following a render. + * @param[in] value Set to true if an partial update is required to be run + */ + virtual void SetPropertyDirty( bool value ); + + /** + * Query the property status following rendering of a frame. + * @return True if the property has changed + */ + virtual bool IsPropertyDirty() const; + public: /** * @copydoc UniformMap::Add @@ -877,6 +916,7 @@ public: // Default properties TransformManagerPropertyVector3 mPosition; ///< Local transform; distance between parent-origin & anchor-point TransformManagerPropertyQuaternion mOrientation; ///< Local transform; rotation relative to parent node TransformManagerPropertyVector3 mScale; ///< Local transform; scale relative to parent node + TransformManagerPropertyVector3 mUpdateSizeHint; ///< Local transform; update size hint is provided for partial update AnimatableProperty mVisible; ///< Visibility can be inherited from the Node hierachy AnimatableProperty mCulled; ///< True if the node is culled. This is not animatable. It is just double-buffered. diff --git a/dali/internal/update/nodes/scene-graph-layer.cpp b/dali/internal/update/nodes/scene-graph-layer.cpp index 8f9ff00b7..d23419cfd 100755 --- a/dali/internal/update/nodes/scene-graph-layer.cpp +++ b/dali/internal/update/nodes/scene-graph-layer.cpp @@ -64,6 +64,7 @@ void Layer::SetSortFunction( Dali::Layer::SortFunctionType function ) { if( mSortFunction != function ) { + SetPropertyDirty( true ); // is a custom sort function used if( function != Internal::Layer::ZValue ) { @@ -84,21 +85,25 @@ void Layer::SetSortFunction( Dali::Layer::SortFunctionType function ) void Layer::SetClipping(bool enabled) { mIsClipping = enabled; + SetPropertyDirty( true ); } void Layer::SetClippingBox(const Dali::ClippingBox& box) { mClippingBox.Set(box.x, box.y, box.width, box.height); + SetPropertyDirty( true ); } void Layer::SetBehavior( Dali::Layer::Behavior behavior ) { mBehavior = behavior; + SetPropertyDirty( true ); } void Layer::SetDepthTestDisabled( bool disable ) { mDepthTestDisabled = disable; + SetPropertyDirty( true ); } bool Layer::IsDepthTestDisabled() const diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp old mode 100644 new mode 100755 index 169be5c82..b7180cb64 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -143,6 +143,7 @@ Renderer::Renderer() mDepthTestMode( DepthTestMode::AUTO ), mRenderingBehavior( DevelRenderer::Rendering::IF_REQUIRED ), mPremultipledAlphaEnabled( false ), + mDirty( false ), mOpacity( 1.0f ), mDepthIndex( 0 ) { @@ -175,12 +176,14 @@ void Renderer::operator delete( void* ptr ) void Renderer::PrepareRender( BufferIndex updateBufferIndex ) { + SetDirty( false ); if( mRegenerateUniformMap == UNIFORM_MAP_READY ) { mUniformMapChanged[updateBufferIndex] = false; } else { + mDirty = true; if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP) { CollectedUniformMap& localMap = mCollectedUniformMap[ updateBufferIndex ]; @@ -215,6 +218,7 @@ void Renderer::PrepareRender( BufferIndex updateBufferIndex ) if( mResendFlag != 0 ) { + mDirty = true; if( mResendFlag & RESEND_GEOMETRY ) { typedef MessageValue1< Render::Renderer, Render::Geometry* > DerivedType; @@ -395,6 +399,7 @@ void Renderer::SetGeometry( Render::Geometry* geometry ) void Renderer::SetDepthIndex( int depthIndex ) { mDepthIndex = depthIndex; + mDirty = true; } void Renderer::SetFaceCullingMode( FaceCullingMode::Type faceCullingMode ) @@ -411,6 +416,7 @@ FaceCullingMode::Type Renderer::GetFaceCullingMode() const void Renderer::SetBlendMode( BlendMode::Type blendingMode ) { mBlendMode = blendingMode; + mDirty = true; } BlendMode::Type Renderer::GetBlendMode() const @@ -583,6 +589,7 @@ const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() cons void Renderer::BakeOpacity( BufferIndex updateBufferIndex, float opacity ) { + mDirty = true; mOpacity.Bake( updateBufferIndex, opacity ); } @@ -594,6 +601,7 @@ float Renderer::GetOpacity( BufferIndex updateBufferIndex ) const void Renderer::SetRenderingBehavior( DevelRenderer::Rendering::Type renderingBehavior ) { mRenderingBehavior = renderingBehavior; + mDirty = true; } DevelRenderer::Rendering::Type Renderer::GetRenderingBehavior() const @@ -612,7 +620,6 @@ void Renderer::ConnectToSceneGraph( SceneController& sceneController, BufferInde mRenderer = Render::Renderer::New( mRenderDataProvider, mGeometry, mBlendBitmask, GetBlendColor(), static_cast< FaceCullingMode::Type >( mFaceCullingMode ), mPremultipledAlphaEnabled, mDepthWriteMode, mDepthTestMode, mDepthFunction, mStencilParameters ); - OwnerPointer< Render::Renderer > transferOwnership( mRenderer ); mSceneController->GetRenderMessageDispatcher().AddRenderer( transferOwnership ); } @@ -650,6 +657,7 @@ void Renderer::UpdateTextureSet() mRenderDataProvider->mTextures.clear(); mRenderDataProvider->mSamplers.clear(); } + mDirty = true; } } @@ -755,6 +763,49 @@ void Renderer::ObservedObjectDestroyed(PropertyOwner& owner) } } +void Renderer::SetDirty( bool value ) +{ + mDirty = value; + if( mShader ) + { + mShader->SetPropertyDirty( value ); + } +} + +bool Renderer::IsDirty() const +{ + bool ret = false; + + if( !mDirty ) + { + if( mShader ) + { + ret = mShader->IsPropertyDirty(); + } + + // check native image + if( !ret && mTextureSet ) + { + uint32_t textureCount = mTextureSet->GetTextureCount(); + + if(textureCount > 0) + { + Dali::Internal::Render::Texture* texture; + for( uint32_t i = 0; i(mTextureSet)->GetTexture(i); + if( texture && texture->IsNativeImage() ) + { + ret = true; + break; + } + } + } + } + } + return ret | mDirty; +} + } // namespace SceneGraph } // namespace Internal } // namespace Dali diff --git a/dali/internal/update/rendering/scene-graph-renderer.h b/dali/internal/update/rendering/scene-graph-renderer.h index 7051e4437..3dda87397 100755 --- a/dali/internal/update/rendering/scene-graph-renderer.h +++ b/dali/internal/update/rendering/scene-graph-renderer.h @@ -380,6 +380,18 @@ public: */ void DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex ); + /** + * Enable/Disable Partial update dirty flag + * @param[in] true to mark dirty else false + */ + void SetDirty( bool value ); + + /** + * Get Partial update dirty flag + * @return true if dirty else false + */ + bool IsDirty() const; + public: // Implementation of ConnectionChangePropagator /** * @copydoc ConnectionChangePropagator::AddObserver @@ -473,6 +485,7 @@ private: bool mUniformMapChanged[2]; ///< Records if the uniform map has been altered this frame bool mPremultipledAlphaEnabled:1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required + bool mDirty:1; ///< Required for marking it dirty in case of partial update. public: -- 2.34.1