utc-Dali-Extents.cpp
utc-Dali-FrameBuffer.cpp
utc-Dali-FrameBufferImage.cpp
+ utc-Dali-FrameCallbackInterface.cpp
utc-Dali-Geometry.cpp
utc-Dali-Gesture.cpp
utc-Dali-GestureDetector.cpp
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+#include <dali/devel-api/common/map-wrapper.h>
+#include <dali/devel-api/common/stage-devel.h>
+#include <dali/devel-api/update/frame-callback-interface.h>
+#include <dali/devel-api/update/update-proxy.h>
+#include <dali-test-suite-utils.h>
+
+using namespace Dali;
+
+void utc_dali_frame_callback_interface_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_frame_callback_interface_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace
+{
+
+class FrameCallbackBasic : public FrameCallbackInterface
+{
+public:
+
+ FrameCallbackBasic()
+ : mCalled( false )
+ {
+ }
+
+ virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
+ {
+ mCalled = true;
+ }
+
+ bool mCalled;
+};
+
+} // anon namespace
+
+class FrameCallbackOneActor : public FrameCallbackBasic
+{
+public:
+
+ FrameCallbackOneActor( unsigned int actorId )
+ : mActorId( actorId )
+ {
+ }
+
+ virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
+ {
+ FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
+ updateProxy.GetWorldMatrixAndSize( mActorId, mWorldMatrix, mSize );
+ mWorldMatrixGetWorldMatrixCall = updateProxy.GetWorldMatrix( mActorId );
+ mSizeGetSizeCall = updateProxy.GetSize( mActorId );
+ mPositionGetPositionCall = updateProxy.GetPosition( mActorId );
+ updateProxy.GetPositionAndSize( mActorId, mPositionGetPositionAndSizeCall, mSizeGetPositionAndSizeCall );
+ mWorldColor = updateProxy.GetWorldColor( mActorId );
+ }
+
+ const unsigned int mActorId;
+
+ Matrix mWorldMatrix;
+ Matrix mWorldMatrixGetWorldMatrixCall;
+ Vector3 mSize;
+ Vector3 mSizeGetSizeCall;
+ Vector3 mPositionGetPositionCall;
+ Vector3 mPositionGetPositionAndSizeCall;
+ Vector3 mSizeGetPositionAndSizeCall;
+ Vector4 mWorldColor;
+};
+
+class FrameCallbackSetter : public FrameCallbackBasic
+{
+public:
+
+ FrameCallbackSetter(
+ unsigned int actorId,
+ const Matrix& matrixToSet,
+ const Vector3& sizeToSet,
+ const Vector3& positionToSet,
+ const Vector4& colorToSet )
+ : mActorId( actorId ),
+ mMatrixToSet( matrixToSet ),
+ mSizeToSet( sizeToSet ),
+ mPositionToSet( positionToSet ),
+ mColorToSet( colorToSet )
+ {
+ }
+
+ virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
+ {
+ FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
+ updateProxy.SetWorldMatrix( mActorId, mMatrixToSet );
+ updateProxy.SetSize( mActorId, mSizeToSet );
+ updateProxy.GetWorldMatrixAndSize( mActorId, mWorldMatrixAfterSetting, mSizeAfterSetting );
+ updateProxy.SetPosition( mActorId, mPositionToSet );
+ mPositionAfterSetting = updateProxy.GetPosition( mActorId );
+ updateProxy.SetWorldColor( mActorId, mColorToSet );
+ mColorAfterSetting = updateProxy.GetWorldColor( mActorId );
+ }
+
+ const unsigned int mActorId;
+ const Matrix& mMatrixToSet;
+ const Vector3& mSizeToSet;
+ const Vector3& mPositionToSet;
+ const Vector4& mColorToSet;
+
+ Matrix mWorldMatrixAfterSetting;
+ Vector3 mSizeAfterSetting;
+ Vector3 mPositionAfterSetting;
+ Vector4 mColorAfterSetting;
+};
+
+class FrameCallbackMultipleActors : public FrameCallbackBasic
+{
+public:
+
+ FrameCallbackMultipleActors()
+ {
+ }
+
+ virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
+ {
+ FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
+ for( auto&& i : mActorIds )
+ {
+ Matrix matrix( false );
+ Vector3 size;
+ updateProxy.GetWorldMatrixAndSize( i, matrix, size );
+ mWorldMatrices[ i ] = matrix;
+ mSizes[ i ] = size;
+ }
+ }
+
+ Vector< unsigned int > mActorIds;
+
+ std::map< unsigned int, Matrix > mWorldMatrices;
+ std::map< unsigned int, Vector3 > mSizes;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+int UtcDaliFrameCallbackCheckInstallationAndRemoval(void)
+{
+ TestApplication application;
+
+ FrameCallbackBasic frameCallback;
+
+ Stage stage = Stage::GetCurrent();
+ DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
+
+ frameCallback.mCalled = false;
+
+ DevelStage::RemoveFrameCallback( stage, frameCallback );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( frameCallback.mCalled, false, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliFrameCallbackGetters(void)
+{
+ TestApplication application;
+ Vector2 actorSize( 200, 300 );
+ Vector4 color( 0.5f, 0.6f, 0.7f, 0.8f );
+ Vector3 position( 10.0f, 20.0f, 30.0f );
+
+ Actor actor = Actor::New();
+ actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ actor.SetSize( actorSize );
+ actor.SetColor( color );
+ actor.SetPosition( position );
+
+ Stage stage = Stage::GetCurrent();
+ stage.Add( actor );
+ Vector2 stageSize = stage.GetSize();
+
+ FrameCallbackOneActor frameCallback( actor.GetId() );
+ DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector3 expectedPosition( -stageSize.width * 0.5f + actorSize.width * 0.5f + position.x,
+ -stageSize.height * 0.5f + actorSize.height * 0.5f + position.y,
+ 0.0f + position.z );
+
+ Matrix expectedWorldMatrix( false );
+ expectedWorldMatrix.SetIdentity();
+ expectedWorldMatrix.SetTranslation( expectedPosition );
+
+ DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mWorldMatrix, expectedWorldMatrix, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mWorldMatrixGetWorldMatrixCall, expectedWorldMatrix, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mSize, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mSizeGetSizeCall, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mPositionGetPositionCall, expectedPosition, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mPositionGetPositionAndSizeCall, expectedPosition, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mSizeGetPositionAndSizeCall, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mWorldColor, color, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliFrameCallbackSetters(void)
+{
+ TestApplication application;
+ Vector2 actorSize( 200, 300 );
+
+ Actor actor = Actor::New();
+ actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ actor.SetSize( actorSize );
+
+ Stage stage = Stage::GetCurrent();
+ stage.Add( actor );
+ Vector2 stageSize = stage.GetSize();
+
+ Matrix matrixToSet( Matrix::IDENTITY );
+ matrixToSet.SetTranslation( Vector3( 100.0f, 500.0f, 50.0f ) );
+ Vector3 sizeToSet( 1.0f, 2.0f, 3.0f );
+ Vector3 positionToSet( 10.0f, 20.0f, 30.0f );
+ Vector4 colorToSet( Color::MAGENTA );
+
+ FrameCallbackSetter frameCallback( actor.GetId(), matrixToSet, sizeToSet, positionToSet, colorToSet );
+ DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
+
+ application.SendNotification();
+ application.Render();
+
+ Matrix expectedWorldMatrix( false );
+ expectedWorldMatrix.SetIdentity();
+ expectedWorldMatrix.SetTranslation( Vector3( -stageSize.width * 0.5f + actorSize.width * 0.5f,
+ -stageSize.height * 0.5f + actorSize.height * 0.5f,
+ 0.0f ) );
+
+ DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
+ DALI_TEST_CHECK( expectedWorldMatrix != matrixToSet );
+ DALI_TEST_EQUALS( frameCallback.mWorldMatrixAfterSetting, matrixToSet, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mSizeAfterSetting, sizeToSet, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mPositionAfterSetting, positionToSet, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mColorAfterSetting, colorToSet, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliFrameCallbackMultipleActors(void)
+{
+ /**
+ * Tree:
+ * root-layer
+ * / \
+ * / \
+ * / \
+ * / \
+ * actorA actorE
+ * / \ / \
+ * / \ / \
+ * actorB actorD actorF actorG
+ * / \
+ * actorC actorH
+ *
+ * Screen positions:
+ * -----------------------
+ * |actorA|actorD |
+ * | actorB |
+ * | actorC |
+ * | |
+ * | |
+ * | |
+ * | |
+ * | |
+ * |actorF actorH |
+ * |actorE|actorG |
+ * -----------------------
+ */
+
+ TestApplication application;
+ Stage stage = Stage::GetCurrent();
+ const Vector2 stageSize = stage.GetSize();
+
+ std::map< char, Vector3 > sizes;
+ sizes['A'] = Vector3( 50.0f, 50.0f, 0.0f );
+ sizes['B'] = Vector3( 100.0f, 100.0f, 0.0f );
+ sizes['C'] = Vector3( 150.0f, 150.0f, 0.0f );
+ sizes['D'] = Vector3( 200.0f, 200.0f, 0.0f );
+ sizes['E'] = Vector3( 250.0f, 250.0f, 0.0f );
+ sizes['F'] = Vector3( 300.0f, 300.0f, 0.0f );
+ sizes['G'] = Vector3( 350.0f, 350.0f, 0.0f );
+ sizes['H'] = Vector3( 400.0f, 350.0f, 0.0f );
+
+ std::map< char, Matrix > matrices;
+ for( char i = 'A'; i <= 'H'; ++i )
+ {
+ matrices[i] = Matrix::IDENTITY;
+ }
+
+ matrices['A'].SetTranslation( Vector3( -stageSize.width * 0.5f + sizes['A'].width * 0.5f,
+ -stageSize.height * 0.5f + sizes['A'].height * 0.5f,
+ 0.0f ) );
+ matrices['B'].SetTranslation( Vector3( matrices['A'].GetTranslation3() + sizes['A'] * 0.5f + sizes['B'] * 0.5f ) );
+ matrices['C'].SetTranslation( Vector3( matrices['B'].GetTranslation3().x,
+ matrices['B'].GetTranslation3().y + sizes['B'].height * 0.5f + sizes['C'].height * 0.5f,
+ 0.0f ) );
+ matrices['D'].SetTranslation( Vector3( matrices['A'].GetTranslation3().x + sizes['A'].width * 0.5f + sizes['D'].width * 0.5f,
+ matrices['A'].GetTranslation3().y,
+ 0.0f ) );
+ matrices['E'].SetTranslation( Vector3( -stageSize.width * 0.5f + sizes['E'].width * 0.5f,
+ stageSize.height * 0.5f - sizes['E'].height * 0.5f,
+ 0.0f ) );
+ matrices['F'].SetTranslation( Vector3( matrices['E'].GetTranslation3().x,
+ matrices['E'].GetTranslation3().y - sizes['E'].height * 0.5f - sizes['F'].height * 0.5f,
+ 0.0f ) );
+ matrices['G'].SetTranslation( Vector3( matrices['E'].GetTranslation3().x + sizes['E'].width * 0.5f + sizes['G'].width * 0.5f,
+ matrices['E'].GetTranslation3().y,
+ 0.0f ) );
+ matrices['H'].SetTranslation( Vector3( matrices['G'].GetTranslation3().x + sizes['G'].width * 0.5f + sizes['H'].width * 0.5f,
+ matrices['G'].GetTranslation3().y - sizes['G'].height * 0.5f - sizes['H'].height * 0.5f,
+ 0.0f ) );
+
+ Actor actorA = Actor::New();
+ actorA.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ actorA.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ actorA.SetSize( sizes['A'] );
+ stage.Add( actorA );
+
+ Actor actorB = Actor::New();
+ actorB.SetParentOrigin( ParentOrigin::BOTTOM_RIGHT );
+ actorB.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ actorB.SetSize( sizes['B'] );
+ actorA.Add( actorB );
+
+ Actor actorC = Actor::New();
+ actorC.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ actorC.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ actorC.SetSize( sizes['C'] );
+ actorB.Add( actorC );
+
+ Actor actorD = Actor::New();
+ actorD.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
+ actorD.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+ actorD.SetSize( sizes['D'] );
+ actorA.Add( actorD );
+
+ Actor actorE = Actor::New();
+ actorE.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
+ actorE.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
+ actorE.SetSize( sizes['E'] );
+ stage.Add( actorE );
+
+ Actor actorF = Actor::New();
+ actorF.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ actorF.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+ actorF.SetSize( sizes['F'] );
+ actorE.Add( actorF );
+
+ Actor actorG = Actor::New();
+ actorG.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
+ actorG.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+ actorG.SetSize( sizes['G'] );
+ actorE.Add( actorG );
+
+ Actor actorH = Actor::New();
+ actorH.SetParentOrigin( ParentOrigin::TOP_RIGHT );
+ actorH.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
+ actorH.SetSize( sizes['H'] );
+ actorG.Add( actorH );
+
+ std::map< char, unsigned int > actorIds;
+ actorIds['A'] = actorA.GetId();
+ actorIds['B'] = actorB.GetId();
+ actorIds['C'] = actorC.GetId();
+ actorIds['D'] = actorD.GetId();
+ actorIds['E'] = actorE.GetId();
+ actorIds['F'] = actorF.GetId();
+ actorIds['G'] = actorG.GetId();
+ actorIds['H'] = actorH.GetId();
+
+ FrameCallbackMultipleActors frameCallback;
+ for( auto&& i : actorIds )
+ {
+ frameCallback.mActorIds.PushBack( i.second );
+ }
+
+ DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
+
+ for( char i = 'A'; i <= 'H'; ++i )
+ {
+ DALI_TEST_EQUALS( frameCallback.mWorldMatrices[ actorIds[ i ] ], matrices[ i ], TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mSizes[ actorIds[ i ] ], sizes[ i ], TEST_LOCATION );
+ }
+
+ // Render again to make sure it still gets called and gives the correct values (in case any optimisations break this)
+ frameCallback.mCalled = false;
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
+
+ for( char i = 'A'; i <= 'H'; ++i )
+ {
+ DALI_TEST_EQUALS( frameCallback.mWorldMatrices[ actorIds[ i ] ], matrices[ i ], TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mSizes[ actorIds[ i ] ], sizes[ i ], TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int UtcDaliFrameCallbackCheckActorNotAdded(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ actor.SetSize( 200, 300 );
+
+ Stage stage = Stage::GetCurrent();
+ FrameCallbackOneActor frameCallback( actor.GetId() );
+ DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mWorldMatrix, Matrix(true) /* Unchanged Matrix */, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mWorldMatrixGetWorldMatrixCall, Matrix::IDENTITY, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mSize, Vector3::ZERO, TEST_LOCATION );
+ DALI_TEST_EQUALS( frameCallback.mSizeGetSizeCall, Vector3::ZERO, TEST_LOCATION );
+
+ END_TEST;
+}
-# 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.
develapiscriptingdir = $(develapidir)/scripting
develapisignalsdir = $(develapidir)/signals
develapithreadingdir = $(develapidir)/threading
+develapiupdatedir = $(develapidir)/update
develapi_HEADERS = $(devel_api_header_files)
develapiactors_HEADERS = $(devel_api_core_actors_header_files)
develapiscripting_HEADERS = $(devel_api_core_scripting_header_files)
develapisignals_HEADERS = $(devel_api_core_signals_header_files)
develapithreading_HEADERS = $(devel_api_core_threading_header_files)
+develapiupdate_HEADERS = $(devel_api_core_update_header_files)
#public api
publicapidir = $(devincludepath)/dali/public-api
return GetImplementation( stage ).GetRenderingBehavior();
}
+void AddFrameCallback( Dali::Stage stage, FrameCallbackInterface& frameCallback, Actor rootActor )
+{
+ GetImplementation( stage ).AddFrameCallback( frameCallback, GetImplementation( rootActor ) );
+}
+
+void RemoveFrameCallback( Dali::Stage stage, FrameCallbackInterface& frameCallback )
+{
+ GetImplementation( stage ).RemoveFrameCallback( frameCallback );
+}
+
} // namespace DevelStage
} // namespace Dali
namespace Dali
{
+class FrameCallbackInterface;
+
namespace DevelStage
{
*/
DALI_CORE_API Rendering GetRenderingBehavior( Dali::Stage stage );
+/*
+ * @brief The FrameCallbackInterface implementation added gets called on every frame from the update-thread.
+ *
+ * @param[in] stage The stage to set the FrameCallbackInterface implementation on
+ * @param[in] frameCallback An implementation of the FrameCallbackInterface
+ * @param[in] rootActor The root-actor in the scene that the callback applies to
+ *
+ * @note Only the rootActor and it's children will be parsed by the UpdateProxy.
+ * @note If the rootActor is destroyed, then the callback is automatically removed
+ * @see FrameCallbackInterface
+ */
+DALI_IMPORT_API void AddFrameCallback( Dali::Stage stage, FrameCallbackInterface& frameCallback, Actor rootActor );
+
+/**
+ * @brief Removes the specified FrameCallbackInterface implementation from being called on every frame.
+ *
+ * @param[in] stage The stage to clear the FrameCallbackInterface on
+ * @param[in] frameCallback The FrameCallbackInterface implementation to remove
+ */
+DALI_IMPORT_API void RemoveFrameCallback( Dali::Stage stage, FrameCallbackInterface& frameCallback );
+
} // namespace DevelStage
} // namespace Dali
$(devel_api_src_dir)/signals/signal-delegate.cpp \
$(devel_api_src_dir)/threading/conditional-wait.cpp \
$(devel_api_src_dir)/threading/mutex.cpp \
- $(devel_api_src_dir)/threading/thread.cpp
+ $(devel_api_src_dir)/threading/thread.cpp \
+ $(devel_api_src_dir)/update/update-proxy.cpp
# Add devel header files here DALi internal developer files used by Adaptor & Toolkit
$(devel_api_src_dir)/threading/conditional-wait.h \
$(devel_api_src_dir)/threading/mutex.h \
$(devel_api_src_dir)/threading/thread.h
+
+devel_api_core_update_header_files = \
+ $(devel_api_src_dir)/update/frame-callback-interface.h \
+ $(devel_api_src_dir)/update/update-proxy.h
--- /dev/null
+#ifndef DALI_FRAME_CALLBACK_INTERFACE_H
+#define DALI_FRAME_CALLBACK_INTERFACE_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+
+namespace Dali
+{
+
+class UpdateProxy;
+
+/**
+ * @brief This interface should be implemented if a callback is required on every frame.
+ *
+ * The Update() method is called from the update-thread after the scene has been updated, and is ready to render.
+ *
+ * As this method is called from the update-thread, no event thread APIs (e.g. Actor::Get...) can be called.
+ * This will invariably lead to crashes.
+ *
+ * Instead, setting and retrieving the values should be done by using the UpdateProxy class returned as a parameter to
+ * the Update() method.
+ *
+ * Actors can be identified using Actor IDs which can be retrieved using Actor::GetId() in the event-thread.
+ * However, calling Actor::GetId() will lead to problems if it is called from the update-thread.
+ * Instead, the Actor IDs should be stored by the implementation of this class or passed via a thread-safe manner from
+ * the event-thread.
+ */
+class DALI_CORE_API FrameCallbackInterface
+{
+public:
+
+ /**
+ * @brief Called from the update-thread after the scene has been updated, and is ready to render.
+ * @param[in] updateProxy Use this to get/set required values for the Actor.
+ * @param[in] elapsedSeconds Time elapsed time since the last frame (in seconds)
+ * @see FrameCallbackInterface
+ */
+ virtual void Update( UpdateProxy& updateProxy, float elapsedSeconds ) = 0;
+
+protected:
+
+ /**
+ * @brief Protected constructor.
+ */
+ FrameCallbackInterface() {}
+
+ /**
+ * @brief Protected virtual destructor.
+ */
+ virtual ~FrameCallbackInterface() {}
+};
+
+} // namespace Dali
+
+#endif // DALI_FRAME_CALLBACK_INTERFACE_H
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/devel-api/update/update-proxy.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/update/manager/update-proxy-impl.h>
+
+namespace Dali
+{
+
+Vector3 UpdateProxy::GetPosition( unsigned int id ) const
+{
+ return mImpl.GetPosition( id );
+}
+
+void UpdateProxy::SetPosition( unsigned int id, const Vector3& position )
+{
+ mImpl.SetPosition( id, position );
+}
+
+const Vector3& UpdateProxy::GetSize( unsigned int id ) const
+{
+ return mImpl.GetSize( id );
+}
+
+void UpdateProxy::SetSize( unsigned int id, const Vector3& size )
+{
+ mImpl.SetSize( id, size );
+}
+
+void UpdateProxy::GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const
+{
+ mImpl.GetPositionAndSize( id, position, size );
+}
+
+Vector4 UpdateProxy::GetWorldColor( unsigned int id ) const
+{
+ return mImpl.GetWorldColor( id );
+}
+
+void UpdateProxy::SetWorldColor( unsigned int id, const Vector4& color ) const
+{
+ mImpl.SetWorldColor( id, color );
+}
+
+void UpdateProxy::GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const
+{
+ mImpl.GetWorldMatrixAndSize( id, worldMatrix, size );
+}
+
+const Matrix& UpdateProxy::GetWorldMatrix( unsigned int id ) const
+{
+ return mImpl.GetWorldMatrix( id );
+}
+
+void UpdateProxy::SetWorldMatrix( unsigned int id, const Matrix& worldMatrix )
+{
+ mImpl.SetWorldMatrix( id, worldMatrix );
+}
+
+UpdateProxy::UpdateProxy( Internal::UpdateProxy& impl )
+: mImpl( impl )
+{
+}
+
+UpdateProxy::~UpdateProxy()
+{
+}
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_UPDATE_PROXY_H
+#define DALI_UPDATE_PROXY_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/vector3.h>
+
+namespace Dali
+{
+
+namespace Internal DALI_INTERNAL
+{
+class UpdateProxy;
+}
+
+/**
+ * @brief This class is used to access data of the actors from the update-thread.
+ *
+ * The Actor API _CANNOT_ be called directly from the update-thread.
+ * This class can be used as a proxy to that required Actor data.
+ * An actor's data can be accessed using the Actor's Unique ID.
+ * The unique ID should be passed to the callback using this class in a thread-safe manner
+ * (as you cannot call Actor::GetId from the update-thread).
+ */
+class DALI_CORE_API UpdateProxy
+{
+public:
+
+ /**
+ * @brief Given the Actor ID, this retrieves that Actor's position.
+ * @param[in] id The Actor ID
+ * @return If valid Actor ID, then the Actor's position is returned.
+ */
+ Vector3 GetPosition( unsigned int id ) const;
+
+ /**
+ * @brief Allows setting an Actor's position from the Frame callback function.
+ * @param[in] id The Actor ID
+ * @param[in] position The position to set.
+ * @note This will get reset to the internally calculated value in the next frame, so will have to be set again.
+ */
+ void SetPosition( unsigned int id, const Vector3& position );
+
+ /**
+ * @brief Given the Actor ID, this retrieves that Actor's size.
+ * @param[in] id The Actor ID
+ * @return If valid Actor ID, then Actor's size is returned, otherwise Vector3::ZERO.
+ */
+ const Vector3& GetSize( unsigned int id ) const;
+
+ /**
+ * @brief Allows setting an Actor's size from the Frame callback function.
+ * @param[in] id The Actor ID
+ * @param[in] size The size to set.
+ * @note This will get reset to the internally calculated value in the next frame, so will have to be set again.
+ */
+ void SetSize( unsigned int id, const Vector3& size );
+
+ /**
+ * @brief Given the Actor ID, this retrieves that Actor's position and size.
+ * @param[in] id The Actor ID
+ * @param[out] position If valid Actor ID, then Actor's position is set
+ * @param[out] size If valid Actor ID, then Actor's size is set
+ */
+ void GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const;
+
+ /**
+ * @brief Given the Actor ID, this retrieves that Actor's color.
+ * @param[in] id The Actor ID
+ * @return If valid Actor ID, then Actor's color is returned, otherwise Vector4::ZERO.
+ */
+ Vector4 GetWorldColor( unsigned int id ) const;
+
+ /**
+ * @brief Allows setting an Actor's color from the Frame callback function.
+ * @param[in] id The Actor ID
+ * @param[in] color The color to set
+ * @note This will get reset to the internally calculated value in the next frame, so will have to be set again.
+ */
+ void SetWorldColor( unsigned int id, const Vector4& color ) const;
+
+ /**
+ * @brief Given the Actor ID, this retrieves that Actor's world-matrix and size.
+ * @param[in] id The Actor ID
+ * @param[out] worldMatrix If valid Actor ID, then Actor's world matrix is set
+ * @param[out] size If valid Actor ID, then Actor's size is set
+ */
+ void GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const;
+
+ /**
+ * @brief Given the Actor ID, this retrieves that Actor's world-matrix.
+ * @param[in] id The Actor ID
+ * @return If valid Actor ID, then Actor's world matrix is returned, otherwise Matrix::IDENTITY.
+ */
+ const Matrix& GetWorldMatrix( unsigned int id ) const;
+
+ /**
+ * @brief Allows the setting an Actor's world-matrix from the Frame callback function.
+ * @param[in] id The Actor ID
+ * @param[in] worldMatrix The world matrix to set.
+ * @note This will get reset to the internally calculated value in the next frame, so will have to be set again.
+ * @note This will only set the world matrix for that particular actor.
+ * The world matrices of the children will not change and will have to be manually changed in the callback
+ * as well (if required).
+ */
+ void SetWorldMatrix( unsigned int id, const Matrix& worldMatrix );
+
+public: // Not intended for application developers
+
+ /// @cond internal
+
+ /**
+ * @brief Constructor.
+ * @param[in] impl A reference to the internal object.
+ */
+ DALI_INTERNAL UpdateProxy( Internal::UpdateProxy& impl );
+
+ /**
+ * @brief Destructor.
+ */
+ DALI_INTERNAL ~UpdateProxy();
+
+ // Not copyable or movable
+
+ UpdateProxy( const UpdateProxy& ) = delete; ///< Deleted copy constructor
+ UpdateProxy( UpdateProxy&& ) = delete; ///< Deleted move constructor
+ UpdateProxy& operator=( const UpdateProxy& ) = delete; ///< Deleted copy assignment operator
+ UpdateProxy& operator=( UpdateProxy&& ) = delete; ///< Deleted move assignment operator
+
+ /// @endcond
+
+private:
+
+ /// @cond internal
+ Internal::UpdateProxy& mImpl;
+ /// @endcond
+};
+
+} // namespace Dali
+
+#endif // DALI_UPDATE_PROXY_H
SceneGraph::Node* Actor::CreateNode() const
{
- return Node::New();
+ return Node::New( mId );
}
bool Actor::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& /* attributes */ )
virtual int GetPropertyComponentIndex( Property::Index index ) const;
/**
+ * Retrieve the actor's node.
+ * @return The node used by this actor
+ */
+ const SceneGraph::Node& GetNode() const
+ {
+ return *mNode;
+ }
+
+ /**
* @copydoc Dali::DevelActor::Raise()
*/
void Raise();
/*
- * 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.
SceneGraph::Node* Layer::CreateNode() const
{
- return SceneGraph::Layer::New();
+ return SceneGraph::Layer::New( mId );
}
void Layer::OnStageConnectionInternal()
return mKeyEventGeneratedSignal;
}
+void Stage::AddFrameCallback( FrameCallbackInterface& frameCallback, Actor& rootActor )
+{
+ AddFrameCallbackMessage( mUpdateManager, frameCallback, rootActor.GetNode() );
+}
+
+void Stage::RemoveFrameCallback( FrameCallbackInterface& frameCallback )
+{
+ RemoveFrameCallbackMessage( mUpdateManager, frameCallback );
+}
+
Dali::Stage::EventProcessingFinishedSignalType& Stage::EventProcessingFinishedSignal()
{
return mEventProcessingFinishedSignal;
Dali::DevelStage::KeyEventGeneratedSignalType& KeyEventGeneratedSignal();
/**
+ * @copydoc Dali::DevelStage::AddFrameCallback()
+ */
+ void AddFrameCallback( FrameCallbackInterface& frameCallback, Actor& rootActor );
+
+ /**
+ * @copydoc Dali::DevelStage::RemoveFrameCallback()
+ */
+ void RemoveFrameCallback( FrameCallbackInterface& frameCallback );
+
+ /**
* Connects a callback function with the object's signals.
* @param[in] object The object providing the signal.
* @param[in] tracker Used to disconnect the signal.
$(internal_src_dir)/update/gestures/pan-gesture-profiling.cpp \
$(internal_src_dir)/update/gestures/scene-graph-pan-gesture.cpp \
$(internal_src_dir)/update/queue/update-message-queue.cpp \
+ $(internal_src_dir)/update/manager/frame-callback-processor.cpp \
$(internal_src_dir)/update/manager/render-instruction-processor.cpp \
$(internal_src_dir)/update/manager/render-task-processor.cpp \
$(internal_src_dir)/update/manager/transform-manager.cpp \
$(internal_src_dir)/update/manager/update-algorithms.cpp \
$(internal_src_dir)/update/manager/update-manager.cpp \
$(internal_src_dir)/update/manager/update-manager-debug.cpp \
+ $(internal_src_dir)/update/manager/update-proxy-impl.cpp \
$(internal_src_dir)/update/render-tasks/scene-graph-camera.cpp \
$(internal_src_dir)/update/nodes/node.cpp \
$(internal_src_dir)/update/nodes/node-messages.cpp \
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/update/manager/frame-callback-processor.h>
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/update/frame-callback-interface.h>
+#include <dali/devel-api/update/update-proxy.h>
+#include <dali/internal/update/manager/update-proxy-impl.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace SceneGraph
+{
+
+namespace
+{
+
+template< typename FrameCallbackInfoT >
+class MatchRootNode
+{
+public:
+
+ MatchRootNode( PropertyOwner& rootNode )
+ : mRootNode( rootNode )
+ {
+ }
+
+ bool operator() ( const FrameCallbackInfoT& info )
+ {
+ return &info.updateProxyImpl->GetRootNode() == &mRootNode;
+ }
+
+private:
+
+ PropertyOwner& mRootNode;
+};
+
+} // unnamed namespace
+
+FrameCallbackProcessor::FrameCallbackProcessor( TransformManager& transformManager, Node& rootNode )
+: mFrameCallbacks(),
+ mTransformManager( transformManager ),
+ mRootNode( rootNode )
+{
+}
+
+FrameCallbackProcessor::~FrameCallbackProcessor()
+{
+}
+
+void FrameCallbackProcessor::AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode )
+{
+ Node& node = const_cast< Node& >( *rootNode ); // Was sent as const from event thread, we need to be able to use non-const version here.
+
+ FrameCallbackInfo info;
+ info.frameCallback = frameCallback;
+ info.updateProxyImpl = new UpdateProxy( mTransformManager, node );
+
+ // We want to be notified when the node is destroyed (if we're not observing it already)
+ auto iter = std::find_if( mFrameCallbacks.begin(), mFrameCallbacks.end(), MatchRootNode< FrameCallbackInfo >( node ) );
+ if( iter == mFrameCallbacks.end() )
+ {
+ node.AddObserver( *this );
+ }
+
+ mFrameCallbacks.push_back( info );
+}
+
+void FrameCallbackProcessor::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
+{
+ auto iter = std::remove_if( mFrameCallbacks.begin(), mFrameCallbacks.end(),
+ [ this, frameCallback ]
+ ( const FrameCallbackInfo& info )
+ {
+ info.updateProxyImpl->GetRootNode().RemoveObserver( *this );
+ delete info.updateProxyImpl;
+ return info.frameCallback == frameCallback;
+ } );
+ mFrameCallbacks.erase( iter, mFrameCallbacks.end() );
+}
+
+void FrameCallbackProcessor::Update( BufferIndex bufferIndex, float elapsedSeconds )
+{
+ for( auto&& iter : mFrameCallbacks )
+ {
+ UpdateProxy& updateProxyImpl = *iter.updateProxyImpl;
+ updateProxyImpl.SetCurrentBufferIndex( bufferIndex );
+ Dali::UpdateProxy updateProxy( updateProxyImpl );
+ iter.frameCallback->Update( updateProxy, elapsedSeconds );
+ }
+}
+
+void FrameCallbackProcessor::PropertyOwnerDestroyed( PropertyOwner& owner )
+{
+ auto iter = std::remove_if( mFrameCallbacks.begin(), mFrameCallbacks.end(), MatchRootNode< FrameCallbackInfo >( owner ) );
+ mFrameCallbacks.erase( iter, mFrameCallbacks.end() );
+}
+
+} // namespace SceneGraph
+
+} // namespace Internal
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_SCENE_GRAPH_FRAME_CALLBACK_PROCESSOR_H
+#define DALI_INTERNAL_SCENE_GRAPH_FRAME_CALLBACK_PROCESSOR_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/internal/common/buffer-index.h>
+#include <dali/internal/update/common/property-owner.h>
+
+namespace Dali
+{
+
+class FrameCallbackInterface;
+
+namespace Internal
+{
+
+class UpdateProxy;
+
+namespace SceneGraph
+{
+
+class Node;
+class TransformManager;
+
+/**
+ * This class processes all the registered frame-callbacks.
+ */
+class FrameCallbackProcessor : public PropertyOwner::Observer
+{
+public:
+
+ /**
+ * Construct a new FrameCallbackProcessor.
+ */
+ FrameCallbackProcessor( TransformManager& transformManager, Node& rootNode );
+
+ /**
+ * Non-virtual Destructor.
+ */
+ ~FrameCallbackProcessor();
+
+ // Movable but not copyable
+
+ FrameCallbackProcessor( const FrameCallbackProcessor& ) = delete; ///< Deleted copy constructor.
+ FrameCallbackProcessor( FrameCallbackProcessor&& ) = default; ///< Default move constructor.
+ FrameCallbackProcessor& operator=( const FrameCallbackProcessor& ) = delete; ///< Deleted copy assignment operator.
+ FrameCallbackProcessor& operator=( FrameCallbackProcessor&& ) = default; ///< Default move assignment operator.
+
+ /**
+ * Adds an implementation of the FrameCallbackInterface.
+ * @param[in] frameCallback A pointer to the implementation of the FrameCallbackInterface
+ * @param[in] rootNode A pointer to the root node to apply the FrameCallback to
+ */
+ void AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode );
+
+ /**
+ * Removes the specified implementation of FrameCallbackInterface.
+ * @param[in] frameCallback A pointer to the implementation of the FrameCallbackInterface to remove.
+ */
+ void RemoveFrameCallback( FrameCallbackInterface* frameCallback );
+
+ /**
+ * Called on Update by the UpdateManager.
+ * @param[in] bufferIndex The bufferIndex to use
+ * @param[in] elapsedSeconds Time elapsed time since the last frame (in seconds)
+ */
+ void Update( BufferIndex bufferIndex, float elapsedSeconds );
+
+private:
+
+ // From PropertyOwner::Observer
+
+ /**
+ * @copydoc PropertyOwner::Observer::PropertyOwnerConnected()
+ */
+ virtual void PropertyOwnerConnected( PropertyOwner& owner ) { /* Nothing to do */ }
+
+ /**
+ * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected()
+ */
+ virtual void PropertyOwnerDisconnected( BufferIndex updateBufferIndex, PropertyOwner& owner ) { /* Nothing to do */ }
+
+ /**
+ * @copydoc PropertyOwner::Observer::PropertyOwnerDisconnected()
+ *
+ * Will use this to disconnect the frame-callback if the accompanying node is destroyed
+ */
+ virtual void PropertyOwnerDestroyed( PropertyOwner& owner );
+
+private:
+
+ struct FrameCallbackInfo
+ {
+ FrameCallbackInterface* frameCallback;
+ UpdateProxy* updateProxyImpl;
+ };
+
+ std::vector< FrameCallbackInfo > mFrameCallbacks;
+
+ TransformManager& mTransformManager;
+ Node& mRootNode;
+};
+
+} // namespace SceneGraph
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_SCENE_GRAPH_FRAME_CALLBACK_PROCESSOR_H
#include <dali/internal/update/controllers/render-message-dispatcher.h>
#include <dali/internal/update/controllers/scene-controller-impl.h>
#include <dali/internal/update/gestures/scene-graph-pan-gesture.h>
+#include <dali/internal/update/manager/frame-callback-processor.h>
#include <dali/internal/update/manager/render-task-processor.h>
#include <dali/internal/update/manager/sorted-layers.h>
#include <dali/internal/update/manager/update-algorithms.h>
shaders(),
panGestureProcessor( NULL ),
messageQueue( renderController, sceneGraphBuffers ),
+ frameCallbackProcessor( NULL ),
keepRenderingSeconds( 0.0f ),
nodeDirtyFlags( TransformFlag ), // set to TransformFlag to ensure full update the first time through Update()
frameCounter( 0 ),
delete sceneController;
}
+ /**
+ * Lazy init for FrameCallbackProcessor.
+ */
+ FrameCallbackProcessor& GetFrameCallbackProcessor()
+ {
+ if( ! frameCallbackProcessor )
+ {
+ frameCallbackProcessor = new FrameCallbackProcessor( transformManager, *root );
+ }
+ return *frameCallbackProcessor;
+ }
+
SceneGraphBuffers sceneGraphBuffers; ///< Used to keep track of which buffers are being written or read
RenderMessageDispatcher renderMessageDispatcher; ///< Used for passing messages to the render-thread
NotificationManager& notificationManager; ///< Queues notification messages for the event-thread.
std::vector<Internal::ShaderDataPtr> updateCompiledShaders; ///< Shaders to be sent from Update to Event
Mutex compiledShaderMutex; ///< lock to ensure no corruption on the renderCompiledShaders
+ OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
+
float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
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.
//Update the transformations of all the nodes
mImpl->transformManager.Update();
+ // Call the frame-callback-processor if set
+ if( mImpl->frameCallbackProcessor )
+ {
+ mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
+ }
+
//Process Property Notifications
ProcessPropertyNotifications( bufferIndex );
return surfaceRectChanged;
}
+void UpdateManager::AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode )
+{
+ mImpl->GetFrameCallbackProcessor().AddFrameCallback( frameCallback, rootNode );
+}
+
+void UpdateManager::RemoveFrameCallback( FrameCallbackInterface* frameCallback )
+{
+ mImpl->GetFrameCallbackProcessor().RemoveFrameCallback( frameCallback );
+}
+
void UpdateManager::AddSampler( OwnerPointer< Render::Sampler >& sampler )
{
// Message has ownership of Sampler while in transit from update to render
namespace Dali
{
+class FrameCallbackInterface;
+
namespace Integration
{
class GlSyncAbstraction;
*/
bool IsDefaultSurfaceRectChanged();
+ /**
+ * Adds an implementation of the FrameCallbackInterface.
+ * @param[in] frameCallback A pointer to the implementation of the FrameCallbackInterface
+ * @param[in] rootNode A pointer to the root node to apply the FrameCallback to
+ */
+ void AddFrameCallback( FrameCallbackInterface* frameCallback, const Node* rootNode );
+
+ /**
+ * Removes the specified implementation of FrameCallbackInterface.
+ * @param[in] frameCallback A pointer to the implementation of the FrameCallbackInterface to remove.
+ */
+ void RemoveFrameCallback( FrameCallbackInterface* frameCallback );
+
private:
// Undefined
new (slot) LocalType( &manager, &UpdateManager::AddPropertyResetter, resetter );
}
+inline void AddFrameCallbackMessage( UpdateManager& manager, FrameCallbackInterface& frameCallback, const Node& rootNode )
+{
+ typedef MessageValue2< UpdateManager, FrameCallbackInterface*, const Node* > 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::AddFrameCallback, &frameCallback, &rootNode );
+}
+
+inline void RemoveFrameCallbackMessage( UpdateManager& manager, FrameCallbackInterface& frameCallback )
+{
+ typedef MessageValue1< UpdateManager, FrameCallbackInterface* > 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::RemoveFrameCallback, &frameCallback );
+}
} // namespace SceneGraph
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/update/manager/update-proxy-impl.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+SceneGraph::Node* FindNodeInSceneGraph( unsigned int id, SceneGraph::Node& node )
+{
+ SceneGraph::Node* matchingNode = NULL;
+
+ if( node.mId == id )
+ {
+ matchingNode = &node;
+ }
+ else
+ {
+ for( auto&& i : node.GetChildren() )
+ {
+ matchingNode = FindNodeInSceneGraph( id, *i );
+ if( matchingNode )
+ {
+ break;
+ }
+ }
+ }
+
+ return matchingNode;
+}
+
+} // unnamed namespace
+
+UpdateProxy::UpdateProxy( SceneGraph::TransformManager& transformManager, SceneGraph::Node& rootNode )
+: mNodeContainer(),
+ mLastCachedIdNodePair( { 0u, NULL } ),
+ mCurrentBufferIndex( 0u ),
+ mTransformManager( transformManager ),
+ mRootNode( rootNode )
+{
+}
+
+UpdateProxy::~UpdateProxy()
+{
+}
+
+Vector3 UpdateProxy::GetPosition( unsigned int id ) const
+{
+ const Dali::Matrix& matrix = GetWorldMatrix( id );
+ return matrix.GetTranslation3();
+}
+
+void UpdateProxy::SetPosition( unsigned int id, const Vector3& position )
+{
+ const SceneGraph::Node* node = GetNodeWithId( id );
+ if( node )
+ {
+ Matrix& matrix = mTransformManager.GetWorldMatrix( node->mTransformId );
+ matrix.SetTranslation( position );
+ }
+}
+
+const Vector3& UpdateProxy::GetSize( unsigned int id ) const
+{
+ const SceneGraph::Node* node = GetNodeWithId( id );
+ if( node )
+ {
+ return mTransformManager.GetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE );
+ }
+
+ return Vector3::ZERO;
+}
+
+void UpdateProxy::SetSize( unsigned int id, const Vector3& size )
+{
+ SceneGraph::Node* node = GetNodeWithId( id );
+ if( node )
+ {
+ mTransformManager.SetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE, size );
+ }
+}
+
+void UpdateProxy::GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const
+{
+ Matrix worldMatrix( false );
+ GetWorldMatrixAndSize( id, worldMatrix, size );
+ position = worldMatrix.GetTranslation3();
+}
+
+Vector4 UpdateProxy::GetWorldColor( unsigned int id ) const
+{
+ SceneGraph::Node* node = GetNodeWithId( id );
+ if( node )
+ {
+ return node->mWorldColor.Get( mCurrentBufferIndex );
+ }
+
+ return Vector4::ZERO;
+}
+
+void UpdateProxy::SetWorldColor( unsigned int id, const Vector4& color ) const
+{
+ SceneGraph::Node* node = GetNodeWithId( id );
+ if( node )
+ {
+ Vector4& currentColor = node->mWorldColor.Get( mCurrentBufferIndex );
+ currentColor = color;
+ }
+}
+
+void UpdateProxy::GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const
+{
+ const SceneGraph::Node* node = GetNodeWithId( id );
+ if( node )
+ {
+ mTransformManager.GetWorldMatrixAndSize( node->mTransformId, worldMatrix, size );
+ }
+}
+
+const Matrix& UpdateProxy::GetWorldMatrix( unsigned int id ) const
+{
+ const SceneGraph::Node* node = GetNodeWithId( id );
+ if( node )
+ {
+ return mTransformManager.GetWorldMatrix( node->mTransformId );
+ }
+
+ return Matrix::IDENTITY;
+}
+
+void UpdateProxy::SetWorldMatrix( unsigned int id, const Matrix& worldMatrix )
+{
+ SceneGraph::Node* node = GetNodeWithId( id );
+ if( node )
+ {
+ Matrix& currentMatrix = mTransformManager.GetWorldMatrix( node->mTransformId );
+ currentMatrix = worldMatrix;
+ }
+}
+
+SceneGraph::Node* UpdateProxy::GetNodeWithId( unsigned int id ) const
+{
+ SceneGraph::Node* node = NULL;
+
+ // Cache the last accessed node so we don't have to traverse
+ if( mLastCachedIdNodePair.node && mLastCachedIdNodePair.id == id )
+ {
+ node = mLastCachedIdNodePair.node;
+ }
+ else
+ {
+ // Find node in vector
+ for( auto&& pair : mNodeContainer )
+ {
+ if( pair.id == id )
+ {
+ node = pair.node;
+ mLastCachedIdNodePair = pair;
+ break;
+ }
+ }
+
+ if( ! node )
+ {
+ // Node not in vector, find in scene-graph
+ node = FindNodeInSceneGraph( id, mRootNode );
+ if( node )
+ {
+ mNodeContainer.push_back( { id, node } );
+ mLastCachedIdNodePair = *mNodeContainer.rbegin();
+ }
+ }
+ }
+
+ return node;
+}
+
+} // namespace Internal
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_UPDATE_PROXY_IMPL_H
+#define DALI_INTERNAL_UPDATE_PROXY_IMPL_H
+
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+
+// INTERNAL INCLUDES
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/vector3.h>
+#include <dali/internal/common/buffer-index.h>
+#include <dali/internal/update/manager/transform-manager.h>
+#include <dali/internal/update/nodes/node.h>
+
+namespace Dali
+{
+
+namespace Internal
+{
+
+/**
+ * @brief The implementation of Dali::UpdateProxy.
+ *
+ * Ref-counting is not required for this object.
+ *
+ * @see Dali::UpdateProxy
+ */
+class UpdateProxy
+{
+public:
+
+ /**
+ * @brief Constructor.
+ * @param[in] transformManager Ref to the TransformManager in order to set/get transform properties of nodes
+ * @param[in] rootNode The root node for this proxy
+ */
+ UpdateProxy( SceneGraph::TransformManager& transformManager, SceneGraph::Node& rootNode );
+
+ /**
+ * @brief Destructor.
+ */
+ ~UpdateProxy();
+
+ // Movable but not copyable
+
+ UpdateProxy( const UpdateProxy& ) = delete; ///< Deleted copy constructor.
+ UpdateProxy( UpdateProxy&& ) = default; ///< Default move constructor.
+ UpdateProxy& operator=( const UpdateProxy& ) = delete; ///< Deleted copy assignment operator.
+ UpdateProxy& operator=( UpdateProxy&& ) = default; ///< Default move assignment operator.
+
+ /**
+ * @copydoc Dali::UpdateProxy::GetPosition()
+ */
+ Vector3 GetPosition( unsigned int id ) const;
+
+ /**
+ * @copydoc Dali::UpdateProxy::SetPosition()
+ */
+ void SetPosition( unsigned int id, const Vector3& position );
+
+ /**
+ * @copydoc Dali::UpdateProxy::GetSize()
+ */
+ const Vector3& GetSize( unsigned int id ) const;
+
+ /**
+ * @copydoc Dali::UpdateProxy::SetSize()
+ */
+ void SetSize( unsigned int id, const Vector3& size );
+
+ /**
+ * @copydoc Dali::UpdateProxy::GetPositionAndSize()
+ */
+ void GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const;
+
+ /**
+ * @copydoc Dali::UpdateProxy::GetColor()
+ */
+ Vector4 GetWorldColor( unsigned int id ) const;
+
+ /**
+ * @copydoc Dali::UpdateProxy::SetColor()
+ */
+ void SetWorldColor( unsigned int id, const Vector4& color ) const;
+
+ /**
+ * @copydoc Dali::UpdateProxy::GetWorldMatrixAndSize()
+ */
+ void GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const;
+
+ /**
+ * @copydoc Dali::UpdateProxy::GetWorldMatrix()
+ */
+ const Matrix& GetWorldMatrix( unsigned int id ) const;
+
+ /**
+ * @copydoc Dali::UpdateProxy::SetWorldMatrix()
+ */
+ void SetWorldMatrix( unsigned int id, const Matrix& worldMatrix );
+
+ /**
+ * @brief Retrieves the root-node used by this class
+ * @return The root node used by this class.
+ */
+ SceneGraph::Node& GetRootNode() const
+ {
+ return mRootNode;
+ }
+
+ void SetCurrentBufferIndex( BufferIndex bufferIndex )
+ {
+ mCurrentBufferIndex = bufferIndex;
+ }
+
+private:
+
+ /**
+ * @brief Retrieves the node with the specified ID.
+ * @param[in] id The ID of the node required
+ * @return A pointer to the required node if found.
+ * @note This caches the last accessed node.
+ */
+ SceneGraph::Node* GetNodeWithId( unsigned int id ) const;
+
+private:
+
+ /**
+ * Structure to store the ID & Node pair
+ */
+ struct IdNodePair
+ {
+ unsigned int id; ///< The ID of the node
+ SceneGraph::Node* node; ///< The node itself
+ };
+
+ mutable std::vector< IdNodePair > mNodeContainer; ///< Used to store cached pointers to already searched for Nodes.
+ mutable IdNodePair mLastCachedIdNodePair; ///< Used to cache the last retrieved id-node pair.
+ unsigned int mCurrentBufferIndex;
+
+ SceneGraph::TransformManager& mTransformManager; ///< Reference to the Transform Manager.
+ SceneGraph::Node& mRootNode; ///< The root node of this update proxy.
+};
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_UPDATE_PROXY_IMPL_H
const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
-Node* Node::New()
+Node* Node::New( unsigned int id )
{
- return new ( gNodeMemoryPool.AllocateRawThreadSafe() ) Node();
+ return new ( gNodeMemoryPool.AllocateRawThreadSafe() ) Node( id );
}
void Node::Delete( Node* node )
}
}
-Node::Node()
+Node::Node( unsigned int id )
: mTransformManager( NULL ),
mTransformId( INVALID_TRANSFORM_ID ),
mParentOrigin( TRANSFORM_PROPERTY_PARENT_ORIGIN ),
mWorldMatrix(),
mWorldColor( Color::WHITE ),
mClippingSortModifier( 0u ),
+ mId( id ),
mParent( NULL ),
mExclusiveRenderTask( NULL ),
mChildren(),
/**
* Construct a new Node.
+ * @param[in] id The unique ID of the node
*/
- static Node* New();
+ static Node* New( unsigned int id );
/**
* Deletes a Node.
/**
* Protected constructor; See also Node::New()
+ * @param[in] id The Unique ID of the actor creating the node
*/
- Node();
+ Node( unsigned int id );
/**
* Protected virtual destructor; See also Node::Delete( Node* )
InheritedColor mWorldColor; ///< Full inherited color
uint32_t mClippingSortModifier; ///< Contains bit-packed clipping information for quick access when sorting
+ const unsigned int mId; ///< The Unique ID of the node.
protected:
/*
- * 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.
namespace SceneGraph
{
-SceneGraph::Layer* Layer::New()
+SceneGraph::Layer* Layer::New( unsigned int id )
{
// Layers are currently heap allocated, unlike Nodes which are in a memory pool
// However Node::Delete( layer ) will correctly delete a layer / node depending on type
- return new Layer();
+ return new Layer( id );
}
-Layer::Layer()
-: mSortFunction( Internal::Layer::ZValue ),
+Layer::Layer( unsigned int id )
+: Node( id ),
+ mSortFunction( Internal::Layer::ZValue ),
mClippingBox( 0,0,0,0 ),
mLastCamera( NULL ),
mBehavior( Dali::Layer::LAYER_2D ),
#define DALI_INTERNAL_SCENE_GRAPH_LAYER_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.
/**
* Construct a new Layer.
+ * @param[in] id The Unique ID of the actor creating the node
* @return A smart-pointer to a newly allocated Node
*/
- static SceneGraph::Layer* New();
+ static SceneGraph::Layer* New( unsigned int id );
/**
* From Node, to convert a node to a layer.
/**
* Private constructor.
+ * @param[in] id The Unique ID of the actor creating the node
* See also Layer::New()
*/
- Layer();
+ Layer( unsigned int id );
// Undefined
Layer(const Layer&);