Adaptor: Fix Klocwork issues
[platform/core/uifw/dali-adaptor.git] / adaptors / base / render-thread.h
index 9915491..40463e5 100644 (file)
@@ -1,28 +1,29 @@
 #ifndef __DALI_INTERNAL_RENDER_THREAD_H__
 #define __DALI_INTERNAL_RENDER_THREAD_H__
 
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
 // EXTERNAL INCLUDES
 #include <boost/thread.hpp>
 
 // INTERNAL INCLUDES
 #include <base/interfaces/egl-interface.h>
-#include <internal/common/render-surface-impl.h> // needed for Dali::Internal::Adaptor::RenderSurface
+#include <render-surface-impl.h> // needed for Dali::Internal::Adaptor::RenderSurface
 
 
 namespace Dali
@@ -43,7 +44,67 @@ class AdaptorInternalServices;
 class RenderSurface;
 class UpdateRenderSynchronization;
 class EglFactoryInterface;
-class LogOptions;
+class EnvironmentOptions;
+
+
+class RenderRequest
+{
+public:
+  enum Request
+  {
+    REPLACE_SURFACE, // Request to replace surface
+  };
+
+  /**
+   * Constructor.
+   * @param[in] type The type of the request
+   */
+  RenderRequest( Request type );
+
+  /**
+   * @return the type of the request
+   */
+  Request GetType();
+
+private:
+  Request mRequestType;
+};
+
+class ReplaceSurfaceRequest : public RenderRequest
+{
+public:
+
+  /**
+   * Constructor
+   */
+  ReplaceSurfaceRequest();
+
+  /**
+   * Set the new surface
+   * @param[in] newSurface The new surface to use
+   */
+  void SetSurface(RenderSurface* newSurface);
+
+  /**
+   * @return the new surface
+   */
+  RenderSurface* GetSurface();
+
+  /**
+   * Called when the request has been completed to set the result.
+   */
+  void ReplaceCompleted();
+
+  /**
+   * @return true if the replace has completed.
+   */
+  bool GetReplaceCompleted();
+
+private:
+  RenderSurface* mNewSurface;     ///< The new surface to use.
+  unsigned int mReplaceCompleted; ///< Set to true when the replace has completed.
+};
+
 
 /**
  * The render-thread is responsible for calling Core::Render() after each update.
@@ -51,16 +112,17 @@ class LogOptions;
 class RenderThread
 {
 public:
+
   /**
    * Create the render-thread; this will not do anything until Start() is called.
    * @param[in] sync update-render synchronization object
    * @param[in] adaptorInterfaces base adaptor interface
-   * @param[in] logOptions log options
+   * @param[in] environmentOptions environment options
 
    */
   RenderThread( UpdateRenderSynchronization& sync,
                 AdaptorInternalServices& adaptorInterfaces,
-                const LogOptions& logOptions );
+                const EnvironmentOptions& environmentOptions );
 
   /**
    * Virtual Destructor
@@ -80,25 +142,6 @@ public:
   void Stop();
 
   /**
-   * Replaces the rendering surface. This method returns immediately
-   * You can call WaitForSurfaceReplaceComplete to block until the
-   * replace is completed in render thread. Note, you need to make sure
-   * that render thread is actually running!!!
-   */
-  void ReplaceSurface( RenderSurface* surface );
-
-  /**
-   * Blocks until surface replace has been completed
-   */
-  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
    */
   void RenderSync();
@@ -119,23 +162,25 @@ private: // Render thread side helpers
   void InitializeEgl();
 
   /**
-   * Check if main thread posted updates
+   * Check if display has events
    * Called from render thread
    */
-  void CheckForUpdates();
+  void ConsumeEvents();
 
   /**
-   * Changes the rendering surface
-   * Used for replacing pixmaps due to resizing
+   * Check if main thread made any requests, e.g. ReplaceSurface
    * Called from render thread
-   * @param newSurface to use
+   * @return true if a request was processed, false otherwise.
    */
-  void ChangeSurface( RenderSurface* newSurface );
+  bool ProcessRequest(RenderRequest* request);
 
   /**
-   * Notify the main thread that surface has really been changed
+   * Replaces the rendering surface
+   * Used for replacing pixmaps due to resizing
+   * Called from render thread
+   * @param newSurface to use
    */
