X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fadaptor%2Fcommon%2Fcombined-update-render-controller.cpp;h=80bc0a3de178576cc9df959914d9340601d6876a;hb=aecc2d4c642e0cdf360e56accd3e5b96622a707f;hp=36fc1331b1af2999b8a2ebf53392bf0581afbaf1;hpb=d0703c50e4cbf4401ee39c6ac9c4e8875761a662;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/adaptor/common/combined-update-render-controller.cpp b/dali/internal/adaptor/common/combined-update-render-controller.cpp index 36fc133..80bc0a3 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.cpp +++ b/dali/internal/adaptor/common/combined-update-render-controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 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. @@ -21,9 +21,10 @@ // EXTERNAL INCLUDES #include #include +#include // INTERNAL INCLUDES -#include +#include #include #include #include @@ -32,6 +33,7 @@ #include #include #include +#include namespace Dali { @@ -91,6 +93,7 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS : mFpsTracker( environmentOptions ), mUpdateStatusLogger( environmentOptions ), mEventThreadSemaphore(), + mGraphicsInitializeSemaphore(), mUpdateRenderThreadWaitCondition(), mAdaptorInterfaces( adaptorInterfaces ), mPerformanceInterface( adaptorInterfaces.GetPerformanceInterface() ), @@ -112,12 +115,12 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS mPendingRequestUpdate( FALSE ), mUseElapsedTimeAfterWait( FALSE ), mNewSurface( NULL ), - mDeletedSurface( nullptr ), mPostRendering( FALSE ), mSurfaceResized( FALSE ), mForceClear( FALSE ), mUploadWithoutRendering( FALSE ), - mFirstFrameAfterResume( FALSE ) + mFirstFrameAfterResume( FALSE ), + mIsRenderingWindows( false ) { LOG_EVENT_TRACE; @@ -131,10 +134,11 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS currentSurface->SetThreadSynchronization( *this ); } - TriggerEventFactoryInterface& triggerFactory = mAdaptorInterfaces.GetTriggerEventFactoryInterface(); - mSleepTrigger = triggerFactory.CreateTriggerEvent( MakeCallback( this, &CombinedUpdateRenderController::ProcessSleepRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ); + mSleepTrigger = TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &CombinedUpdateRenderController::ProcessSleepRequest ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ); - sem_init( &mEventThreadSemaphore, 0, 0 ); // Initialize to 0 so that it just waits if sem_post has not been called + // Initialize to 0 so that it just waits if sem_post has not been called + sem_init( &mEventThreadSemaphore, 0, 0 ); + sem_init( &mGraphicsInitializeSemaphore, 0, 0 ); } CombinedUpdateRenderController::~CombinedUpdateRenderController() @@ -175,7 +179,7 @@ void CombinedUpdateRenderController::Start() sem_wait( &mEventThreadSemaphore ); } - Integration::RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + Dali::RenderSurfaceInterface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); if( currentSurface ) { currentSurface->StartRender(); @@ -232,7 +236,7 @@ void CombinedUpdateRenderController::Stop() LOG_EVENT_TRACE; // Stop Rendering and the Update/Render Thread - Integration::RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + Dali::RenderSurfaceInterface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); if( currentSurface ) { currentSurface->StopRender(); @@ -320,26 +324,18 @@ void CombinedUpdateRenderController::ReplaceSurface( Dali::RenderSurfaceInterfac } } -void CombinedUpdateRenderController::DeleteSurface( Dali::RenderSurfaceInterface* surface ) +void CombinedUpdateRenderController::WaitForGraphicsInitialization() { LOG_EVENT_TRACE; if( mUpdateRenderThread ) { - LOG_EVENT( "Starting to delete the surface, event-thread blocked" ); + LOG_EVENT( "Waiting for graphics initialisation, event-thread blocked" ); - // Start replacing the surface. - { - ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); - mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will delete the surface now - mDeletedSurface = surface; - mUpdateRenderThreadWaitCondition.Notify( lock ); - } - - // Wait until the surface has been deleted - sem_wait( &mEventThreadSemaphore ); + // Wait until the graphics has been initialised + sem_wait( &mGraphicsInitializeSemaphore ); - LOG_EVENT( "Surface deleted, event-thread continuing" ); + LOG_EVENT( "graphics initialised, event-thread continuing" ); } } @@ -381,6 +377,17 @@ void CombinedUpdateRenderController::SetPreRenderCallback( CallbackBase* callbac mPreRenderCallback = callback; } +void CombinedUpdateRenderController::AddSurface( Dali::RenderSurfaceInterface* surface ) +{ + LOG_EVENT_TRACE; + LOG_EVENT( "Surface is added" ); + if( mUpdateRenderThread ) + { + // Set the ThreadSyncronizationInterface on the added surface + surface->SetThreadSynchronization( *this ); + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // EVENT THREAD /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -457,6 +464,9 @@ void CombinedUpdateRenderController::UpdateRenderThread() Dali::DisplayConnection& displayConnection = mAdaptorInterfaces.GetDisplayConnectionInterface(); displayConnection.Initialize(); + // EGL has been initialised at this point + NotifyGraphicsInitialised(); + RenderSurfaceInterface* currentSurface = nullptr; GraphicsInterface& graphics = mAdaptorInterfaces.GetGraphicsInterface(); @@ -544,19 +554,21 @@ void CombinedUpdateRenderController::UpdateRenderThread() // REPLACE SURFACE ////////////////////////////// - Integration::RenderSurface* newSurface = ShouldSurfaceBeReplaced(); + Dali::RenderSurfaceInterface* newSurface = ShouldSurfaceBeReplaced(); if( DALI_UNLIKELY( newSurface ) ) { LOG_UPDATE_RENDER_TRACE_FMT( "Replacing Surface" ); - // This is designed for replacing pixmap surfaces, but should work for window as well // we need to delete the surface and renderable (pixmap / window) // Then create a new pixmap/window and new surface // If the new surface has a different display connection, then the context will be lost - mAdaptorInterfaces.GetDisplayConnectionInterface().Initialize(); newSurface->InitializeGraphics(); - newSurface->ReplaceGraphicsSurface(); + newSurface->MakeContextCurrent(); + // TODO: ReplaceGraphicsSurface doesn't work, InitializeGraphics() + // already creates new surface window, the surface and the context. + // We probably don't need ReplaceGraphicsSurface at all. + // newSurface->ReplaceGraphicsSurface(); SurfaceReplaced(); } @@ -602,6 +614,7 @@ void CombinedUpdateRenderController::UpdateRenderThread() } // Check resize + bool surfaceResized = false; bool shouldSurfaceBeResized = ShouldSurfaceBeResized(); if( DALI_UNLIKELY( shouldSurfaceBeResized ) ) { @@ -609,6 +622,7 @@ void CombinedUpdateRenderController::UpdateRenderThread() { LOG_UPDATE_RENDER_TRACE_FMT( "Resizing Surface" ); SurfaceResized(); + surfaceResized = true; } } @@ -648,22 +662,48 @@ void CombinedUpdateRenderController::UpdateRenderThread() Integration::RenderStatus renderStatus; AddPerformanceMarker( PerformanceInterface::RENDER_START ); - mCore.Render( renderStatus, mForceClear, mUploadWithoutRendering ); - ////////////////////////////// - // DELETE SURFACE - ////////////////////////////// + mIsRenderingWindows = true; + + // Upload shared resources + mCore.PreRender( renderStatus, mForceClear, mUploadWithoutRendering ); - Integration::RenderSurface* deletedSurface = ShouldSurfaceBeDeleted(); - if( DALI_UNLIKELY( deletedSurface ) ) + if ( !mUploadWithoutRendering ) { - LOG_UPDATE_RENDER_TRACE_FMT( "Deleting Surface" ); + // Go through each window + WindowContainer windows; + mAdaptorInterfaces.GetWindowContainerInterface( windows ); - mCore.SurfaceDeleted( deletedSurface ); + for( auto&& window : windows ) + { + if ( window && !window->IsBeingDeleted() ) + { + Dali::Integration::Scene scene = window->GetScene(); + Dali::RenderSurfaceInterface* windowSurface = window->GetSurface(); + + if ( scene && windowSurface ) + { + windowSurface->InitializeGraphics(); + + // Render off-screen frame buffers first if any + mCore.RenderScene( scene, true ); - SurfaceDeleted(); + // Switch to the EGL context of the surface + windowSurface->PreRender( surfaceResized ); // Switch GL context + + // Render the surface + mCore.RenderScene( scene, false ); + + windowSurface->PostRender( false, false, surfaceResized ); // Swap Buffer + } + } + } } + mCore.PostRender( mUploadWithoutRendering ); + + mIsRenderingWindows = false; + AddPerformanceMarker( PerformanceInterface::RENDER_END ); mForceClear = false; @@ -748,14 +788,12 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo ( mUpdateRenderThreadCanSleep && ! updateRequired && ! mPendingRequestUpdate ) ) && // Ensure we wait if we're supposed to be sleeping AND do not require another update ! mDestroyUpdateRenderThread && // Ensure we don't wait if the update-render-thread is supposed to be destroyed ! mNewSurface && // Ensure we don't wait if we need to replace the surface - ! mDeletedSurface && // Ensure we don't wait if we need to delete the surface ! mSurfaceResized ) // Ensure we don't wait if we need to resize the surface { LOG_UPDATE_RENDER( "WAIT: mUpdateRenderRunCount: %d", mUpdateRenderRunCount ); LOG_UPDATE_RENDER( " mUpdateRenderThreadCanSleep: %d, updateRequired: %d, mPendingRequestUpdate: %d", mUpdateRenderThreadCanSleep, updateRequired, mPendingRequestUpdate ); LOG_UPDATE_RENDER( " mDestroyUpdateRenderThread: %d", mDestroyUpdateRenderThread ); LOG_UPDATE_RENDER( " mNewSurface: %d", mNewSurface ); - LOG_UPDATE_RENDER( " mDeletedSurface: %d", mDeletedSurface ); LOG_UPDATE_RENDER( " mSurfaceResized: %d", mSurfaceResized ); // Reset the time when the thread is waiting, so the sleep-until time for @@ -775,7 +813,6 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo LOG_COUNTER_UPDATE_RENDER( "mUpdateRenderThreadCanSleep: %d, updateRequired: %d, mPendingRequestUpdate: %d", mUpdateRenderThreadCanSleep, updateRequired, mPendingRequestUpdate ); LOG_COUNTER_UPDATE_RENDER( "mDestroyUpdateRenderThread: %d", mDestroyUpdateRenderThread ); LOG_COUNTER_UPDATE_RENDER( "mNewSurface: %d", mNewSurface ); - LOG_COUNTER_UPDATE_RENDER( "mDeletedSurface: %d", mDeletedSurface ); LOG_COUNTER_UPDATE_RENDER( "mSurfaceResized: %d", mSurfaceResized ); mUseElapsedTimeAfterWait = FALSE; @@ -793,11 +830,11 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo return ! mDestroyUpdateRenderThread; } -Integration::RenderSurface* CombinedUpdateRenderController::ShouldSurfaceBeReplaced() +Dali::RenderSurfaceInterface* CombinedUpdateRenderController::ShouldSurfaceBeReplaced() { ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); - Integration::RenderSurface* newSurface = mNewSurface; + Dali::RenderSurfaceInterface* newSurface = mNewSurface; mNewSurface = NULL; return newSurface; @@ -809,22 +846,6 @@ void CombinedUpdateRenderController::SurfaceReplaced() sem_post( &mEventThreadSemaphore ); } -Integration::RenderSurface* CombinedUpdateRenderController::ShouldSurfaceBeDeleted() -{ - ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); - - Integration::RenderSurface* deletedSurface = mDeletedSurface; - mDeletedSurface = NULL; - - return deletedSurface; -} - -void CombinedUpdateRenderController::SurfaceDeleted() -{ - // Just increment the semaphore - sem_post( &mEventThreadSemaphore ); -} - bool CombinedUpdateRenderController::ShouldSurfaceBeResized() { ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); @@ -847,6 +868,11 @@ void CombinedUpdateRenderController::NotifyThreadInitialised() sem_post( &mEventThreadSemaphore ); } +void CombinedUpdateRenderController::NotifyGraphicsInitialised() +{ + sem_post( &mGraphicsInitializeSemaphore ); +} + void CombinedUpdateRenderController::AddPerformanceMarker( PerformanceInterface::MarkerType type ) { if( mPerformanceInterface ) @@ -881,8 +907,6 @@ void CombinedUpdateRenderController::PostRenderWaitForCompletion() ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); while( mPostRendering && ! mNewSurface && // We should NOT wait if we're replacing the surface - ! mDeletedSurface && // We should NOT wait if we're deleting the surface - ! mSurfaceResized && // We should NOT wait if we're resizing the surface ! mDestroyUpdateRenderThread ) { mUpdateRenderThreadWaitCondition.Wait( lock );