Redesigning render sync to handle reduced frequency 61/26461/13
authorDavid Steele <david.steele@partner.samsung.com>
Fri, 22 Aug 2014 17:40:12 +0000 (18:40 +0100)
committerDavid Steele <david.steele@partner.samsung.com>
Fri, 5 Sep 2014 15:10:32 +0000 (16:10 +0100)
[Problem] Update and render timers are out of step with expected results.
[Solution] Manage frame skipping and synchronisation with VSync in a single
place.

Moved all compositor syncing to reside in PixmapRenderSurface only.

Change-Id: I5577fc2c4c4d2ac7fb514a01c4956e402a31a038
Signed-off-by: David Steele <david.steele@partner.samsung.com>
40 files changed:
adaptors/base/frame-time.cpp
adaptors/base/frame-time.h
adaptors/base/interfaces/adaptor-internal-services.h
adaptors/base/interfaces/egl-interface.h
adaptors/base/interfaces/vsync-monitor-interface.h
adaptors/base/performance-logging/performance-server.cpp
adaptors/base/render-thread.cpp
adaptors/base/render-thread.h
adaptors/base/update-render-controller.cpp
adaptors/base/update-render-controller.h
adaptors/base/update-render-synchronization.cpp
adaptors/base/update-render-synchronization.h
adaptors/base/update-thread.cpp
adaptors/base/vsync-notifier.cpp
adaptors/base/vsync-notifier.h
adaptors/common/adaptor-impl.cpp
adaptors/common/adaptor-impl.h
adaptors/common/application-impl.cpp
adaptors/common/gl/egl-implementation.h
adaptors/common/render-surface-impl.h
adaptors/common/vsync-monitor.h
adaptors/public-api/adaptor-framework/adaptor.cpp
adaptors/public-api/adaptor-framework/adaptor.h
adaptors/public-api/adaptor-framework/render-surface.h
adaptors/tizen/vsync-monitor-tizen.cpp
adaptors/ubuntu/vsync-monitor-ubuntu.cpp
adaptors/wayland/ecore-wl-render-surface.cpp
adaptors/wayland/ecore-wl-render-surface.h
adaptors/wayland/egl-implementation-wl.cpp
adaptors/wayland/pixmap-render-surface-wl.cpp
adaptors/wayland/pixmap-render-surface.h
adaptors/wayland/window-render-surface-wl.cpp
adaptors/wayland/window-render-surface.h
adaptors/x11/ecore-x-render-surface.cpp
adaptors/x11/ecore-x-render-surface.h
adaptors/x11/egl-implementation-x.cpp
adaptors/x11/pixmap-render-surface-x.cpp
adaptors/x11/pixmap-render-surface.h
adaptors/x11/window-render-surface-x.cpp
adaptors/x11/window-render-surface.h

index e7269921f9f48c20f9f3f44981fbb7991c352e87..6c0824172f162de625ca7ff60456d8c3152d5c5b 100644 (file)
@@ -52,14 +52,14 @@ const unsigned int HISTORY_SIZE(3);
 FrameTime::FrameTime( PlatformAbstraction& platform )
 : mPlatform( platform ),
   mMinimumFrameTimeInterval( DEFAULT_MINIMUM_FRAME_TIME_INTERVAL ),
-  mLastVSyncTime( 0u ),
-  mLastVSyncTimeAtUpdate( 0u ),
-  mLastVSyncFrameNumber( 0u ),
+  mLastSyncTime( 0u ),
+  mLastSyncTimeAtUpdate( 0u ),
+  mLastSyncFrameNumber( 0u ),
   mLastUpdateFrameNumber( 0u ),
   mRunning( true ),
   mFirstFrame( true ),
   writePos( 0u ),
-  mExtraUpdatesSinceVSync( 0u )
+  mExtraUpdatesSinceSync( 0u )
 {
   // Clear buffer
   for ( unsigned int i = 0; i < HISTORY_SIZE; ++i )
@@ -67,8 +67,8 @@ FrameTime::FrameTime( PlatformAbstraction& platform )
     mPreviousUpdateFrames[i] = 0;
   }
 
-  SetLastVSyncTime();
-  mLastVSyncTimeAtUpdate = mLastVSyncTime;
+  SetLastSyncTime();
+  mLastSyncTimeAtUpdate = mLastSyncTime;
 
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "FrameTime Initialized\n" );
 }
@@ -82,16 +82,16 @@ void FrameTime::SetMinimumFrameTimeInterval( unsigned int interval )
   mMinimumFrameTimeInterval = interval;
 }
 
-void FrameTime::SetVSyncTime( unsigned int frameNumber )
+void FrameTime::SetSyncTime( unsigned int frameNumber )
 {
   // Only set the render time if we are running
   if ( mRunning )
   {
-    SetLastVSyncTime();
+    SetLastSyncTime();
 
-    mLastVSyncFrameNumber = frameNumber;
+    mLastSyncFrameNumber = frameNumber;
 
-    DALI_LOG_INFO( gLogFilter, Debug::General, "FrameTime: Frame: %u: Time: %u\n", mLastVSyncFrameNumber, (unsigned int) ( mLastVSyncTime / MICROSECONDS_PER_MILLISECOND ) );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "FrameTime: SetSyncTime(): Frame: %u: Time: %u\n", mLastSyncFrameNumber, (unsigned int) ( mLastSyncTime / MICROSECONDS_PER_MILLISECOND ) );
   }
 }
 
@@ -100,10 +100,10 @@ void FrameTime::Suspend()
   mRunning = false;
 
   // Reset members
-  mLastVSyncFrameNumber = 0;
+  mLastSyncFrameNumber = 0;
   mLastUpdateFrameNumber = 0;
   writePos = 0;
-  mExtraUpdatesSinceVSync = 0;
+  mExtraUpdatesSinceSync = 0;
 
   // Clear buffer
   for ( unsigned int i = 0; i < HISTORY_SIZE; ++i )
@@ -118,7 +118,7 @@ void FrameTime::Resume()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "FrameTime: Resuming\n" );
 
-  SetLastVSyncTime();   // Should only update the last VSync time so the elapsed time during suspension is taken into consideration when we next update.
+  SetLastSyncTime();   // Should only update the last Sync time so the elapsed time during suspension is taken into consideration when we next update.
   mFirstFrame = true;
 
   mRunning = true;
@@ -136,47 +136,48 @@ void FrameTime::WakeUp()
 {
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "FrameTime: Waking Up\n" );
 
-  SetLastVSyncTime();
-  mLastVSyncTimeAtUpdate = mLastVSyncTime; // We do not want any animations to progress as we have just been woken up.
+  SetLastSyncTime();
+  mLastSyncTimeAtUpdate = mLastSyncTime; // We do not want any animations to progress as we have just been woken up.
   mFirstFrame = true;
-
   mRunning = true;
 }
 
-void FrameTime::PredictNextVSyncTime( float& lastFrameDeltaSeconds, unsigned int& lastVSyncTimeMilliseconds, unsigned int& nextVSyncTimeMilliseconds )
+void FrameTime::PredictNextSyncTime( float& lastFrameDeltaSeconds, unsigned int& lastSyncTimeMilliseconds, unsigned int& nextSyncTimeMilliseconds )
 {
   if ( mRunning )
   {
     const unsigned int minimumFrameTimeInterval( mMinimumFrameTimeInterval );
-    const uint64_t lastVSyncTime( mLastVSyncTime );
-    const unsigned int lastVSyncFrameNumber( mLastVSyncFrameNumber );
+    const uint64_t lastSyncTime( mLastSyncTime );
+    const unsigned int lastSyncFrameNumber( mLastSyncFrameNumber );
 
     float lastFrameDelta( 0.0f ); // Assume the last update frame delta is 0.
-    unsigned int framesTillNextVSync( 1 ); // Assume next render will be in one VSync frame time.
+    unsigned int framesTillNextSync( 1 ); // Assume next render will be in one Sync frame time.
 
-    unsigned int framesInLastUpdate( lastVSyncFrameNumber - mLastUpdateFrameNumber );
-    lastFrameDelta = lastVSyncTime - mLastVSyncTimeAtUpdate;
+    unsigned int framesInLastUpdate( lastSyncFrameNumber - mLastUpdateFrameNumber );
+    lastFrameDelta = lastSyncTime - mLastSyncTimeAtUpdate;
 
     // We should only evaluate the previous frame values if this is not the first frame.
     if ( !mFirstFrame )
     {
-      // Check whether we have had any VSyncs since we last did an Update.
+      // Check whether we have had any Syncs since we last did an Update.
       if ( framesInLastUpdate == 0 )
       {
-        // We have had another update before a VSync, increment counter.
-        ++mExtraUpdatesSinceVSync;
+        // We have had another update before a Sync, increment counter.
+        ++mExtraUpdatesSinceSync;
 
-        // This update frame will be rendered mUpdatesSinceVSync later.
-        framesTillNextVSync += mExtraUpdatesSinceVSync;
+        // This update frame will be rendered mUpdatesSinceSync later.
+        framesTillNextSync += mExtraUpdatesSinceSync;
+        DALI_LOG_INFO(gLogFilter, Debug::Concise, "PredictNextSyncTime UpdateBeforeSync\n");
       }
       else
       {
-        mExtraUpdatesSinceVSync = 0;
+        mExtraUpdatesSinceSync = 0;
       }
 
       // If more than one frame elapsed since last Update, then check if this is a recurring theme so we can accurately predict when this Update is rendered.
       if ( framesInLastUpdate > 1 )
       {
+        DALI_LOG_INFO(gLogFilter, Debug::Concise, "PredictNextSyncTime framesInLastUpdate:%u\n", framesInLastUpdate);
         unsigned int average(0);
         for ( unsigned int i = 0; i < HISTORY_SIZE; ++i )
         {
@@ -187,7 +188,7 @@ void FrameTime::PredictNextVSyncTime( float& lastFrameDeltaSeconds, unsigned int
         if ( average > 1 )
         {
           // Our average shows a recurring theme, we are missing frames when rendering so calculate number of frames this will take.
-          framesTillNextVSync = average;
+          framesTillNextSync = average;
         }
       }
 
@@ -196,32 +197,31 @@ void FrameTime::PredictNextVSyncTime( float& lastFrameDeltaSeconds, unsigned int
       writePos = ( writePos + 1 ) % HISTORY_SIZE;
     }
 
-    mLastUpdateFrameNumber = lastVSyncFrameNumber;
-    mLastVSyncTimeAtUpdate = lastVSyncTime;
+    mLastUpdateFrameNumber = lastSyncFrameNumber;
+    mLastSyncTimeAtUpdate = lastSyncTime;
     mFirstFrame = false;
 
     // Calculate the time till the next render
-    unsigned int timeTillNextRender( minimumFrameTimeInterval * framesTillNextVSync );
+    unsigned int timeTillNextRender( minimumFrameTimeInterval * framesTillNextSync );
 
     // Set the input variables
     lastFrameDeltaSeconds = lastFrameDelta * MICROSECONDS_TO_SECONDS;
-    lastVSyncTimeMilliseconds = lastVSyncTime / MICROSECONDS_PER_MILLISECOND;
-    nextVSyncTimeMilliseconds = ( lastVSyncTime + timeTillNextRender ) / MICROSECONDS_PER_MILLISECOND;
+    lastSyncTimeMilliseconds = lastSyncTime / MICROSECONDS_PER_MILLISECOND;
+    nextSyncTimeMilliseconds = ( lastSyncTime + timeTillNextRender ) / MICROSECONDS_PER_MILLISECOND;
 
-    DALI_LOG_INFO( gLogFilter, Debug::General, "FrameTime: Frame: %u, Time: %u, NextTime: %u, LastDelta: %f\n", mLastUpdateFrameNumber, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds, lastFrameDeltaSeconds );
-    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                      FramesInLastUpdate: %u, FramesTillNextVSync: %u\n", framesInLastUpdate, framesTillNextVSync );
+    DALI_LOG_INFO( gLogFilter, Debug::General, "FrameTime: Frame: %u, Time: %u, NextTime: %u, LastDelta: %f\n", mLastUpdateFrameNumber, lastSyncTimeMilliseconds, nextSyncTimeMilliseconds, lastFrameDeltaSeconds );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "                      FramesInLastUpdate: %u, FramesTillNextSync: %u\n", framesInLastUpdate, framesTillNextSync );
   }
 }
 
-inline void FrameTime::SetLastVSyncTime()
+inline void FrameTime::SetLastSyncTime()
 {
   unsigned int seconds( 0u );
   unsigned int microseconds( 0u );
 
   mPlatform.GetTimeMicroseconds( seconds, microseconds );
 
-  mLastVSyncTime = seconds;
-  mLastVSyncTime = ( mLastVSyncTime * MICROSECONDS_PER_SECOND ) + microseconds;
+  mLastSyncTime = ( seconds * MICROSECONDS_PER_SECOND ) + microseconds;
 }
 
 } // namespace Adaptor
index 5c0d7a962826cbaa56d06de7ea0280b52c03d334..06881d80080a4aac8925fd118fa59dc7791c876d 100644 (file)
@@ -86,30 +86,30 @@ public:
    * Predicts when the next render time will occur.
    *
    * @param[out]  lastFrameDeltaSeconds      The delta, in seconds (with float precision), between the last two renders.
-   * @param[out]  lastVSyncTimeMilliseconds  The time, in milliseconds, of the last VSync.
-   * @param[out]  nextVSyncTimeMilliseconds  The estimated time, in milliseconds, at the next VSync.
+   * @param[out]  lastSyncTimeMilliseconds  The time, in milliseconds, of the last Sync.
+   * @param[out]  nextSyncTimeMilliseconds  The estimated time, in milliseconds, at the next Sync.
    *
    * @note Should only be called once per tick, from the update thread.
    */
-  void PredictNextVSyncTime( float& lastFrameDeltaSeconds, unsigned int& lastVSyncTimeMilliseconds, unsigned int& nextVSyncTimeMilliseconds );
+  void PredictNextSyncTime( float& lastFrameDeltaSeconds, unsigned int& lastVSyncTimeMilliseconds, unsigned int& nextVSyncTimeMilliseconds );
 
   // Called from VSync thread
 
   /**
-   * Tells the FrameTime object that a VSync has occurred.
+   * Tells the FrameTime object that a Sync has occurred.
    *
-   * @param[in]  frameNumber  The frame number of the current VSync.
+   * @param[in]  frameNumber  The frame number of the current Sync.
    *
    * @note Should only be called from the VSync thread.
    */
-  void SetVSyncTime( unsigned int frameNumber );
+  void SetSyncTime( unsigned int frameNumber );
 
 private:
 
   /**
    * Sets the current time to be the last Vsync time.
    */
-  inline void SetLastVSyncTime();
+  inline void SetLastSyncTime();
 
 private:
 
@@ -117,11 +117,11 @@ private:
 
   unsigned int mMinimumFrameTimeInterval;   ///< The minimum frame time interval, set by Adaptor.
 
-  uint64_t mLastVSyncTime;                  ///< The last VSync time (in microseconds).
-  uint64_t mLastVSyncTimeAtUpdate;          ///< The last VSync time at Update (in microseconds).
+  uint64_t mLastSyncTime;                  ///< The last Sync time (in microseconds).
+  uint64_t mLastSyncTimeAtUpdate;          ///< The last Sync time at Update (in microseconds).
 
-  unsigned int mLastVSyncFrameNumber;       ///< The last VSync frame number
-  unsigned int mLastUpdateFrameNumber;      ///< The last VSync frame number handled in Update.
+  unsigned int mLastSyncFrameNumber;       ///< The last Sync frame number
+  unsigned int mLastUpdateFrameNumber;      ///< The last Sync frame number handled in Update.
 
   bool         mRunning:1;                  ///< The state of the FrameTime object.
   bool         mFirstFrame:1;               ///< Whether the current update is the first frame (after initialisation, resume or wake up).
@@ -129,7 +129,7 @@ private:
   unsigned int mPreviousUpdateFrames[3];    ///< Array holding the number of frames Update took in the last three iterations.
   unsigned int writePos;                    ///< The current write position in the array.
 
-  unsigned int mExtraUpdatesSinceVSync;     ///< The number of extra updates since the last VSync.
+  unsigned int mExtraUpdatesSinceSync;     ///< The number of extra updates since the last Sync.
 };
 
 } // namespace Adaptor