-  void NotifySurfaceChangeCompleted();
+  void ReplaceSurface( RenderSurface* newSurface );
 
   /**
    * Shuts down EGL.
@@ -159,82 +204,15 @@ private: // Render thread side helpers
 
 private: // Data
 
-  UpdateRenderSynchronization&        mUpdateRenderSync; ///< Used to synchronize the update & render threads
-  Dali::Integration::Core&            mCore;             ///< Dali core reference
-  Integration::GlAbstraction&         mGLES;             ///< GL abstraction rerefence
-  EglFactoryInterface*                mEglFactory;       ///< Factory class to create EGL implementation
-  EglInterface*                       mEGL;              ///< Interface to EGL implementation
-
-  boost::thread*                      mThread;           ///< render thread
-  bool                                mUsingPixmap;      ///< whether we're using a pixmap or a window
-  bool                                mSurfaceReplacing; ///< whether the surface is replacing. If true, need to notify surface changing after rendering
-
-  /**
-   * Structure to hold values that are set by main thread and read in render thread
-   * There is two copies of this data to avoid locking and prevent concurrent access
-   */
-  struct RenderData
-  {
-    /**
-     * Default constructor to reset values
-     */
-    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
-  };
-
-  RenderData                mCurrent;             ///< Current values, must not be used from main thread
-  RenderData                mNewValues;           ///< New values, sent from main thread to render thread
-  boost::mutex              mThreadDataLock;      ///< mutex to lock values while reading them into render thread
-  volatile int              mNewDataAvailable;    ///< atomic flag to notify the render thread that there's new data
-
-  /**
-   * Helper class for sending message to render thread
-   */
-  class SendMessageGuard
-  {
-  public: // API
-    /**
-     * Constructor, sets the lock
-     */
-    SendMessageGuard( RenderThread& parent )
-    : mLock( parent.mThreadDataLock ), mFlag( &parent.mNewDataAvailable )
-    { // Nothing to do, unique lock will lock automatically and unlock when destructed
-    }
-    /**
-     * Destructor, releases lock and sets flag
-     */
-    ~SendMessageGuard()
-    {
-      // set the flag to tell render thread there are new values, ignoring the return value here
-      (void)__sync_or_and_fetch( mFlag, 1 );
-    }
-
-  private: // Data
-    boost::unique_lock< boost::mutex > mLock;
-    volatile int* mFlag;
-  };
-
-  // sync for waiting offscreen flushed to onscreen
-  boost::mutex              mPixmapSyncMutex;      ///< mutex to lock during waiting sync
-  boost::condition_variable mPixmapSyncNotify;     ///< condition to notify main thread that pixmap was flushed to onscreen
-  bool                      mPixmapSyncReceived;   ///< true, when a pixmap sync has occurred, (cleared after reading)
-  bool                      mPixmapSyncRunning;    ///< true, while render thread is running and needs to wait for pixmap syncs
-  unsigned long             mCurrentMicroSec;
-
-  // sync for waiting for surface change
-  boost::mutex              mSurfaceChangedMutex;  ///< mutex to lock during surface replacing
-  boost::condition_variable mSurfaceChangedNotify; ///< condition to notify main thread that surface has been changed
-  bool                      mSurfaceReplaceCompleted;///< true, while render thread is running and needs to wait for pixmap syncs
-  const LogOptions&         mLogOptions;           ///< Log options
-
+  UpdateRenderSynchronization&  mUpdateRenderSync;       ///< Used to synchronize the update & render threads
+  Dali::Integration::Core&      mCore;                   ///< Dali core reference
+  Integration::GlAbstraction&   mGLES;                   ///< GL abstraction reference
+  EglFactoryInterface*          mEglFactory;             ///< Factory class to create EGL implementation
+  EglInterface*                 mEGL;                    ///< Interface to EGL implementation
+  boost::thread*                mThread;                 ///< render thread
+  RenderSurface*                mSurface;                ///< Current surface
+  const EnvironmentOptions&     mEnvironmentOptions;     ///< Environment options
+  bool                          mSurfaceReplaced;        ///< True when new surface has been initialzed.
 };
 
 } // namespace Adaptor
@@ -244,4 +222,3 @@ private: // Data
 } // namespace Dali
 
 #endif // __DALI_INTERNAL_RENDER_THREAD_H__
-