[Tizen] Call PostRender method of the surface if needed
[platform/core/uifw/dali-adaptor.git] / dali / internal / adaptor / common / combined-update-render-controller.cpp
index 80bc0a3..3291c4b 100644 (file)
@@ -115,12 +115,12 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS
   mPendingRequestUpdate( FALSE ),
   mUseElapsedTimeAfterWait( FALSE ),
   mNewSurface( NULL ),
+  mDeletedSurface( nullptr ),
   mPostRendering( FALSE ),
   mSurfaceResized( FALSE ),
   mForceClear( FALSE ),
   mUploadWithoutRendering( FALSE ),
-  mFirstFrameAfterResume( FALSE ),
-  mIsRenderingWindows( false )
+  mFirstFrameAfterResume( FALSE )
 {
   LOG_EVENT_TRACE;
 
@@ -324,6 +324,29 @@ void CombinedUpdateRenderController::ReplaceSurface( Dali::RenderSurfaceInterfac
   }
 }
 
+void CombinedUpdateRenderController::DeleteSurface( Dali::RenderSurfaceInterface* surface )
+{
+  LOG_EVENT_TRACE;
+
+  if( mUpdateRenderThread )
+  {
+    LOG_EVENT( "Starting to delete 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 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::WaitForGraphicsInitialization()
 {
   LOG_EVENT_TRACE;
@@ -663,8 +686,6 @@ void CombinedUpdateRenderController::UpdateRenderThread()
 
     AddPerformanceMarker( PerformanceInterface::RENDER_START );
 
-    mIsRenderingWindows = true;
-
     // Upload shared resources
     mCore.PreRender( renderStatus, mForceClear, mUploadWithoutRendering );
 
@@ -676,24 +697,24 @@ void CombinedUpdateRenderController::UpdateRenderThread()
 
       for( auto&& window : windows )
       {
-        if ( window && !window->IsBeingDeleted() )
-        {
-          Dali::Integration::Scene scene = window->GetScene();
-          Dali::RenderSurfaceInterface* windowSurface = window->GetSurface();
+        Dali::Integration::Scene scene = window->GetScene();
+        Dali::RenderSurfaceInterface* windowSurface = window->GetSurface();
 
-          if ( scene && windowSurface )
-          {
-            windowSurface->InitializeGraphics();
+        if ( scene && windowSurface )
+        {
+          windowSurface->InitializeGraphics();
 
-            // Render off-screen frame buffers first if any
-            mCore.RenderScene( scene, true );
+          // Render off-screen frame buffers first if any
+          mCore.RenderScene( scene, true );
 
-            // Switch to the EGL context of the surface
-            windowSurface->PreRender( surfaceResized ); // Switch GL context
+          // Switch to the EGL context of the surface
+          windowSurface->PreRender( surfaceResized ); // Switch GL context
 
-            // Render the surface
-            mCore.RenderScene( scene, false );
+          // Render the surface
+          mCore.RenderScene( scene, false );
 
+          if( renderStatus.NeedsPostRender() )
+          {
             windowSurface->PostRender( false, false, surfaceResized ); // Swap Buffer
           }
         }
@@ -702,7 +723,19 @@ void CombinedUpdateRenderController::UpdateRenderThread()
 
     mCore.PostRender( mUploadWithoutRendering );
 
-    mIsRenderingWindows = false;
+    //////////////////////////////
+    // DELETE SURFACE
+    //////////////////////////////
+
+    Dali::RenderSurfaceInterface* deletedSurface = ShouldSurfaceBeDeleted();
+    if( DALI_UNLIKELY( deletedSurface ) )
+    {
+      LOG_UPDATE_RENDER_TRACE_FMT( "Deleting Surface" );
+
+      deletedSurface->DestroySurface();
+
+      SurfaceDeleted();
+    }
 
     AddPerformanceMarker( PerformanceInterface::RENDER_END );
 
@@ -764,7 +797,7 @@ void CombinedUpdateRenderController::UpdateRenderThread()
     }
   }
 
-  // Inform core of context destruction & shutdown EGL
+  // Inform core of context destruction
   mCore.ContextDestroyed();
   currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface();
   if( currentSurface )
@@ -773,6 +806,9 @@ void CombinedUpdateRenderController::UpdateRenderThread()
     currentSurface = nullptr;
   }
 
+  // Shutdown EGL
+  eglInterface->TerminateGles();
+
   LOG_UPDATE_RENDER( "THREAD DESTROYED" );
 
   // Uninstall the logging function
@@ -788,12 +824,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
@@ -813,6 +851,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;
@@ -846,6 +885,22 @@ void CombinedUpdateRenderController::SurfaceReplaced()
   sem_post( &mEventThreadSemaphore );
 }
 
+Dali::RenderSurfaceInterface* CombinedUpdateRenderController::ShouldSurfaceBeDeleted()
+{
+  ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition );
+
+  Dali::RenderSurfaceInterface* deletedSurface = mDeletedSurface;
+  mDeletedSurface = NULL;
+
+  return deletedSurface;
+}
+
+void CombinedUpdateRenderController::SurfaceDeleted()
+{
+  // Just increment the semaphore
+  sem_post( &mEventThreadSemaphore );
+}
+
 bool CombinedUpdateRenderController::ShouldSurfaceBeResized()
 {
   ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition );
@@ -907,6 +962,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
          ! mDestroyUpdateRenderThread )
   {
     mUpdateRenderThreadWaitCondition.Wait( lock );