X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fcommon%2Fcore-impl.cpp;h=f1c6cd4081ed4c6f524c26a8678a1ec24d43f967;hb=79881246746f65474b24ea4fe14151ccef8df3f4;hp=35827ad616dca54933a7d494a64b9d8a5d316419;hpb=ffe49cb03ceb58033f12af6b4ba283f5c6cd5698;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index 35827ad..f1c6cd4 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -19,12 +19,13 @@ #include // INTERNAL INCLUDES -#include #include #include #include #include +#include #include +#include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -41,28 +43,22 @@ #include #include -#include #include -#include #include -#include #include #include -#include #include using Dali::Internal::SceneGraph::UpdateManager; using Dali::Internal::SceneGraph::RenderManager; using Dali::Internal::SceneGraph::DiscardQueue; using Dali::Internal::SceneGraph::RenderQueue; -using Dali::Internal::SceneGraph::TextureCache; -using Dali::Internal::SceneGraph::TextureCacheDispatcher; 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"); @@ -78,28 +74,24 @@ namespace Internal using Integration::RenderController; using Integration::PlatformAbstraction; using Integration::GlSyncAbstraction; -using Integration::GestureManager; using Integration::GlAbstraction; +using Integration::GlContextHelperAbstraction; using Integration::Event; 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, + GlContextHelperAbstraction& glContextHelperAbstraction, + Integration::RenderToFrameBuffer renderToFboEnabled, + Integration::DepthBufferAvailable depthBufferAvailable, + Integration::StencilBufferAvailable stencilBufferAvailable ) : mRenderController( renderController ), mPlatform(platform), - mGestureEventProcessor(NULL), - mEventProcessor(NULL), - mUpdateManager(NULL), - mRenderManager(NULL), - mDiscardQueue(NULL), - mTextureUploadedQueue(), - mNotificationManager(NULL), - mShaderFactory(NULL), - mGeometryBatcher( NULL ), - mIsActive(true), - mProcessingEvent(false) + mProcessingEvent(false), + mForceNextUpdate( false ) { // Create the thread local storage CreateThreadLocalStorage(); @@ -113,58 +105,33 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, mPropertyNotificationManager = PropertyNotificationManager::New(); - mTextureUploadedQueue = new LockedResourceQueue; - - mGeometryBatcher = new SceneGraph::GeometryBatcher(); - mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor(); - mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mGeometryBatcher, *mTextureUploadedQueue ); + mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, glContextHelperAbstraction, depthBufferAvailable, stencilBufferAvailable ); RenderQueue& renderQueue = mRenderManager->GetRenderQueue(); - TextureCache& textureCache = mRenderManager->GetTextureCache(); - - ResourcePolicy::Discardable discardPolicy = ResourcePolicy::OWNED_DISCARD; - if( dataRetentionPolicy == ResourcePolicy::DALI_RETAINS_ALL_DATA ) - { - discardPolicy = ResourcePolicy::OWNED_RETAIN; - } - textureCache.SetDiscardBitmapsPolicy(discardPolicy); - - mTextureCacheDispatcher = new SceneGraph::TextureCacheDispatcher( renderQueue, textureCache ); mDiscardQueue = new DiscardQueue( renderQueue ); - mResourceManager = new ResourceManager( mPlatform, - *mNotificationManager, - *mTextureCacheDispatcher, - *mTextureUploadedQueue, - *mDiscardQueue, - renderQueue ); - mUpdateManager = new UpdateManager( *mNotificationManager, *mAnimationPlaylist, *mPropertyNotificationManager, - *mResourceManager, *mDiscardQueue, renderController, *mRenderManager, renderQueue, - *mTextureCacheDispatcher, - *mGeometryBatcher, *mRenderTaskProcessor ); mRenderManager->SetShaderSaver( *mUpdateManager ); - mStage = IntrusivePtr( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) ); + mObjectRegistry = ObjectRegistry::New(); + + mStage = IntrusivePtr( Stage::New( *mUpdateManager ) ); // This must be called after stage is created but before stage initialization mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) ); - mStage->Initialize(); - - mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController); - mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor); + mGestureEventProcessor = new GestureEventProcessor( *mUpdateManager, mRenderController ); mShaderFactory = new ShaderFactory(); mUpdateManager->SetShaderSaver( *mShaderFactory ); @@ -174,12 +141,6 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, Core::~Core() { - /** - * TODO this should be done by Adaptor, Core does not know about threading - * First stop the resource loading thread(s) - */ - mPlatform.JoinLoaderThreads(); - /* * The order of destructing these singletons is important!!! */ @@ -191,30 +152,22 @@ Core::~Core() if( tls ) { tls->Remove(); - delete tls; + tls->Unreference(); } + mObjectRegistry.Reset(); + // Stop relayout requests being raised on stage destruction mRelayoutController.Reset(); - // Clean-up stage - remove default camera and root layer - mStage->Uninitialize(); - // remove (last?) reference to stage mStage.Reset(); - delete mEventProcessor; - delete mGestureEventProcessor; - delete mNotificationManager; - delete mShaderFactory; - delete mResourceManager; - delete mDiscardQueue; - delete mTextureCacheDispatcher; - delete mUpdateManager; - delete mRenderManager; - delete mRenderTaskProcessor; - delete mGeometryBatcher; - delete mTextureUploadedQueue; +} + +void Core::Initialize() +{ + mStage->Initialize( *mScenes[0] ); } Integration::ContextNotifierInterface* Core::GetContextNotifier() @@ -239,30 +192,7 @@ void Core::ContextDestroyed() mRenderManager->ContextDestroyed(); } -void Core::SurfaceResized( unsigned int width, unsigned int height ) -{ - mStage->SurfaceResized( width, height ); - - // The stage-size may be less than surface-size (reduced by top-margin) - Vector2 size = mStage->GetSize(); - mRelayoutController->SetStageSize( size.width, size.height ); -} - -void Core::SetTopMargin( unsigned int 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 ); -} - -void Core::SetDpi( unsigned int dpiHorizontal, unsigned int dpiVertical ) -{ - mStage->SetDpi( Vector2( dpiHorizontal , 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 @@ -272,43 +202,33 @@ void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, // 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 - - if ( mResourceManager->ResourcesToProcess() ) - { - // If we are still processing resources, then we have to continue the update - status.keepUpdating |= Integration::KeepUpdating::LOADING_RESOURCES; - } } -void Core::Render( RenderStatus& status ) +void Core::PreRender( RenderStatus& status, bool forceClear, bool uploadOnly ) { - bool updateRequired = mRenderManager->Render( status ); - - status.SetNeedsUpdate( updateRequired ); + mRenderManager->PreRender( status, forceClear, uploadOnly ); } -void Core::Suspend() +void Core::RenderScene( Integration::Scene& scene, bool renderToFbo ) { - mPlatform.Suspend(); - - mIsActive = false; + mRenderManager->RenderScene( scene, renderToFbo ); } -void Core::Resume() +void Core::PostRender( bool uploadOnly ) { - mPlatform.Resume(); - - mIsActive = true; - - // trigger processing of events queued up while paused - ProcessEvents(); + mRenderManager->PostRender( uploadOnly ); } void Core::SceneCreated() @@ -316,11 +236,20 @@ void Core::SceneCreated() mStage->EmitSceneCreatedSignal(); mRelayoutController->OnApplicationSceneCreated(); + + for( auto iter = mScenes.begin(); iter != mScenes.end(); ++iter ) + { + Dali::Actor sceneRootLayer = (*iter)->GetRootLayer(); + mRelayoutController->RequestRelayoutTree( sceneRootLayer ); + } } void Core::QueueEvent( const Integration::Event& event ) { - mEventProcessor->QueueEvent( event ); + if (mScenes.size() != 0) + { + mScenes.front()->QueueEvent( event ); + } } void Core::ProcessEvents() @@ -329,7 +258,7 @@ void Core::ProcessEvents() if( mProcessingEvent ) { DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" ); - mRenderController.RequestProcessEventsOnIdle(); + mRenderController.RequestProcessEventsOnIdle( false ); return; } @@ -339,30 +268,48 @@ void Core::ProcessEvents() // Signal that any messages received will be flushed soon mUpdateManager->EventProcessingStarted(); - mEventProcessor->ProcessEvents(); + // Scene could be added or removed while processing the events + // Copy the Scene container locally to avoid possibly invalid iterator + SceneContainer scenes = mScenes; + + // process events in all scenes + for( auto scene : scenes ) + { + scene->ProcessEvents(); + } 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. + for( auto scene : scenes ) { - // Emit signal here to inform listeners that event processing has finished. - mStage->EmitEventProcessingFinishedSignal(); + scene->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(); + // Rebuild depth tree after event processing has finished + for( auto scene : scenes ) + { + scene->RebuildDepthTree(); + } - if( messagesToProcess || gestureNeedsUpdate ) - { - // tell the render controller to keep update thread running - mRenderController.RequestUpdate(); - } + // 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 = IsNextUpdateForced(); + + if( messagesToProcess || gestureNeedsUpdate || forceUpdate ) + { + // tell the render controller to keep update thread running + mRenderController.RequestUpdate( forceUpdate ); } mRelayoutController->SetProcessingCoreEvents( false ); @@ -371,34 +318,37 @@ void Core::ProcessEvents() mProcessingEvent = false; } -unsigned int Core::GetMaximumUpdateCount() const +uint32_t Core::GetMaximumUpdateCount() const { return MAXIMUM_UPDATE_COUNT; } -Integration::SystemOverlay& Core::GetSystemOverlay() -{ - return mStage->GetSystemOverlay(); -} - -void Core::SetViewMode( ViewMode viewMode ) +void Core::RegisterProcessor( Integration::Processor& processor ) { - mStage->SetViewMode( viewMode ); + mProcessors.PushBack(&processor); } -ViewMode Core::GetViewMode() const +void Core::UnregisterProcessor( Integration::Processor& processor ) { - return mStage->GetViewMode(); + auto iter = std::find( mProcessors.Begin(), mProcessors.End(), &processor ); + if( iter != mProcessors.End() ) + { + mProcessors.Erase( iter ); + } } -void Core::SetStereoBase( float stereoBase ) +void Core::RunProcessors() { - mStage->SetStereoBase( stereoBase ); -} + // Copy processor pointers to prevent changes to vector affecting loop iterator. + Dali::Vector processors( mProcessors ); -float Core::GetStereoBase() const -{ - return mStage->GetStereoBase(); + for( auto processor : processors ) + { + if( processor ) + { + processor->Process(); + } + } } StagePtr Core::GetCurrentStage() @@ -426,11 +376,6 @@ NotificationManager& Core::GetNotificationManager() return *(mNotificationManager); } -ResourceManager& Core::GetResourceManager() -{ - return *(mResourceManager); -} - ShaderFactory& Core::GetShaderFactory() { return *(mShaderFactory); @@ -446,11 +391,85 @@ RelayoutController& Core::GetRelayoutController() return *(mRelayoutController.Get()); } +ObjectRegistry& Core::GetObjectRegistry() const +{ + return *(mObjectRegistry.Get()); +} + +EventThreadServices& Core::GetEventThreadServices() +{ + return *this; +} + +PropertyNotificationManager& Core::GetPropertyNotificationManager() const +{ + return *(mPropertyNotificationManager); +} + +AnimationPlaylist& Core::GetAnimationPlaylist() const +{ + return *(mAnimationPlaylist); +} + +void Core::AddScene( Scene* scene ) +{ + mScenes.push_back( scene ); +} + +void Core::RemoveScene( Scene* scene ) +{ + auto iter = std::find( mScenes.begin(), mScenes.end(), scene ); + if( iter != mScenes.end() ) + { + mScenes.erase( iter ); + } +} + void Core::CreateThreadLocalStorage() { // a pointer to the ThreadLocalStorage object will be stored in TLS // The ThreadLocalStorage object should be deleted by the Core destructor - new ThreadLocalStorage(this); + ThreadLocalStorage* tls = new ThreadLocalStorage(this); + tls->Reference(); +} + +void Core::RegisterObject( Dali::BaseObject* object ) +{ + mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry(); + mObjectRegistry->RegisterObject( object ); +} + +void Core::UnregisterObject( Dali::BaseObject* object ) +{ + mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry(); + mObjectRegistry->UnregisterObject( object ); +} + +Integration::RenderController& Core::GetRenderController() +{ + return mRenderController; +} + +uint32_t* Core::ReserveMessageSlot( uint32_t size, bool updateScene ) +{ + return mUpdateManager->ReserveMessageSlot( size, updateScene ); +} + +BufferIndex Core::GetEventBufferIndex() const +{ + return mUpdateManager->GetEventBufferIndex(); +} + +void Core::ForceNextUpdate() +{ + mForceNextUpdate = true; +} + +bool Core::IsNextUpdateForced() +{ + bool nextUpdateForced = mForceNextUpdate; + mForceNextUpdate = false; + return nextUpdateForced; } } // namespace Internal