/*
- * 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
{
// The Update for frame N+1 may be processed whilst frame N is being rendered.
-const unsigned int MAXIMUM_UPDATE_COUNT = 2u;
+const uint32_t MAXIMUM_UPDATE_COUNT = 2u;
#if defined(DEBUG_ENABLED)
Debug::Filter* gCoreFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CORE");
using Integration::UpdateStatus;
using Integration::RenderStatus;
-Core::Core( RenderController& renderController, PlatformAbstraction& platform,
- GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction,
- GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy)
+Core::Core( RenderController& renderController,
+ PlatformAbstraction& platform,
+ GlAbstraction& glAbstraction,
+ GlSyncAbstraction& glSyncAbstraction,
+ GestureManager& gestureManager,
+ ResourcePolicy::DataRetention dataRetentionPolicy,
+ Integration::RenderToFrameBuffer renderToFboEnabled,
+ Integration::DepthBufferAvailable depthBufferAvailable,
+ Integration::StencilBufferAvailable stencilBufferAvailable )
: mRenderController( renderController ),
mPlatform(platform),
- mIsActive(true),
mProcessingEvent(false)
{
// Create the thread local storage
mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
- mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction );
+ mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, depthBufferAvailable, stencilBufferAvailable );
RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
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 ) );
- mStage->Initialize();
+ mStage->Initialize( renderToFboEnabled == Integration::RenderToFrameBuffer::TRUE );
- mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
- mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
+ mGestureEventProcessor = new GestureEventProcessor( *mStage, *mUpdateManager, gestureManager, mRenderController );
+ mEventProcessor = new EventProcessor( *mStage, *mNotificationManager, *mGestureEventProcessor );
mShaderFactory = new ShaderFactory();
mUpdateManager->SetShaderSaver( *mShaderFactory );
mRenderManager->ContextDestroyed();
}
-void Core::SurfaceResized( unsigned int width, unsigned int height )
+void Core::SurfaceResized( uint32_t width, uint32_t height )
{
- mStage->SurfaceResized( width, height );
+ mStage->SurfaceResized( static_cast<float>( width ), static_cast<float>( height ) );
// The stage-size may be less than surface-size (reduced by top-margin)
Vector2 size = mStage->GetSize();
- mRelayoutController->SetStageSize( size.width, size.height );
+ mRelayoutController->SetStageSize( static_cast<uint32_t>( size.width ), static_cast<uint32_t>( size.height ) ); // values get truncated
}
-void Core::SetTopMargin( unsigned int margin )
+void Core::SetTopMargin( uint32_t margin )
{
mStage->SetTopMargin( margin );
// The stage-size may be less than surface-size (reduced by top-margin)
Vector2 size = mStage->GetSize();
- mRelayoutController->SetStageSize( size.width, size.height );
+ mRelayoutController->SetStageSize( static_cast<uint32_t>( size.width ), static_cast<uint32_t>( size.height ) ); // values get truncated
}
-void Core::SetDpi( unsigned int dpiHorizontal, unsigned int dpiVertical )
+void Core::SetDpi( uint32_t dpiHorizontal, uint32_t dpiVertical )
{
- mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
+ mStage->SetDpi( Vector2( static_cast<float>( dpiHorizontal ), static_cast<float>( dpiVertical ) ) );
}
-void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status )
+void Core::Update( float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo )
{
// set the time delta so adaptor can easily print FPS with a release build with 0 as
// it is cached by frametime
// Use the estimated time diff till we render as the elapsed time.
status.keepUpdating = mUpdateManager->Update( elapsedSeconds,
lastVSyncTimeMilliseconds,
- nextVSyncTimeMilliseconds );
+ nextVSyncTimeMilliseconds,
+ renderToFboEnabled,
+ isRenderingToFbo );
// Check the Notification Manager message queue to set needsNotification
status.needsNotification = mNotificationManager->MessagesToProcess();
+ // Check if the default surface is changed
+ status.surfaceRectChanged = mUpdateManager->IsDefaultSurfaceRectChanged();
+
// No need to keep update running if there are notifications to process.
// Any message to update will wake it up anyways
}
-void Core::Render( RenderStatus& status )
-{
- bool updateRequired = mRenderManager->Render( status );
-
- status.SetNeedsUpdate( updateRequired );
-}
-
-void Core::Suspend()
-{
- mIsActive = false;
-}
-
-void Core::Resume()
+void Core::Render( RenderStatus& status, bool forceClear )
{
- mIsActive = true;
-
- // trigger processing of events queued up while paused
- ProcessEvents();
+ mRenderManager->Render( status, forceClear );
}
void Core::SceneCreated()
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 any registered processors
+ RunProcessors();
- // Flush any queued messages for the update-thread
- const bool messagesToProcess = mUpdateManager->FlushQueue();
+ // Run the size negotiation after event processing finished signal
+ mRelayoutController->Relayout();
- // Check if the touch or gestures require updates.
- const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
- if( messagesToProcess || gestureNeedsUpdate )
- {
- // tell the render controller to keep update thread running
- mRenderController.RequestUpdate();
- }
+ // Rebuild depth tree after event processing has finished
+ mStage->RebuildDepthTree();
+
+ // 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 next update is forced.
+ const bool forceUpdate = mStage->IsNextUpdateForced();
+
+ if( messagesToProcess || gestureNeedsUpdate || forceUpdate )
+ {
+ // tell the render controller to keep update thread running
+ mRenderController.RequestUpdate( forceUpdate );
}
mRelayoutController->SetProcessingCoreEvents( false );
mProcessingEvent = false;
}
-unsigned int Core::GetMaximumUpdateCount() const
+uint32_t Core::GetMaximumUpdateCount() const
{
return MAXIMUM_UPDATE_COUNT;
}
mStage->SetStereoBase( stereoBase );
}
+void Core::RegisterProcessor( Integration::Processor& processor )
+{
+ mProcessors.PushBack(&processor);
+}
+
+void Core::UnregisterProcessor( Integration::Processor& processor )
+{
+ auto iter = std::find( mProcessors.Begin(), mProcessors.End(), &processor );
+ if( iter != mProcessors.End() )
+ {
+ mProcessors.Erase( iter );
+ }
+}
+
+void Core::RunProcessors()
+{
+ // Copy processor pointers to prevent changes to vector affecting loop iterator.
+ Dali::Vector<Integration::Processor*> processors( mProcessors );
+
+ for( auto processor : processors )
+ {
+ if( processor )
+ {
+ processor->Process();
+ }
+ }
+}
+
float Core::GetStereoBase() const
{
return mStage->GetStereoBase();