index 5ed86a65908e99e5384b2d891e98d479d524ccf0..8585a924a604c2f4249306c874a29aa493a04c8e 100644 (file)
@@ -19,7 +19,6 @@
  */
 
 // INTERNAL INCLUDES
-#include <slp-platform-abstraction.h>
 #include <dali/integration-api/core.h>
 #include <dali/integration-api/gl-abstraction.h>
 #include <base/interfaces/egl-factory-interface.h>
index 9eaffaa9c3633834fa950beea907033ee9faf1d6..9eb006f35bbff2eb422b5f02b0da94b644e23bd4 100644 (file)
@@ -31,14 +31,6 @@ namespace Adaptor
 class EglInterface
 {
 public:
-  enum  SyncMode
-  {
-    NO_SYNC      = 0,  ///< not synchronised to display (driver might over-ride?)
-    FULL_SYNC    = 1,  ///< redraw at display refresh rate
-    HALF_SYNC    = 2,  ///< redraw at half display refresh rate
-    QUARTER_SYNC = 4   ///< redraw at quarter display refresh rate
-  };
-
   /**
     * Create the OpenGL context.
     * @return true if successful
@@ -55,12 +47,6 @@ public:
    */
   virtual void TerminateGles() = 0;
 
-  /**
-   * Sets the refresh sync mode.
-   * @see SyncMode
-   */
-  virtual bool SetRefreshSync( SyncMode mode ) = 0;
-
   /**
    * Performs an OpenGL swap buffers command
    */
@@ -90,4 +76,3 @@ protected:
 } // namespace Dali
 
 #endif // __DALI_INTERNAL_ADAPTOR_BASE_EGL_INTERFACE_H__
-
index 9e90cb4658bbccf5c9381d24ab73840c8b5e801a..2fc11450917436a36939340c686392d290637e33 100644 (file)
@@ -49,8 +49,8 @@ public:
   virtual void Terminate() = 0;
 
   /**
-   * Checks if hardware syncs are available
-   * @return true if hardware syncs are available
+   * Checks if hardware sync is available and enabled
+   * @return true if hardware sync is available and enabled
    */
   virtual bool UseHardware() = 0;
 
index 03202aa791d9afb96e155b1fc08c6320d508b6e7..6634eec7774711bebabd9569794c44c49a1cc7bd 100644 (file)
@@ -20,6 +20,7 @@
 
 // INTERNAL INCLUDES
 #include <base/environment-options.h>
+#include <dali/integration-api/platform-abstraction.h>
 
 namespace Dali
 {
index cb100bebb645b81d503a5e87910a18ef6d0cd222..35566bf82ab5fb753676d3f76fe440e9fa6adbda 100644 (file)
@@ -37,10 +37,10 @@ namespace Adaptor
 
 namespace
 {
-
-const unsigned int TIME_PER_FRAME_IN_MICROSECONDS = 16667;
-
-} // unnamed namespace
+#if defined(DEBUG_ENABLED)
+Integration::Log::Filter* gRenderLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_RENDER_THREAD");
+#endif
+}
 
 RenderThread::RenderThread( UpdateRenderSynchronization& sync,
                             AdaptorInternalServices& adaptorInterfaces,
@@ -68,21 +68,21 @@ RenderThread::~RenderThread()
 
 void RenderThread::Start()
 {
+  DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Start()\n");
+
   // initialise GL and kick off render thread
   DALI_ASSERT_ALWAYS( !mEGL && "Egl already initialized" );
 
-  // Tell frame timer what the minimum frame interval is
-  mUpdateRenderSync.SetMinimumFrameTimeInterval( mCurrent.syncMode * TIME_PER_FRAME_IN_MICROSECONDS );
-
   // create the render thread, initially we are rendering
   mThread = new boost::thread(boost::bind(&RenderThread::Run, this));
 
-  // Inform surface to block waiting for RenderSync
-  mCurrent.surface->SetSyncMode( RenderSurface::SYNC_MODE_WAIT );
+  mCurrent.surface->StartRender();
 }
 
 void RenderThread::Stop()
 {
+  DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Stop()\n");
+
   // shutdown the render thread and destroy the opengl context
   if( mThread )
   {
@@ -99,6 +99,8 @@ void RenderThread::Stop()
 
 void RenderThread::ReplaceSurface( RenderSurface* surface )
 {
+  DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::ReplaceSurface()\n");
+
   // Make sure it's a new surface. Note! we are reading the current value of render thread here, but reading is ok
   DALI_ASSERT_ALWAYS( surface != mCurrent.surface && "Trying to replace surface with itself" );
 
@@ -116,15 +118,14 @@ void RenderThread::ReplaceSurface( RenderSurface* surface )
     mNewValues.surface = surface;
   }
 
-  /*
-   * Reset the mPixmapFlushed condition if surface was changed.
-   * : in this case, client can not handle the previous damage because surface was changed.
-   */
-  RenderSync();
+  // Ensure the current surface releases any locks.
+  mCurrent.surface->StopRender();
 }
 
 void RenderThread::WaitForSurfaceReplaceComplete()
 {
+  DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::WaitForSurfaceReplaceComplete()\n");
+
   boost::unique_lock<boost::mutex> lock( mSurfaceChangedMutex );
 
   // if already completed no need to wait
@@ -134,19 +135,6 @@ void RenderThread::WaitForSurfaceReplaceComplete()
   }
 }
 
-void RenderThread::SetVSyncMode( EglInterface::SyncMode syncMode )
-{
-  // lock cache and set update flag at the end of function
-  SendMessageGuard msg( *this );
-  // set new values to cache
-  mNewValues.syncMode = syncMode;
-}
-
-void RenderThread::RenderSync()
-{
-  mCurrent.surface->RenderSync();
-}
-
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // The following methods are all executed inside render thread !!!
@@ -172,6 +160,8 @@ bool RenderThread::Run()
   // render loop, we stay inside here when rendering
   while( running )
   {
+    DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 1 - Begin loop\n");
+
     // Consume any pending events
     ConsumeEvents();
 
@@ -179,12 +169,15 @@ bool RenderThread::Run()
     CheckForUpdates();
 
     // perform any pre-render operations
+    DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 2 - PreRender\n");
     if(PreRender() == true)
     {
        // Render
+      DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 3 - Core.Render()\n");
       mCore.Render( renderStatus );
 
       // Notify the update-thread that a render has completed
+      DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 4 - Sync.RenderFinished()\n");
       mUpdateRenderSync.RenderFinished( renderStatus.NeedsUpdate() );
 
       uint64_t newTime( mUpdateRenderSync.GetTimeMicroseconds() );
@@ -192,6 +185,7 @@ bool RenderThread::Run()
       // perform any post-render operations
       if ( renderStatus.HasRendered() )
       {
+        DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 5 - PostRender()\n");
         PostRender( static_cast< unsigned int >(newTime - currentTime) );
       }
 
@@ -205,6 +199,8 @@ bool RenderThread::Run()
       currentTime = newTime;
     }
 
+    DALI_LOG_INFO( gRenderLogFilter, Debug::Verbose, "RenderThread::Run. 6 - RenderSyncWithUpdate()\n");
+
     // Wait until another frame has been updated
     running = mUpdateRenderSync.RenderSyncWithUpdate();
   }
@@ -238,8 +234,6 @@ void RenderThread::InitializeEgl()
 
   // set the initial sync mode
 
-  //@todo This needs to call the render surface instead
-  mEGL->SetRefreshSync( mCurrent.syncMode );
 
   // tell core it has a context
   mCore.ContextCreated();
@@ -263,15 +257,6 @@ void RenderThread::CheckForUpdates()
       // need to lock to access new values
       boost::unique_lock< boost::mutex > lock( mThreadDataLock );
 
-      // did the sync mode change
-      if( mCurrent.syncMode != mNewValues.syncMode )
-      {
-        mCurrent.syncMode = mNewValues.syncMode;
-
-        //@todo This needs to call the render surface instead
-        mEGL->SetRefreshSync( mCurrent.syncMode );
-      }
-
       // check if the surface needs replacing
       if( mNewValues.replaceSurface )
       {
@@ -350,8 +335,7 @@ void RenderThread::PostRender( unsigned int timeDelta )
   mGLES.PostRender(timeDelta);
 
   // Inform the surface that rendering this frame has finished.
-  mCurrent.surface->PostRender( *mEGL, mGLES, timeDelta,
-                                mSurfaceReplacing ? RenderSurface::SYNC_MODE_NONE : RenderSurface::SYNC_MODE_WAIT );
+  mCurrent.surface->PostRender( *mEGL, mGLES, timeDelta, mSurfaceReplacing );
 }
 
 } // namespace Adaptor
