Change setting background color for Scene. 18/222418/5
authorAnton Obzhirov <a.obzhirov@samsung.com>
Fri, 10 Jan 2020 14:20:51 +0000 (14:20 +0000)
committerAnton Obzhirov <a.obzhirov@samsung.com>
Mon, 20 Jan 2020 12:41:59 +0000 (12:41 +0000)
Sets clear color to the default render task of the scene
instead of setting background color via frame buffer property.

Fixes problem when the scene surface is replaced and the background color
information is lost when new frame buffer is created.

Change-Id: I036837f790d1db0540baf82ff9305811d05ffa51

13 files changed:
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali/utc-Dali-RenderTask.cpp
automated-tests/src/dali/utc-Dali-Scene.cpp
dali/internal/event/common/scene-impl.cpp
dali/internal/event/rendering/frame-buffer-impl.cpp
dali/internal/event/rendering/frame-buffer-impl.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/common/render-manager.h
dali/internal/render/renderers/render-surface-frame-buffer.cpp
dali/internal/render/renderers/render-surface-frame-buffer.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-manager.h

index 8372e03..207d9a4 100644 (file)
@@ -58,6 +58,7 @@ void TestGlAbstraction::Initialize()
 
   mLastShaderCompiled = 0;
   mLastClearBitMask = 0;
+  mLastClearColor = Color::TRANSPARENT;
   mClearCount = 0;
 
   mLastBlendEquationRgb   = 0;
@@ -131,3 +132,4 @@ bool BlendDisabled(const Dali::TraceCallStack& callStack)
   bool blendEnabled = callStack.FindMethodAndParams( "Disable", out.str() );
   return blendEnabled;
 }
+
index 3fae461..3edad10 100644 (file)
@@ -275,6 +275,15 @@ public:
 
   inline void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
   {
+    mLastClearColor.r = red;
+    mLastClearColor.g = green;
+    mLastClearColor.b = blue;
+    mLastClearColor.a = alpha;
+  }
+
+  inline const Vector4& GetLastClearColor() const
+  {
+    return mLastClearColor;
   }
 
   inline void ClearDepthf(GLclampf depth)
@@ -2182,6 +2191,7 @@ private:
   ShaderSourceMap mShaderSources;
   GLuint     mLastShaderCompiled;
   GLbitfield mLastClearBitMask;
+  Vector4 mLastClearColor;
   unsigned int mClearCount;
 
   Vector4 mLastBlendColor;
index 8067f58..0b86a22 100644 (file)
@@ -1641,13 +1641,13 @@ int UtcDaliRenderTaskSetClearEnabledP(void)
   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
 
   RenderTask task = taskList.GetTask( 0u );
-  DALI_TEST_CHECK( !task.GetClearEnabled() ); // defaults to false
-
-  task.SetClearEnabled( true );
-  DALI_TEST_EQUALS( task.GetClearEnabled(), true, TEST_LOCATION );
+  DALI_TEST_CHECK( task.GetClearEnabled() ); // defaults to true
 
   task.SetClearEnabled( false );
   DALI_TEST_EQUALS( task.GetClearEnabled(), false, TEST_LOCATION );
+
+  task.SetClearEnabled( true );
+  DALI_TEST_EQUALS( task.GetClearEnabled(), true, TEST_LOCATION );
   END_TEST;
 }
 
@@ -1679,7 +1679,7 @@ int UtcDaliRenderTaskGetClearEnabledP(void)
   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
 
   RenderTask task = taskList.GetTask( 0u );
-  DALI_TEST_CHECK( !task.GetClearEnabled() ); // defaults to false
+  DALI_TEST_CHECK( task.GetClearEnabled() ); // defaults to true
   END_TEST;
 }
 
index 8508728..b439957 100644 (file)
@@ -922,25 +922,47 @@ int UtcDaliSceneEnsureEmptySceneCleared(void)
 
   TestApplication application;
 
-  // Create a new scene and set the background colors of both the new and the main scenes
-  auto defaultScene = application.GetScene();
-  defaultScene.SetBackgroundColor( Color::WHITE );
+  auto& glAbstraction = application.GetGlAbstraction();
+  auto clearCountBefore = glAbstraction.GetClearCountCalled();
 
