test_return_value = TET_PASS;
}
+namespace
+{
+
+class RelayoutSignalHandler : public Dali::ConnectionTracker
+{
+public:
+
+ RelayoutSignalHandler( TestApplication& application )
+ : mApplication( application ),
+ mSignalCalled( false )
+ {
+ }
+
+ // callback to be connected to RelayoutSignal
+ void RelayoutCallback( Actor actor )
+ {
+ tet_infoline("RelayoutCallback is called");
+
+ mSignalCalled = true;
+
+ mApplication.SendNotification();
+ }
+
+ TestApplication& mApplication;
+ bool mSignalCalled;
+};
+
+} // anonymous namespace
int UtcDaliCoreTopMargin(void)
{
END_TEST;
}
+
+int UtcDaliCoreProcessEvents(void)
+{
+ TestApplication application;
+ tet_infoline("Testing Dali::Integration::Core::ProcessEvents");
+
+ Vector3 size( 100.0f, 100.0f, 0.0f );
+ Vector3 position( 100.0f, 100.0f, 0.0f );
+
+ Actor actor = Actor::New();
+ actor.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+ actor.SetSize( size );
+ actor.SetPosition( position );
+ Stage::GetCurrent().Add( actor );
+
+ RelayoutSignalHandler relayoutSignal( application );
+ actor.OnRelayoutSignal().Connect( &relayoutSignal, &RelayoutSignalHandler::RelayoutCallback );
+
+ application.SendNotification();
+
+ DALI_TEST_EQUALS( relayoutSignal.mSignalCalled, true, TEST_LOCATION );
+
+ DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::SIZE ).Get< Vector3 >(), size, TEST_LOCATION );
+ DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::POSITION ).Get< Vector3 >(), position, TEST_LOCATION );
+
+ END_TEST;
+}
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
{
}
-void TestRenderController::RequestUpdate()
+void TestRenderController::RequestUpdate( bool forceUpdate )
{
mRequestUpdateCalled = true;
}
-void TestRenderController::RequestProcessEventsOnIdle()
+void TestRenderController::RequestProcessEventsOnIdle( bool forceProcess )
{
mRequestProcessEventsOnIdleCalled = true;
}
#define __TEST_RENDER_CONTROLLER_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
TestRenderController();
~TestRenderController();
- virtual void RequestUpdate();
- virtual void RequestProcessEventsOnIdle();
+ virtual void RequestUpdate( bool forceUpdate );
+ virtual void RequestProcessEventsOnIdle( bool forceProcess );
typedef enum
{
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
mImpl->SetDpi(dpiHorizontal, dpiVertical);
}
-void Core::Suspend()
-{
- mImpl->Suspend();
-}
-
-void Core::Resume()
-{
- mImpl->Resume();
-}
-
void Core::SceneCreated()
{
mImpl->SceneCreated();
*
* 7) Provide an implementation of the GestureManager interface, used to register gestures provided by the platform.
*
- * Suspend/Resume behaviour:
- *
- * The Core has no knowledge of the application lifecycle, but can be suspended.
- * In the suspended state, input events will not be processed, and animations will not progress any further.
- * The Core can still render in the suspended state; the same frame will be produced each time.
- *
* Multi-threading notes:
*
* The Dali API methods are not reentrant. If you access the API from multiple threads simultaneously, then the results
// Core Lifecycle
/**
- * Put Core into the suspended state.
- * Any ongoing event processing will be cancelled, for example multi-touch sequences.
- * The core expects the system has suspended us. Animation time will continue during the suspended
- * state.
- * Multi-threading note: this method should be called from the main thread
- * @post The Core is in the suspended state.
- */
- void Suspend();
-
- /**
- * Resume the Core from the suspended state.
- * At the first update, the elapsed time passed to the animations will be equal to the time spent
- * suspended.
- * Multi-threading note: this method should be called from the main thread
- * @post The Core is not in the suspended state.
- */
- void Resume();
-
- /**
* Notify Core that the scene has been created.
*/
void SceneCreated();
#define __DALI_INTEGRATION_RENDER_CONTROLLER_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
* Requests a future call to Dali::Integration::Core::Update().
* This is called when Dali has new content, typically in response to Actors/Animations being added.
* Multi-threading note: this method will be called from the main thread only.
+ * @param[in] forceUpdate true to update forcely.
*/
- virtual void RequestUpdate() = 0;
+ virtual void RequestUpdate( bool forceUpdate ) = 0;
/**
* Requests a future call to Dali::Integration::Core::ProcessEvents(), when the application is idle.
* Multi-threading note: this method will be called from the main thread only.
+ * @param[in] forceProcess true to process events forcely.
*/
- virtual void RequestProcessEventsOnIdle() = 0;
+ virtual void RequestProcessEventsOnIdle( bool forceProcess ) = 0;
};
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy)
: mRenderController( renderController ),
mPlatform(platform),
- mIsActive(true),
mProcessingEvent(false)
{
// Create the thread local storage
mRenderManager->SetShaderSaver( *mUpdateManager );
- mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) );
+ mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager, mRenderController ) );
// This must be called after stage is created but before stage initialization
mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) );
mRenderManager->Render( status );
}
-void Core::Suspend()
-{
- mIsActive = false;
-}
-
-void Core::Resume()
-{
- mIsActive = true;
-
- // trigger processing of events queued up while paused
- ProcessEvents();
-}
-
void Core::SceneCreated()
{
mStage->EmitSceneCreatedSignal();
if( mProcessingEvent )
{
DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" );
- mRenderController.RequestProcessEventsOnIdle();
+ mRenderController.RequestProcessEventsOnIdle( false );
return;
}
mNotificationManager->ProcessMessages();
- // Avoid allocating MessageBuffers, triggering size-negotiation or sending any other spam whilst paused
- if( mIsActive )
- {
- // Emit signal here to inform listeners that event processing has finished.
- mStage->EmitEventProcessingFinishedSignal();
+ // Emit signal here to inform listeners that event processing has finished.
+ mStage->EmitEventProcessingFinishedSignal();
- // Run the size negotiation after event processing finished signal
- mRelayoutController->Relayout();
+ // Run the size negotiation after event processing finished signal
+ mRelayoutController->Relayout();
- // Rebuild depth tree after event processing has finished
- mStage->RebuildDepthTree();
+ // Rebuild depth tree after event processing has finished
+ mStage->RebuildDepthTree();
- // Flush any queued messages for the update-thread
- const bool messagesToProcess = mUpdateManager->FlushQueue();
+ // Flush any queued messages for the update-thread
+ const bool messagesToProcess = mUpdateManager->FlushQueue();
- // Check if the touch or gestures require updates.
- const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
+ // Check if the touch or gestures require updates.
+ const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
+ // Check if the next update is forced.
+ const bool forceUpdate = mStage->IsNextUpdateForced();
- if( messagesToProcess || gestureNeedsUpdate )
- {
- // tell the render controller to keep update thread running
- mRenderController.RequestUpdate();
- }
+ if( messagesToProcess || gestureNeedsUpdate || forceUpdate )
+ {
+ // tell the render controller to keep update thread running
+ mRenderController.RequestUpdate( forceUpdate );
}
mRelayoutController->SetProcessingCoreEvents( false );
#define DALI_INTERNAL_CORE_H
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
void Render( Integration::RenderStatus& status );
/**
- * @copydoc Dali::Integration::Core::Suspend()
- */
- void Suspend();
-
- /**
- * @copydoc Dali::Integration::Core::Resume()
- */
- void Resume();
-
- /**
* @copydoc Dali::Integration::Core::SceneCreated()
*/
void SceneCreated();
AnimationPlaylistOwner mAnimationPlaylist; ///< For 'Fire and forget' animation support
OwnerPointer<PropertyNotificationManager> mPropertyNotificationManager; ///< For safe signal emmision of property changed notifications
IntrusivePtr< RelayoutController > mRelayoutController; ///< Size negotiation relayout controller
- bool mIsActive : 1; ///< Whether Core is active or suspended
bool mProcessingEvent : 1; ///< True during ProcessEvents()
OwnerPointer<SceneGraph::RenderTaskProcessor> mRenderTaskProcessor; ///< Handles the processing of render tasks
#define __DALI_INTERNAL_EVENT_THREAD_SERVICES_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
class BaseObject;
+namespace Integration
+{
+class RenderController;
+}
+
namespace Internal
{
virtual SceneGraph::UpdateManager& GetUpdateManager() = 0;
/**
+ * @brief Get a reference to the RenderController
+ *
+ * @return the render controller
+ */
+ virtual Integration::RenderController& GetRenderController() = 0;
+
+ /**
* Reserve space for another message in the queue; this must then be initialized by the caller.
* The message will be read from the update-thread after the next FlushMessages is called.
* @post Calling this method may invalidate any previously returned slots.
virtual BufferIndex GetEventBufferIndex() const = 0;
/**
+ * @brief Indicate that the next rendering is really required.
+ */
+ virtual void ForceNextUpdate() = 0;
+
+ /**
+ * @brief Check if the next rendering is really required.
+ *
+ * @return true if the next rendering is really required.
+ */
+ virtual bool IsNextUpdateForced() = 0;
+
+ /**
* @return true if core is still running and we can send messages
*/
static bool IsCoreRunning();
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
StagePtr Stage::New( AnimationPlaylist& playlist,
PropertyNotificationManager& propertyNotificationManager,
SceneGraph::UpdateManager& updateManager,
- NotificationManager& notificationManager )
+ NotificationManager& notificationManager,
+ Integration::RenderController& renderController )
{
- return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager ) );
+ return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager, renderController ) );
}
void Stage::Initialize()
Stage::Stage( AnimationPlaylist& playlist,
PropertyNotificationManager& propertyNotificationManager,
SceneGraph::UpdateManager& updateManager,
- NotificationManager& notificationManager )
+ NotificationManager& notificationManager,
+ Integration::RenderController& renderController )
: mAnimationPlaylist( playlist ),
- mPropertyNotificationManager(propertyNotificationManager),
- mUpdateManager(updateManager),
- mNotificationManager(notificationManager),
- mSize(Vector2::ZERO),
- mBackgroundColor(Dali::Stage::DEFAULT_BACKGROUND_COLOR),
+ mPropertyNotificationManager( propertyNotificationManager ),
+ mUpdateManager( updateManager ),
+ mNotificationManager( notificationManager ),
+ mRenderController( renderController ),
+ mSize( Vector2::ZERO ),
+ mBackgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
mViewMode( MONO ),
mStereoBase( DEFAULT_STEREO_BASE ),
mTopMargin( 0 ),
- mSystemOverlay(NULL),
- mDepthTreeDirty( false )
+ mSystemOverlay( NULL ),
+ mDepthTreeDirty( false ),
+ mForceNextUpdate( false )
{
}
return mUpdateManager;
}
+Integration::RenderController& Stage::GetRenderController()
+{
+ return mRenderController;
+}
+
unsigned int* Stage::ReserveMessageSlot( std::size_t size, bool updateScene )
{
return mUpdateManager.ReserveMessageSlot( size, updateScene );
return mUpdateManager.GetEventBufferIndex();
}
+void Stage::ForceNextUpdate()
+{
+ mForceNextUpdate = true;
+}
+
+bool Stage::IsNextUpdateForced()
+{
+ bool nextUpdateForced = mForceNextUpdate;
+ mForceNextUpdate = false;
+ return nextUpdateForced;
+}
+
Stage::~Stage()
{
delete mSystemOverlay;
#define __DALI_INTERNAL_STAGE_H__
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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 Integration
{
class SystemOverlay;
+class RenderController;
}
namespace Internal
* @param[in] propertyNotificationManager
* @param[in] updateManager
* @param[in] notificationManager
+ * @param[in] renderController
*/
static StagePtr New( AnimationPlaylist& playlist,
PropertyNotificationManager& propertyNotificationManager,
SceneGraph::UpdateManager& updateManager,
- NotificationManager& notificationManager );
+ NotificationManager& notificationManager,
+ Integration::RenderController& renderController );
/**
* Initialize the stage.
virtual SceneGraph::UpdateManager& GetUpdateManager();
/**
+ * @copydoc EventThreadServices::GetRenderController
+ */
+ virtual Integration::RenderController& GetRenderController();
+
+ /**
* @copydoc EventThreadServices::ReserveMessageSlot
*/
virtual unsigned int* ReserveMessageSlot( std::size_t size, bool updateScene );
virtual BufferIndex GetEventBufferIndex() const;
/**
+ * @copydoc EventThreadServices::ForceNextUpdate
+ */
+ virtual void ForceNextUpdate();
+
+ /**
+ * @copydoc EventThreadServices::IsNextUpdateForced
+ */
+ virtual bool IsNextUpdateForced();
+
+ /**
* Request that the depth tree is rebuilt
*/
void RequestRebuildDepthTree();
Stage( AnimationPlaylist& playlist,
PropertyNotificationManager& propertyNotificationManager,
SceneGraph::UpdateManager& updateManager,
- NotificationManager& notificationManager );
+ NotificationManager& notificationManager,
+ Integration::RenderController& renderController );
/**
* A reference counted object may only be deleted by calling Unreference()
NotificationManager& mNotificationManager;
+ Integration::RenderController& mRenderController;
+
// The stage-size may be less than surface-size (reduced by top-margin)
Vector2 mSize;
Vector2 mSurfaceSize;
Integration::SystemOverlay* mSystemOverlay; ///< SystemOverlay stage access
+ bool mDepthTreeDirty; ///< True if the depth tree needs recalculating
+ bool mForceNextUpdate; ///< True if the next rendering is really required.
+
// The key event signal
Dali::Stage::KeyEventSignalType mKeyEventSignal;
Dali::DevelStage::KeyEventGeneratedSignalType mKeyEventGeneratedSignal;
// The touched signals
Dali::Stage::TouchedSignalType mTouchedSignal;
Dali::Stage::TouchSignalType mTouchSignal;
- bool mDepthTreeDirty; ///< True if the depth tree needs recalculating
// The wheel event signal
Dali::Stage::WheelEventSignalType mWheelEventSignal;
/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
SetUpdateRequired();
// We may not be updating so we need to ask the render controller for an update.
- mRenderController.RequestUpdate();
+ mRenderController.RequestUpdate( false );
}
switch ( gesture.type )
// INTERNAL INCLUDES
#include <dali/internal/update/manager/update-manager.h>
#include <dali/internal/event/common/stage-impl.h>
+#include <dali/integration-api/render-controller.h>
namespace Dali
{
static_cast< uint16_t >( width ),
static_cast< uint16_t >( height ) };
UploadTextureMessage( mEventThreadServices.GetUpdateManager(), *mRenderObject, pixelData, params );
+
+ // Request event processing and update forcely
+ mEventThreadServices.GetRenderController().RequestProcessEventsOnIdle( true );
+ mEventThreadServices.ForceNextUpdate();
+
result = true;
}
}
if ( !mProcessingCoreEvents )
{
- mRenderController.RequestProcessEventsOnIdle();
+ mRenderController.RequestProcessEventsOnIdle( false );
}
}
// If we are outside, then we have to request a call to Core::ProcessEvents() on idle.
if ( false == mImpl->processingEvents )
{
- mImpl->renderController.RequestProcessEventsOnIdle();
+ mImpl->renderController.RequestProcessEventsOnIdle( false );
}
return mImpl->currentMessageBuffer->ReserveMessageSlot( requestedSize );