index 9e706c29536fa93276696d8e30a664d3361f3b29..ff1a4a666228519ca7ceb15911b590338267540b 100644 (file)
@@ -93,12 +93,6 @@ public:
    */
   void WaitForSurfaceReplaceComplete();
 
-  /**
-   * Sets the EGL VSync mode synchronisation with the display.
-   * @param syncMode to use
-   */
-  void SetVSyncMode( EglInterface::SyncMode syncMode );
-
   /**
    * Offscreen was posted to onscreen
    */
@@ -187,13 +181,11 @@ private: // Data
      */
     RenderData()
     : replaceSurface( false ),
-      syncMode( EglInterface::FULL_SYNC ),
       surface( NULL )
     {
     }
 
     volatile int                replaceSurface; ///< whether the surface needs replacing
-    EglInterface::SyncMode      syncMode;       ///< sync mode for EGL
     RenderSurface*              surface;        ///< Current surface
   };
 
index cdbbcb550350e9a8f2efbfc0deed0a3ee634bc7c..4d0ef66a80669d92070be74d4db720e7c21a3d3c 100644 (file)
@@ -41,9 +41,10 @@ UpdateRenderController::UpdateRenderController( AdaptorInternalServices& adaptor
 : mUpdateThread( NULL ),
   mRenderThread( NULL ),
   mVSyncNotifier( NULL ),
-  mUpdateRenderSync( NULL )
+  mUpdateRenderSync( NULL ),
+  mNumberOfVSyncsPerRender( 1 )
 {
-  mUpdateRenderSync = new UpdateRenderSynchronization( adaptorInterfaces );
+  mUpdateRenderSync = new UpdateRenderSynchronization( adaptorInterfaces, mNumberOfVSyncsPerRender );
 
   mUpdateThread = new UpdateThread( *mUpdateRenderSync, adaptorInterfaces, environmentOptions );
 
@@ -125,15 +126,12 @@ void UpdateRenderController::ReplaceSurface( RenderSurface* surface )
   mRenderThread->WaitForSurfaceReplaceComplete();
 }
 
-void UpdateRenderController::RenderSync()
+void UpdateRenderController::SetRenderRefreshRate(unsigned int numberOfVSyncsPerRender )
 {
-  mRenderThread->RenderSync();
+  mNumberOfVSyncsPerRender = numberOfVSyncsPerRender;
+  mUpdateRenderSync->SetRenderRefreshRate(numberOfVSyncsPerRender);
 }
 
-void UpdateRenderController::DisableVSync()
-{
-  mRenderThread->SetVSyncMode( EglInterface::NO_SYNC );
-}
 
 } // namespace Adaptor
 
index 7e49c2d2042ab056a9170560ad2e330f87b9270a..aaf5f306a0e661b1c558eff6657e750e8bb9a1c8 100644 (file)
@@ -96,14 +96,9 @@ public:
   void ReplaceSurface( RenderSurface* surface );
 
   /**
-   * @copydoc Dali::Adaptor::RenderSync()
+   * @copydoc Dali::Adaptor::SetRenderRefreshRate()
    */
-  void RenderSync();
-
-  /**
-   * @copydoc Dali::Internal::Adaptor::RenderSync()
-   */
-  void DisableVSync();
+  void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
 
 private:
 
@@ -117,6 +112,7 @@ private:
   RenderThread*                mRenderThread;     ///< The render-thread owned by UpdateRenderController
   VSyncNotifier*               mVSyncNotifier;    ///< The vsync-thread owned by UpdateRenderController
   UpdateRenderSynchronization* mUpdateRenderSync; ///< Used to synchronize the update & render threads; also owned by UpdateRenderController
+  unsigned int                 mNumberOfVSyncsPerRender; ///< Frame skipping count
 };
 
 } // namespace Adaptor
index de2ebfc1a584e9ba1e063f6ceb24454a7179856d..2cae3debd69192d5dc3ef108a53c2861beb7dbc5 100644 (file)
@@ -33,14 +33,16 @@ namespace Adaptor
 
 namespace
 {
-
+const unsigned int TIME_PER_FRAME_IN_MICROSECONDS = 16667;
 const unsigned int MICROSECONDS_PER_SECOND( 1000000 );
 const unsigned int INPUT_EVENT_UPDATE_PERIOD( MICROSECONDS_PER_SECOND / 90 ); // period between ecore x event updates
 
 } // unnamed namespace
 
-UpdateRenderSynchronization::UpdateRenderSynchronization( AdaptorInternalServices& adaptorInterfaces )
+UpdateRenderSynchronization::UpdateRenderSynchronization( AdaptorInternalServices& adaptorInterfaces,
+                                                          unsigned int numberOfVSyncsPerRender)
 : mMaximumUpdateCount( adaptorInterfaces.GetCore().GetMaximumUpdateCount()),
+  mNumberOfVSyncsPerRender( numberOfVSyncsPerRender ),
   mUpdateReadyCount( 0u ),
   mRunning( false ),
   mUpdateRequired( false ),
