X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fcommon%2Fcore-impl.cpp;h=5e02c3648a88ec516d41cf2acadca521691227a3;hb=refs%2Fchanges%2F30%2F273930%2F3;hp=6b59def010619444c1d1a0845be918a62efbeafd;hpb=7eef78e7b6db3688d677dafd4215572cb71ba47d;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index 6b59def..5e02c36 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2021 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,16 +19,18 @@ #include // INTERNAL INCLUDES -#include +#include #include #include #include -#include +#include #include +#include #include #include #include +#include #include #include #include @@ -41,17 +43,16 @@ #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::RenderManager; using Dali::Internal::SceneGraph::RenderQueue; +using Dali::Internal::SceneGraph::UpdateManager; namespace { @@ -61,41 +62,38 @@ const uint32_t MAXIMUM_UPDATE_COUNT = 2u; #if defined(DEBUG_ENABLED) Debug::Filter* gCoreFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CORE"); #endif -} +} // namespace namespace Dali { - namespace Internal { - -using Integration::RenderController; -using Integration::PlatformAbstraction; -using Integration::GlSyncAbstraction; -using Integration::GestureManager; -using Integration::GlAbstraction; using Integration::Event; -using Integration::UpdateStatus; +using Integration::GlAbstraction; +using Integration::GlContextHelperAbstraction; +using Integration::PlatformAbstraction; +using Integration::RenderController; using Integration::RenderStatus; +using Integration::UpdateStatus; -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 ), +Core::Core(RenderController& renderController, + PlatformAbstraction& platform, + Graphics::Controller& graphicsController, + Integration::RenderToFrameBuffer renderToFboEnabled, + Integration::DepthBufferAvailable depthBufferAvailable, + Integration::StencilBufferAvailable stencilBufferAvailable, + Integration::PartialUpdateAvailable partialUpdateAvailable) +: mRenderController(renderController), mPlatform(platform), - mProcessingEvent(false) + mGraphicsController(graphicsController), + mProcessingEvent(false), + mForceNextUpdate(false) { // Create the thread local storage CreateThreadLocalStorage(); // This does nothing until Core is built with --enable-performance-monitor - PERFORMANCE_MONITOR_INIT( platform ); + PERFORMANCE_MONITOR_INIT(platform); mNotificationManager = new NotificationManager(); @@ -105,35 +103,34 @@ Core::Core( RenderController& renderController, mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor(); - mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, depthBufferAvailable, stencilBufferAvailable ); + mRenderManager = RenderManager::New(graphicsController, depthBufferAvailable, stencilBufferAvailable, partialUpdateAvailable); RenderQueue& renderQueue = mRenderManager->GetRenderQueue(); - mDiscardQueue = new DiscardQueue( renderQueue ); + mDiscardQueue = new DiscardQueue(renderQueue); - mUpdateManager = new UpdateManager( *mNotificationManager, - *mAnimationPlaylist, - *mPropertyNotificationManager, - *mDiscardQueue, - renderController, - *mRenderManager, - renderQueue, - *mRenderTaskProcessor ); + mUpdateManager = new UpdateManager(*mNotificationManager, + *mAnimationPlaylist, + *mPropertyNotificationManager, + *mDiscardQueue, + renderController, + *mRenderManager, + renderQueue, + *mRenderTaskProcessor); - mRenderManager->SetShaderSaver( *mUpdateManager ); + mRenderManager->SetShaderSaver(*mUpdateManager); - mStage = IntrusivePtr( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager, mRenderController ) ); + mObjectRegistry = ObjectRegistry::New(); - // This must be called after stage is created but before stage initialization - mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) ); + mStage = IntrusivePtr(Stage::New(*mUpdateManager)); - mStage->Initialize( renderToFboEnabled == Integration::RenderToFrameBuffer::TRUE ); + // This must be called after stage is created but before stage initialization + mRelayoutController = IntrusivePtr(new RelayoutController(mRenderController)); - mGestureEventProcessor = new GestureEventProcessor( *mStage, *mUpdateManager, gestureManager, mRenderController ); - mEventProcessor = new EventProcessor( *mStage, *mNotificationManager, *mGestureEventProcessor ); + mGestureEventProcessor = new GestureEventProcessor(*mUpdateManager, mRenderController); mShaderFactory = new ShaderFactory(); - mUpdateManager->SetShaderSaver( *mShaderFactory ); + mUpdateManager->SetShaderSaver(*mShaderFactory); GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions(); } @@ -148,21 +145,24 @@ Core::~Core() // allows core to be created / deleted many times in the same thread (how TET cases work). // Do this before mStage.Reset() so Stage::IsInstalled() returns false ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal(); - if( tls ) + 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(); +} +void Core::Initialize() +{ + mStage->Initialize(*mScenes[0]); } Integration::ContextNotifierInterface* Core::GetContextNotifier() @@ -179,38 +179,13 @@ void Core::RecoverFromContextLoss() void Core::ContextCreated() { - mRenderManager->ContextCreated(); } void Core::ContextDestroyed() { - mRenderManager->ContextDestroyed(); -} - -void Core::SurfaceResized( uint32_t width, uint32_t height ) -{ - mStage->SurfaceResized( static_cast( width ), static_cast( height ) ); - - // The stage-size may be less than surface-size (reduced by top-margin) - Vector2 size = mStage->GetSize(); - mRelayoutController->SetStageSize( static_cast( size.width ), static_cast( size.height ) ); // values get truncated -} - -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( static_cast( size.width ), static_cast( size.height ) ); // values get truncated } -void Core::SetDpi( uint32_t dpiHorizontal, uint32_t dpiVertical ) -{ - mStage->SetDpi( Vector2( static_cast( dpiHorizontal ), static_cast( dpiVertical ) ) ); -} - -void Core::Update( float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo ) +void Core::Update(float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo, bool uploadOnly) { // set the time delta so adaptor can easily print FPS with a release build with 0 as // it is cached by frametime @@ -218,25 +193,43 @@ void Core::Update( float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uin // Render returns true when there are updates on the stage or one or more animations are completed. // Use the estimated time diff till we render as the elapsed time. - status.keepUpdating = mUpdateManager->Update( elapsedSeconds, - lastVSyncTimeMilliseconds, - nextVSyncTimeMilliseconds, - renderToFboEnabled, - isRenderingToFbo ); + status.keepUpdating = mUpdateManager->Update(elapsedSeconds, + lastVSyncTimeMilliseconds, + nextVSyncTimeMilliseconds, + renderToFboEnabled, + isRenderingToFbo, + uploadOnly); // 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 forceClear ) +void Core::PreRender(RenderStatus& status, bool forceClear) +{ + mRenderManager->PreRender(status, forceClear); +} + +void Core::PreRender(Integration::Scene& scene, std::vector>& damagedRects) +{ + mRenderManager->PreRender(scene, damagedRects); +} + +void Core::RenderScene(RenderStatus& status, Integration::Scene& scene, bool renderToFbo) +{ + mRenderManager->RenderScene(status, scene, renderToFbo); +} + +void Core::RenderScene(RenderStatus& status, Integration::Scene& scene, bool renderToFbo, Rect& clippingRect) +{ + mRenderManager->RenderScene(status, scene, renderToFbo, clippingRect); +} + +void Core::PostRender() { - mRenderManager->Render( status, forceClear ); + mRenderManager->PostRender(); } void Core::SceneCreated() @@ -244,35 +237,55 @@ void Core::SceneCreated() mStage->EmitSceneCreatedSignal(); mRelayoutController->OnApplicationSceneCreated(); + + for(const auto& scene : mScenes) + { + Dali::Actor sceneRootLayer = scene->GetRootLayer(); + mRelayoutController->RequestRelayoutTree(sceneRootLayer); + } } -void Core::QueueEvent( const Integration::Event& event ) +void Core::QueueEvent(const Integration::Event& event) { - mEventProcessor->QueueEvent( event ); + if(mScenes.size() != 0) + { + mScenes.front()->QueueEvent(event); + } } void Core::ProcessEvents() { // Guard against calls to ProcessEvents() during ProcessEvents() - if( mProcessingEvent ) + if(mProcessingEvent) { - DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" ); - mRenderController.RequestProcessEventsOnIdle( false ); + DALI_LOG_ERROR("ProcessEvents should not be called from within ProcessEvents!\n"); + mRenderController.RequestProcessEventsOnIdle(false); return; } mProcessingEvent = true; - mRelayoutController->SetProcessingCoreEvents( true ); + mRelayoutController->SetProcessingCoreEvents(true); // 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(); // Emit signal here to inform listeners that event processing has finished. - mStage->EmitEventProcessingFinishedSignal(); + for(auto scene : scenes) + { + scene->EmitEventProcessingFinishedSignal(); + } // Run any registered processors RunProcessors(); @@ -280,9 +293,14 @@ void Core::ProcessEvents() // Run the size negotiation after event processing finished signal mRelayoutController->Relayout(); + // Run any registered post processors + RunPostProcessors(); // Rebuild depth tree after event processing has finished - mStage->RebuildDepthTree(); + for(auto scene : scenes) + { + scene->RebuildDepthTree(); + } // Flush any queued messages for the update-thread const bool messagesToProcess = mUpdateManager->FlushQueue(); @@ -290,15 +308,15 @@ void Core::ProcessEvents() // 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(); + const bool forceUpdate = IsNextUpdateForced(); - if( messagesToProcess || gestureNeedsUpdate || forceUpdate ) + if(messagesToProcess || gestureNeedsUpdate || forceUpdate) { // tell the render controller to keep update thread running - mRenderController.RequestUpdate( forceUpdate ); + mRenderController.RequestUpdate(forceUpdate); } - mRelayoutController->SetProcessingCoreEvents( false ); + mRelayoutController->SetProcessingCoreEvents(false); // ProcessEvents() may now be called again mProcessingEvent = false; @@ -309,35 +327,62 @@ uint32_t Core::GetMaximumUpdateCount() const return MAXIMUM_UPDATE_COUNT; } -Integration::SystemOverlay& Core::GetSystemOverlay() +void Core::RegisterProcessor(Integration::Processor& processor, bool postProcessor) { - return mStage->GetSystemOverlay(); + if(postProcessor) + { + mPostProcessors.PushBack(&processor); + } + else + { + mProcessors.PushBack(&processor); + } } -void Core::RegisterProcessor( Integration::Processor& processor ) +void Core::UnregisterProcessor(Integration::Processor& processor, bool postProcessor) { - mProcessors.PushBack(&processor); + if(postProcessor) + { + auto iter = std::find(mPostProcessors.Begin(), mPostProcessors.End(), &processor); + if(iter != mPostProcessors.End()) + { + mPostProcessors.Erase(iter); + } + } + else + { + auto iter = std::find(mProcessors.Begin(), mProcessors.End(), &processor); + if(iter != mProcessors.End()) + { + mProcessors.Erase(iter); + } + } } -void Core::UnregisterProcessor( Integration::Processor& processor ) +void Core::RunProcessors() { - auto iter = std::find( mProcessors.Begin(), mProcessors.End(), &processor ); - if( iter != mProcessors.End() ) + // Copy processor pointers to prevent changes to vector affecting loop iterator. + Dali::Vector processors(mProcessors); + + for(auto processor : processors) { - mProcessors.Erase( iter ); + if(processor) + { + processor->Process(false); + } } } -void Core::RunProcessors() +void Core::RunPostProcessors() { // Copy processor pointers to prevent changes to vector affecting loop iterator. - Dali::Vector processors( mProcessors ); + Dali::Vector processors(mPostProcessors); - for( auto processor : processors ) + for(auto processor : processors) { - if( processor ) + if(processor) { - processor->Process(); + processor->Process(true); } } } @@ -382,11 +427,90 @@ 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); +} + +Integration::GlAbstraction& Core::GetGlAbstraction() const +{ + return mGraphicsController.GetGlAbstraction(); +} + +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