return true;
}
+void FrameCallback( int frameId )
+{
+}
+
} // unnamed namespace
int UtcDaliSceneAdd(void)
END_TEST;
}
+
+int UtcDaliSceneFrameRenderedPresentedCallback(void)
+{
+ tet_infoline( "UtcDaliSceneFrameRenderedCallback" );
+
+ TestApplication application;
+
+ // Add a Renderer
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = CreateShader();
+ Renderer renderer = Renderer::New( geometry, shader );
+
+ Actor actor = Actor::New();
+ actor.AddRenderer( renderer );
+ Stage::GetCurrent().Add( actor );
+
+ Dali::Integration::Scene scene = application.GetScene();
+
+ int frameId = 1;
+ scene.AddFrameRenderedCallback( std::unique_ptr< CallbackBase >( MakeCallback( &FrameCallback ) ), frameId );
+ scene.AddFramePresentedCallback( std::unique_ptr< CallbackBase >( MakeCallback( &FrameCallback ) ), frameId );
+
+ // Render
+ application.SendNotification();
+ application.Render();
+
+ Dali::Integration::Scene::FrameCallbackContainer callbackContainer;
+ scene.GetFrameRenderedCallback( callbackContainer );
+
+ DALI_TEST_EQUALS( callbackContainer.size(), 1, TEST_LOCATION );
+ DALI_TEST_EQUALS( callbackContainer[0].second, frameId, TEST_LOCATION );
+
+ callbackContainer.clear();
+
+ scene.GetFramePresentedCallback( callbackContainer );
+
+ DALI_TEST_EQUALS( callbackContainer.size(), 1, TEST_LOCATION );
+ DALI_TEST_EQUALS( callbackContainer[0].second, frameId, TEST_LOCATION );
+
+ END_TEST;
+}
GetImplementation(*this).ProcessEvents();
}
+void Scene::AddFrameRenderedCallback( std::unique_ptr< CallbackBase > callback, int32_t frameId )
+{
+ GetImplementation( *this ).AddFrameRenderedCallback( std::move( callback ), frameId );
+}
+
+void Scene::AddFramePresentedCallback( std::unique_ptr< CallbackBase > callback, int32_t frameId )
+{
+ GetImplementation( *this ).AddFramePresentedCallback( std::move( callback ), frameId );
+}
+
+void Scene::GetFrameRenderedCallback( FrameCallbackContainer& callbacks )
+{
+ GetImplementation( *this ).GetFrameRenderedCallback( callbacks );
+}
+
+void Scene::GetFramePresentedCallback( FrameCallbackContainer& callbacks )
+{
+ GetImplementation( *this ).GetFramePresentedCallback( callbacks );
+}
+
Scene::EventProcessingFinishedSignalType& Scene::EventProcessingFinishedSignal()
{
return GetImplementation(*this).EventProcessingFinishedSignal();
*
*/
+// EXTERNAL INCLUDES
+#include <memory>
+
// INTERNAL INCLUDES
#include <dali/public-api/object/handle.h>
#include <dali/public-api/math/vector2.h>
#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/common/vector-wrapper.h>
namespace Dali
{
typedef Signal< void (const Dali::TouchData&) > TouchSignalType; ///< Touch signal type
typedef Signal< void (const Dali::WheelEvent&) > WheelEventSignalType; ///< Touched signal type
+ using FrameCallbackContainer = std::vector< std::pair< std::unique_ptr< CallbackBase >, int32_t > >;
+
/**
* @brief Create an initialized Scene handle.
*
void ProcessEvents();
/**
+ * @brief Adds a callback that is called when the frame rendering is done by the graphics driver.
+ *
+ * @param[in] callback The function to call
+ * @param[in] frameId The Id to specify the frame. It will be passed when the callback is called.
+ *
+ * @note A callback of the following type may be used:
+ * @code
+ * void MyFunction( int frameId );
+ * @endcode
+ * This callback will be deleted once it is called.
+ *
+ * @note Ownership of the callback is passed onto this class.
+ */
+ void AddFrameRenderedCallback( std::unique_ptr< CallbackBase > callback, int32_t frameId );
+
+ /**
+ * @brief Adds a callback that is called when the frame is displayed on the display.
+ *
+ * @param[in] callback The function to call
+ * @param[in] frameId The Id to specify the frame. It will be passed when the callback is called.
+ *
+ * @note A callback of the following type may be used:
+ * @code
+ * void MyFunction( int frameId );
+ * @endcode
+ * This callback will be deleted once it is called.
+ *
+ * @note Ownership of the callback is passed onto this class.
+ */
+ void AddFramePresentedCallback( std::unique_ptr< CallbackBase > callback, int32_t frameId );
+
+ /**
+ * @brief Gets the callback list that is called when the frame rendering is done by the graphics driver.
+ *
+ * @param[out] callbacks The callback list
+ *
+ * @note This is called in the update thread.
+ */
+ void GetFrameRenderedCallback( FrameCallbackContainer& callbacks );
+
+ /**
+ * @brief Gets the callback list that is called when the frame is displayed on the display.
+ *
+ * @param[out] callbacks The callback list
+ *
+ * @note This is called in the update thread.
+ */
+ void GetFramePresentedCallback( FrameCallbackContainer& callbacks );
+
+ /**
* @brief This signal is emitted just after the event processing is finished.
*
* @return The signal to connect to
}
}
+void Scene::AddFrameRenderedCallback( std::unique_ptr< CallbackBase > callback, int32_t frameId )
+{
+ ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+ AddFrameRenderedCallbackMessage( tls->GetEventThreadServices(), *mSceneObject, callback.release(), frameId );
+}
+
+void Scene::AddFramePresentedCallback( std::unique_ptr< CallbackBase > callback, int32_t frameId )
+{
+ ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+ AddFramePresentedCallbackMessage( tls->GetEventThreadServices(), *mSceneObject, callback.release(), frameId );
+}
+
+void Scene::GetFrameRenderedCallback( Dali::Integration::Scene::FrameCallbackContainer& callbacks )
+{
+ mSceneObject->GetFrameRenderedCallback( callbacks );
+}
+
+void Scene::GetFramePresentedCallback( Dali::Integration::Scene::FrameCallbackContainer& callbacks )
+{
+ mSceneObject->GetFramePresentedCallback( callbacks );
+}
+
Integration::Scene::KeyEventSignalType& Scene::KeyEventSignal()
{
return mKeyEventSignal;
void EmitWheelEventSignal( const WheelEvent& event );
/**
+ * @copydoc Dali::Integration::Scene::AddFrameRenderedCallback
+ */
+ void AddFrameRenderedCallback( std::unique_ptr< CallbackBase > callback, int32_t frameId );
+
+ /**
+ * @copydoc Dali::Integration::Scene::AddFramePresentedCallback
+ */
+ void AddFramePresentedCallback( std::unique_ptr< CallbackBase > callback, int32_t frameId );
+
+ /**
+ * @copydoc Dali::Integration::Scene::GetFrameRenderedCallback
+ */
+ void GetFrameRenderedCallback( Dali::Integration::Scene::FrameCallbackContainer& callbacks );
+
+ /**
+ * @copydoc Dali::Integration::Scene::GetFramePresentedCallback
+ */
+ void GetFramePresentedCallback( Dali::Integration::Scene::FrameCallbackContainer& callbacks );
+
+ /**
* @copydoc Integration::Scene::KeyEventSignal()
*/
Integration::Scene::KeyEventSignalType& KeyEventSignal();
{
Scene::Scene()
-: mContext( nullptr )
+: mContext( nullptr ),
+ mFrameRenderedCallbacks(),
+ mFramePresentedCallbacks()
{
}
delete mContext;
mContext = nullptr;
}
+
+ mFrameRenderedCallbacks.clear();
+ mFramePresentedCallbacks.clear();
}
void Scene::GlContextDestroyed()
return mInstructions;
}
+void Scene::AddFrameRenderedCallback( CallbackBase* callback, int32_t frameId )
+{
+ mFrameRenderedCallbacks.push_back( std::make_pair( std::unique_ptr< CallbackBase >( callback ), frameId ) );
+}
+
+void Scene::AddFramePresentedCallback( CallbackBase* callback, int32_t frameId )
+{
+ mFramePresentedCallbacks.push_back( std::make_pair( std::unique_ptr< CallbackBase >( callback ), frameId ) );
+}
+
+void Scene::GetFrameRenderedCallback( Dali::Integration::Scene::FrameCallbackContainer& callbacks )
+{
+ // Transfer owership of the callbacks
+ for( auto&& iter : mFrameRenderedCallbacks )
+ {
+ callbacks.push_back( std::make_pair( std::move( iter.first ), iter.second ) );
+ }
+
+ mFrameRenderedCallbacks.clear();
+}
+
+void Scene::GetFramePresentedCallback( Dali::Integration::Scene::FrameCallbackContainer& callbacks )
+{
+ // Transfer owership of the callbacks
+ for( auto&& iter : mFramePresentedCallbacks )
+ {
+ callbacks.push_back( std::make_pair( std::move( iter.first ), iter.second ) );
+ }
+
+ mFramePresentedCallbacks.clear();
+}
+
} //SceneGraph
} //Internal
// INTERNAL INCLUDES
#include <dali/integration-api/scene.h>
#include <dali/integration-api/gl-defines.h>
+#include <dali/internal/common/message.h>
+#include <dali/internal/event/common/event-thread-services.h>
#include <dali/internal/render/gl-resources/context.h>
#include <dali/internal/render/common/render-instruction-container.h>
+#include <dali/public-api/common/vector-wrapper.h>
namespace Dali
{
*/
RenderInstructionContainer& GetRenderInstructions();
+ /**
+ * @brief Adds a callback that is called when the frame rendering is done by the graphics driver.
+ *
+ * @param[in] callback The function to call
+ * @param[in] frameId The Id to specify the frame. It will be passed when the callback is called.
+ *
+ * @note A callback of the following type may be used:
+ * @code
+ * void MyFunction( int frameId );
+ * @endcode
+ * This callback will be deleted once it is called.
+ *
+ * @note Ownership of the callback is passed onto this class.
+ */
+ void AddFrameRenderedCallback( CallbackBase* callback, int32_t frameId );
+
+ /**
+ * @brief Adds a callback that is called when the frame is displayed on the display.
+ *
+ * @param[in] callback The function to call
+ * @param[in] frameId The Id to specify the frame. It will be passed when the callback is called.
+ *
+ * @note A callback of the following type may be used:
+ * @code
+ * void MyFunction( int frameId );
+ * @endcode
+ * This callback will be deleted once it is called.
+ *
+ * @note Ownership of the callback is passed onto this class.
+ */
+ void AddFramePresentedCallback( CallbackBase* callback, int32_t frameId );
+
+ /**
+ * @brief Gets the callback list that is called when the frame rendering is done by the graphics driver.
+ *
+ * @param[out] callbacks The callback list
+ */
+ void GetFrameRenderedCallback( Dali::Integration::Scene::FrameCallbackContainer& callbacks );
+
+ /**
+ * @brief Gets the callback list that is called when the frame is displayed on the display.
+ *
+ * @param[out] callbacks The callback list
+ */
+ void GetFramePresentedCallback( Dali::Integration::Scene::FrameCallbackContainer& callbacks );
+
private:
Context* mContext; ///< The context holding the GL state of rendering for the scene
// Update manager updates instructions for the next frame while we render the current one
RenderInstructionContainer mInstructions; ///< Render instructions for the scene
+
+ Dali::Integration::Scene::FrameCallbackContainer mFrameRenderedCallbacks; ///< Frame rendered callbacks
+ Dali::Integration::Scene::FrameCallbackContainer mFramePresentedCallbacks; ///< Frame presented callbacks
};
+/// Messages
+inline void AddFrameRenderedCallbackMessage( EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId )
+{
+ typedef MessageValue2< Scene, CallbackBase*, int32_t > LocalType;
+
+ // Reserve some memory inside the message queue
+ uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+ // Construct message in the message queue memory; note that delete should not be called on the return value
+ new (slot) LocalType( &scene, &Scene::AddFrameRenderedCallback, const_cast< CallbackBase* >( callback ), frameId );
+}
+
+inline void AddFramePresentedCallbackMessage( EventThreadServices& eventThreadServices, const Scene& scene, const CallbackBase* callback, int32_t frameId )
+{
+ typedef MessageValue2< Scene, CallbackBase*, int32_t > LocalType;
+
+ // Reserve some memory inside the message queue
+ uint32_t* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+ // Construct message in the message queue memory; note that delete should not be called on the return value
+ new (slot) LocalType( &scene, &Scene::AddFramePresentedCallback, const_cast< CallbackBase* >( callback ), frameId );
+}
} // namespace SceneGraph