@@ -48,9 +50,9 @@ UpdateRenderSynchronization::UpdateRenderSynchronization( AdaptorInternalService
   mUpdateRequested( false ),
   mAllowUpdateWhilePaused( false ),
   mVSyncSleep( false ),
-  mVSyncFrameNumber( 0u ),
-  mVSyncSeconds( 0u ),
-  mVSyncMicroseconds( 0u ),
+  mSyncFrameNumber( 0u ),
+  mSyncSeconds( 0u ),
+  mSyncMicroseconds( 0u ),
   mFrameTime( adaptorInterfaces.GetPlatformAbstractionInterface() ),
   mPerformanceInterface( adaptorInterfaces.GetPerformanceInterface() )
 {
@@ -62,6 +64,7 @@ UpdateRenderSynchronization::~UpdateRenderSynchronization()
 
 void UpdateRenderSynchronization::Start()
 {
+  mFrameTime.SetMinimumFrameTimeInterval( mNumberOfVSyncsPerRender * TIME_PER_FRAME_IN_MICROSECONDS );
   mRunning = true;
 }
 
@@ -154,8 +157,8 @@ void UpdateRenderSynchronization::UpdateReadyToRun()
 
   if ( !wokenFromPause )
   {
-    // Wait for the next VSync
-    WaitVSync();
+    // Wait for the next Sync
+    WaitSync();
   }
 
   AddPerformanceMarker( PerformanceMarker::UPDATE_START );
@@ -284,18 +287,17 @@ bool UpdateRenderSynchronization::RenderSyncWithUpdate()
   return mRunning;
 }
 
-void UpdateRenderSynchronization::WaitVSync()
+void UpdateRenderSynchronization::WaitSync()
 {
-  // Block until the start of a new vsync.
+  // Block until the start of a new sync.
   // If we're experiencing slowdown and are behind by more than a frame
-  // then we should wait for the next frame as the Video output will also
-  // do this (lock-step to 60Hz)
+  // then we should wait for the next frame
 
-  unsigned int updateFrameNumber = mVSyncFrameNumber;
+  unsigned int updateFrameNumber = mSyncFrameNumber;
 
   boost::unique_lock< boost::mutex > lock( mMutex );
 
-  while ( mRunning && ( updateFrameNumber == mVSyncFrameNumber ) )
+  while ( mRunning && ( updateFrameNumber == mSyncFrameNumber ) )
   {
     // Wait will atomically add the thread to the set of threads waiting on
     // the condition variable mVSyncReceivedCondition and unlock the mutex.
@@ -306,18 +308,25 @@ void UpdateRenderSynchronization::WaitVSync()
   mAllowUpdateWhilePaused = false;
 }
 
-bool UpdateRenderSynchronization::VSyncNotifierSyncWithUpdateAndRender( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds )
+bool UpdateRenderSynchronization::VSyncNotifierSyncWithUpdateAndRender( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds, unsigned int& numberOfVSyncsPerRender )
 {
+  // This may have changed since the last sync. Update VSyncNotifier's copy here if so.
+  if( numberOfVSyncsPerRender != mNumberOfVSyncsPerRender )
+  {
+    numberOfVSyncsPerRender = mNumberOfVSyncsPerRender; // save it back
+    mFrameTime.SetMinimumFrameTimeInterval( mNumberOfVSyncsPerRender * TIME_PER_FRAME_IN_MICROSECONDS );
+  }
+
   if( validSync )
   {
-    mFrameTime.SetVSyncTime( frameNumber );
+    mFrameTime.SetSyncTime( frameNumber );
   }
 
   boost::unique_lock< boost::mutex > lock( mMutex );
 
-  mVSyncFrameNumber = frameNumber;
-  mVSyncSeconds = seconds;
-  mVSyncMicroseconds = microseconds;
+  mSyncFrameNumber = frameNumber;
+  mSyncSeconds = seconds;
+  mSyncMicroseconds = microseconds;
 
   mVSyncReceivedCondition.notify_all();
 
@@ -337,7 +346,7 @@ bool UpdateRenderSynchronization::VSyncNotifierSyncWithUpdateAndRender( bool val
 
 unsigned int UpdateRenderSynchronization::GetFrameNumber() const
 {
-  return mVSyncFrameNumber;
+  return mSyncFrameNumber;
 }
 
 uint64_t UpdateRenderSynchronization::GetTimeMicroseconds()
@@ -347,14 +356,19 @@ uint64_t UpdateRenderSynchronization::GetTimeMicroseconds()
   {
     boost::unique_lock< boost::mutex > lock( mMutex );
 
-    currentTime = mVSyncSeconds;
+    currentTime = mSyncSeconds;
     currentTime *= MICROSECONDS_PER_SECOND;
-    currentTime += mVSyncMicroseconds;
+    currentTime += mSyncMicroseconds;
   }
 
   return currentTime;
 }
 
+void UpdateRenderSynchronization::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
+{
+  mNumberOfVSyncsPerRender = numberOfVSyncsPerRender;
+}
+
 inline void UpdateRenderSynchronization::AddPerformanceMarker( PerformanceMarker::MarkerType type )
 {
   if( mPerformanceInterface )
@@ -363,17 +377,12 @@ inline void UpdateRenderSynchronization::AddPerformanceMarker( PerformanceMarker
   }
 }
 
-void UpdateRenderSynchronization::SetMinimumFrameTimeInterval( unsigned int timeInterval )
-{
-  mFrameTime.SetMinimumFrameTimeInterval( timeInterval );
-}
-
-void UpdateRenderSynchronization::PredictNextVSyncTime(
+void UpdateRenderSynchronization::PredictNextSyncTime(
   float& lastFrameDeltaSeconds,
-  unsigned int& lastVSyncTimeMilliseconds,
-  unsigned int& nextVSyncTimeMilliseconds )
+  unsigned int& lastSyncTimeMilliseconds,
+  unsigned int& nextSyncTimeMilliseconds )
 {
-  mFrameTime.PredictNextVSyncTime( lastFrameDeltaSeconds, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds );
+  mFrameTime.PredictNextSyncTime( lastFrameDeltaSeconds, lastSyncTimeMilliseconds, nextSyncTimeMilliseconds );
 }
 
 } // namespace Adaptor
index fd0ff24bf50f3b98a17c82897146d4afbf2f8935..dc2d37db6ce44c2248a0921654358535d8d3ccc2 100644 (file)
@@ -51,6 +51,7 @@ class AdaptorInternalServices;
  * The Core::GetMaximumUpdateCount() method determines how many frames may be prepared, ahead of the rendering.
  * For example if the maximum update count is 2, then Core::Update() for frame N+1 may be processed whilst frame N is being rendered.
  * However the Core::Update() for frame N+2 may not be called, until the Core::Render() method for frame N has returned.
+ *
  */
 class UpdateRenderSynchronization
 {
@@ -59,11 +60,12 @@ public:
   /**
    * Create an update/render synchronization object.
    * @param[in] adaptorInterfaces base adaptor interface
+   * @param[in] numberOfVSyncsPerRender The number of frames per render
   */
-  UpdateRenderSynchronization( AdaptorInternalServices& adaptorInterfaces );
+  UpdateRenderSynchronization( AdaptorInternalServices& adaptorInterfaces, unsigned int numberOfVSyncsPerRender );
 
   /**
-   * Non virtual destructor. Not inteded as base class.
+   * Non virtual destructor. Not intended as base class.
    */
   ~UpdateRenderSynchronization();
 
@@ -148,9 +150,9 @@ public:
   bool RenderSyncWithUpdate();
 
   /**
-   * Called by the render/update threads to wait for a VSync.
+   * Called by the render/update threads to wait for a Synchronization
    */
-  void WaitVSync();
+  void WaitSync();
 
   /**
    * Called by the VSync notifier thread so it can sleep if Update/Render threads are sleeping/paused
@@ -158,9 +160,10 @@ public:
    * @param[in] frameNumber The current frame number
    * @param[in] seconds The current time
    * @param[in] microseconds The current time
+   * @param[out] numberOfVSyncsPerRender The number of frames per render.
    * @return true if VSync monitoring/notifications should continue.
    */
-  bool VSyncNotifierSyncWithUpdateAndRender( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds );
+  bool VSyncNotifierSyncWithUpdateAndRender( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds, unsigned int& numberOfVSyncsPerRender );
 
   /**
    * Sets the expected minimum frame time interval.
@@ -172,18 +175,21 @@ public:
    * Predicts when the next render time will occur.
    *
    * @param[out]  lastFrameDeltaSeconds      The delta, in seconds (with float precision), between the last two renders.
-   * @param[out]  lastVSyncTimeMilliseconds  The time, in milliseconds, of the last VSync.
-   * @param[out]  nextVSyncTimeMilliseconds  The estimated time, in milliseconds, at the next VSync.
+   * @param[out]  lastSyncTimeMilliseconds  The time, in milliseconds, of the last Sync.
+   * @param[out]  nextSyncTimeMilliseconds  The estimated time, in milliseconds, at the next Sync.
    *
    * @note Should only be called once per tick, from the update thread.
    */
-  void PredictNextVSyncTime( float& lastFrameDeltaSeconds,
-                             unsigned int& lastVSyncTimeMilliseconds,
-                             unsigned int& nextVSyncTimeMilliseconds );
+  void PredictNextSyncTime( float& lastFrameDeltaSeconds,
+                            unsigned int& lastSyncTimeMilliseconds,
+                            unsigned int& nextSyncTimeMilliseconds );
 
   /**
-   * Retrieves the last VSync frame number
-   * @return The VSync frame number.
+   * Retrieves the last sync frame number.
+   * This is a count of the number of synchronised update/render
+   * frames, not a count of hardware VSync frames.
+   *
+   * @return The sync frame number.
    */
   unsigned int GetFrameNumber() const;
 
@@ -193,6 +199,12 @@ public:
    */
   uint64_t GetTimeMicroseconds();
 
+  /**
+   * Set the refresh rate for rendering
+   * @param[in] numberOfVSyncsPerRender The number of vsync frames per render
+   */
+  void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
+
 private:
 
   // Undefined copy constructor.
@@ -210,6 +222,9 @@ private:
 private:
 
   const unsigned int mMaximumUpdateCount;             ///< How many frames may be prepared, ahead of the rendering.
+
+  unsigned int mNumberOfVSyncsPerRender;              ///< How many frames for each update/render cycle.
+
   volatile unsigned int mUpdateReadyCount;            ///< Incremented after each update, decremented after each render (protected by mMutex)
   // ARM CPUs perform aligned 32 bit read/writes atomically, so the following variables do not require mutex protection on modification
   volatile int mRunning;                              ///< Used during UpdateThread::Stop() to exit the update & render loops
@@ -218,9 +233,9 @@ private:
   volatile int mUpdateRequested;                      ///< An update has been requested
   volatile int mAllowUpdateWhilePaused;               ///< whether to allow (one) update while paused
   volatile int mVSyncSleep;                           ///< Set true when the VSync thread should sleep
-  volatile unsigned int mVSyncFrameNumber;            ///< Frame number of latest VSync
-  volatile unsigned int mVSyncSeconds;                ///< Timestamp (seconds) of latest VSync
-  volatile unsigned int mVSyncMicroseconds;           ///< Timestamp (microseconds) of latest VSync
+  volatile unsigned int mSyncFrameNumber;            ///< Frame number of latest Sync
+  volatile unsigned int mSyncSeconds;                ///< Timestamp (seconds) of latest Sync
+  volatile unsigned int mSyncMicroseconds;           ///< Timestamp (microseconds) of latest Sync
 
   boost::mutex mMutex;                                ///< This mutex must be locked before reading/writing mUpdateReadyCount
   boost::condition_variable mUpdateFinishedCondition; ///< The render thread waits for this condition
index 33ee373854732d874e7afe10269a35efe5a30efc..5a45d4b87f43ae060e48e3cd773b18605b392b76 100644 (file)
@@ -41,9 +41,11 @@ namespace Adaptor
 
 namespace
 {
-
 const unsigned int MICROSECONDS_PER_MILLISECOND( 1000 );
 
+#if defined(DEBUG_ENABLED)
+Integration::Log::Filter* gUpdateLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_THREAD");
+#endif
 } // unnamed namespace
 
 UpdateThread::UpdateThread( UpdateRenderSynchronization& sync,
@@ -77,6 +79,7 @@ UpdateThread::~UpdateThread()
 
 void UpdateThread::Start()
 {
+  DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Start()\n");
   if ( !mThread )
   {
     // Create and run the update-thread
@@ -86,6 +89,7 @@ void UpdateThread::Start()
 
 void UpdateThread::Stop()
 {
+  DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Stop()\n");
   if( mThread )
   {
     // wait for the thread to finish
@@ -98,6 +102,7 @@ void UpdateThread::Stop()
 
 bool UpdateThread::Run()
 {
+  DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run()\n");
   Integration::UpdateStatus status;
 
   // install a function for logging
@@ -108,16 +113,21 @@ bool UpdateThread::Run()
   // Update loop, we stay inside here while the update-thread is running
   while ( running )
   {
+    DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run. 1 - Sync()\n");
+
     // Inform synchronization object update is ready to run, this will pause update thread if required.
     mUpdateRenderSync.UpdateReadyToRun();
+    DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run. 2 - Ready()\n");
 
     // 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 );
-    mUpdateRenderSync.PredictNextVSyncTime( lastFrameDelta, lastVSyncTime, nextVSyncTime );
+    unsigned int lastSyncTime( 0 );
+    unsigned int nextSyncTime( 0 );
+    mUpdateRenderSync.PredictNextSyncTime( lastFrameDelta, lastSyncTime, nextSyncTime );
 
-    mCore.Update( lastFrameDelta, lastVSyncTime, nextVSyncTime, status );
+    DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run. 3 - Update(delta:%f, lastSync:%u, nextSync:%u)\n", lastFrameDelta, lastSyncTime, nextSyncTime);
+
+    mCore.Update( lastFrameDelta, lastSyncTime, nextSyncTime, status );
 
     if( mFpsTrackingSeconds > 0 )
     {
@@ -136,6 +146,7 @@ bool UpdateThread::Run()
     // tell the synchronisation class that a buffer has been written to,
     // and to wait until there is a free buffer to write to
     running = mUpdateRenderSync.UpdateSyncWithRender( renderNeedsUpdate );
+    DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run. 4 - UpdateSyncWithRender complete\n");
 
     if( running )
     {
@@ -154,6 +165,8 @@ bool UpdateThread::Run()
 
       if( !runUpdate )
       {
+        DALI_LOG_INFO( gUpdateLogFilter, Debug::Verbose, "UpdateThread::Run. 5 - Nothing to update, trying to sleep\n");
+
         running = mUpdateRenderSync.UpdateTryToSleep();
       }
     }
index 82296e45bfde533948d513b4cf54148f2296e456..ebf7c0ec6537410ace7fdfdb37a663676b631694 100644 (file)
  */
 
 // EXTERNAL INCLUDES
-#include <xf86drm.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
 #include <boost/thread.hpp>
 
 #include <dali/integration-api/core.h>
@@ -43,11 +39,11 @@ namespace Adaptor
 namespace
 {
 
-const unsigned int MICROSECONDS_PER_SECOND( 100000u );
+const unsigned int MICROSECONDS_PER_SECOND( 1000000u );
 const unsigned int TIME_PER_FRAME_IN_MICROSECONDS( 16667u );
 
 #if defined(DEBUG_ENABLED)
-Integration::Log::Filter* gLogFilter = Integration::Log::Filter::New(Debug::Concise, false, "LOG_VSYNC_NOTIFIER");
+Integration::Log::Filter* gSyncLogFilter = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_VSYNC_NOTIFIER");
 #endif
 
 } // unnamed namespace
@@ -60,20 +56,21 @@ VSyncNotifier::VSyncNotifier( UpdateRenderSynchronization& sync,
   mPlatformAbstraction( adaptorInterfaces.GetPlatformAbstractionInterface() ),
   mVSyncMonitor( adaptorInterfaces.GetVSyncMonitorInterface() ),
   mThread( NULL ),
-  mEnvironmentOptions( environmentOptions )
+  mEnvironmentOptions( environmentOptions ),
+  mNumberOfVSyncsPerRender(1)
 {
 }
 
 VSyncNotifier::~VSyncNotifier()
 {
-  DALI_LOG_INFO( gLogFilter, Debug::General, "%s\n", __func__ );
+  DALI_LOG_INFO( gSyncLogFilter, Debug::General, "%s\n", __func__ );
 
   Stop();
 }
 
 void VSyncNotifier::Start()
 {
-  DALI_LOG_INFO( gLogFilter, Debug::General, "%s\n", __func__ );
+  DALI_LOG_INFO( gSyncLogFilter, Debug::General, "%s\n", __func__ );
 
   if ( !mThread )
   {
@@ -85,7 +82,7 @@ void VSyncNotifier::Start()
 
 void VSyncNotifier::Stop()
 {
-  DALI_LOG_INFO( gLogFilter, Debug::General, "%s\n", __func__ );
+  DALI_LOG_INFO( gSyncLogFilter, Debug::General, "%s\n", __func__ );
 
   if( mThread )
   {
@@ -112,21 +109,28 @@ void VSyncNotifier::Run()
 
   unsigned int frameNumber( 0u );             // frameCount, updated when the thread is paused
   unsigned int currentSequenceNumber( 0u );   // platform specific vsync sequence number (increments with each vsync)
-  unsigned int currentSeconds( 0u );          // timestamp at latest vsync
-  unsigned int currentMicroseconds( 0u );     // timestamp at latest vsync
+  unsigned int currentSeconds( 0u );          // timestamp at latest sync
+  unsigned int currentMicroseconds( 0u );     // timestamp at latest sync
   unsigned int seconds( 0u );
   unsigned int microseconds( 0u );
 
   bool running( true );
   while( running )
   {
+    DALI_LOG_INFO( gSyncLogFilter, Debug::General, "VSyncNotifier::Run. 1 Start loop \n");
+
     bool validSync( true );
 
     // Hardware VSyncs available?
     if( mVSyncMonitor->UseHardware() )
     {
-      // Yes..wait for hardware VSync
-      validSync = mVSyncMonitor->DoSync( currentSequenceNumber, currentSeconds, currentMicroseconds );
+      DALI_LOG_INFO( gSyncLogFilter, Debug::General, "VSyncNotifier::Run. 2 Start hardware sync (%d frames) \n", mNumberOfVSyncsPerRender);
+
+      for( unsigned int i=0; i<mNumberOfVSyncsPerRender; ++i )
+      {
+        // Yes..wait for N hardware VSync ticks
+        validSync = mVSyncMonitor->DoSync( currentSequenceNumber, currentSeconds, currentMicroseconds );
+      }
     }
     else
     {
@@ -143,17 +147,25 @@ void VSyncNotifier::Run()
         timeDelta += microseconds - currentMicroseconds;
       }
 
+      currentSeconds = seconds;
+      currentMicroseconds = microseconds;
+
+      unsigned int sleepTimeInMicroseconds = 0;
+
       if( timeDelta < TIME_PER_FRAME_IN_MICROSECONDS )
       {
-          usleep( TIME_PER_FRAME_IN_MICROSECONDS - timeDelta );
-      }
-      else
-      {
-        usleep( TIME_PER_FRAME_IN_MICROSECONDS );
+        sleepTimeInMicroseconds = TIME_PER_FRAME_IN_MICROSECONDS - timeDelta;
       }
+      sleepTimeInMicroseconds += mNumberOfVSyncsPerRender * TIME_PER_FRAME_IN_MICROSECONDS;
+
+      DALI_LOG_INFO( gSyncLogFilter, Debug::General, "VSyncNotifier::Run. 2 Start software sync (%d frames, %u microseconds) \n", mNumberOfVSyncsPerRender, sleepTimeInMicroseconds);
+      usleep( sleepTimeInMicroseconds );
     }
 
-    running = mUpdateRenderSync.VSyncNotifierSyncWithUpdateAndRender( validSync, ++frameNumber, currentSeconds, currentMicroseconds );
+    DALI_LOG_INFO( gSyncLogFilter, Debug::General, "VSyncNotifier::Run. 3 SyncWithUpdateAndRender(frame#:%d, current Sec:%u current uSec:%u)\n", frameNumber+1, currentSeconds, currentMicroseconds);
+
+    running = mUpdateRenderSync.VSyncNotifierSyncWithUpdateAndRender( validSync, ++frameNumber, currentSeconds, currentMicroseconds, mNumberOfVSyncsPerRender );
+    // The number of vsyncs per render may have been modified by this call.
   }
 
   // uninstall a function for logging
index 87bb0feba7012918c71712af27ebfcccf610228d..e2e28c4cc27ea8c81ffc877f2f862163c5147f41 100644 (file)
@@ -48,8 +48,8 @@ class EnvironmentOptions;
 class AdaptorInternalServices;
 
 /**
- * Implements a simple class that monitors vertical blanks from libdrm
- * and sends a notification to Core.
+ * Implements a simple class that either monitors vertical blanks from libdrm, or manages
+ * a software timer to handle syncing.
  */
 class VSyncNotifier
 {
@@ -97,6 +97,7 @@ private:
   VSyncMonitorInterface*              mVSyncMonitor;        ///< VSyncMonitor interface
   boost::thread*                      mThread;              ///< The actual thread.
   const EnvironmentOptions&           mEnvironmentOptions;  ///< Environment options
+  unsigned int                        mNumberOfVSyncsPerRender;///< How many frames for each update/render cycle.
 
 }; // class VSyncNotifier
 
index 34822505167bab69c3f6793135253def04113d1b..59039d2011960c686b162ac3d91458d38686b6f0 100644 (file)
@@ -509,14 +509,14 @@ void Adaptor::ReplaceSurface( Dali::RenderSurface& surface )
   mUpdateRenderController->ReplaceSurface(internalSurface);
 }
 
-void Adaptor::RenderSync()
+Dali::RenderSurface& Adaptor::GetSurface() const
 {
-  mUpdateRenderController->RenderSync();
+  return *mSurface;
 }
 
-Dali::RenderSurface& Adaptor::GetSurface() const
+void Adaptor::ReleaseSurfaceLock()
 {
-  return *mSurface;
+  mSurface->ReleaseLock();
 }
 
 Dali::TtsPlayer Adaptor::GetTtsPlayer(Dali::TtsPlayer::Mode mode)
@@ -572,9 +572,14 @@ Dali::Integration::Core& Adaptor::GetCore()
   return *mCore;
 }
 
-void Adaptor::DisableVSync()
+void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
+{
+  mUpdateRenderController->SetRenderRefreshRate( numberOfVSyncsPerRender );
+}
+
+void Adaptor::SetUseHardwareVSync( bool useHardware )
 {
-  mUpdateRenderController->DisableVSync();
+  mVSyncMonitor->SetUseHardwareVSync( useHardware );
 }
 
 void Adaptor::SetDpi(size_t hDpi, size_t vDpi)
index fa068e24a09d324f165a49b87bb1bf1f508df336..dbb243117fd88c18a4163e065ab2eac7134cf0e9 100644 (file)
@@ -175,14 +175,14 @@ public: // AdaptorInternalServices implementation
   virtual void ReplaceSurface( Dali::RenderSurface& surface );
 
   /**
-   * @copydoc AdaptorInterface::RenderSync()
+   * @copydoc Dali::Adaptor::GetSurface()
    */
-  virtual void RenderSync();
+  virtual Dali::RenderSurface& GetSurface() const;
 
   /**
-   * @copydoc Dali::Adaptor::GetSurface()
+   * @copydoc Dali::Adaptor::ReleaseSurfaceLock()
    */
-  virtual Dali::RenderSurface& GetSurface() const;
+  virtual void ReleaseSurfaceLock();
 
   /**
    * Retrieve the TtsPlayer.
@@ -219,9 +219,14 @@ public:
   virtual Dali::Integration::Core& GetCore();
 
   /**
-   * Disables GL draw synchronisation with the display.
+   * @copydoc Dali::Adaptor::SetRenderRefreshRate()
+   */
+  void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
+
+  /**
+   * @copydoc Dali::Adaptor::SetUseHardwareVSync()
    */
-  DALI_IMPORT_API void DisableVSync();
+  void SetUseHardwareVSync(bool useHardware);
 
   /**
    * Overrides DPI.
index 79a666a9b3ca7bdc82459d3ec291b007ee9a4519..21fda5ea0acefc2700c1b3d547768fd93d7c7b44 100644 (file)
@@ -182,7 +182,7 @@ void Application::OnInit()
   // Check if user requires no vsyncing and set on X11 Adaptor
   if (mCommandLineOptions->noVSyncOnRender)
   {
-    Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).DisableVSync();
+    mAdaptor->SetUseHardwareVSync(false);
   }
 
   Internal::Adaptor::Adaptor::GetImplementation( *mAdaptor ).SetStereoBase( mCommandLineOptions->stereoBase );
index 972b44132a316e19dc69666bc4aa791976ca6c7c..b74830b26cb49b67b2194457aa469fca1bede2ff 100644 (file)
@@ -104,12 +104,6 @@ public:
    */
   bool IsGlesInitialized() const;
 
-  /**
-   * Sets the refresh sync mode.
-   * @see SyncMode
-   */
-  virtual bool SetRefreshSync( SyncMode mode );
-
   /**
    * Performs an OpenGL swap buffers command
    */
@@ -193,7 +187,6 @@ private:
 
   bool                 mGlesInitialized;
   bool                 mIsOwnSurface;
-  SyncMode             mSyncMode;
   bool                 mContextCurrent;
   bool                 mIsWindow;
   ColorDepth           mColorDepth;
index ef71e8639b533bf884a53346ea03ec5c8e5ff0ef..b3d94a847d9cca380ad202c46bc34a613bbc83f2 100644 (file)
@@ -22,6 +22,7 @@
 #include <render-surface.h>
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/view-mode.h>
+#include <base/interfaces/egl-interface.h>
 
 namespace Dali
 {
@@ -46,14 +47,6 @@ class EglInterface;
  */
 class DALI_IMPORT_API RenderSurface : public Dali::RenderSurface
 {
-public:
-
-  enum SyncMode
-  {
-    SYNC_MODE_NONE,               ///< Do not wait for RenderSync
-    SYNC_MODE_WAIT                ///< Wait for RenderSync
-  };
-
 public:
 
   /**
@@ -81,7 +74,7 @@ public: // API
   virtual void CreateEglSurface( EglInterface& egl ) = 0;
 
   /**
-   * Destroyes EGL Surface
+   * Destroys EGL Surface
    * @param egl implementation to use for the destruction
    */
   virtual void DestroyEglSurface( EglInterface& egl ) = 0;
@@ -129,9 +122,9 @@ public: // API
   virtual void SetViewMode( ViewMode viewMode ) = 0;
 
   /**
-   * Called after offscreen is posted to onscreen
+   * Called when Render thread has started
    */
-  virtual void RenderSync() = 0;
+  virtual void StartRender() = 0;
 
   /**
    * Invoked by render thread before Core::Render
@@ -146,10 +139,9 @@ public: // API
    * @param[in] egl The Egl interface
    * @param[in] glAbstraction OpenGLES abstraction interface
    * @param[in] deltaTime Time (in microseconds) since PostRender was last called.
-   * @param[in] syncMode Wait for render sync flag.
-   *                     RenderSync will be skipped if this or SetSyncMode() is set to SYNC_MODE_NONE.
+   * @param[in] replacingSurface True if the surface is being replaced.
    */
-  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int deltaTime, SyncMode syncMode ) = 0;
+  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int deltaTime, bool replacingSurface ) = 0;
 
   /**
    * Invoked by render thread when the thread should be stop
@@ -157,10 +149,9 @@ public: // API
   virtual void StopRender() = 0;
 
   /**
-   * Set whether the surface should wait for RenderSync notifications
-   * @param[in] syncMode Wait for render sync flag. A member of SyncMode
+   * Invoked by Event Thread when the compositor lock should be released and rendering should resume.
    */
-  virtual void SetSyncMode( SyncMode syncMode ) = 0;
+  virtual void ReleaseLock() = 0;
 };
 
 } // namespace Adaptor
index df148c544ad3373a5fc67c02c90076eb904d691c..601a584732c7e3b574323aa92f7930425ac8a355 100644 (file)
@@ -55,7 +55,13 @@ public:
    * Set the use hardware flag
    * @param[in] useHardware The new state for the use hardware flag.
    */
-  void SetUseHardware( bool useHardware );
+  void SetUseHardwareVSync( bool useHardware );
+
+  /**
+   * Set whether the vsync hardware is available.
+   * (This is public to allow callback method to work...)
+   */
+  void SetHardwareVSyncAvailable(bool available);
 
 private: // From Dali::Internal::Adaptor::VSyncMonitorInterface
 
@@ -83,8 +89,8 @@ private:
 
   int       mFileDescriptor;  ///< DRM dev node file descriptor
   drmVBlank mVBlankInfo;
-  bool      mUseHardware;     ///< Hardware VSyncs available flag
-
+  bool      mUseHardwareVSync; ///< Whether to use hardware vsync
+  bool      mHardwareVSyncAvailable; ///< Whether hardware vsync is available
 };
 
 } // namespace Adaptor
index 1f54f6738ce16d403a12338f2b1476d74e38d455..6f4c1ca7d65abeff68506fdba0be1db737726a80 100644 (file)
@@ -91,6 +91,21 @@ RenderSurface& Adaptor::GetSurface()
   return mImpl->GetSurface();
 }
 
+void Adaptor::ReleaseSurfaceLock()
+{
+  mImpl->ReleaseSurfaceLock();
+}
+
+void Adaptor::SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender )
+{
+  mImpl->SetRenderRefreshRate( numberOfVSyncsPerRender );
+}
+
+void Adaptor::SetUseHardwareVSync(bool useHardware)
+{
+  mImpl->SetUseHardwareVSync( useHardware );
+}
+
 Adaptor& Adaptor::Get()
 {
   return Internal::Adaptor::Adaptor::Get();
index 0f8c2557e3ffa2edccc8d7cddc626d0f0591d018..70d3be2fd7286e50a8047ad3c6f077b2293a407b 100644 (file)
@@ -172,6 +172,35 @@ public:
    */
   RenderSurface& GetSurface();
 
+  /**
+   * @brief Release any locks the surface may hold.
+   *
+   * For example, after compositing an offscreen surface, use this method to allow
+   * rendering to continue.
+   */
+  void ReleaseSurfaceLock();
+
+  /**
+   * @brief Set the number of frames per render.
+   *
+   * This enables an application to deliberately render with a reduced FPS.
+   * @param[in] numberOfVSyncsPerRender The number of vsyncs between successive renders.
+   * Suggest this is a power of two:
+   * 1 - render each vsync frame
+   * 2 - render every other vsync frame
+   * 4 - render every fourth vsync frame
+   * 8 - render every eighth vsync frame
+   */
+  void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
+
+  /**
+   * @brief Set whether the frame count per render is managed using the hardware VSync or
+   * manually timed.
+   *
+   * @param[in] useHardware True if the hardware VSync should be used
+   */
+  void SetUseHardwareVSync(bool useHardware);
+
   /**
    * @brief Returns a reference to the instance of the adaptor used by the current thread.
    *
index d08e6c0874f7f46431168240af3c170aa6f630a4..c746754a9592aad7a23fc22d9a087ab560ed2aa9 100644 (file)
@@ -57,21 +57,6 @@ public:
     NATIVE_BUFFER   ///< Native Buffer
   };
 
-  /**
-   * @brief When application uses pixmap surface, it can select rendering mode.
-   *
-   * RENDER_SYNC : application should call RenderSync() after posting the offscreen to onscreen
-   * RENDER_#FPS : the maximum performance will be limited designated number of frame
-   */
-  enum RenderMode
-  {
-    RENDER_DEFAULT = -1,
-    RENDER_SYNC = 0,
-    RENDER_24FPS = 24,
-    RENDER_30FPS = 30,
-    RENDER_60FPS = 60
-  };
-
   /**
    * @brief Constructor
    *
@@ -109,17 +94,6 @@ public:
    */
   virtual PositionSize GetPositionSize() const = 0;
 
-  /**
-   * @brief Set frame update rate for pixmap surface type
-   */
-  virtual void SetRenderMode(RenderMode mode) = 0;
-
-  /**
-   * @brief Get current fps for pixmap surface type
-   * @return The render mode
-   */
-  virtual RenderMode GetRenderMode() const = 0;
-
 private:
 
   /**
index 0bb4f99cd9d3e4a3901453188972cabf580134db..ea38d94a8b731705082c76ba955b84208adf94eb 100644 (file)
@@ -61,7 +61,7 @@ void ScreenStatusChanged(keynode_t* node, void* data)
   //  - VCONFKEY_PM_STATE_SLEEP : turn vsync off
   const bool screenOn( VCONFKEY_PM_STATE_NORMAL == status );
 
-  vsyncMonitor->SetUseHardware( screenOn );
+  vsyncMonitor->SetHardwareVSyncAvailable( screenOn );
 
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "%s, Screen %s.\n", __PRETTY_FUNCTION__, screenOn ? "On" : "Off" );
 }
@@ -70,7 +70,8 @@ void ScreenStatusChanged(keynode_t* node, void* data)
 
 VSyncMonitor::VSyncMonitor()
 : mFileDescriptor( FD_NONE ),
-  mUseHardware( true )
+  mUseHardwareVSync( true ),
+  mHardwareVSyncAvailable( false )
 {
   vconf_notify_key_changed( VCONFKEY_PM_STATE, ScreenStatusChanged, this );
 }
@@ -82,9 +83,14 @@ VSyncMonitor::~VSyncMonitor()
   vconf_ignore_key_changed( VCONFKEY_PM_STATE, ScreenStatusChanged );
 }
 
-void VSyncMonitor::SetUseHardware( bool useHardware )
+void VSyncMonitor::SetUseHardwareVSync( bool useHardware )
 {
-  mUseHardware = useHardware;
+  mUseHardwareVSync = useHardware;
+}
+
+void VSyncMonitor::SetHardwareVSyncAvailable( bool hardwareVSyncAvailable )
+{
+  mHardwareVSyncAvailable = hardwareVSyncAvailable;
 }
 
 void VSyncMonitor::Initialize()
@@ -120,10 +126,9 @@ void VSyncMonitor::Terminate()
 
 bool VSyncMonitor::UseHardware()
 {
-  return mUseHardware && (FD_NONE != mFileDescriptor );
+  return mUseHardwareVSync && mHardwareVSyncAvailable && (FD_NONE != mFileDescriptor );
 }
 
-
 bool VSyncMonitor::DoSync( unsigned int& frameNumber, unsigned int& seconds, unsigned int& microseconds )
 {
   DALI_ASSERT_DEBUG( mFileDescriptor != FD_NONE && "ECoreX::VSyncMonitor is not initialized" );
index 13592a74f437eec5cff600246fd0dff4ec745801..d91aa715c76c31cf1b7bef1b638315c4fa0a31ad 100644 (file)
@@ -48,7 +48,8 @@ const int FD_NONE( -1 );
 
 VSyncMonitor::VSyncMonitor()
 : mFileDescriptor( FD_NONE ),
-  mUseHardware( false )
+  mUseHardwareVSync( false ),
+  mHardwareVsyncAvailable( false )
 {
 }
 
@@ -57,9 +58,14 @@ VSyncMonitor::~VSyncMonitor()
   Terminate();
 }
 
-void VSyncMonitor::SetUseHardware( bool useHardware )
+void VSyncMonitor::SetUseHardwareVsync( bool useHardware )
 {
-  mUseHardware = useHardware;
+  mUseHardwareVSync = useHardware;
+}
+
+void VSyncMonitor::SetHardwareVSyncAvailable( bool hardwareVSyncAvailable )
+{
+  mHardwareVsyncAvailable = hardwareVSyncAvailable;
 }
 
 void VSyncMonitor::Initialize()
@@ -80,11 +86,6 @@ void VSyncMonitor::Initialize()
 
 void VSyncMonitor::Terminate()
 {
-  if( mFileDescriptor != FD_NONE )
-  {
-    close( mFileDescriptor );
-    mFileDescriptor = FD_NONE;
-  }
 }
 
 bool VSyncMonitor::UseHardware()
index 0345024c26f9c74fe1dd8e868e0c60ce82fe4d33..158323e421313c93fb8a4a83a05651a272d6b1c5 100644 (file)
@@ -63,12 +63,9 @@ RenderSurface::RenderSurface( SurfaceType type,
   mPosition(positionSize),
   mTitle(name),
   mColorDepth(isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24),
-  mRenderMode((type == PIXMAP) ? RENDER_SYNC : RENDER_DEFAULT),
   mRenderNotification( NULL ),
-  mSyncReceived( false ),
   mOwnSurface(false),
-  mOwnDisplay(false),
-  mIsStopped( false )
+  mOwnDisplay(false)
 {
   // see if there is a display in Any display
   SetDisplay( display );
@@ -154,16 +151,6 @@ PositionSize RenderSurface::GetPositionSize() const
   return mPosition;
 }
 
-void RenderSurface::SetRenderMode(RenderMode mode)
-{
-  mRenderMode = mode;
-}
-
-Dali::RenderSurface::RenderMode RenderSurface::GetRenderMode() const
-{
-  return mRenderMode;
-}
-
 void RenderSurface::MoveResize( Dali::PositionSize positionSize )
 {
   // nothing to do in base class
@@ -211,16 +198,6 @@ void RenderSurface::ConsumeEvents()
 {
 }
 
-void RenderSurface::StopRender()
-{
-  // Stop blocking waiting for sync
-  SetSyncMode( RenderSurface::SYNC_MODE_NONE );
-  // Simulate a RenderSync in case render-thread is currently blocked
-  RenderSync();
-
-  mIsStopped = true;
-}
-
 void RenderSurface::SetViewMode( ViewMode )
 {
 }
@@ -267,38 +244,6 @@ unsigned int RenderSurface::GetSurfaceId( Any surface ) const
   return surfaceId;
 }
 
-void RenderSurface::RenderSync()
-{
-  // nothing to do
-}
-
-void RenderSurface::DoRenderSync( unsigned int timeDelta, SyncMode syncMode )
-{
-  // Should block waiting for RenderSync?
-  if( mRenderMode == Dali::RenderSurface::RENDER_SYNC )
-  {
-    boost::unique_lock< boost::mutex > lock( mSyncMutex );
-
-    // wait for sync
-    if( syncMode != SYNC_MODE_NONE &&
-        mSyncMode != SYNC_MODE_NONE &&
-        !mSyncReceived )
-    {
-      mSyncNotify.wait( lock );
-    }
-    mSyncReceived = false;
-  }
-  // Software sync based on a timed delay?
-  else if( mRenderMode > Dali::RenderSurface::RENDER_SYNC )
-  {
-    unsigned int syncPeriod( MICROSECONDS_PER_SECOND / static_cast< unsigned int >( mRenderMode ) - MILLISECONDS_PER_SECOND );
-    if( timeDelta < syncPeriod )
-    {
-      usleep( syncPeriod - timeDelta );
-    }
-  }
-}
-
 } // namespace ECore
 
 } // namespace Adaptor
index 6467ad8de4f39abb595d32b5c6b087d27b91b124..a2aac02ac525f27ee49b226e96589baf5fac9b67 100644 (file)
@@ -126,16 +126,6 @@ public: // from Dali::RenderSurface
    */
   virtual PositionSize GetPositionSize() const;
 
-  /**
-   * @copydoc Dali::RenderSurface::SetRenderMode()
-   */
-  virtual void SetRenderMode(RenderMode mode);
-
-  /**
-   * @copydoc Dali::RenderSurface::GetRenderMode()
-   */
-  virtual RenderMode GetRenderMode() const;
-
 public:  // from Internal::Adaptor::RenderSurface
 
   /**
@@ -178,11 +168,6 @@ public:  // from Internal::Adaptor::RenderSurface
    */
   virtual void ConsumeEvents();
 
-  /**
-   * @copydoc Dali::Internal::Adaptor::RenderSurface::RenderSync()
-   */
-  virtual void RenderSync();
-
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::SetViewMode()
    */
@@ -196,17 +181,7 @@ public:  // from Internal::Adaptor::RenderSurface
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PostRender()
    */
-  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode ) = 0;
-
-  /**
-   * @copydoc Dali::Internal::Adaptor::RenderSurface::StopRender()
-   */
-  virtual void StopRender();
-
-  /**
-   * @copydoc Dali::Internal::Adaptor::RenderSurface::SetSyncMode()
-   */
-  virtual void SetSyncMode( SyncMode syncMode ) { mSyncMode = syncMode; }
+  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, bool replacingSurface ) = 0;
 
 private:
 
@@ -236,13 +211,6 @@ protected:
    */
   virtual void UseExistingRenderable( unsigned int surfaceId ) = 0;
 
-  /**
-   * Perform render sync
-   * @param[in] currentTime Current time in microseconds
-   * @param[in] syncMode Wait for RenderSync (from Adaptor) flag. A member of SyncMode
-   */
-  void DoRenderSync( unsigned int timeDelta, SyncMode syncMode );
-
 protected: // Data
 
   WlDisplay*                  mMainDisplay;        ///< Wayland-connection for rendering
@@ -250,15 +218,10 @@ protected: // Data
   PositionSize                mPosition;           ///< Position
   std::string                 mTitle;              ///< Title of window which shows from "xinfo -topvwins" command
   ColorDepth                  mColorDepth;         ///< Color depth of surface (32 bit or 24 bit)
-  RenderMode                  mRenderMode;         ///< Render mode for pixmap surface type
-  TriggerEvent*               mRenderNotification; ///< Render notificatin trigger
-  boost::mutex                mSyncMutex;          ///< mutex to lock during waiting sync
-  boost::condition_variable   mSyncNotify;         ///< condition to notify main thread that pixmap was flushed to onscreen
-  SyncMode                    mSyncMode;
-  bool                        mSyncReceived;       ///< true, when a pixmap sync has occurred, (cleared after reading)
+  TriggerEvent*               mRenderNotification; ///< Render notification trigger
+
   bool                        mOwnSurface;         ///< Whether we own the surface (responsible for deleting it)
   bool                        mOwnDisplay;         ///< Whether we own the display (responsible for deleting it)
-  bool                        mIsStopped;          ///< Render should be stopped
 };
 
 } // namespace ECore
index e1543064de486b40d5adcb92696a8f8bfd00afd9..72e9696a962bdb1e1e78f0651705bee7659148d4 100644 (file)
@@ -56,7 +56,6 @@ EglImplementation::EglImplementation()
     mEglSurface(0),
     mGlesInitialized(false),
     mIsOwnSurface(true),
-    mSyncMode(FULL_SYNC),
     mContextCurrent(false),
     mIsWindow(true),
     mColorDepth(COLOR_DEPTH_24)
@@ -232,10 +231,6 @@ void EglImplementation::MakeContextCurrent()
       eglQueryString(mEglDisplay, EGL_CLIENT_APIS),
       eglQueryString(mEglDisplay, EGL_EXTENSIONS));
 
-  if ( mIsWindow )
-  {
-    SetRefreshSync( mSyncMode );
-  }
 }
 
 void EglImplementation::MakeContextNull()
@@ -276,32 +271,6 @@ bool EglImplementation::IsGlesInitialized() const
   return mGlesInitialized;
 }
 
-bool EglImplementation::SetRefreshSync( SyncMode mode )
-{
-  if ( mIsWindow == false )
-  {
-    return false;
-  }
-  mSyncMode = mode;
-
-  // eglSwapInterval specifies the minimum number of video frame periods
-  // per buffer swap for the window associated with the current context.
-
-  if ( !mContextCurrent )
-  {
-    return true;
-  }
-
-  EGLBoolean ok = eglSwapInterval( mEglDisplay, mode );
-  if ( !ok )
-  {
-    TEST_EGL_ERROR("eglSwapInterval");
-    return false;
-  }
-
-  return true;
-}
-
 void EglImplementation::SwapBuffers()
 {
   eglSwapBuffers( mEglDisplay, mEglSurface );
@@ -576,4 +545,3 @@ EGLDisplay EglImplementation::GetContext() const
 } // namespace Internal
 
 } // namespace Dali
