Add REQUIRES_SYNC property to RenderTask 85/64485/4
authorXiangyin Ma <x1.ma@samsung.com>
Fri, 19 Feb 2016 09:33:52 +0000 (09:33 +0000)
committerXiangyin Ma <x1.ma@samsung.com>
Thu, 14 Apr 2016 10:10:53 +0000 (11:10 +0100)
Change-Id: Idca837dd62e3f66a47935f8b7d93b577999d54c7

automated-tests/src/dali/utc-Dali-RenderTask.cpp
dali/internal/event/render-tasks/render-task-impl.cpp
dali/internal/event/render-tasks/render-task-impl.h
dali/internal/update/render-tasks/scene-graph-render-task.cpp
dali/internal/update/render-tasks/scene-graph-render-task.h
dali/public-api/render-tasks/render-task.h

index a83a92e..37f7535 100644 (file)
@@ -255,6 +255,7 @@ RenderTask CreateRenderTask(TestApplication& application,
   newTask.SetExclusive( true );
   newTask.SetRefreshRate( refreshRate );
   newTask.SetTargetFrameBuffer( frameBufferImage );
+  newTask.SetProperty( RenderTask::Property::REQUIRES_SYNC, glSync );
   return newTask;
 }
 
@@ -1760,6 +1761,7 @@ int UtcDaliRenderTaskSignalFinished(void)
   newTask.SetExclusive( true );
   newTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
   newTask.SetTargetFrameBuffer( frameBufferImage );
+  newTask.SetProperty( RenderTask::Property::REQUIRES_SYNC, true );
 
   bool finished = false;
   RenderTaskFinished renderTaskFinished( finished );
@@ -3388,6 +3390,7 @@ int UtcDaliRenderTaskFinishInvisibleSourceActor(void)
   newTask.SetExclusive( true );
   newTask.SetRefreshRate( RenderTask::REFRESH_ONCE );
   newTask.SetTargetFrameBuffer( frameBufferImage );
+  newTask.SetProperty( RenderTask::Property::REQUIRES_SYNC, true );
 
   // Framebuffer doesn't actually get created until Connected, i.e. by previous line
 
index ce43396..196719f 100644 (file)
@@ -58,6 +58,7 @@ DALI_PROPERTY_TABLE_BEGIN
 DALI_PROPERTY( "viewportPosition",   VECTOR2,    true,    true,    true,    Dali::RenderTask::Property::VIEWPORT_POSITION )
 DALI_PROPERTY( "viewportSize",       VECTOR2,    true,    true,    true,    Dali::RenderTask::Property::VIEWPORT_SIZE     )
 DALI_PROPERTY( "clearColor",         VECTOR4,    true,    true,    true,    Dali::RenderTask::Property::CLEAR_COLOR       )
+DALI_PROPERTY( "requiresSync",       BOOLEAN,    true,    false,   false,   Dali::RenderTask::Property::REQUIRES_SYNC     )
 DALI_PROPERTY_TABLE_END( DEFAULT_OBJECT_PROPERTY_START_INDEX )
 
 // Signals
@@ -279,6 +280,25 @@ const Vector4& RenderTask::GetClearColor() const
   return mSceneObject->GetClearColor( GetEventThreadServices().GetEventBufferIndex() );
 }
 