-  TestRenderSurface surface( PositionSize( 0.0f, 0.0f, 480.0f, 800.0f ) );
-  auto newScene = Integration::Scene::New( surface );
-  newScene.SetBackgroundColor( Color::RED );
+  application.SendNotification();
+  application.Render();
+
+  // No actor, no rendering at all
+  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::TRANSPARENT, TEST_LOCATION );
 
   // Need to create a renderable as we don't start rendering until we have at least one
   // We don't need to add this to any scene
   auto actor = CreateRenderableActor();
 
-  auto& glAbstraction = application.GetGlAbstraction();
-  auto clearCountBefore = glAbstraction.GetClearCountCalled();
+  application.SendNotification();
+  application.Render();
+
+  // Default background color
+  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::BLACK, TEST_LOCATION );
+
+  // Create a new scene and set the background colors of both the new and the main scenes
+  auto defaultScene = application.GetScene();
+  defaultScene.SetBackgroundColor( Color::WHITE );
 
   application.SendNotification();
   application.Render();
 
   DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 2, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::WHITE, TEST_LOCATION );
+
+  TestRenderSurface surface( PositionSize( 0.0f, 0.0f, 480.0f, 800.0f ) );
+  auto newScene = Integration::Scene::New( surface );
+  newScene.SetBackgroundColor( Color::RED );
+
+  application.SendNotification();
+  application.Render();
+
+  // + 2 clear for 2 scenes
+  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 4, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::RED, TEST_LOCATION );
 
   // Add the actor to the main scene
   defaultScene.Add( actor );
@@ -948,18 +970,21 @@ int UtcDaliSceneEnsureEmptySceneCleared(void)
   application.SendNotification();
   application.Render();
 
-  // Add another scene and set its background color, ensure we clear it to the appropriate color
+  // + 2 clear for 2 scenes
+  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 6, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::RED, TEST_LOCATION );
 
+  // Add another scene and set its background color, ensure we clear it to the appropriate color
+  // + 3 clear for 3 scenes
   TestRenderSurface surface2( PositionSize( 0.0f, 0.0f, 480.0f, 800.0f ) );
   auto thirdScene = Integration::Scene::New( surface2 );
   thirdScene.SetBackgroundColor( Color::BLUE );
 
-  clearCountBefore = glAbstraction.GetClearCountCalled();
-
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 3, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 9, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::BLUE, TEST_LOCATION );
 
   END_TEST;
 }
@@ -1231,3 +1256,64 @@ int UtcDaliSceneKeyEventGeneratedSignalP(void)
   DALI_TEST_CHECK( event4.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
   END_TEST;
 }
+
+int UtcDaliSceneEnsureReplacedSurfaceKeepsClearColor(void)
+{
+  tet_infoline( "Ensure we keep background color when the scene surface is replaced " );
+
+  TestApplication application;
+
+  // Create a new scene and set the background color of the main scene
+  auto defaultScene = application.GetScene();
+  defaultScene.SetBackgroundColor( Color::BLUE );
+
+  // Need to create a renderable as we don't start rendering until we have at least one
+  // We don't need to add this to any scene
+  auto actor = CreateRenderableActor();
+
+  auto& glAbstraction = application.GetGlAbstraction();
+  auto clearCountBefore = glAbstraction.GetClearCountCalled();
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 1, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::BLUE, TEST_LOCATION );
+
+  TestRenderSurface surface( PositionSize( 0.0f, 0.0f, 480.0f, 800.0f ) );
+  defaultScene.SetSurface( surface );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 2, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::BLUE, TEST_LOCATION );
+
+  // Check when the main render task viewport is set the clear color is clipped using scissors
+  TraceCallStack& scissorTrace = glAbstraction.GetScissorTrace();
+  TraceCallStack& enabledDisableTrace = glAbstraction.GetEnableDisableTrace();
+  scissorTrace.Enable( true );
+  enabledDisableTrace.Enable( true );
+
+  defaultScene.GetRenderTaskList().GetTask( 0 ).SetViewport( Viewport( 0.0f, 0.0f, 100.0f, 100.0f ) );
+
+  application.SendNotification();
+  application.Render();
+
+  // Check scissor test was enabled.
+  DALI_TEST_CHECK( enabledDisableTrace.FindMethodAndParams( "Enable", "3089" ) ); // 3089 = 0xC11 (GL_SCISSOR_TEST)
+
+  // Check the scissor was set, and the coordinates are correct.
+  DALI_TEST_CHECK( scissorTrace.FindMethodAndParams( "Scissor", "0, 700, 100, 100" ) );
+
+  DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 3, TEST_LOCATION );
+  DALI_TEST_EQUALS( glAbstraction.GetLastClearColor(), Color::BLUE, TEST_LOCATION );
+
+  scissorTrace.Enable( false );
+  scissorTrace.Reset();
+
+  enabledDisableTrace.Enable( false );
+  enabledDisableTrace.Reset();
+
+  END_TEST;
+}
index c14470d..69b0724 100644 (file)
@@ -303,7 +303,8 @@ void Scene::SetBackgroundColor( const Vector4& color )
 
   if( mSurface )
   {
-    mRenderTaskList->GetTask( 0u )->GetFrameBuffer()->SetBackgroundColor( color );
+    mRenderTaskList->GetTask( 0u )->SetClearColor( color );
+    mRenderTaskList->GetTask( 0u )->SetClearEnabled( true );
   }
 }
 