-
index b2b537892a14ceb6981dc1e452718ec41a1e725b..0ccba73b987ac3ed01d38f4ea2e0bae15a373ed8 100644 (file)
@@ -114,13 +114,17 @@ bool PixmapRenderSurface::ReplaceEGLSurface( EglInterface& eglIf )
   return false;
 }
 
+void PixmapRenderSurface::StartRender()
+{
+}
+
 bool PixmapRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
 {
   // nothing to do for pixmaps
   return true;
 }
 
-void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode )
+void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, bool replacingSurface )
 {
   // flush gl instruction queue
   glAbstraction.Flush();
@@ -140,7 +144,11 @@ void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstract
   }
 
   // Do render synchronisation
-  DoRenderSync( timeDelta, syncMode );
+  // AcquireLock( replacingSurface ? SYNC_MODE_NONE : SYNC_MODE_WAIT );
+}
+
+void PixmapRenderSurface::StopRender()
+{
 }
 
 void PixmapRenderSurface::CreateWlRenderable()
@@ -155,15 +163,16 @@ void PixmapRenderSurface::UseExistingRenderable( unsigned int surfaceId )
 {
 }
 
-void PixmapRenderSurface::RenderSync()
+void PixmapRenderSurface::SetSyncMode( SyncMode syncMode )
 {
-  {
-    boost::unique_lock< boost::mutex > lock( mSyncMutex );
-    mSyncReceived = true;
-  }
+}
+
+void PixmapRenderSurface::AcquireLock( SyncMode syncMode )
+{
+}
 
