mPendingRequestUpdate( FALSE ),
mUseElapsedTimeAfterWait( FALSE ),
mNewSurface( NULL ),
+ mDeletedSurface( nullptr ),
mPostRendering( FALSE ),
mSurfaceResized( FALSE ),
mForceClear( FALSE )
LOG_EVENT( "Startup Complete, starting Update/Render Thread" );
RunUpdateRenderThread( CONTINUOUS, false /* No animation progression */ );
+
+ DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Start\n" );
}
void CombinedUpdateRenderController::Pause()
PauseUpdateRenderThread();
AddPerformanceMarker( PerformanceInterface::PAUSED );
+
+ DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Pause\n" );
}
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 );
}
}
}
mRunning = FALSE;
+
+ DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Stop\n" );
}
void CombinedUpdateRenderController::RequestUpdate()
{
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;
- // Wait until the surface has been replaced
- sem_wait( &mEventThreadSemaphore );
+ if( mUpdateRenderThread )
+ {
+ LOG_EVENT( "Starting to delete the surface, event-thread blocked" );
- LOG_EVENT( "Surface replaced, event-thread continuing" );
+ // 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 deleted, event-thread continuing" );
+ }
}
void CombinedUpdateRenderController::ResizeSurface()
RenderSurfaceInterface* currentSurface = nullptr;
-#if DALI_GLES_VERSION >= 30
-
GraphicsInterface& graphics = mAdaptorInterfaces.GetGraphicsInterface();
EglGraphics* eglGraphics = static_cast<EglGraphics *>(&graphics);
EglInterface* eglInterface = &eglGraphics->GetEglInterface();
Internal::Adaptor::EglImplementation& eglImpl = static_cast<Internal::Adaptor::EglImplementation&>( *eglInterface );
- eglImpl.ChooseConfig( true, COLOR_DEPTH_32 ); // Always use this for shared context???
- // Create a surfaceless OpenGL context for shared resources
- eglImpl.CreateContext();
- eglImpl.MakeContextCurrent( EGL_NO_SURFACE, eglImpl.GetContext() );
+ // 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 ) )
+ {
+ // Retry to use OpenGL es 2.0
+ eglGraphics->SetGlesVersion( 20 );
+ eglImpl.ChooseConfig( true, COLOR_DEPTH_32 );
+ }
-#else // DALI_GLES_VERSION >= 30
+ // Check whether surfaceless context is supported
+ bool isSurfacelessContextSupported = eglImpl.IsSurfacelessContextSupported();
+ eglGraphics->SetIsSurfacelessContextSupported( isSurfacelessContextSupported );
- currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface();
- if( currentSurface )
+ if ( isSurfacelessContextSupported )
{
- currentSurface->InitializeGraphics();
- currentSurface->MakeContextCurrent();
+ // 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();
+ }
}
-
-#endif
// Tell core it has a context
mCore.ContextCreated();
}
}
-#if DALI_GLES_VERSION >= 30
- // Make the shared surfaceless context as current before rendering
- eglImpl.MakeContextCurrent( EGL_NO_SURFACE, eglImpl.GetContext() );
-#endif
+ if( eglImpl.IsSurfacelessContextSupported() )
+ {
+ // Make the shared surfaceless context as current before rendering
+ eglImpl.MakeContextCurrent( EGL_NO_SURFACE, eglImpl.GetContext() );
+ }
Integration::RenderStatus renderStatus;
AddPerformanceMarker( PerformanceInterface::RENDER_START );
mCore.Render( renderStatus, mForceClear );
+
+ //////////////////////////////
+ // DELETE SURFACE
+ //////////////////////////////
+
+ Integration::RenderSurface* deletedSurface = ShouldSurfaceBeDeleted();
+ if( DALI_UNLIKELY( deletedSurface ) )
+ {
+ LOG_UPDATE_RENDER_TRACE_FMT( "Deleting Surface" );
+
+ mCore.SurfaceDeleted( deletedSurface );
+
+ SurfaceDeleted();
+ }
+
AddPerformanceMarker( PerformanceInterface::RENDER_END );
mForceClear = false;
( 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
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;
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 );
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 )
{