+void RenderTask::SetSyncRequired( bool requiresSync )
+{
+  if( mRequiresSync != requiresSync )
+  {
+    mRequiresSync = requiresSync;
+
+    if( mSceneObject )
+    {
+      // mSceneObject is being used in a separate thread; queue a message to set the value
+      SetSyncRequiredMessage( GetEventThreadServices(), *mSceneObject, requiresSync );
+    }
+  }
+}
+
+bool RenderTask::IsSyncRequired() const
+{
+  return mRequiresSync;
+}
+
 void RenderTask::SetClearEnabled( bool enabled )
 {
   if ( mClearEnabled != enabled )
@@ -593,6 +613,11 @@ void RenderTask::SetDefaultProperty( Property::Index index, const Property::Valu
       SetClearColor( property.Get<Vector4>() );
       break;
     }
+    case Dali::RenderTask::Property::REQUIRES_SYNC:
+    {
+      SetSyncRequired( property.Get<bool>() );
+      break;
+    }
     default:
     {
       // nothing to do
@@ -623,6 +648,11 @@ Property::Value RenderTask::GetDefaultProperty(Property::Index index) const
       value = GetClearColor();
       break;
     }
+    case Dali::RenderTask::Property::REQUIRES_SYNC:
+    {
+      value = IsSyncRequired();
+      break;
+    }
 
     default:
     {
@@ -686,7 +716,7 @@ const PropertyInputImpl* RenderTask::GetSceneObjectInputProperty( Property::Inde
         break;
 
       case Dali::RenderTask::Property::CLEAR_COLOR:
-        property = &mSceneObject->mViewportSize;
+        property = &mSceneObject->mClearColor;
         break;
 
       default:
@@ -760,7 +790,8 @@ RenderTask::RenderTask( bool isSystemLevel )
   mInputEnabled( Dali::RenderTask::DEFAULT_INPUT_ENABLED ),
   mClearEnabled( Dali::RenderTask::DEFAULT_CLEAR_ENABLED ),
   mCullMode( Dali::RenderTask::DEFAULT_CULL_MODE ),
-  mIsSystemLevel( isSystemLevel )
+  mIsSystemLevel( isSystemLevel ),
+  mRequiresSync( false )
 {
   DALI_LOG_INFO(gLogRender, Debug::General, "RenderTask::RenderTask(this:%p)\n", this);
 }
index c1d8537..4c434a2 100644 (file)
@@ -162,6 +162,18 @@ public:
   const Vector4& GetClearColor() const;
 
   /**
+   * Set whether whether GL sync is required for native render target.
+   * @param[in] requiresSync whether whether GL sync is required.
+   */
+  void SetSyncRequired( bool requiresSync );
+
+  /**
+   * Query whether the sync object is required for native render target.
+   * @return True if the sync object is required, false otherwise.
+   */
+ bool IsSyncRequired() const;
+
+  /**
    * @copydoc Dali::RenderTask::SetClearEnabled()
    */
   void SetClearEnabled( bool enabled );
@@ -445,6 +457,7 @@ private:
   bool mClearEnabled  : 1; ///< True if the render-task should be clear the color buffer.
   bool mCullMode      : 1; ///< True if the render-task's actors should be culled
   bool mIsSystemLevel : 1; ///< True if the render-task is on the system level task list.
+  bool mRequiresSync  : 1; ///< True if the GL sync is required to track the render of
 
   //Signals
   Dali::RenderTask::RenderTaskSignalType  mSignalFinished; ///< Signal emmited when the render task has been processed.
index d22fd54..d04b2b9 100644 (file)
@@ -419,7 +419,7 @@ void RenderTask::PrepareRenderInstruction( RenderInstruction& instruction, Buffe
                      viewportSet ? &viewport : NULL,
                      mClearEnabled ? &GetClearColor( updateBufferIndex ) : NULL );
 
-  if( mTargetIsNativeFramebuffer &&
+  if( mTargetIsNativeFramebuffer && mRequiresSync &&
       mRefreshRate == Dali::RenderTask::REFRESH_ONCE &&
       mResourcesFinished )
   {
@@ -496,6 +496,11 @@ Node* RenderTask::GetCamera() const
   return mCameraNode;
 }
 
+void RenderTask::SetSyncRequired( bool requiresSync )
+{
+  mRequiresSync = requiresSync;
+}
+
 void RenderTask::ResetDefaultProperties( BufferIndex updateBufferIndex )
 {
   // Reset default properties
@@ -528,7 +533,8 @@ RenderTask::RenderTask()
   mRefreshRate( Dali::RenderTask::DEFAULT_REFRESH_RATE ),
   mFrameCounter( 0u ),
   mRenderedOnceCounter( 0u ),
-  mTargetIsNativeFramebuffer( false )
+  mTargetIsNativeFramebuffer( false ),
+  mRequiresSync( false )
 {
 }
 
index 698abe6..d7abf26 100644 (file)
@@ -333,6 +333,12 @@ public:
    */
   Node* GetCamera() const;
 
+  /**
+   * Set whether GL sync is required for native render target.
+   * @param[in] whether GL sync is required for native render target
+   */
+  void SetSyncRequired( bool requiresSync );
+
 private:
 
   /**
@@ -380,6 +386,7 @@ private:
 
   unsigned int mRenderedOnceCounter;  ///< Incremented whenever state changes to RENDERED_ONCE_AND_NOTIFIED
   bool mTargetIsNativeFramebuffer; ///< Tells if our target is a native framebuffer
+  bool mRequiresSync;              ///< Whether sync is needed to track the render
 
 };
 
@@ -490,6 +497,17 @@ inline void SetExclusiveMessage( EventThreadServices& eventThreadServices, Rende
   new (slot) LocalType( &task, &RenderTask::SetExclusive, exclusive );
 }
 
+inline void SetSyncRequiredMessage(EventThreadServices& eventThreadServices, RenderTask& task, bool requiresSync )
+{
+  typedef MessageValue1< RenderTask, bool > LocalType;
+
+  // Reserve some memory inside the message queue
+  unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
+
+  // Construct message in the message queue memory; note that delete should not be called on the return value
+  new (slot) LocalType( &task, &RenderTask::SetSyncRequired, requiresSync );
+}
+
 inline void BakeViewportPositionMessage( EventThreadServices& eventThreadServices, const RenderTask& task, const Vector2& value )
 {
   typedef MessageDoubleBuffered1< RenderTask, Vector2 > LocalType;
index ea3c0de..cc0f0d6 100644 (file)
@@ -92,9 +92,30 @@ public:
   {
     enum
     {
-      VIEWPORT_POSITION = DEFAULT_OBJECT_PROPERTY_START_INDEX, ///< name "viewportPosition",  type Vector2 @SINCE_1_0.0
-      VIEWPORT_SIZE,                                           ///< name "viewportSize",      type Vector2 @SINCE_1_0.0
-      CLEAR_COLOR,                                             ///< name "clearColor",        type Vector4 @SINCE_1_0.0
+      /**
+       * @brief name "viewportPosition", type Vector2
+       * @SINCE_1_0.0
+       */
+      VIEWPORT_POSITION = DEFAULT_OBJECT_PROPERTY_START_INDEX,
+      /**
+       * @brief name "viewportSize", type Vector2
+       * @SINCE_1_0.0
+       */
+      VIEWPORT_SIZE,
+      /**
+       * @brief name "clearColor", type Vector4
+       * @SINCE_1_0.0
+       */
+      CLEAR_COLOR,
+      /**
+       * @brief name "requiresSync", type BOOLEAN
+       * @details By default, the sync object is not created.
+       *  When native image source is used as render target, in order to track when the render to pixmap is completed, the GL sync should be enabled.
+       *  Thus the RENDER_ONCE finished signal can be emit at the correct timing.
+       * @note The use of GL sync might cause deadlock with multiple access to the single pixmap happening in the same time.
+       * @SINCE_1_1.29
+       */
+      REQUIRES_SYNC,
     };
   };