-  // wake render thread if it was waiting for the notify
-  mSyncNotify.notify_all();
+void PixmapRenderSurface::ReleaseLock()
+{
 }
 
 } // namespace ECore
index ce8cb5cf2bc08ef44bd795e41bd684b71a2a9932..87a81bf4e175c5a07dab861bb8a1b018af089986 100644 (file)
@@ -97,9 +97,9 @@ public: // from Internal::Adaptor::RenderSurface
   virtual bool ReplaceEGLSurface( EglInterface& egl );
 
   /**
-   * @copydoc Dali::Internal::Adaptor::RenderSurface::RenderSync()
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::StartRender()
    */
-  virtual void RenderSync();
+  virtual void StartRender();
 
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PreRender()
@@ -109,9 +109,34 @@ public: // from Internal::Adaptor::RenderSurface
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PostRender()
    */
-  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode );
+  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, bool replacingSurface );
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::StopRender()
+   */
+  virtual void StopRender();
 
 private:
+  enum SyncMode
+  {
+    SYNC_MODE_NONE,
+    SYNC_MODE_WAIT
+  };
+
+  void SetSyncMode( SyncMode syncMode );
+
+  /**
+   * If sync mode is WAIT, then acquire a lock. This prevents render thread from
+   * continuing until the pixmap has been drawn by the compositor.
+   * It must be released for rendering to continue.
+   * @param[in] syncMode The current sync mode
+   */
+  void AcquireLock( SyncMode syncMode );
+
+  /**
+   * Release any locks.
+   */
+  void ReleaseLock();
 
   /**
    * Create XPixmap
index fcd272542a6c069f478e4881ceb7d78bf0db210a..a9c0505968a15539dc7a5401277bd74955942ab7 100644 (file)
@@ -178,13 +178,17 @@ void WindowRenderSurface::Map()
   ecore_wl_window_show(mWlWindow);
 }
 
+void WindowRenderSurface::StartRender()
+{
+}
+
 bool WindowRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
 {
   // nothing to do for windows
   return true;
 }
 
-void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int, SyncMode )
+void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int, bool )
 {
   EglImplementation& eglImpl = static_cast<EglImplementation&>( egl );
   eglImpl.SwapBuffers();
@@ -199,6 +203,10 @@ void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstract
   }
 }
 
+void WindowRenderSurface::StopRender()
+{
+}
+
 void WindowRenderSurface::SetViewMode( ViewMode viewMode )
 {
 }
@@ -228,6 +236,11 @@ void WindowRenderSurface::UseExistingRenderable( unsigned int surfaceId )
   mWlWindow = AnyCast< Ecore_Wl_Window* >( surfaceId );
 }
 
+void WindowRenderSurface::ReleaseLock()
+{
+  // Nothing to do.
+}
+
 } // namespace ECore
 
 } // namespace Adaptor
index 980e2732fca1b964b90e42670e960fe61f0b386e..81a10267630d9585109bb016f4e75e64d3094aea 100644 (file)
@@ -123,6 +123,11 @@ public:  // from Internal::Adaptor::RenderSurface
    */
   virtual void Map();
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::StartRender()
+   */
+  virtual void StartRender();
+
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PreRender()
    */