index 33afe35..a2ac30c 100644 (file)
@@ -117,14 +117,6 @@ void FrameBuffer::SetSize( uint32_t width, uint32_t height )
   }
 }
 
-void FrameBuffer::SetBackgroundColor( const Vector4& color )
-{
-  if( mRenderObject->IsSurfaceBacked() )
-  {
-    SetFrameBufferBackgroundColorMessage( mEventThreadServices.GetUpdateManager(), static_cast<Render::SurfaceFrameBuffer*>( mRenderObject ), color );
-  }
-}
-
 void FrameBuffer::MarkSurfaceAsInvalid()
 {
   if ( mIsSurfaceBacked )
index 8484948..2073209 100644 (file)
@@ -99,12 +99,6 @@ public:
   void SetSize( uint32_t width, uint32_t height );
 
   /**
-   * @brief Sets the background color
-   * @param[in] color The new background color
-   */
-  void SetBackgroundColor( const Vector4& color );
-
-  /**
    * @brief Mark the render surface as invalid
    *
    * The render surface is maked as invalid when it is deleted.
index a3e6db9..ec299cb 100644 (file)
@@ -80,7 +80,6 @@ struct RenderManager::Impl
     renderQueue(),
     instructions(),
     renderAlgorithms(),
-    backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
     frameCount( 0u ),
     renderBufferIndex( SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX ),
     defaultSurfaceRect(),
@@ -148,8 +147,6 @@ struct RenderManager::Impl
   RenderInstructionContainer                instructions;
   Render::RenderAlgorithms                  renderAlgorithms;        ///< The RenderAlgorithms object is used to action the renders required by a RenderInstruction
 
-  Vector4                                   backgroundColor;         ///< The glClear color used at the beginning of each frame.
-
   uint32_t                                  frameCount;              ///< The current frame count
   BufferIndex                               renderBufferIndex;       ///< The index of the buffer to read from; this is opposite of the "update" buffer
 
@@ -249,11 +246,6 @@ RenderInstructionContainer& RenderManager::GetRenderInstructionContainer()
   return mImpl->instructions;
 }
 
-void RenderManager::SetBackgroundColor( const Vector4& color )
-{
-  mImpl->backgroundColor = color;
-}
-
 void RenderManager::SetDefaultSurfaceRect(const Rect<int32_t>& rect)
 {
   mImpl->defaultSurfaceRect = rect;
@@ -605,7 +597,6 @@ void RenderManager::DoRender( RenderInstruction& instruction )
   }
 
   Rect<int32_t> surfaceRect = mImpl->defaultSurfaceRect;
-  Vector4 backgroundColor = mImpl->backgroundColor;
   Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable;
   Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable;
 
@@ -637,7 +628,6 @@ void RenderManager::DoRender( RenderInstruction& instruction )
       }
 
       surfaceRect = Rect<int32_t>( 0, 0, static_cast<int32_t>( surfaceFrameBuffer->GetWidth() ), static_cast<int32_t>( surfaceFrameBuffer->GetHeight() ) );
-      backgroundColor = surfaceFrameBuffer->GetBackgroundColor();
     }
     else
     {
@@ -679,20 +669,12 @@ void RenderManager::DoRender( RenderInstruction& instruction )
                               surfaceRect.y,
                               surfaceRect.width,
                               surfaceRect.height );
-
-    mImpl->currentContext->ClearColor( backgroundColor.r,
-                                backgroundColor.g,
-                                backgroundColor.b,
-                                backgroundColor.a );
   }
 
   // Clear the entire color, depth and stencil buffers for the default framebuffer, if required.
   // It is important to clear all 3 buffers when they are being used, for performance on deferred renderers
   // e.g. previously when the depth & stencil buffers were NOT cleared, it caused the DDK to exceed a "vertex count limit",
   // and then stall. That problem is only noticeable when rendering a large number of vertices per frame.
-
-  mImpl->currentContext->SetScissorTest( false );
-
   GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
 
   mImpl->currentContext->ColorMask( true );
@@ -710,8 +692,6 @@ void RenderManager::DoRender( RenderInstruction& instruction )
     clearMask |= GL_STENCIL_BUFFER_BIT;
   }
 
-  mImpl->currentContext->Clear( clearMask, Context::FORCE_CLEAR );
-
   if( !instruction.mIgnoreRenderToFbo && ( instruction.mFrameBuffer != 0 ) )
   {
     if ( instruction.mFrameBuffer->IsSurfaceBacked() ) // Surface rendering
@@ -764,21 +744,34 @@ void RenderManager::DoRender( RenderInstruction& instruction )
     }
   }
 
+  bool clearFullFrameRect = true;
+  if( instruction.mFrameBuffer != 0 )
+  {
+    Viewport frameRect( 0, 0, instruction.mFrameBuffer->GetWidth(), instruction.mFrameBuffer->GetHeight() );
+    clearFullFrameRect = ( frameRect == viewportRect );
+  }
+  else
+  {
+    clearFullFrameRect = ( surfaceRect == viewportRect );
+  }
+
   mImpl->currentContext->Viewport(viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height);
+  mImpl->currentContext->ClearColor( clearColor.r,
+                                     clearColor.g,
+                                     clearColor.b,
+                                     clearColor.a );
 
-  if ( instruction.mIsClearColorSet )
+  if( instruction.mIsClearColorSet && !clearFullFrameRect )
   {
-    mImpl->currentContext->ClearColor( clearColor.r,
-                                       clearColor.g,
-                                       clearColor.b,
-                                       clearColor.a );
-
-    // Clear the viewport area only
     mImpl->currentContext->SetScissorTest( true );
     mImpl->currentContext->Scissor( viewportRect.x, viewportRect.y, viewportRect.width, viewportRect.height );
-    mImpl->currentContext->ColorMask( true );
-    mImpl->currentContext->Clear( GL_COLOR_BUFFER_BIT , Context::CHECK_CACHED_VALUES );
+    mImpl->currentContext->Clear( clearMask, Context::FORCE_CLEAR );
+    mImpl->currentContext->SetScissorTest( false );
+  }
+  else
+  {
     mImpl->currentContext->SetScissorTest( false );
+    mImpl->currentContext->Clear( clearMask, Context::FORCE_CLEAR );
   }
 
   // Clear the list of bound textures
index cc70287..5aa90d8 100644 (file)
@@ -122,12 +122,6 @@ public:
 
   // The following methods should be called via RenderQueue messages
 
-  /**
-   * Set the background color i.e. the glClear color used at the beginning of each frame.
-   * @param[in] color The new background color.
-   */
-  void SetBackgroundColor( const Vector4& color );
-
   /*
    * Set the frame time delta (time elapsed since the last frame.
    * @param[in] deltaTime the delta time
index 7154ff6..396af00 100644 (file)
@@ -33,7 +33,6 @@ SurfaceFrameBuffer::SurfaceFrameBuffer( Integration::RenderSurface* surface )
   mContext( nullptr ),
   mWidth( mSurface->GetPositionSize().width ),
   mHeight( mSurface->GetPositionSize().height ),
-  mBackgroundColor( 0.f, 0.f, 0.f, 1.f ),
   mSizeChanged( false ),
   mIsSurfaceInvalid( false )
 {
@@ -119,11 +118,6 @@ void SurfaceFrameBuffer::MakeContextCurrent()
   }
 }
 
-Vector4 SurfaceFrameBuffer::GetBackgroundColor()
-{
-  return mBackgroundColor;
-}
-
 void SurfaceFrameBuffer::SetSize( uint32_t width, uint32_t height )
 {
   mWidth = width;
@@ -131,11 +125,6 @@ void SurfaceFrameBuffer::SetSize( uint32_t width, uint32_t height )
   mSizeChanged = true;
 }
 
-void SurfaceFrameBuffer::SetBackgroundColor( const Vector4& color )
-{
-  mBackgroundColor = color;
-}
-
 bool SurfaceFrameBuffer::IsSurfaceValid() const
 {
   return mSurface && !mIsSurfaceInvalid;
index edd667d..e08666c 100644 (file)
@@ -94,12 +94,6 @@ public:
   void SetSize( uint32_t width, uint32_t height );
 
   /**
-   * @brief Sets the background color.
-   * @param[in] color The new background color
-   */
-  void SetBackgroundColor( const Vector4& color );
-
-  /**
    * @copydoc Dali::Internal::FrameBuffer::MarkSurfaceAsInvalid()
    */
   void MarkSurfaceAsInvalid() { mIsSurfaceInvalid = true; };
@@ -129,12 +123,6 @@ public:
    */
   void MakeContextCurrent();
 
-  /**
-   * @brief Gets the background color of the surface.
-   * @return The background color
-   */
-  Vector4 GetBackgroundColor();
-
 private:
 
   Integration::RenderSurface* mSurface;   ///< The render surface
@@ -142,7 +130,6 @@ private:
 
   uint32_t                    mWidth;
   uint32_t                    mHeight;
-  Vector4                     mBackgroundColor;
   bool                        mSizeChanged;
   std::atomic<bool>           mIsSurfaceInvalid; ///< This is set only from the event thread and read only from the render thread
 };
