mLastShaderCompiled = 0;
mLastClearBitMask = 0;
+ mLastClearColor = Color::TRANSPARENT;
mClearCount = 0;
mLastBlendEquationRgb = 0;
bool blendEnabled = callStack.FindMethodAndParams( "Disable", out.str() );
return blendEnabled;
}
+
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)
ShaderSourceMap mShaderSources;
GLuint mLastShaderCompiled;
GLbitfield mLastClearBitMask;
+ Vector4 mLastClearColor;
unsigned int mClearCount;
Vector4 mLastBlendColor;
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;
}
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;
}
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 );
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;
}
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;
+}
if( mSurface )
{
- mRenderTaskList->GetTask( 0u )->GetFrameBuffer()->SetBackgroundColor( color );
+ mRenderTaskList->GetTask( 0u )->SetClearColor( color );
+ mRenderTaskList->GetTask( 0u )->SetClearEnabled( true );
}
}
}
}
-void FrameBuffer::SetBackgroundColor( const Vector4& color )
-{
- if( mRenderObject->IsSurfaceBacked() )
- {
- SetFrameBufferBackgroundColorMessage( mEventThreadServices.GetUpdateManager(), static_cast<Render::SurfaceFrameBuffer*>( mRenderObject ), color );
- }
-}
-
void FrameBuffer::MarkSurfaceAsInvalid()
{
if ( mIsSurfaceBacked )
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.
renderQueue(),
instructions(),
renderAlgorithms(),
- backgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
frameCount( 0u ),
renderBufferIndex( SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX ),
defaultSurfaceRect(),
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
return mImpl->instructions;
}
-void RenderManager::SetBackgroundColor( const Vector4& color )
-{
- mImpl->backgroundColor = color;
-}
-
void RenderManager::SetDefaultSurfaceRect(const Rect<int32_t>& rect)
{
mImpl->defaultSurfaceRect = rect;
}
Rect<int32_t> surfaceRect = mImpl->defaultSurfaceRect;
- Vector4 backgroundColor = mImpl->backgroundColor;
Integration::DepthBufferAvailable depthBufferAvailable = mImpl->depthBufferAvailable;
Integration::StencilBufferAvailable stencilBufferAvailable = mImpl->stencilBufferAvailable;
}
surfaceRect = Rect<int32_t>( 0, 0, static_cast<int32_t>( surfaceFrameBuffer->GetWidth() ), static_cast<int32_t>( surfaceFrameBuffer->GetHeight() ) );
- backgroundColor = surfaceFrameBuffer->GetBackgroundColor();
}
else
{
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 );
clearMask |= GL_STENCIL_BUFFER_BIT;
}
- mImpl->currentContext->Clear( clearMask, Context::FORCE_CLEAR );
-
if( !instruction.mIgnoreRenderToFbo && ( instruction.mFrameBuffer != 0 ) )
{
if ( instruction.mFrameBuffer->IsSurfaceBacked() ) // Surface rendering
}
}
+ 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
// 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
mContext( nullptr ),
mWidth( mSurface->GetPositionSize().width ),
mHeight( mSurface->GetPositionSize().height ),
- mBackgroundColor( 0.f, 0.f, 0.f, 1.f ),
mSizeChanged( false ),
mIsSurfaceInvalid( false )
{
}
}
-Vector4 SurfaceFrameBuffer::GetBackgroundColor()
-{
- return mBackgroundColor;
-}
-
void SurfaceFrameBuffer::SetSize( uint32_t width, uint32_t height )
{
mWidth = width;
mSizeChanged = true;
}
-void SurfaceFrameBuffer::SetBackgroundColor( const Vector4& color )
-{
- mBackgroundColor = color;
-}
-
bool SurfaceFrameBuffer::IsSurfaceValid() const
{
return mSurface && !mIsSurfaceInvalid;
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; };
*/
void MakeContextCurrent();
- /**
- * @brief Gets the background color of the surface.
- * @return The background color
- */
- Vector4 GetBackgroundColor();
-
private:
Integration::RenderSurface* mSurface; ///< The render surface
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
};
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
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;
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.
*/
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;