Ensure XEvent queue for the render display is flushed 00/18100/4
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Mon, 17 Mar 2014 11:16:46 +0000 (11:16 +0000)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 18 Mar 2014 14:48:48 +0000 (14:48 +0000)
[Problem]  The main display event queue (used by the render-thread) has events which keep building up
[Cause]    We do not handle these events.
[Solution] Check events when we render and flush the queue if there are any events.

Change-Id: I53ebdfdb8ac5acbf0dff0698becf082af3d4196a
Signed-off-by: Adeel Kazmi <adeel.kazmi@samsung.com>
adaptors/base/render-thread.cpp
adaptors/base/render-thread.h
adaptors/tizen/internal/common/ecore-x/ecore-x-render-surface.cpp
adaptors/tizen/internal/common/ecore-x/ecore-x-render-surface.h
adaptors/tizen/internal/common/render-surface-impl.h

index 494c6a9..1b3ba39 100644 (file)
@@ -205,6 +205,9 @@ bool RenderThread::Run()
   // render loop, we stay inside here when rendering
   while( running )
   {
+    // Consume any pending events
+    ConsumeEvents();
+
     // Check if we've got updates from the main thread
     CheckForUpdates();
 
@@ -282,6 +285,12 @@ void RenderThread::InitializeEgl()
   DALI_LOG_INFO(Debug::Filter::gShader, Debug::General, "*** Supported Extensions ***\n%s\n\n", mGLES.GetString(GL_EXTENSIONS));
 }
 
+void RenderThread::ConsumeEvents()
+{
+  // tell surface to consume any events to avoid memory leaks
+  mCurrent.surface->ConsumeEvents();
+}
+
 void RenderThread::CheckForUpdates()
 {
   // atomic check to see if we've got updates, resets the flag int
index 9915491..eb4fa89 100644 (file)
@@ -119,6 +119,12 @@ private: // Render thread side helpers
   void InitializeEgl();
 
   /**
+   * Check if display has events
+   * Called from render thread
+   */
+  void ConsumeEvents();
+
+  /**
    * Check if main thread posted updates
    * Called from render thread
    */
index 04c5ef2..2a33569 100644 (file)
@@ -214,6 +214,31 @@ void RenderSurface::TransferDisplayOwner( Internal::Adaptor::RenderSurface& newS
   }
 }
 
+void RenderSurface::ConsumeEvents()
+{
+  // if the render surface has own display, check events so that we can flush the queue and avoid
+  // any potential memory leaks in X
+  if( mOwnDisplay )
+  {
+    // looping if events remain
+    int events( 0 );
+    do
+    {
+      // Check if there are any events in the queue
+      events = XEventsQueued( mMainDisplay, QueuedAfterFlush );
+
+      if ( events > 0 )
+      {
+        // Just flush event to prevent memory leak from event queue as the events get built up in
+        // memory but are only deleted when we retrieve them
+        XEvent ev;
+        XNextEvent( mMainDisplay, &ev );
+      }
+    }
+    while( events > 0 );
+  }
+}
+
 void RenderSurface::SetDisplay( boost::any display )
 {
   // the render surface can be passed either EFL e-core types, or x11 types
index 9ad2d1d..5a60b86 100644 (file)
@@ -172,6 +172,11 @@ public:  // from Internal::Adaptor::RenderSurface
   virtual void TransferDisplayOwner( Internal::Adaptor::RenderSurface& newSurface );
 
   /**
+   * @copydoc Dali::Internal::Adaptor::RenderSurface::ConsumeEvents()
+   */
+  virtual void ConsumeEvents();
+
+  /**
    * @copydoc Dali::Internal::Adaptor::RenderSurface::PreRender()
    */
   virtual bool PreRender( EglInterface& egl, Integration::GlAbstraction& glAbstraction ) = 0;
index 4ab14f6..c1e818f 100644 (file)
@@ -108,6 +108,11 @@ public: // API
   virtual void TransferDisplayOwner( Internal::Adaptor::RenderSurface& newSurface ) = 0;
 
   /**
+   *  Consumes any possible events on the queue so that there is no leaking between frames
+   */
+  virtual void ConsumeEvents() = 0;
+
+  /**
    * Invoked by render thread before Core::Render
    * @param[in] egl The Egl interface
    * @param[in] glAbstraction OpenGLES abstraction interface