/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
END_TEST;
}
+
+int utcDaliEnsureRenderWhenRemovingLastRenderableActor(void)
+{
+ TestApplication application;
+ auto stage = Stage::GetCurrent();
+
+ tet_infoline( "Ensure we clear the screen when the last actor is removed" );
+
+ Actor actor = CreateRenderableActor();
+ actor.SetSize( 100.0f, 100.0f );
+ stage.Add( actor );
+
+ application.SendNotification();
+ application.Render();
+
+ auto& glAbstraction = application.GetGlAbstraction();
+ const auto clearCountBefore = glAbstraction.GetClearCountCalled();
+
+ actor.Unparent();
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( glAbstraction.GetClearCountCalled(), clearCountBefore + 1, TEST_LOCATION );
+
+ END_TEST;
+}
namespace SceneGraph
{
+#if defined(DEBUG_ENABLED)
+namespace
+{
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_RENDER_MANAGER" );
+} // unnamed namespace
+#endif
+
/**
* Structure to contain internal data
*/
const uint32_t count = mImpl->instructions.Count( mImpl->renderBufferIndex );
const bool haveInstructions = count > 0u;
+ DALI_LOG_INFO( gLogFilter, Debug::General,
+ "Render: haveInstructions(%s) || mImpl->lastFrameWasRendered(%s) || forceClear(%s)\n",
+ haveInstructions ? "true" : "false",
+ mImpl->lastFrameWasRendered ? "true" : "false",
+ forceClear ? "true" : "false" );
+
// Only render if we have instructions to render, or the last frame was rendered (and therefore a clear is required).
if( haveInstructions || mImpl->lastFrameWasRendered || forceClear )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Render: Processing\n" );
+
// Mark that we will require a post-render step to be performed (includes swap-buffers).
status.SetNeedsPostRender( true );
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
#if defined(DEBUG_ENABLED)
extern Debug::Filter* gRenderTaskLogFilter;
+namespace
+{
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_UPDATE_MANAGER" );
+} // unnamed namespace
#endif
previousUpdateScene( false ),
renderTaskWaiting( false ),
renderersAdded( false ),
- surfaceRectChanged( false )
+ surfaceRectChanged( false ),
+ nodeDisconnected( false )
{
sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue );
bool renderTaskWaiting; ///< A REFRESH_ONCE render task is waiting to be rendered
bool renderersAdded; ///< Flag to keep track when renderers have been added to avoid unnecessary processing
bool surfaceRectChanged; ///< True if the default surface rect is changed
+ bool nodeDisconnected; ///< True if a node is disconnected in the current update
private:
// Nodes must be sorted by pointer
Node* rawNode = node.Release();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddNode\n", rawNode );
+
Vector<Node*>::Iterator begin = mImpl->nodes.Begin();
for( Vector<Node*>::Iterator iter = mImpl->nodes.End()-1; iter >= begin; --iter )
{
DALI_ASSERT_ALWAYS( NULL != node );
DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] ConnectNode\n", node );
+
parent->ConnectChild( node );
// Inform the frame-callback-processor, if set, about the node-hierarchy changing
void UpdateManager::DisconnectNode( Node* node )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DisconnectNode\n", node );
+
+ mImpl->nodeDisconnected = true;
+
Node* parent = node->GetParent();
DALI_ASSERT_ALWAYS( NULL != parent );
parent->SetDirtyFlag( NodePropertyFlags::CHILD_DELETED ); // make parent dirty so that render items dont get reused
DALI_ASSERT_ALWAYS( NULL != node );
DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should have been disconnected
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] DestroyNode\n", node );
+
Vector<Node*>::Iterator iter = mImpl->nodes.Begin()+1;
Vector<Node*>::Iterator endIter = mImpl->nodes.End();
for(;iter!=endIter;++iter)
void UpdateManager::AddRenderer( OwnerPointer< Renderer >& renderer )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] AddRenderer\n", renderer.Get() );
+
renderer->ConnectToSceneGraph( *mImpl->sceneController, mSceneGraphBuffers.GetUpdateBufferIndex() );
mImpl->renderers.PushBack( renderer.Release() );
mImpl->renderersAdded = true;
void UpdateManager::RemoveRenderer( Renderer* renderer )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "[%x] RemoveRenderer\n", renderer );
+
// Find the renderer and destroy it
EraseUsingDiscardQueue( mImpl->renderers, renderer, mImpl->discardQueue, mSceneGraphBuffers.GetUpdateBufferIndex() );
// Need to remove the render object as well
isRenderingToFbo );
}
}
+
+ DALI_LOG_INFO( gLogFilter, Debug::General,
+ "Update: numberOfRenderTasks(%d), taskListCount(%d), Render Instructions(%d)\n",
+ numberOfRenderTasks, taskListCount, mImpl->renderInstructions.Count( bufferIndex ) );
+
+ // If a node has been disconnected in this update and we do not have any instructions to send, then generate a dummy instruction to force another render
+ if( mImpl->nodeDisconnected && ( mImpl->renderInstructions.Count( bufferIndex ) == 0 ) )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Node disconnected, creating dummy instruction\n" );
+ mImpl->renderInstructions.GetNextInstruction( bufferIndex ); // This creates and adds an empty instruction. We do not need to modify it.
+ }
+
+ mImpl->nodeDisconnected = false;
}
}