X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fcommon%2Fcore-impl.cpp;h=dccaacf607260ce78e91224a587212c5fa73e754;hb=b30bdab12215357d26d8b3aca47d225419eae5fd;hp=0b0b1f3e2251ddecf093bf2b6c051afd4062870e;hpb=5c66381841dd4dfd82c5a118d34104a00a2e0e1c;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index 0b0b1f3..dccaacf 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -1,18 +1,19 @@ -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +/* + * Copyright (c) 2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ // CLASS HEADER #include @@ -20,44 +21,47 @@ // INTERNAL INCLUDES #include #include -#include +#include +#include #include +#include #include + #include -#include #include -#include #include -#include +#include +#include +#include +#include +#include #include #include +#include +#include + +#include #include +#include + #include #include -#include -#include -#include -#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; +namespace +{ // The Update for frame N+1 may be processed whilst frame N is being rendered. -static const unsigned int MAXIMUM_UPDATE_COUNT = 2u; +const unsigned int MAXIMUM_UPDATE_COUNT = 2u; + +#if defined(DEBUG_ENABLED) +Debug::Filter* gCoreFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CORE"); +#endif +} namespace Dali { @@ -76,7 +80,7 @@ using Integration::RenderStatus; Core::Core( RenderController& renderController, PlatformAbstraction& platform, GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction, - GestureManager& gestureManager) + GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy) : mRenderController( renderController ), mPlatform(platform), mGestureEventProcessor(NULL), @@ -84,14 +88,8 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, mUpdateManager(NULL), mRenderManager(NULL), mDiscardQueue(NULL), - mResourcePostProcessQueue(), mNotificationManager(NULL), - mFrameTime(NULL), - mFontFactory(NULL), - mImageFactory(NULL), - mModelFactory(NULL), mShaderFactory(NULL), - mEmojiFactory(NULL), mIsActive(true), mProcessingEvent(false) { @@ -107,67 +105,43 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform, mPropertyNotificationManager = PropertyNotificationManager::New(); - std::vector< ResourcePostProcessRequest> init; - mResourcePostProcessQueue = new ResourcePostProcessList(init); + mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor(); - mRenderManager = RenderManager::New( glAbstraction, *mResourcePostProcessQueue ); + mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction ); RenderQueue& renderQueue = mRenderManager->GetRenderQueue(); - TextureCache& textureCache = mRenderManager->GetTextureCache(); - mDiscardQueue = new DiscardQueue( renderQueue ); - - mResourceManager = new ResourceManager( mPlatform, - *mNotificationManager, - textureCache, - *mResourcePostProcessQueue, - *mRenderManager, - *mDiscardQueue, - renderQueue ); - mTouchResampler = TouchResampler::New(); + mDiscardQueue = new DiscardQueue( renderQueue ); mUpdateManager = new UpdateManager( *mNotificationManager, - glSyncAbstraction, *mAnimationPlaylist, *mPropertyNotificationManager, - *mResourceManager, *mDiscardQueue, renderController, *mRenderManager, renderQueue, - textureCache, - *mTouchResampler ); + *mRenderTaskProcessor ); - mResourceClient = new ResourceClient( *mResourceManager, *mUpdateManager ); + mRenderManager->SetShaderSaver( *mUpdateManager ); mStage = IntrusivePtr( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) ); - mStage->Initialize(); + // This must be called after stage is created but before stage initialization + mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) ); - mUpdateManager->SetRenderTaskList( &mStage->GetRenderTaskList() ); + mStage->Initialize(); mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController); mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor); - mFrameTime = new FrameTime( mPlatform ); - mFontFactory = new FontFactory(*mResourceClient); - mImageFactory = new ImageFactory( *mResourceClient ); - mModelFactory = new ModelFactory(*mResourceClient); - mShaderFactory = new ShaderFactory(*mResourceClient); - mShaderFactory->LoadDefaultShaders(); - mEmojiFactory = new EmojiFactory(); + mShaderFactory = new ShaderFactory(); + mUpdateManager->SetShaderSaver( *mShaderFactory ); GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions(); } 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!!! */ @@ -175,7 +149,15 @@ Core::~Core() // clear the thread local storage first // 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::Get().Remove(); + ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal(); + if( tls ) + { + tls->Remove(); + delete tls; + } + + // Stop relayout requests being raised on stage destruction + mRelayoutController.Reset(); // Clean-up stage - remove default camera and root layer mStage->Uninitialize(); @@ -186,19 +168,23 @@ Core::~Core() delete mEventProcessor; delete mGestureEventProcessor; delete mNotificationManager; - delete mFontFactory; - delete mImageFactory; - delete mModelFactory; delete mShaderFactory; - delete mResourceClient; - delete mResourceManager; + delete mDiscardQueue; delete mUpdateManager; - delete mTouchResampler; - delete mEmojiFactory; delete mRenderManager; - delete mDiscardQueue; - delete mResourcePostProcessQueue; - delete mFrameTime; + delete mRenderTaskProcessor; +} + +Integration::ContextNotifierInterface* Core::GetContextNotifier() +{ + return mStage.Get(); +} + +void Core::RecoverFromContextLoss() +{ + DALI_LOG_INFO(gCoreFilter, Debug::Verbose, "Core::RecoverFromContextLoss()\n"); + + mStage->GetRenderTaskList().RecoverFromContextLoss(); // Re-trigger render-tasks } void Core::ContextCreated() @@ -206,61 +192,51 @@ void Core::ContextCreated() mRenderManager->ContextCreated(); } -void Core::ContextToBeDestroyed() +void Core::ContextDestroyed() { mRenderManager->ContextDestroyed(); } -void Core::SurfaceResized(unsigned int width, unsigned int height) +void Core::SurfaceResized( unsigned int width, unsigned int height ) { - mStage->SetSize(width, 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::SetDpi(unsigned int dpiHorizontal, unsigned int dpiVertical) +void Core::SetTopMargin( unsigned int margin ) { - mPlatform.SetDpi( dpiHorizontal, dpiVertical ); - mFontFactory->SetDpi( dpiHorizontal, dpiVertical); - mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) ); + 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::SetMinimumFrameTimeInterval(unsigned int interval) +void Core::SetDpi( unsigned int dpiHorizontal, unsigned int dpiVertical ) { - mFrameTime->SetMinimumFrameTimeInterval(interval); + mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) ); } -void Core::Update( UpdateStatus& status ) +void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status ) { - // get the last delta and the predict when this update will be rendered - float lastFrameDelta( 0.0f ); - unsigned int lastVSyncTime( 0 ); - unsigned int nextVSyncTime( 0 ); - mFrameTime->PredictNextVSyncTime( lastFrameDelta, lastVSyncTime, nextVSyncTime ); - // set the time delta so adaptor can easily print FPS with a release build with 0 as // it is cached by frametime - status.secondsFromLastFrame = lastFrameDelta; + status.secondsFromLastFrame = elapsedSeconds; // 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( lastFrameDelta, lastVSyncTime, nextVSyncTime ); + status.keepUpdating = mUpdateManager->Update( elapsedSeconds, + lastVSyncTimeMilliseconds, + nextVSyncTimeMilliseconds ); // Check the Notification Manager message queue to set needsNotification status.needsNotification = mNotificationManager->MessagesToProcess(); - // If there are notifications to process keep the update thread running as well. - // A notification event might add a new actor or animation to the stage which needs - // update thread to process it. This also prevents update thread from sleeping - // while actor thread is still processing events. - if ( status.needsNotification ) - { - status.keepUpdating |= Integration::KeepUpdating::NOTIFICATIONS_PENDING; - } - - if ( mResourceManager->ResourcesToProcess() ) - { - // If we are still processing resources, then we have to continue the update - status.keepUpdating |= Integration::KeepUpdating::LOADING_RESOURCES; - } + // 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 ) @@ -272,51 +248,22 @@ void Core::Render( RenderStatus& status ) void Core::Suspend() { - if( mFrameTime ) - { - mFrameTime->Suspend(); - } - - mPlatform.Suspend(); - mIsActive = false; } void Core::Resume() { - if( mFrameTime ) - { - mFrameTime->Resume(); - } - - mPlatform.Resume(); - mIsActive = true; // trigger processing of events queued up while paused ProcessEvents(); } -void Core::Sleep() +void Core::SceneCreated() { - if( mFrameTime ) - { - mFrameTime->Sleep(); - } -} + mStage->EmitSceneCreatedSignal(); -void Core::WakeUp() -{ - if( mFrameTime ) - { - mFrameTime->WakeUp(); - } -} - -void Core::VSync( unsigned int frameNumber, unsigned int seconds, unsigned int microseconds ) -{ - // Can't use passed in time as that is not the clock the touch events use so our predicted render value will be meaningless. - mFrameTime->SetVSyncTime( frameNumber ); + mRelayoutController->OnApplicationSceneCreated(); } void Core::QueueEvent( const Integration::Event& event ) @@ -329,17 +276,16 @@ void Core::ProcessEvents() // Guard against calls to ProcessEvents() during ProcessEvents() if( mProcessingEvent ) { - DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!" ); + DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" ); mRenderController.RequestProcessEventsOnIdle(); return; } mProcessingEvent = true; - - EventToUpdate& eventToUpdate = mUpdateManager->GetEventToUpdate(); + mRelayoutController->SetProcessingCoreEvents( true ); // Signal that any messages received will be flushed soon - eventToUpdate.EventProcessingStarted(); + mUpdateManager->EventProcessingStarted(); mEventProcessor->ProcessEvents(); @@ -348,38 +294,31 @@ void Core::ProcessEvents() // Avoid allocating MessageBuffers, triggering size-negotiation or sending any other spam whilst paused if( mIsActive ) { - // Emit signal here to start size negotiation and control relayout. + // Emit signal here to inform listeners that event processing has finished. mStage->EmitEventProcessingFinishedSignal(); - // Flush discard queue for image factory - mImageFactory->FlushReleaseQueue(); - - // send text requests if required - mFontFactory->SendTextRequests(); + // Run the size negotiation after event processing finished signal + mRelayoutController->Relayout(); // Flush any queued messages for the update-thread - const bool messagesToProcess = eventToUpdate.FlushQueue(); + const bool messagesToProcess = mUpdateManager->FlushQueue(); // Check if the touch or gestures require updates. - const bool touchNeedsUpdate = mTouchResampler->NeedsUpdate(); const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate(); - if( messagesToProcess || touchNeedsUpdate || gestureNeedsUpdate ) + if( messagesToProcess || gestureNeedsUpdate ) { // tell the render controller to keep update thread running mRenderController.RequestUpdate(); } } + mRelayoutController->SetProcessingCoreEvents( false ); + // ProcessEvents() may now be called again mProcessingEvent = false; } -void Core::UpdateTouchData(const Integration::TouchData& touch) -{ - mTouchResampler->SendTouchData( touch ); -} - unsigned int Core::GetMaximumUpdateCount() const { return MAXIMUM_UPDATE_COUNT; @@ -435,31 +374,6 @@ NotificationManager& Core::GetNotificationManager() return *(mNotificationManager); } -ResourceManager& Core::GetResourceManager() -{ - return *(mResourceManager); -} - -ResourceClient& Core::GetResourceClient() -{ - return *(mResourceClient); -} - -FontFactory& Core::GetFontFactory() -{ - return *(mFontFactory); -} - -ImageFactory& Core::GetImageFactory() -{ - return *(mImageFactory); -} - -ModelFactory& Core::GetModelFactory() -{ - return *(mModelFactory); -} - ShaderFactory& Core::GetShaderFactory() { return *(mShaderFactory); @@ -470,15 +384,15 @@ GestureEventProcessor& Core::GetGestureEventProcessor() return *(mGestureEventProcessor); } -EmojiFactory& Core::GetEmojiFactory() +RelayoutController& Core::GetRelayoutController() { - return *mEmojiFactory; + return *(mRelayoutController.Get()); } void Core::CreateThreadLocalStorage() { // a pointer to the ThreadLocalStorage object will be stored in TLS - // and automatically deleted when the thread is killed + // The ThreadLocalStorage object should be deleted by the Core destructor new ThreadLocalStorage(this); }