@@ -159,17 +146,6 @@ inline void SetFrameBufferSizeMessage( SceneGraph::UpdateManager& updateManager,
   new (slot) LocalType( surfaceFrameBuffer, &SurfaceFrameBuffer::SetSize, width, height );
 }
 
-inline void SetFrameBufferBackgroundColorMessage( SceneGraph::UpdateManager& updateManager, SurfaceFrameBuffer* surfaceFrameBuffer, const Vector4& color )
-{
-  typedef MessageValue1< SurfaceFrameBuffer, Vector4 > LocalType;
-
-  // Reserve some memory inside the message queue
-  uint32_t* slot = updateManager.ReserveMessageSlot( sizeof( LocalType ) );
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( surfaceFrameBuffer, &SurfaceFrameBuffer::SetBackgroundColor, color );
-}
-
 } // namespace Render
 
 } // namespace Internal
index 9f07b69..9b1eae0 100644 (file)
@@ -1089,17 +1089,6 @@ uint32_t UpdateManager::KeepUpdatingCheck( float elapsedSeconds ) const
   return keepUpdatingRequest;
 }
 
-void UpdateManager::SetBackgroundColor( const Vector4& color )
-{
-  typedef MessageValue1< RenderManager, Vector4 > DerivedType;
-
-  // Reserve some memory inside the render queue
-  uint32_t* slot = mImpl->renderQueue.ReserveMessageSlot( mSceneGraphBuffers.GetUpdateBufferIndex(), sizeof( DerivedType ) );
-
-  // Construct message in the render queue memory; note that delete should not be called on the return value
-  new (slot) DerivedType( &mImpl->renderManager, &RenderManager::SetBackgroundColor, color );
-}
-
 void UpdateManager::SetDefaultSurfaceRect( const Rect<int32_t>& rect )
 {
   mImpl->surfaceRectChanged = true;
index 039e054..a11fc40 100644 (file)
@@ -594,12 +594,6 @@ public:
                    bool isRenderingToFbo );
 
   /**
-   * Set the background color i.e. the glClear color used at the beginning of each frame.
-   * @param[in] color The new background color.
-   */
-  void SetBackgroundColor(const Vector4& color);
-
-  /**
    * Set the default surface rect.
    * @param[in] rect The rect value representing the surface.
    */
@@ -1008,17 +1002,6 @@ inline void SetShaderProgramMessage( UpdateManager& manager,
   new (slot) LocalType( &manager, &UpdateManager::SetShaderProgram, const_cast<Shader*>( &shader ), shaderData, modifiesGeometry );
 }
 
-inline void SetBackgroundColorMessage( UpdateManager& manager, const Vector4& color )
-{
-  typedef MessageValue1< UpdateManager, Vector4 > LocalType;
-
-  // Reserve some memory inside the message queue
-  uint32_t* slot = manager.ReserveMessageSlot( sizeof( LocalType ) );
-
-  // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &manager, &UpdateManager::SetBackgroundColor, color );
-}
-
 inline void SetDefaultSurfaceRectMessage( UpdateManager& manager, const Rect<int32_t>& rect  )
 {
   typedef MessageValue1< UpdateManager, Rect<int32_t> > LocalType;