END_TEST;
}
+int UtcDaliRenderTaskRenderUntil06(void)
+{
+ TestApplication application;
+ tet_infoline("Testing RenderTask::RenderUntil(actor) Check that stopper actor scene off and destroyed");
+
+ // Get default rendertask
+ RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+ RenderTask task = taskList.GetTask(0u);
+
+ Integration::Scene stage = application.GetScene();
+
+ auto CreateRenderableActorWithName = [](const char* name) -> Actor {
+ Actor actor = CreateRenderableActor();
+ actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ actor.SetProperty(Actor::Property::NAME, name);
+
+ return actor;
+ };
+
+ // Compose a tree
+ //
+ // stage (depth = 0)
+ // |- a0 (renderable)
+ // |- a1 (renderable)
+ // |- target (stopper node)
+ // |- a2 (renderable)
+ Actor a0 = CreateRenderableActorWithName("a0");
+ Actor a1 = CreateRenderableActorWithName("a1");
+ Actor a2 = CreateRenderableActorWithName("a2");
+ Actor target = CreateRenderableActorWithName("target");
+
+ stage.Add(a0);
+ stage.Add(a1);
+ stage.Add(a2);
+ a1.Add(target);
+
+ // draw a0, a1 (2 items)
+ task.RenderUntil(target);
+
+ // Update & Render with the actor on-stage
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& drawTrace = gl.GetDrawTrace();
+ drawTrace.Enable(true);
+
+ // Update & Render
+ application.SendNotification();
+ application.Render();
+
+ // Check that rendering was cut
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 2, TEST_LOCATION);
+
+ drawTrace.Reset();
+
+ // Destroy target
+ //
+ // stage (depth = 0)
+ // |- a0 (renderable)
+ // |- a1 (renderable)
+ // |- a2 (renderable)
+ target.Unparent();
+ target.Reset();
+
+ DALI_TEST_EQUALS(task.GetStopperActor(), Actor(), TEST_LOCATION);
+
+ // After now, draw all actors, a0, a1, and a2.
+
+ // Update & Render
+ application.SendNotification();
+ application.Render();
+
+ // Check that rendering was cut
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 3, TEST_LOCATION);
+
+ drawTrace.Reset();
+
+ // To make ensure the destroyed target has same pointer with new one, try this test multiple times
+ for(int tryCount = 0; tryCount < 50; tryCount++)
+ {
+ // Create new target, which might have same pointer with previous one.
+ target = CreateRenderableActorWithName("target");
+
+ // Add target under a0.
+ //
+ // stage (depth = 0)
+ // |- a0 (renderable)
+ // |- target (renderable)
+ // |- a1 (renderable)
+ // |- a2 (renderable)
+ a0.Add(target);
+
+ // After now, draw all actors (4 items).
+
+ // Update & Render
+ application.SendNotification();
+ application.Render();
+
+ // Check that rendering was cut
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 4, TEST_LOCATION);
+
+ drawTrace.Reset();
+ target.Unparent();
+ }
+
+ END_TEST;
+}
+
int UtcDaliRenderTaskSetExclusive(void)
{
TestApplication application;
END_TEST;
}
+int UtcDaliRenderTaskViewportGuideActorDestroyed(void)
+{
+ TestApplication application;
+ tet_infoline("Testing RenderTask with ViewportGuideActor, and check viewport if guide actor destroyed");
+
+ Stage stage = Stage::GetCurrent();
+ Vector2 stageSize(stage.GetSize());
+
+ Actor blue = Actor::New();
+ blue[Dali::Actor::Property::NAME] = "Blue";
+ blue[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
+ blue[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
+ blue[Dali::Actor::Property::SIZE] = Vector2(300, 300);
+ blue[Dali::Actor::Property::POSITION] = Vector2(0, 0);
+
+ Actor red = Actor::New();
+ red[Dali::Actor::Property::NAME] = "Red";
+ red[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
+ red[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
+ red[Dali::Actor::Property::SIZE] = Vector2(300, 300);
+ red[Dali::Actor::Property::POSITION] = Vector2(0, 0);
+
+ Geometry geometry = Geometry::New();
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ Renderer renderer = Renderer::New(geometry, shader);
+ red.AddRenderer(renderer);
+
+ stage.Add(blue);
+ stage.Add(red);
+
+ RenderTaskList renderTaskList = stage.GetRenderTaskList();
+ RenderTask renderTask = renderTaskList.CreateTask();
+
+ Dali::CameraActor cameraActor = Dali::CameraActor::New(stageSize);
+ cameraActor[Dali::Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER;
+ cameraActor[Dali::Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER;
+ stage.Add(cameraActor);
+
+ renderTask.SetExclusive(true);
+ renderTask.SetInputEnabled(true);
+ renderTask.SetCameraActor(cameraActor);
+ renderTask.SetSourceActor(red);
+ application.SendNotification();
+ application.Render(16);
+
+ Vector2 viewportPosition = renderTask.GetCurrentViewportPosition();
+ Vector2 viewportSize = renderTask.GetCurrentViewportSize();
+
+ // Check viewport return 0 without guide actor
+ DALI_TEST_EQUALS(viewportSize, Vector2(0, 0), TEST_LOCATION);
+ DALI_TEST_EQUALS(viewportPosition, Vector2(0, 0), TEST_LOCATION);
+
+ // Set ViewportGuideActor
+ renderTask.SetViewportGuideActor(blue);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render(16);
+
+ viewportPosition = renderTask.GetCurrentViewportPosition();
+ viewportSize = renderTask.GetCurrentViewportSize();
+
+ DALI_TEST_EQUALS(viewportSize, Vector2(300, 300), TEST_LOCATION);
+ DALI_TEST_EQUALS(viewportPosition, Vector2(90, 250), TEST_LOCATION);
+
+ // Render several frames.
+ application.SendNotification();
+ application.Render(16);
+ application.SendNotification();
+ application.Render(16);
+ application.SendNotification();
+ application.Render(16);
+
+ viewportPosition = renderTask.GetCurrentViewportPosition();
+ viewportSize = renderTask.GetCurrentViewportSize();
+
+ DALI_TEST_EQUALS(viewportSize, Vector2(300, 300), TEST_LOCATION);
+ DALI_TEST_EQUALS(viewportPosition, Vector2(90, 250), TEST_LOCATION);
+
+ tet_printf("Destroy blue. RenderTask don't hold actor's reference, so ViewportGuideActor invalide now\n");
+
+ blue.Unparent();
+ blue.Reset();
+
+ DALI_TEST_EQUALS(renderTask.GetViewportGuideActor(), Actor(), TEST_LOCATION);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render(16);
+
+ viewportPosition = renderTask.GetCurrentViewportPosition();
+ viewportSize = renderTask.GetCurrentViewportSize();
+
+ // Check view port revert as origin well.
+ DALI_TEST_EQUALS(viewportSize, Vector2(0, 0), TEST_LOCATION);
+ DALI_TEST_EQUALS(viewportPosition, Vector2(0, 0), TEST_LOCATION);
+
+ // Render several frames.
+ application.SendNotification();
+ application.Render(16);
+ application.SendNotification();
+ application.Render(16);
+ application.SendNotification();
+ application.Render(16);
+
+ viewportPosition = renderTask.GetCurrentViewportPosition();
+ viewportSize = renderTask.GetCurrentViewportSize();
+
+ DALI_TEST_EQUALS(viewportSize, Vector2(0, 0), TEST_LOCATION);
+ DALI_TEST_EQUALS(viewportPosition, Vector2(0, 0), TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliRenderTaskSetPartialUpdate(void)
{
TestApplication application(
{
DALI_ASSERT_ALWAYS(!mObserverNotifying && "Cannot add observer while notifying PropertyOwner::Observers");
- //Check for duplicates in debug builds
- DALI_ASSERT_DEBUG(mObservers.End() == mObservers.Find(&observer));
-
- mObservers.PushBack(&observer);
+ auto [iter, inserted] = mObservers.emplace(&observer, 1u);
+ if(!inserted)
+ {
+ // Increase the number of observer count
+ ++(iter->second);
+ }
}
void PropertyOwner::RemoveObserver(Observer& observer)
{
DALI_ASSERT_ALWAYS(!mObserverNotifying && "Cannot remove observer while notifying PropertyOwner::Observers");
- const auto iter = mObservers.Find(&observer);
- if(iter != mObservers.End())
+ auto iter = mObservers.find(&observer);
+ DALI_ASSERT_ALWAYS(iter != mObservers.end());
+
+ if(--(iter->second) == 0u)
{
- mObservers.Erase(iter);
+ mObservers.erase(iter);
}
}
bool PropertyOwner::IsObserved()
{
- return mObservers.Count() != 0u;
+ return mObservers.size() != 0u;
}
void PropertyOwner::Destroy()
// Notification for observers
for(auto&& item : mObservers)
{
- item->PropertyOwnerDestroyed(*this);
+ item.first->PropertyOwnerDestroyed(*this);
}
// Note : We don't need to restore mObserverNotifying to false as we are in delete the object.
// If someone call AddObserver / RemoveObserver after this, assert.
// Remove all observers
- mObservers.Clear();
+ mObservers.clear();
// Remove all constraints when disconnected from scene-graph
mConstraints.Clear();
// Notification for observers
for(auto&& item : mObservers)
{
- item->PropertyOwnerConnected(*this);
+ item.first->PropertyOwnerConnected(*this);
}
mObserverNotifying = false;
mObserverNotifying = true;
// Notification for observers
- for(auto iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter;)
+ for(auto iter = mObservers.begin(); iter != mObservers.end();)
{
- auto returnValue = (*iter)->PropertyOwnerDisconnected(updateBufferIndex, *this);
+ auto returnValue = (*iter).first->PropertyOwnerDisconnected(updateBufferIndex, *this);
if(returnValue == Observer::KEEP_OBSERVING)
{
++iter;
}
else
{
- iter = mObservers.Erase(iter);
+ iter = mObservers.erase(iter);
}
}
mSourceNode->RemoveExclusiveRenderTask(this);
}
}
+ if(mStopperNode)
+ {
+ mStopperNode->RemoveObserver(*this);
+ }
if(mCameraNode)
{
mCameraNode->RemoveObserver(*this);
}
+ if(mViewportGuideNode)
+ {
+ mViewportGuideNode->RemoveObserver(*this);
+ }
if(mRenderSyncTracker)
{
if(DALI_LIKELY(mRenderMessageDispatcher))
void RenderTask::SetStopperNode(Node* node)
{
+ if(mStopperNode)
+ {
+ mStopperNode->RemoveObserver(*this);
+ }
+
mStopperNode = node;
+
+ if(mStopperNode)
+ {
+ mStopperNode->AddObserver(*this);
+ }
}
Node* RenderTask::GetStopperNode() const
void RenderTask::SetViewportGuideNode(Node* node)
{
+ if(mViewportGuideNode)
+ {
+ mViewportGuideNode->RemoveObserver(*this);
+ }
+
mViewportGuideNode = node;
+
+ if(mViewportGuideNode)
+ {
+ mViewportGuideNode->AddObserver(*this);
+ }
}
Node* RenderTask::GetViewportGuideNode() const
Vector2 screenPosition(halfSceneSize.width + worldPosition.x - halfNodeSize.x,
halfSceneSize.height + worldPosition.y - halfNodeSize.y);
- /* This is an implicit constraint - the properties will be dirty until the node
+ /**
+ * This is an implicit constraint - the properties will be dirty until the node
* is removed. (RenderTask::Impl manages this)
+ *
+ * TODO : Need to make Resseter for these properties.
*/
mViewportPosition.Set(updateBufferIndex, screenPosition);
mViewportSize.Set(updateBufferIndex, Vector2(nodeSize));
void RenderTask::PropertyOwnerConnected(PropertyOwner& owner)
{
- // check if we've gone from inactive to active
- SetActiveStatus();
+ if(&owner == static_cast<PropertyOwner*>(mSourceNode) || &owner == static_cast<PropertyOwner*>(mCameraNode))
+ {
+ // check if we've gone from inactive to active
+ SetActiveStatus();
+ }
}
PropertyOwner::Observer::NotifyReturnType RenderTask::PropertyOwnerDisconnected(BufferIndex /*updateBufferIndex*/, PropertyOwner& owner)
{
- mActive = false; // if either source or camera disconnected, we're no longer active
+ if(&owner == static_cast<PropertyOwner*>(mSourceNode) || &owner == static_cast<PropertyOwner*>(mCameraNode))
+ {
+ mActive = false; // if either source or camera disconnected, we're no longer active
+ }
return PropertyOwner::Observer::NotifyReturnType::KEEP_OBSERVING;
}
if(static_cast<PropertyOwner*>(mSourceNode) == &owner)
{
mSourceNode = nullptr;
+
+ mActive = false; // if either source or camera destroyed, we're no longer active
}
- else if(static_cast<PropertyOwner*>(mCameraNode) == &owner)
+ if(static_cast<PropertyOwner*>(mCameraNode) == &owner)
{
mCameraNode = nullptr;
+
+ mActive = false; // if either source or camera destroyed, we're no longer active
+ }
+ if(static_cast<PropertyOwner*>(mStopperNode) == &owner)
+ {
+ mStopperNode = nullptr;
}
+ if(static_cast<PropertyOwner*>(mViewportGuideNode) == &owner)
+ {
+ mViewportGuideNode = nullptr;
- mActive = false; // if either source or camera destroyed, we're no longer active
+ if(DALI_LIKELY(!Dali::Stage::IsShuttingDown()))
+ {
+ // TODO : Until SG::RenderTask Resseter preopared, just call this internal API without dirty flag down.
+ mViewportPosition.ResetToBaseValueInternal(0);
+ mViewportPosition.ResetToBaseValueInternal(1);
+ mViewportSize.ResetToBaseValueInternal(0);
+ mViewportSize.ResetToBaseValueInternal(1);
+ }
+ }
}
void RenderTask::AddInitializeResetter(ResetterManager& manager) const