/*
- * 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.
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/event/common/property-notification-manager.h>
#include <dali/internal/event/render-tasks/render-task-list-impl.h>
+#include <dali/internal/event/update/frame-callback-interface-impl.h>
#include <dali/internal/update/nodes/node.h>
+#include <dali/internal/update/manager/scene-graph-frame-callback.h>
#include <dali/internal/event/common/object-registry-impl.h>
#include <dali/integration-api/platform-abstraction.h>
#include <dali/public-api/common/constants.h>
#include <dali/public-api/events/touch-data.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/public-api/rendering/frame-buffer.h>
using Dali::Internal::SceneGraph::Node;
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()
+void Stage::Initialize( bool renderToFbo )
{
+ mRenderToFbo = renderToFbo;
mObjectRegistry = ObjectRegistry::New();
// Create the ordered list of layers
- mLayerList = LayerList::New( mUpdateManager, false/*not system-level*/ );
+ mLayerList = LayerList::New( mUpdateManager );
// The stage owns the default layer
- mRootLayer = Layer::NewRoot( *mLayerList, mUpdateManager, false/*not system-level*/ );
+ mRootLayer = Layer::NewRoot( *mLayerList, mUpdateManager );
mRootLayer->SetName("RootLayer");
// The root layer needs to have a fixed resize policy (as opposed to the default USE_NATURAL_SIZE).
// This stops actors parented to the stage having their relayout requests propagating
CreateDefaultCameraActor();
// Create the list of render-tasks
- mRenderTaskList = RenderTaskList::New( *this, *this, false/*not system-level*/ );
+ mRenderTaskList = RenderTaskList::New();
// Create the default render-task
- Dali::RenderTask defaultRenderTask = mRenderTaskList->CreateTask();
+ Dali::RenderTask defaultRenderTask = mRenderTaskList->CreateTask( mRootLayer.Get(), mDefaultCamera.Get() );
}
void Stage::Uninitialize()
// signals or send messages to update
mRootLayer.Reset();
}
+
+ if( mRenderTaskList )
+ {
+ mRenderTaskList.Reset();
+ }
}
StagePtr Stage::GetCurrent()
mRootLayer->Remove( actor );
}
-void Stage::SurfaceResized(float width, float height)
+void Stage::SurfaceResized( float width, float height )
{
- mSurfaceSize.width = width;
- mSurfaceSize.height = height;
+ if( ( fabsf( width - mSurfaceSize.width ) > Math::MACHINE_EPSILON_1000 ) || ( fabsf( height - mSurfaceSize.height ) > Math::MACHINE_EPSILON_1000 ) )
+ {
+ mSurfaceSize.width = width;
+ mSurfaceSize.height = height;
- // Internally we want to report the actual size of the stage.
- mSize.width = width;
- mSize.height = height - mTopMargin;
+ // Internally we want to report the actual size of the stage.
+ mSize.width = width;
+ mSize.height = height - static_cast<float>( mTopMargin );
- // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
- mDefaultCamera->SetPerspectiveProjection( mSurfaceSize );
+ // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
+ mDefaultCamera->SetPerspectiveProjection( mSurfaceSize );
- // Adjust the camera height to allow for top-margin
- SetDefaultCameraPosition();
+ // Adjust the camera height to allow for top-margin
+ SetDefaultCameraPosition();
- mRootLayer->SetSize( mSize.width, mSize.height );
+ mRootLayer->SetSize( mSize.width, mSize.height );
- // Repeat for SystemOverlay actors
- if( mSystemOverlay )
- {
- // Note that the SystemOverlay has a separate camera, configured for the full surface-size.
- // This will remain unaffected by changes in SetDefaultCameraPosition()
- mSystemOverlay->GetImpl()->SetSize( width, height );
- }
+ // Repeat for SystemOverlay actors
+ if( mSystemOverlay )
+ {
+ // Note that the SystemOverlay has a separate camera, configured for the full surface-size.
+ // This will remain unaffected by changes in SetDefaultCameraPosition()
+ mSystemOverlay->GetImpl()->SetSize( width, height );
+ }
- SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int>( 0, 0, width, height ) );
+ SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int32_t>( 0, 0, static_cast<int32_t>( width ), static_cast<int32_t>( height ) ) ); // truncated
- // if single render task to screen then set its viewport parameters
- if( 1 == mRenderTaskList->GetTaskCount() )
- {
- Dali::RenderTask mDefaultRenderTask = mRenderTaskList->GetTask(0);
+ // if single render task to screen then set its viewport parameters
+ if( 1 == mRenderTaskList->GetTaskCount() )
+ {
+ Dali::RenderTask defaultRenderTask = mRenderTaskList->GetTask( 0u );
+
+ if(!defaultRenderTask.GetTargetFrameBuffer())
+ {
+ defaultRenderTask.SetViewport( Viewport( 0, 0, static_cast<int32_t>( width ), static_cast<int32_t>( height ) ) ); // truncated
+ }
+ }
- if(!mDefaultRenderTask.GetTargetFrameBuffer())
+ if( mRenderToFbo )
{
- mDefaultRenderTask.SetViewport( Viewport(0, 0, width, height) );
+ Dali::FrameBuffer frameBuffer = Dali::FrameBuffer::New( static_cast<uint32_t>( width ), static_cast<uint32_t>( height ), Dali::FrameBuffer::Attachment::NONE );
+ Dali::Texture texture = Dali::Texture::New( Dali::TextureType::TEXTURE_2D, Dali::Pixel::RGB888, static_cast<uint32_t>( width ), static_cast<uint32_t>( height ) );
+ frameBuffer.AttachColorTexture( texture );
+
+ Dali::RenderTask defaultRenderTask = mRenderTaskList->GetTask( 0u );
+ defaultRenderTask.SetFrameBuffer( frameBuffer );
}
}
-
}
Vector2 Stage::GetSize() const
return mSize;
}
-void Stage::SetTopMargin( unsigned int margin )
+void Stage::SetTopMargin( uint32_t margin )
{
if (mTopMargin == margin)
{
mTopMargin = margin;
mSize.width = mSurfaceSize.width;
- mSize.height = mSurfaceSize.height - mTopMargin;
+ mSize.height = mSurfaceSize.height - static_cast<float>( mTopMargin );
// Adjust the camera height to allow for top-margin
SetDefaultCameraPosition();
return *mDefaultCamera;
}
-unsigned int Stage::GetLayerCount() const
+uint32_t Stage::GetLayerCount() const
{
return mLayerList->GetLayerCount();
}
-Dali::Layer Stage::GetLayer( unsigned int depth ) const
+Dali::Layer Stage::GetLayer( uint32_t depth ) const
{
return Dali::Layer(mLayerList->GetLayer( depth ));
}
mLeftCamera->SetOrientation( -Dali::ANGLE_90, Vector3::ZAXIS );
mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
- mLeftRenderTask.SetViewport( Viewport(0, mSize.height * 0.5f, mSize.width, mSize.height * 0.5f) );
+ mLeftRenderTask.SetViewport( Viewport(0, static_cast<int32_t>( mSize.height * 0.5f ), static_cast<int32_t>( mSize.width ), static_cast<int32_t>( mSize.height * 0.5f ) ) ); // truncated
- mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, -stereoBase) );
+ mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, -stereoBase ) );
mRightCamera->SetAspectRatio( aspect );
mRightCamera->SetOrientation( -Dali::ANGLE_90, Vector3::ZAXIS );
mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
- mRightRenderTask.SetViewport( Viewport(0, 0, mSize.width, mSize.height * 0.5f ) );
+ mRightRenderTask.SetViewport( Viewport(0, 0, static_cast<int32_t>( mSize.width ), static_cast<int32_t>( mSize.height * 0.5f ) ) ); // truncated
break;
}
mLeftCamera->SetFieldOfView( fov );
mLeftCamera->SetOrientation( Dali::ANGLE_0, Vector3::ZAXIS );
mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
- mLeftRenderTask.SetViewport( Viewport(0, 0, mSize.width * 0.5f, mSize.height ) );
+ mLeftRenderTask.SetViewport( Viewport(0, 0, static_cast<int32_t>( mSize.width * 0.5f ), static_cast<int32_t>( mSize.height ) ) ); // truncated
mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
mRightCamera->SetFieldOfView( fov );
mRightCamera->SetOrientation( Dali::ANGLE_0, Vector3::ZAXIS );
mRightCamera->SetPosition( Vector3( -stereoBase, 0.0f, 0.0f ) );
- mRightRenderTask.SetViewport( Viewport(mSize.width * 0.5f, 0, mSize.width * 0.5f, mSize.height ) );
+ mRightRenderTask.SetViewport( Viewport( static_cast<int32_t>( mSize.width * 0.5f ), 0, static_cast<int32_t>( mSize.width * 0.5f ), static_cast<int32_t>( mSize.height ) ) ); // truncated
break;
}
KeepRenderingMessage( mUpdateManager, durationSeconds );
}
+void Stage::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
+{
+ if( mRenderingBehavior != renderingBehavior )
+ {
+ // Send message to change the rendering behavior
+ SetRenderingBehaviorMessage( mUpdateManager, renderingBehavior );
+
+ mRenderingBehavior = renderingBehavior;
+ }
+}
+
+DevelStage::Rendering Stage::GetRenderingBehavior() const
+{
+ return mRenderingBehavior;
+}
+
bool Stage::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
{
bool connected( true );
return mKeyEventGeneratedSignal;
}
+void Stage::AddFrameCallback( FrameCallbackInterface& frameCallback, Actor& rootActor )
+{
+ DALI_ASSERT_ALWAYS( ( ! FrameCallbackInterface::Impl::Get( frameCallback ).IsConnectedToSceneGraph() )
+ && "FrameCallbackInterface implementation already added" );
+
+ // Create scene-graph object and transfer to UpdateManager
+ OwnerPointer< SceneGraph::FrameCallback > transferOwnership( SceneGraph::FrameCallback::New( frameCallback ) );
+ AddFrameCallbackMessage( mUpdateManager, transferOwnership, rootActor.GetNode() );
+}
+
+void Stage::RemoveFrameCallback( FrameCallbackInterface& frameCallback )
+{
+ FrameCallbackInterface::Impl::Get( frameCallback ).Invalidate();
+ RemoveFrameCallbackMessage( mUpdateManager, frameCallback );
+}
+
Dali::Stage::EventProcessingFinishedSignalType& Stage::EventProcessingFinishedSignal()
{
return mEventProcessingFinishedSignal;
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 ),
+ mSurfaceSize( Vector2::ZERO ),
+ mBackgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
mViewMode( MONO ),
mStereoBase( DEFAULT_STEREO_BASE ),
mTopMargin( 0 ),
- mSystemOverlay(NULL),
- mDepthTreeDirty( false )
+ mDpi( Vector2::ZERO ),
+ mRightRenderTask(),
+ mLeftRenderTask(),
+ mSystemOverlay( NULL ),
+ mKeyEventSignal(),
+ mKeyEventGeneratedSignal(),
+ mEventProcessingFinishedSignal(),
+ mTouchedSignal(),
+ mTouchSignal(),
+ mWheelEventSignal(),
+ mContextLostSignal(),
+ mContextRegainedSignal(),
+ mSceneCreatedSignal(),
+ mRenderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
+ mDepthTreeDirty( false ),
+ mForceNextUpdate( false ),
+ mRenderToFbo( false )
{
}
return mUpdateManager;
}
-unsigned int* Stage::ReserveMessageSlot( std::size_t size, bool updateScene )
+Integration::RenderController& Stage::GetRenderController()
+{
+ return mRenderController;
+}
+
+uint32_t* Stage::ReserveMessageSlot( uint32_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;