X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fadaptor%2Fcommon%2Fcombined-update-render-controller.cpp;h=66f32d51c2761f9a35cc0ebda9a863025cdd12cf;hb=fbf678ce8817987af608a0ebe6da592a315c44d0;hp=a73104a7a03534e4411bd30e2fa1763c1da23be1;hpb=803e8299a9916479bc4cc60f2e4763d5bea6739a;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 a73104a..66f32d5 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) 2018 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include namespace Dali { @@ -109,6 +112,7 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS mPendingRequestUpdate( FALSE ), mUseElapsedTimeAfterWait( FALSE ), mNewSurface( NULL ), + mDeletedSurface( nullptr ), mPostRendering( FALSE ), mSurfaceResized( FALSE ), mForceClear( FALSE ) @@ -119,7 +123,7 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS SetRenderRefreshRate( environmentOptions.GetRenderRefreshRate() ); // Set the thread-synchronization interface on the render-surface - RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + Dali::RenderSurfaceInterface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); if( currentSurface ) { currentSurface->SetThreadSynchronization( *this ); @@ -169,7 +173,7 @@ void CombinedUpdateRenderController::Start() sem_wait( &mEventThreadSemaphore ); } - RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + Integration::RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); if( currentSurface ) { currentSurface->StartRender(); @@ -180,6 +184,8 @@ void CombinedUpdateRenderController::Start() LOG_EVENT( "Startup Complete, starting Update/Render Thread" ); RunUpdateRenderThread( CONTINUOUS, false /* No animation progression */ ); + + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Start\n" ); } void CombinedUpdateRenderController::Pause() @@ -191,6 +197,8 @@ void CombinedUpdateRenderController::Pause() PauseUpdateRenderThread(); AddPerformanceMarker( PerformanceInterface::PAUSED ); + + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Pause\n" ); } void CombinedUpdateRenderController::Resume() @@ -207,6 +215,12 @@ void CombinedUpdateRenderController::Resume() mRunning = TRUE; mForceClear = TRUE; + + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Resume\n" ); + } + else + { + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Resume: Already resumed [%d, %d, %d]\n", mRunning, mUpdateRenderRunCount, mUpdateRenderThreadCanSleep ); } } @@ -215,7 +229,7 @@ void CombinedUpdateRenderController::Stop() LOG_EVENT_TRACE; // Stop Rendering and the Update/Render Thread - RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + Integration::RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); if( currentSurface ) { currentSurface->StopRender(); @@ -235,6 +249,8 @@ void CombinedUpdateRenderController::Stop() } mRunning = FALSE; + + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Stop\n" ); } void CombinedUpdateRenderController::RequestUpdate() @@ -275,27 +291,53 @@ void CombinedUpdateRenderController::RequestUpdateOnce() } } -void CombinedUpdateRenderController::ReplaceSurface( RenderSurface* newSurface ) +void CombinedUpdateRenderController::ReplaceSurface( Dali::RenderSurfaceInterface* newSurface ) { LOG_EVENT_TRACE; - // Set the ThreadSyncronizationInterface on the new surface - newSurface->SetThreadSynchronization( *this ); + if( mUpdateRenderThread ) + { + // Set the ThreadSyncronizationInterface on the new surface + newSurface->SetThreadSynchronization( *this ); - LOG_EVENT( "Starting to replace the surface, event-thread blocked" ); + LOG_EVENT( "Starting to replace the surface, event-thread blocked" ); - // Start replacing the surface. - { - ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); - mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will replace the surface now - mNewSurface = newSurface; - mUpdateRenderThreadWaitCondition.Notify( lock ); + // Start replacing the surface. + { + ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); + mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will replace the surface now + mNewSurface = newSurface; + mUpdateRenderThreadWaitCondition.Notify( lock ); + } + + // Wait until the surface has been replaced + sem_wait( &mEventThreadSemaphore ); + + LOG_EVENT( "Surface replaced, event-thread continuing" ); } +} + +void CombinedUpdateRenderController::DeleteSurface( Dali::RenderSurfaceInterface* surface ) +{ + LOG_EVENT_TRACE; + + if( mUpdateRenderThread ) + { + LOG_EVENT( "Starting to delete the surface, event-thread blocked" ); - // Wait until the surface has been replaced - sem_wait( &mEventThreadSemaphore ); + // 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 ); - LOG_EVENT( "Surface replaced, event-thread continuing" ); + LOG_EVENT( "Surface deleted, event-thread continuing" ); + } } void CombinedUpdateRenderController::ResizeSurface() @@ -407,12 +449,52 @@ void CombinedUpdateRenderController::UpdateRenderThread() LOG_UPDATE_RENDER( "THREAD CREATED" ); - RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); - if( currentSurface ) + // Initialize EGL & OpenGL + Dali::DisplayConnection& displayConnection = mAdaptorInterfaces.GetDisplayConnectionInterface(); + displayConnection.Initialize(); + + RenderSurfaceInterface* currentSurface = nullptr; + + GraphicsInterface& graphics = mAdaptorInterfaces.GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + + // This will only be created once + EglInterface* eglInterface = &eglGraphics->GetEglInterface(); + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( *eglInterface ); + + // Try to use OpenGL es 3.0 + // ChooseConfig returns false here when the device only support gles 2.0. + // Because eglChooseConfig with gles 3.0 setting fails when the device only support gles 2.0 and Our default setting is gles 3.0. + if( !eglImpl.ChooseConfig( true, COLOR_DEPTH_32 ) ) { - currentSurface->InitializeGraphics( mAdaptorInterfaces.GetGraphicsInterface(), mAdaptorInterfaces.GetDisplayConnectionInterface() ); + // Retry to use OpenGL es 2.0 + eglGraphics->SetGlesVersion( 20 ); + eglImpl.ChooseConfig( true, COLOR_DEPTH_32 ); } + // Check whether surfaceless context is supported + bool isSurfacelessContextSupported = eglImpl.IsSurfacelessContextSupported(); + eglGraphics->SetIsSurfacelessContextSupported( isSurfacelessContextSupported ); + + if ( isSurfacelessContextSupported ) + { + // Create a surfaceless OpenGL context for shared resources + eglImpl.CreateContext(); + eglImpl.MakeContextCurrent( EGL_NO_SURFACE, eglImpl.GetContext() ); + } + else + { + currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + if( currentSurface ) + { + currentSurface->InitializeGraphics(); + currentSurface->MakeContextCurrent(); + } + } + + eglGraphics->GetGlesInterface().ContextCreated(); + // Tell core it has a context mCore.ContextCreated(); @@ -458,7 +540,7 @@ void CombinedUpdateRenderController::UpdateRenderThread() // REPLACE SURFACE ////////////////////////////// - RenderSurface* newSurface = ShouldSurfaceBeReplaced(); + Integration::RenderSurface* newSurface = ShouldSurfaceBeReplaced(); if( DALI_UNLIKELY( newSurface ) ) { LOG_UPDATE_RENDER_TRACE_FMT( "Replacing Surface" ); @@ -469,6 +551,7 @@ void CombinedUpdateRenderController::UpdateRenderThread() // If the new surface has a different display connection, then the context will be lost mAdaptorInterfaces.GetDisplayConnectionInterface().Initialize(); + newSurface->InitializeGraphics(); newSurface->ReplaceGraphicsSurface(); SurfaceReplaced(); } @@ -515,8 +598,8 @@ void CombinedUpdateRenderController::UpdateRenderThread() } // Check resize - bool surfaceResized = ShouldSurfaceBeResized(); - if( DALI_UNLIKELY( surfaceResized ) ) + bool shouldSurfaceBeResized = ShouldSurfaceBeResized(); + if( DALI_UNLIKELY( shouldSurfaceBeResized ) ) { if( updateStatus.SurfaceRectChanged() ) { @@ -544,28 +627,40 @@ void CombinedUpdateRenderController::UpdateRenderThread() } } - RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); - if( currentSurface ) + if( eglImpl.IsSurfacelessContextSupported() ) { - currentSurface->PreRender( mSurfaceResized ); + // Make the shared surfaceless context as current before rendering + eglImpl.MakeContextCurrent( EGL_NO_SURFACE, eglImpl.GetContext() ); + } + + if( timeToSleepUntil == 0 ) + { + eglImpl.SetFirstFrameAfterResume(); } Integration::RenderStatus renderStatus; AddPerformanceMarker( PerformanceInterface::RENDER_START ); mCore.Render( renderStatus, mForceClear ); - AddPerformanceMarker( PerformanceInterface::RENDER_END ); - mForceClear = false; + ////////////////////////////// + // DELETE SURFACE + ////////////////////////////// - if( renderStatus.NeedsPostRender() ) + Integration::RenderSurface* deletedSurface = ShouldSurfaceBeDeleted(); + if( DALI_UNLIKELY( deletedSurface ) ) { - if( currentSurface ) - { - currentSurface->PostRender( isRenderingToFbo, ( mNewSurface != NULL ), mSurfaceResized ); - } + LOG_UPDATE_RENDER_TRACE_FMT( "Deleting Surface" ); + + mCore.SurfaceDeleted( deletedSurface ); + + SurfaceDeleted(); } + AddPerformanceMarker( PerformanceInterface::RENDER_END ); + + mForceClear = false; + // Trigger event thread to request Update/Render thread to sleep if update not required if( ( Integration::KeepUpdating::NOT_REQUESTED == keepUpdatingStatus ) && !renderStatus.NeedsUpdate() ) { @@ -624,6 +719,7 @@ void CombinedUpdateRenderController::UpdateRenderThread() // Inform core of context destruction & shutdown EGL mCore.ContextDestroyed(); + currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); if( currentSurface ) { currentSurface->DestroySurface(); @@ -645,12 +741,14 @@ 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 @@ -670,6 +768,7 @@ 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; @@ -687,11 +786,11 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo return ! mDestroyUpdateRenderThread; } -RenderSurface* CombinedUpdateRenderController::ShouldSurfaceBeReplaced() +Integration::RenderSurface* CombinedUpdateRenderController::ShouldSurfaceBeReplaced() { ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); - RenderSurface* newSurface = mNewSurface; + Integration::RenderSurface* newSurface = mNewSurface; mNewSurface = NULL; return newSurface; @@ -703,6 +802,22 @@ 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 ); @@ -759,6 +874,7 @@ 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 ) {