@@ -131,13 +136,23 @@ public:  // from Internal::Adaptor::RenderSurface
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PostRender()
    */
-  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode );
+  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, bool replacingSurface );
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::StopRender()
+   */
+  virtual void StopRender();
 
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::SetViewMode()
    */
   void SetViewMode( ViewMode viewMode );
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::ReleaseLock()
+   */
+  virtual void ReleaseLock();
+
 protected:
 
   /**
index f831dbfbe5bf0957a3038628245d9329e3f9da36..6bdb5b31f2735cd7e92ea9bdcc82d0d4278e1b1f 100644 (file)
@@ -70,13 +70,9 @@ RenderSurface::RenderSurface( SurfaceType type,
   mPosition(positionSize),
   mTitle(name),
   mColorDepth(isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24),
-  mRenderMode((type == PIXMAP) ? RENDER_SYNC : RENDER_DEFAULT),
   mRenderNotification( NULL ),
-  mSyncMode(SYNC_MODE_NONE),
-  mSyncReceived( false ),
   mOwnSurface(false),
-  mOwnDisplay(false),
-  mIsStopped( false )
+  mOwnDisplay(false)
 {
   // see if there is a display in Any display
   SetDisplay( display );
@@ -164,16 +160,6 @@ PositionSize RenderSurface::GetPositionSize() const
   return mPosition;
 }
 
-void RenderSurface::SetRenderMode(RenderMode mode)
-{
-  mRenderMode = mode;
-}
-
-Dali::RenderSurface::RenderMode RenderSurface::GetRenderMode() const
-{
-  return mRenderMode;
-}
-
 void RenderSurface::MoveResize( Dali::PositionSize positionSize )
 {
   // nothing to do in base class
@@ -242,16 +228,6 @@ void RenderSurface::ConsumeEvents()
   }
 }
 
-void RenderSurface::StopRender()
-{
-  // Stop blocking waiting for sync
-  SetSyncMode( RenderSurface::SYNC_MODE_NONE );
-  // Simulate a RenderSync in case render-thread is currently blocked
-  RenderSync();
-
-  mIsStopped = true;
-}
-
 void RenderSurface::SetViewMode( ViewMode )
 {
 }
@@ -313,39 +289,6 @@ unsigned int RenderSurface::GetSurfaceId( Any surface ) const
   return surfaceId;
 }
 
-void RenderSurface::RenderSync()
-{
-  // nothing to do
-}
-
-void RenderSurface::DoRenderSync( unsigned int timeDelta, SyncMode syncMode )
-{
-  // Should block waiting for RenderSync?
-  if( mRenderMode == Dali::RenderSurface::RENDER_SYNC )
-  {
-    boost::unique_lock< boost::mutex > lock( mSyncMutex );
-
-    // wait for sync
-    if( syncMode != SYNC_MODE_NONE &&
-        mSyncMode != SYNC_MODE_NONE &&
-        !mSyncReceived )
-    {
-      mSyncNotify.wait( lock );
-    }
-    mSyncReceived = false;
-  }
-  // Software sync based on a timed delay?
-  else if( mRenderMode > Dali::RenderSurface::RENDER_SYNC )
-  {
-    unsigned int syncPeriod( MICROSECONDS_PER_SECOND / static_cast< unsigned int >( mRenderMode ) - MILLISECONDS_PER_SECOND );
-
-    if( timeDelta < syncPeriod )
-    {
-      usleep( syncPeriod - timeDelta );
-    }
-  }
-}
-
 } // namespace ECore
 
 } // namespace Adaptor
index 7e2ed2f8b44e18a23736270011becc71bb71aaba..d1434afaa39ebf6583e4f34556f4be2578e39729 100644 (file)
@@ -125,16 +125,6 @@ public: // from Dali::RenderSurface
    */
   virtual PositionSize GetPositionSize() const;
 
-  /**
-   * @copydoc Dali::RenderSurface::SetRenderMode()
-   */
-  virtual void SetRenderMode(RenderMode mode);
-
-  /**
-   * @copydoc Dali::RenderSurface::GetRenderMode()
-   */
-  virtual RenderMode GetRenderMode() const;
-
 public:  // from Internal::Adaptor::RenderSurface
 
   /**
@@ -177,11 +167,6 @@ public:  // from Internal::Adaptor::RenderSurface
    */
   virtual void ConsumeEvents();
 
-  /**
-   * @copydoc Dali::Internal::Adaptor::RenderSurface::RenderSync()
-   */
-  virtual void RenderSync();
-
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::SetViewMode()
    */
@@ -195,17 +180,7 @@ public:  // from Internal::Adaptor::RenderSurface
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PostRender()
    */
-  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode ) = 0;
-
-  /**
-   * @copydoc Dali::Internal::Adaptor::RenderSurface::StopRender()
-   */
-  virtual void StopRender();
-
-  /**
-   * @copydoc Dali::Internal::Adaptor::RenderSurface::SetSyncMode()
-   */
-  virtual void SetSyncMode( SyncMode syncMode ) { mSyncMode = syncMode; }
+  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, bool replacingSurface ) = 0;
 
 private:
 
@@ -235,13 +210,6 @@ protected:
    */
   virtual void UseExistingRenderable( unsigned int surfaceId ) = 0;
 
-  /**
-   * Perform render sync
-   * @param[in] currentTime Current time in microseconds
-   * @param[in] syncMode Wait for RenderSync (from Adaptor) flag. A member of SyncMode
-   */
-  void DoRenderSync( unsigned int timeDelta, SyncMode syncMode );
-
 protected: // Data
 
   XDisplay*                   mMainDisplay;        ///< X-connection for rendering
@@ -250,15 +218,10 @@ protected: // Data
   PositionSize                mPosition;           ///< Position
   std::string                 mTitle;              ///< Title of window which shows from "xinfo -topvwins" command
   ColorDepth                  mColorDepth;         ///< Color depth of surface (32 bit or 24 bit)
-  RenderMode                  mRenderMode;         ///< Render mode for pixmap surface type
-  TriggerEvent*               mRenderNotification; ///< Render notificatin trigger
-  boost::mutex                mSyncMutex;          ///< mutex to lock during waiting sync
-  boost::condition_variable   mSyncNotify;         ///< condition to notify main thread that pixmap was flushed to onscreen
-  SyncMode                    mSyncMode;
-  bool                        mSyncReceived;       ///< true, when a pixmap sync has occurred, (cleared after reading)
+  TriggerEvent*               mRenderNotification; ///< Render notification trigger
+
   bool                        mOwnSurface;         ///< Whether we own the surface (responsible for deleting it)
   bool                        mOwnDisplay;         ///< Whether we own the display (responsible for deleting it)
-  bool                        mIsStopped;          ///< Render should be stopped
 };
 
 } // namespace ECore
index e8610ae787dda4ae9f56de18963286c407b35917..d00734794f4283efcbce86ee3e6c5e2e9ecdec11 100644 (file)
@@ -57,7 +57,6 @@ EglImplementation::EglImplementation()
     mEglSurface(0),
     mGlesInitialized(false),
     mIsOwnSurface(true),
-    mSyncMode(FULL_SYNC),
     mContextCurrent(false),
     mIsWindow(true),
     mColorDepth(COLOR_DEPTH_24)
@@ -238,11 +237,6 @@ void EglImplementation::MakeContextCurrent()
       eglQueryString(mEglDisplay, EGL_VERSION),
       eglQueryString(mEglDisplay, EGL_CLIENT_APIS),
       eglQueryString(mEglDisplay, EGL_EXTENSIONS));
-
-  if ( mIsWindow )
-  {
-    SetRefreshSync( mSyncMode );
-  }
 }
 
 void EglImplementation::MakeContextNull()
@@ -283,32 +277,6 @@ bool EglImplementation::IsGlesInitialized() const
   return mGlesInitialized;
 }
 
-bool EglImplementation::SetRefreshSync( SyncMode mode )
-{
-  if ( mIsWindow == false )
-  {
-    return false;
-  }
-  mSyncMode = mode;
-
-  // eglSwapInterval specifies the minimum number of video frame periods
-  // per buffer swap for the window associated with the current context.
-
-  if ( !mContextCurrent )
-  {
-    return true;
-  }
-
-  EGLBoolean ok = eglSwapInterval( mEglDisplay, mode );
-  if ( !ok )
-  {
-    TEST_EGL_ERROR("eglSwapInterval");
-    return false;
-  }
-
-  return true;
-}
-
 void EglImplementation::SwapBuffers()
 {
   eglSwapBuffers( mEglDisplay, mEglSurface );
@@ -586,4 +554,3 @@ EGLDisplay EglImplementation::GetContext() const
 } // namespace Internal
 
 } // namespace Dali
-
index f950648a1d6c88adb93679240ab1f6b79ed2d216..1cfd6ff54a4b05a3bdf54f0ca33999456ad76709 100644 (file)
@@ -54,7 +54,9 @@ PixmapRenderSurface::PixmapRenderSurface( Dali::PositionSize positionSize,
                               Any display,
                               const std::string& name,
                               bool isTransparent)
-: RenderSurface( Dali::RenderSurface::PIXMAP, positionSize, surface, display, name, isTransparent )
+: RenderSurface( Dali::RenderSurface::PIXMAP, positionSize, surface, display, name, isTransparent ),
+  mSyncMode(SYNC_MODE_NONE),
+  mSyncReceived(false)
 {
   Init( surface );
 }
@@ -129,13 +131,18 @@ bool PixmapRenderSurface::ReplaceEGLSurface( EglInterface& eglIf )
                                        reinterpret_cast< EGLNativeDisplayType >( mMainDisplay ) );
 }
 
+void PixmapRenderSurface::StartRender()
+{
+  mSyncMode = SYNC_MODE_WAIT;
+}
+
 bool PixmapRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
 {
   // nothing to do for pixmaps
   return true;
 }
 
-void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode )
+void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, bool replacingSurface )
 {
   // flush gl instruction queue
   glAbstraction.Flush();
@@ -173,8 +180,13 @@ void PixmapRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstract
     }
   }
 
-  // Do render synchronisation
-  DoRenderSync( timeDelta, syncMode );
+  AcquireLock( replacingSurface ? SYNC_MODE_NONE : SYNC_MODE_WAIT );
+}
+
+void PixmapRenderSurface::StopRender()
+{
+  SetSyncMode(SYNC_MODE_NONE);
+  ReleaseLock();
 }
 
 void PixmapRenderSurface::CreateXRenderable()
@@ -207,7 +219,26 @@ void PixmapRenderSurface::UseExistingRenderable( unsigned int surfaceId )
   mX11Pixmap = static_cast< Ecore_X_Pixmap >( surfaceId );
 }
 
-void PixmapRenderSurface::RenderSync()
+void PixmapRenderSurface::SetSyncMode( SyncMode syncMode )
+{
+  mSyncMode = syncMode;
+}
+
+void PixmapRenderSurface::AcquireLock( SyncMode syncMode )
+{
+  boost::unique_lock< boost::mutex > lock( mSyncMutex );
+
+  // wait for sync
+  if( syncMode != SYNC_MODE_NONE &&
+      mSyncMode != SYNC_MODE_NONE &&
+      !mSyncReceived )
+  {
+    mSyncNotify.wait( lock );
+  }
+  mSyncReceived = false;
+}
+
+void PixmapRenderSurface::ReleaseLock()
 {
   {
     boost::unique_lock< boost::mutex > lock( mSyncMutex );
@@ -218,6 +249,7 @@ void PixmapRenderSurface::RenderSync()
   mSyncNotify.notify_all();
 }
 
+
 } // namespace ECore
 
 } // namespace Adaptor
index 641e8a80f0396ca75c26ed34568d4c29909579bd..b4af9c8bc9f698f52d45fcad409b98feed0f9ac1 100644 (file)
@@ -102,9 +102,9 @@ public: // from Internal::Adaptor::RenderSurface
   virtual bool ReplaceEGLSurface( EglInterface& egl );
 
   /**
-   * @copydoc Dali::Internal::Adaptor::RenderSurface::RenderSync()
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::StartRender()
    */
-  virtual void RenderSync();
+  virtual void StartRender();
 
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PreRender()
@@ -114,9 +114,38 @@ public: // from Internal::Adaptor::RenderSurface
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PostRender()
    */
-  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode );
+  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, bool replacingSurface );
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::StopRender()
+   */
+  virtual void StopRender();
 
 private:
+  enum SyncMode
+  {
+    SYNC_MODE_NONE,
+    SYNC_MODE_WAIT
+  };
+
+  /**
+   * Set the sync mode.
+   * @param[in] syncMode The sync mode
+   */
+  void SetSyncMode( SyncMode syncMode );
+
+  /**
+   * If sync mode is WAIT, then acquire a lock. This prevents render thread from
+   * continuing until the pixmap has been drawn by the compositor.
+   * It must be released for rendering to continue.
+   * @param[in] syncMode The sync mode
+   */
+  void AcquireLock( SyncMode syncMode );
+
+  /**
+   * Release any locks.
+   */
+  void ReleaseLock();
 
   /**
    * Create XPixmap
@@ -131,7 +160,10 @@ private:
 private: // Data
 
   Ecore_X_Pixmap   mX11Pixmap;    ///< X-Pixmap
-
+  SyncMode         mSyncMode;     ///< Stores whether the post render should block waiting for compositor
+  boost::mutex                mSyncMutex;  ///< mutex to lock during waiting sync
+  boost::condition_variable   mSyncNotify; ///< condition to notify main thread that pixmap was flushed to onscreen
+  bool             mSyncReceived; ///< true, when a pixmap sync has occurred, (cleared after reading)
 };
 
 } // namespace ECore
index 8006eee7e339bd0a66881cacd032e239e9a8402a..1cf78e1218398d47ada3512e4621ab20a0c96372 100644 (file)
@@ -188,13 +188,17 @@ void WindowRenderSurface::Map()
   ecore_x_window_show(mX11Window);
 }
 
+void WindowRenderSurface::StartRender()
+{
+}
+
 bool WindowRenderSurface::PreRender( EglInterface&, Integration::GlAbstraction& )
 {
   // nothing to do for windows
   return true;
 }
 
-void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int, SyncMode )
+void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int, bool )
 {
   EglImplementation& eglImpl = static_cast<EglImplementation&>( egl );
   eglImpl.SwapBuffers();
@@ -220,6 +224,10 @@ void WindowRenderSurface::PostRender( EglInterface& egl, Integration::GlAbstract
   }
 }
 
+void WindowRenderSurface::StopRender()
+{
+}
+
 void WindowRenderSurface::SetViewMode( ViewMode viewMode )
 {
   Ecore_X_Atom viewModeAtom( ecore_x_atom_get( "_E_COMP_3D_APP_WIN" ) );
@@ -288,6 +296,11 @@ void WindowRenderSurface::UseExistingRenderable( unsigned int surfaceId )
   mX11Window = static_cast< Ecore_X_Window >( surfaceId );
 }
 
+void WindowRenderSurface::ReleaseLock()
+{
+  // Nothing to do.
+}
+
 } // namespace ECore
 
 } // namespace Adaptor
index e8fc702b78f4f3e2aba82cf2a8f8df62165df72b..3074aeb5bb06fac0d21251666057e2f105c3750e 100644 (file)
@@ -122,6 +122,11 @@ public:  // from Internal::Adaptor::RenderSurface
    */
   virtual void Map();
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::StartRender()
+   */
+  virtual void StartRender();
+
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PreRender()
    */
@@ -130,13 +135,23 @@ public:  // from Internal::Adaptor::RenderSurface
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PostRender()
    */
-  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, SyncMode syncMode );
+  virtual void PostRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction, unsigned int timeDelta, bool replacingSurface );
+
+  /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::StopRender()
+   */
+  virtual void StopRender();
 
   /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::SetViewMode()
    */
   void SetViewMode( ViewMode viewMode );
 
+  /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::ReleaseLock()
+   */
+  virtual void ReleaseLock();
+
 protected:
 
   /**