float TestCalculateChildSizeBase(const Dali::Actor& child, Dali::Dimension::Type dimension);
bool TestRelayoutDependentOnChildrenBase(Dali::Dimension::Type dimension);
+ void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+ {
+ }
+
public:
Dali::Property::Index mDaliProperty;
std::vector<std::string> mMethodsCalled;
{
return false;
}
+
+ void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+ {
+ }
};
} //namespace Impl
virtual void OnLayoutNegotiated(float size, Dimension::Type dimension)
{
}
+
+ void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+ {
+ }
};
} // namespace Impl
struct UnregisteredCustomActor : public Dali::CustomActor
END_TEST;
}
+
+namespace Impl
+{
+
+class OffScreenCustomActor : public UnregisteredCustomActor
+{
+public:
+ void OnSceneConnection(int depth) override
+ {
+ tet_printf("tyty : %d\n", GetOffScreenRenderableType());
+ Dali::Integration::Scene scene = Dali::Integration::Scene::Get(Self());
+ if(scene)
+ {
+ mScene = scene;
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ mForwardRenderTask = taskList.CreateTask();
+ mBackwardRenderTask = taskList.CreateTask();
+ FrameBuffer forwardFrameBuffer = FrameBuffer::New(1, 1);
+ FrameBuffer backwardFrameBuffer = FrameBuffer::New(1, 1);
+
+ mForwardRenderTask.SetFrameBuffer(forwardFrameBuffer);
+ mBackwardRenderTask.SetFrameBuffer(backwardFrameBuffer);
+ }
+ }
+
+ void OnSceneDisconnection() override
+ {
+ Dali::Integration::Scene scene = mScene.GetHandle();
+ if(scene)
+ {
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ taskList.RemoveTask(mForwardRenderTask);
+ taskList.RemoveTask(mBackwardRenderTask);
+ }
+ mForwardRenderTask.Reset();
+ mBackwardRenderTask.Reset();
+ mScene.Reset();
+ }
+
+ void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+ {
+ tasks.clear();
+ if(isForward && GetOffScreenRenderableType() & OffScreenRenderable::Type::FORWARD && mForwardRenderTask)
+ {
+ tasks.push_back(mForwardRenderTask);
+ }
+ if(!isForward && GetOffScreenRenderableType() & OffScreenRenderable::Type::BACKWARD && mBackwardRenderTask)
+ {
+ tasks.push_back(mBackwardRenderTask);
+ }
+ }
+
+ Dali::WeakHandle<Dali::Integration::Scene> mScene;
+ Dali::RenderTask mForwardRenderTask;
+ Dali::RenderTask mBackwardRenderTask;
+};
+
+} // namespace Impl
+
+class OffScreenCustomActor : public UnregisteredCustomActor
+{
+public:
+ static OffScreenCustomActor New(OffScreenRenderable::Type type)
+ {
+ Impl::OffScreenCustomActor* impl = new Impl::OffScreenCustomActor;
+ OffScreenCustomActor custom(*impl, type); // takes ownership
+ return custom;
+ }
+ OffScreenCustomActor()
+ {
+ }
+ ~OffScreenCustomActor()
+ {
+ }
+ OffScreenCustomActor(Internal::CustomActor* impl)
+ : UnregisteredCustomActor(impl)
+ {
+ }
+ OffScreenCustomActor(Impl::OffScreenCustomActor& impl, OffScreenRenderable::Type type)
+ : UnregisteredCustomActor(impl)
+ {
+ mImpl = &impl;
+ mImpl->SetOffScreenRenderableType(type);
+ }
+ Dali::RenderTask GetForwardRenderTask()
+ {
+ return mImpl->mForwardRenderTask;
+ }
+ Dali::RenderTask GetBackwardRenderTask()
+ {
+ return mImpl->mBackwardRenderTask;
+ }
+ OffScreenRenderable::Type GetOffScreenRenderableType()
+ {
+ tet_printf("type : %d\n", mImpl->GetOffScreenRenderableType());
+ return mImpl->GetOffScreenRenderableType();
+ }
+
+ Impl::OffScreenCustomActor* mImpl;
+};
+
+int UtcDaliCustomActorReordering(void)
+{
+ TestApplication application; // Need the type registry
+
+ DALI_TEST_EQUALS(application.GetScene().GetRenderTaskList().GetTaskCount(), 1, TEST_LOCATION);
+
+ /**
+ * Al
+ * / \
+ * Bb Cl
+ * / \ / \
+ * D Efb Jb K
+ * / \
+ * Fb Gf
+ * / \
+ * H I
+ *
+ * A, C are Layer. C has smaller Depth value than A.
+ * B, E, F, G, and J are OffScreenCustomActor.
+ * B, F, and J are Type BACKWARD.
+ * E and G are Type FORWARD.
+ *
+ * After reordering, The order of OrderIndex of each RenderTask becomes
+ * G(Forward) - F(Backward) - E(Forward) - J(BACKWARD) - B(BACKWARD) - E(BACKWARD)
+ */
+
+ Layer A_layer = Layer::New();
+ OffScreenCustomActor B_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::BACKWARD);
+ Layer C_layer = Layer::New();
+ Actor D_actor = Actor::New();
+ OffScreenCustomActor E_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::BOTH);
+ OffScreenCustomActor F_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::BACKWARD);
+ OffScreenCustomActor G_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::FORWARD);
+ Actor H_actor = Actor::New();
+ Actor I_actor = Actor::New();
+ OffScreenCustomActor J_offScreenCustomActor = OffScreenCustomActor::New(OffScreenRenderable::Type::BACKWARD);
+
+ A_layer.Add(B_offScreenCustomActor);
+ A_layer.Add(C_layer);
+ B_offScreenCustomActor.Add(D_actor);
+ B_offScreenCustomActor.Add(E_offScreenCustomActor);
+ E_offScreenCustomActor.Add(F_offScreenCustomActor);
+ E_offScreenCustomActor.Add(G_offScreenCustomActor);
+ G_offScreenCustomActor.Add(H_actor);
+ G_offScreenCustomActor.Add(I_actor);
+ C_layer.Add(J_offScreenCustomActor);
+
+ DALI_TEST_EQUALS(application.GetScene().GetRenderTaskList().GetTaskCount(), 1, TEST_LOCATION);
+ tet_printf("task cnt before : %d\n", application.GetScene().GetRenderTaskList().GetTaskCount());
+
+ application.GetScene().Add(A_layer);
+
+ DALI_TEST_EQUALS(application.GetScene().GetRenderTaskList().GetTaskCount(), 11, TEST_LOCATION);
+
+ C_layer.MoveBelow(A_layer);
+
+ application.GetScene().GetRenderTaskList().GetTaskCount();
+
+ tet_printf("task cnt after : %d\n", application.GetScene().GetRenderTaskList().GetTaskCount());
+ tet_printf("c depth : %d, a depth : %d\n", C_layer.GetProperty<int>(Dali::Layer::Property::DEPTH), A_layer.GetProperty<int>(Dali::Layer::Property::DEPTH));
+ tet_printf("c id : %d, a id : %d\n", C_layer.GetProperty<int>(Dali::Actor::Property::ID), A_layer.GetProperty<int>(Dali::Actor::Property::ID));
+
+ DALI_TEST_CHECK(C_layer.GetProperty<int>(Dali::Layer::Property::DEPTH) < A_layer.GetProperty<int>(Dali::Layer::Property::DEPTH));
+
+ application.SendNotification();
+
+ tet_printf("B task order F : %d, task order B : %d\n", B_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), B_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+ tet_printf("E task order F : %d, task order B : %d\n", E_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), E_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+ tet_printf("F task order F : %d, task order B : %d\n", F_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), F_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+ tet_printf("G task order F : %d, task order B : %d\n", G_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), G_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+ tet_printf("J task order F : %d, task order B : %d\n", J_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex(), J_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+
+ DALI_TEST_CHECK(G_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex() < F_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+ DALI_TEST_CHECK(F_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex() < E_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex());
+ DALI_TEST_CHECK(E_offScreenCustomActor.GetForwardRenderTask().GetOrderIndex() < J_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+ DALI_TEST_CHECK(J_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex() < B_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+ DALI_TEST_CHECK(B_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex() < E_offScreenCustomActor.GetBackwardRenderTask().GetOrderIndex());
+
+ END_TEST;
+}
\ No newline at end of file
RenderTask renderTask1 = renderTaskList.CreateTask();
application.SendNotification();
- uint32_t answer1[2] = {0u, 0u};
+ int32_t answer1[2] = {INT32_MIN, 0};
DALI_TEST_EQUALS(2, renderTaskList.GetTaskCount(), TEST_LOCATION);
for(uint32_t i = 0; i < 2; ++i)
{
RenderTask renderTask2 = renderTaskList.CreateTask();
application.SendNotification();
- int32_t answer2[3] = {0u, 0u, 0u};
+ int32_t answer2[3] = {INT32_MIN, 0, 0};
DALI_TEST_EQUALS(3, renderTaskList.GetTaskCount(), TEST_LOCATION);
for(uint32_t i = 0; i < 3; ++i)
{
RenderTask renderTask3 = renderTaskList.CreateTask();
application.SendNotification();
- int32_t answer3[4] = {0u, 0u, 0u, 0u};
+ int32_t answer3[4] = {INT32_MIN, 0, 0, 0};
DALI_TEST_EQUALS(4, renderTaskList.GetTaskCount(), TEST_LOCATION);
for(uint32_t i = 0; i < 4; ++i)
{
renderTask1.SetOrderIndex(3);
application.SendNotification();
- int32_t answer4[4] = {0u, 0u, 0u, 3u};
+ int32_t answer4[4] = {INT32_MIN, 0, 0, 3};
for(uint32_t i = 0; i < 4; ++i)
{
DALI_TEST_EQUALS(answer4[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
renderTask2.SetOrderIndex(7);
application.SendNotification();
- int32_t answer5[4] = {0u, 0u, 3u, 7u};
+ int32_t answer5[4] = {INT32_MIN, 0, 3, 7};
for(uint32_t i = 0; i < 4; ++i)
{
DALI_TEST_EQUALS(answer5[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
scene.GetOverlayLayer();
application.SendNotification();
DALI_TEST_EQUALS(5, renderTaskList.GetTaskCount(), TEST_LOCATION);
- int32_t answer6[5] = {0u, 0u, 3u, 7u, INT32_MAX};
+ int32_t answer6[5] = {INT32_MIN, 0, 3, 7, INT32_MAX};
for(uint32_t i = 0; i < 5; ++i)
{
DALI_TEST_EQUALS(answer6[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
renderTask3.SetOrderIndex(4);
application.SendNotification();
- int32_t answer7[5] = {0u, 3u, 4u, 7u, INT32_MAX};
+ int32_t answer7[5] = {INT32_MIN, 3, 4, 7, INT32_MAX};
for(uint32_t i = 0; i < 5; ++i)
{
DALI_TEST_EQUALS(answer7[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
renderTask2.SetOrderIndex(2);
application.SendNotification();
- int32_t answer8[5] = {0u, 2u, 3u, 4u, INT32_MAX};
+ int32_t answer8[5] = {INT32_MIN, 2, 3, 4, INT32_MAX};
for(uint32_t i = 0; i < 5; ++i)
{
DALI_TEST_EQUALS(answer8[i], renderTaskList.GetTask(i).GetOrderIndex(), TEST_LOCATION);
return false;
}
+ void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+ {
+ }
+
public:
SignalType mSignal;
};
return false;
}
+ void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) override
+ {
+ }
+
public:
SignalType mSignal;
};
scene->RebuildDepthTree();
}
+ // process events in all scenes
+ for(auto scene : scenes)
+ {
+ auto& renderTaskList = scene->GetRenderTaskList();
+ renderTaskList.ReorderTasks(scene->GetLayerList());
+ }
+
// Flush any queued messages for the update-thread
const bool messagesToProcess = mUpdateManager->FlushQueue();
{
if(mProcessorsOnce[mProcessorOnceIndex].Count() != 0)
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS_ONCE", [&](std::ostringstream& oss) {
- oss << "[" << mProcessorOnceIndex << ":" << mProcessorsOnce[mProcessorOnceIndex].Count() << "]";
- });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS_ONCE", [&](std::ostringstream& oss)
+ { oss << "[" << mProcessorOnceIndex << ":" << mProcessorsOnce[mProcessorOnceIndex].Count() << "]"; });
// Swap processor index.
uint32_t currentIndex = mProcessorOnceIndex;
// Clear once processor.
mProcessorsOnce[currentIndex].Clear();
- DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS_ONCE", [&](std::ostringstream& oss) {
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS_ONCE", [&](std::ostringstream& oss)
+ {
oss << "[" << currentIndex;
if(mProcessorUnregistered)
{
oss << ", processor changed";
}
- oss << "]";
- });
+ oss << "]"; });
}
if(mProcessors.Count() != 0)
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS", [&](std::ostringstream& oss) {
- oss << "[" << mProcessors.Count() << "]";
- });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS", [&](std::ostringstream& oss)
+ { oss << "[" << mProcessors.Count() << "]"; });
// Copy processor pointers to prevent changes to vector affecting loop iterator.
Dali::Vector<Integration::Processor*> processors(mProcessors);
{
if(!mProcessorUnregistered)
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss) {
- oss << "[" << processor->GetProcessorName() << "]";
- });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss)
+ { oss << "[" << processor->GetProcessorName() << "]"; });
processor->Process(false);
- DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss) {
- oss << "[" << processor->GetProcessorName() << "]";
- });
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss)
+ { oss << "[" << processor->GetProcessorName() << "]"; });
}
else
{
auto iter = std::find(mProcessors.Begin(), mProcessors.End(), processor);
if(iter != mProcessors.End())
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss) {
- oss << "[" << processor->GetProcessorName() << "]";
- });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss)
+ { oss << "[" << processor->GetProcessorName() << "]"; });
processor->Process(false);
- DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss) {
- oss << "[" << processor->GetProcessorName() << "]";
- });
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSOR", [&](std::ostringstream& oss)
+ { oss << "[" << processor->GetProcessorName() << "]"; });
}
}
}
}
- DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS", [&](std::ostringstream& oss) {
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_PROCESSORS", [&](std::ostringstream& oss)
+ {
oss << "[" << mProcessors.Count();
if(mProcessorUnregistered)
{
oss << ", processor changed";
}
- oss << "]";
- });
+ oss << "]"; });
}
}
{
if(mPostProcessorsOnce[mPostProcessorOnceIndex].Count() != 0)
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS_ONCE", [&](std::ostringstream& oss) {
- oss << "[" << mPostProcessorOnceIndex << ":" << mPostProcessorsOnce[mPostProcessorOnceIndex].Count() << "]";
- });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS_ONCE", [&](std::ostringstream& oss)
+ { oss << "[" << mPostProcessorOnceIndex << ":" << mPostProcessorsOnce[mPostProcessorOnceIndex].Count() << "]"; });
// Swap processor index.
uint32_t currentIndex = mPostProcessorOnceIndex;
// Clear once processor.
mPostProcessorsOnce[currentIndex].Clear();
- DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS_ONCE", [&](std::ostringstream& oss) {
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS_ONCE", [&](std::ostringstream& oss)
+ {
oss << "[" << currentIndex;
if(mPostProcessorUnregistered)
{
oss << ", processor changed";
}
- oss << "]";
- });
+ oss << "]"; });
}
if(mPostProcessors.Count() != 0)
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS", [&](std::ostringstream& oss) {
- oss << "[" << mPostProcessors.Count() << "]";
- });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS", [&](std::ostringstream& oss)
+ { oss << "[" << mPostProcessors.Count() << "]"; });
// Copy processor pointers to prevent changes to vector affecting loop iterator.
Dali::Vector<Integration::Processor*> processors(mPostProcessors);
{
if(!mPostProcessorUnregistered)
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss) {
- oss << "[" << processor->GetProcessorName() << "]";
- });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss)
+ { oss << "[" << processor->GetProcessorName() << "]"; });
processor->Process(true);
- DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss) {
- oss << "[" << processor->GetProcessorName() << "]";
- });
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss)
+ { oss << "[" << processor->GetProcessorName() << "]"; });
}
else
{
auto iter = std::find(mPostProcessors.Begin(), mPostProcessors.End(), processor);
if(iter != mPostProcessors.End())
{
- DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss) {
- oss << "[" << processor->GetProcessorName() << "]";
- });
+ DALI_TRACE_BEGIN_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss)
+ { oss << "[" << processor->GetProcessorName() << "]"; });
processor->Process(true);
- DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss) {
- oss << "[" << processor->GetProcessorName() << "]";
- });
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSOR", [&](std::ostringstream& oss)
+ { oss << "[" << processor->GetProcessorName() << "]"; });
}
}
}
}
- DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS", [&](std::ostringstream& oss) {
+ DALI_TRACE_END_WITH_MESSAGE_GENERATOR(gTraceFilter, "DALI_CORE_RUN_POST_PROCESSORS", [&](std::ostringstream& oss)
+ {
oss << "[" << mPostProcessors.Count();
if(mPostProcessorUnregistered)
{
oss << ", processor changed";
}
- oss << "]";
- });
+ oss << "]"; });
}
}
return mParentImpl.ChildOrderChangedSignal();
}
+void Actor::GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward)
+{
+}
+
+void Actor::SetOffScreenRenderableType(OffScreenRenderable::Type offScreenRenderableType)
+{
+ mOffScreenRenderableType = offScreenRenderableType;
+}
+
+OffScreenRenderable::Type Actor::GetOffScreenRenderableType() const
+{
+ return mOffScreenRenderableType;
+}
+
+void Actor::RequestRenderTaskReorder()
+{
+ if(mScene && GetOffScreenRenderableType() != OffScreenRenderable::Type::NONE)
+ {
+ mScene->GetRenderTaskList().RequestReorder();
+ }
+}
+
Actor::Actor(DerivedType derivedType, const SceneGraph::Node& node)
: Object(&node),
mParentImpl(*this),
mColorMode(Node::DEFAULT_COLOR_MODE),
mClippingMode(ClippingMode::DISABLED),
mHoverState(PointState::FINISHED),
- mBlendEquation(DevelBlendEquation::ADD)
+ mBlendEquation(DevelBlendEquation::ADD),
+ mOffScreenRenderableType(OffScreenRenderable::Type::NONE)
{
}
#include <string>
// INTERNAL INCLUDES
-#include <dali/public-api/actors/actor.h>
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/common/vector-wrapper.h>
-#include <dali/public-api/events/gesture.h>
-#include <dali/public-api/math/viewport.h>
-#include <dali/public-api/object/ref-object.h>
-#include <dali/public-api/size-negotiation/relayout-container.h>
-
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/rendering/renderer-devel.h>
-
#include <dali/integration-api/events/touch-event-integ.h>
-
#include <dali/internal/common/const-string.h>
#include <dali/internal/common/internal-constants.h>
#include <dali/internal/common/memory-pool-object-allocator.h>
#include <dali/internal/event/common/object-impl.h>
#include <dali/internal/event/common/stage-def.h>
#include <dali/internal/update/nodes/node-declarations.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/events/gesture.h>
+#include <dali/public-api/math/viewport.h>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/render-tasks/render-task.h>
+#include <dali/public-api/size-negotiation/relayout-container.h>
namespace Dali
{
{
}
+public:
+ // For Internal RenderTask Ordering
+
+ /**
+ * @brief Retrieves the off-screen RenderTasks associated with the Actor.
+ * This method returns the internal RenderTasks held by the Actor. This tasks are
+ * used for off-screen rendering, and the system will assign order index to each
+ * tasks based on the render order.
+ *
+ * Actor with a non-NONE OffScreenRenderableType should override this method to
+ * provide their render tasks.
+ *
+ * @param[out] tasks A list of RenderTasks to be populated with the Actor's forward
+ * or backward off-screen RenderTask.
+ * @param[in] isForward Indicates whether to retrieve forward (true) or backward (false)
+ * RenderTasks.
+ */
+ virtual void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward);
+
+ /**
+ * @brief Sets OffScreenRenderableType of this Actor.
+ * This method is called by child class to set type itself.
+ *
+ * @param[in] offScreenRenderableType OffScreenRenderableType for this Actor.
+ * It could be one of NONE, FORWARD, BACKWARD, and BOTH.
+ */
+ void SetOffScreenRenderableType(OffScreenRenderable::Type offScreenRenderableType);
+
+ /**
+ * @brief Retrieves OffScreenRenderableType of this Actor.
+ *
+ * @return OffScreenRenderableType for this Actor.
+ */
+ OffScreenRenderable::Type GetOffScreenRenderableType() const;
+
+ /**
+ * @brief Requests RenderTask reordering when the offscreen properties of this Actor are changed.
+ */
+ void RequestRenderTaskReorder();
+
protected:
enum DerivedType
{
private:
static ActorContainer mNullChildren; ///< Empty container (shared by all actors, returned by GetChildren() const)
+ // OffScreenRenderable
+ OffScreenRenderable::Type mOffScreenRenderableType;
+
struct PropertyHandler;
struct SiblingHandler;
mOwner.mLayer3DParentsCount = static_cast<uint16_t>(layer3DParentsCount); // overflow ignored, not expected in practice
mOwner.ConnectToSceneGraph();
+ mOwner.RequestRenderTaskReorder();
+
// Notification for internal derived classes
mOwner.OnSceneConnectionInternal();
mImpl->OnSizeAnimation(animationHandle, targetSize);
}
+ void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward)
+ {
+ mImpl->GetOffScreenRenderTasks(tasks, isForward);
+ }
+
/**
* @copydoc Internal::Actor::OnRelayout
*/
// Create the default render-task and ensure clear is enabled on it to show the background color
RenderTaskPtr renderTask = mRenderTaskList->CreateTask(mRootLayer.Get(), mDefaultCamera.Get());
+ renderTask->SetOrderIndex(INT32_MIN);
renderTask->SetClearEnabled(true);
// Create scene graph object
{
namespace Internal
{
+
+typedef std::vector<Actor*> OffScreenRenderableContainer;
+typedef std::pair<Actor*, OffScreenRenderableContainer> ForwardOffScreenRenderableSubTree;
+typedef std::vector<ForwardOffScreenRenderableSubTree> OffScreenRenderableData;
+
namespace
{
static constexpr uint32_t ORDER_INDEX_OVERLAY_RENDER_TASK = INT32_MAX;
mIsRequestedToSortTask = false;
}
+bool IsWithinSourceActors(const Actor& sourceActor, Actor& actor)
+{
+ bool isInside = false;
+ Actor* currentActor = &actor;
+ while(currentActor)
+ {
+ if(&sourceActor == currentActor)
+ {
+ isInside = true;
+ break;
+ }
+
+ if(currentActor->GetOffScreenRenderableType() & OffScreenRenderable::Type::FORWARD)
+ {
+ isInside = false;
+ break;
+ }
+ currentActor = currentActor->GetParent();
+ }
+ return isInside;
+}
+
+void FindOffScreenRenderableWithinSubTree(Actor& rootActor, Actor& actor, uint32_t subTreeIndex, std::vector<Actor*>& onScreenSources, OffScreenRenderableData& renderableData, std::vector<bool>& traverseFinished)
+{
+ if(&actor != renderableData[subTreeIndex].first)
+ {
+
+ // New BACKWARD OffScreen Renderable
+ if(actor.GetOffScreenRenderableType() & OffScreenRenderable::Type::BACKWARD)
+ {
+ renderableData[subTreeIndex].second.push_back(&actor);
+ }
+
+ // New FORWARD OffScreen Renderable. It makes new subTree.
+ if(actor.GetOffScreenRenderableType() & OffScreenRenderable::Type::FORWARD)
+ {
+ ForwardOffScreenRenderableSubTree newSubTree;
+ newSubTree.first = &actor;
+ renderableData.push_back(newSubTree);
+ traverseFinished.push_back(false);
+ return;
+ }
+
+ // OnScreen Source and its child will be traversed by next loop.
+ if(std::find(onScreenSources.begin(), onScreenSources.end(), &actor) != onScreenSources.end())
+ {
+ return;
+ }
+
+ if(rootActor.GetId() != actor.GetId() && actor.GetLayer().GetProperty<int32_t>(Dali::Actor::Property::ID) == static_cast<int32_t>(actor.GetId()))
+ {
+ return;
+ }
+ }
+
+ uint32_t childCount = actor.GetChildCount();
+ for(uint32_t i = 0; i < childCount; ++i)
+ {
+ auto child = actor.GetChildAt(i);
+ FindOffScreenRenderableWithinSubTree(rootActor, *(child.Get()), subTreeIndex, onScreenSources, renderableData, traverseFinished);
+ }
+}
+
+void RenderTaskList::ReorderTasks(Dali::Internal::LayerList& layerList)
+{
+ if(mIsRequestedToReorderTask)
+ {
+ std::vector<bool> traverseFinished;
+ OffScreenRenderableData renderableData;
+ uint32_t layerCount = layerList.GetLayerCount();
+ uint32_t taskCount = GetTaskCount();
+ std::vector<Actor*> onScreenSources;
+ for(uint32_t i = 0; i < taskCount; ++i)
+ {
+ auto renderTask = GetTask(i);
+ if(!renderTask->GetFrameBuffer())
+ {
+ onScreenSources.push_back(renderTask->GetSourceActor());
+ }
+ }
+
+ for(uint32_t i = 0; i < taskCount; ++i)
+ {
+ auto renderTask = GetTask(i);
+ if(renderTask->GetFrameBuffer())
+ {
+ continue;
+ }
+
+ auto* sourceActor = renderTask->GetSourceActor();
+ ForwardOffScreenRenderableSubTree subTree;
+ subTree.first = sourceActor;
+ renderableData.push_back(subTree);
+ traverseFinished.push_back(false);
+
+ uint32_t currentSubTreeIndex = 0;
+ Actor* root = subTree.first;
+ while(root)
+ {
+ Dali::Layer sourceLayer = root->GetLayer();
+ const uint32_t sourceLayerDepth = sourceLayer.GetProperty<int32_t>(Dali::Layer::Property::DEPTH);
+ for(uint32_t currentLayerIndex = 0; currentLayerIndex < layerCount; ++currentLayerIndex)
+ {
+ auto* layer = layerList.GetLayer(currentLayerIndex);
+ Dali::Internal::Actor* rootActor = nullptr;
+ if(sourceLayerDepth == currentLayerIndex)
+ {
+ rootActor = root;
+ }
+ else
+ {
+ if(!IsWithinSourceActors(*root, *layer))
+ {
+ continue;
+ }
+ rootActor = layer;
+ }
+ FindOffScreenRenderableWithinSubTree(*rootActor, *rootActor, currentSubTreeIndex, onScreenSources, renderableData, traverseFinished);
+ }
+
+ traverseFinished[currentSubTreeIndex] = true;
+
+ root = nullptr;
+ for(currentSubTreeIndex = 0; currentSubTreeIndex < traverseFinished.size(); ++currentSubTreeIndex)
+ {
+ if(!traverseFinished[currentSubTreeIndex])
+ {
+ root = renderableData[currentSubTreeIndex].first;
+ break;
+ }
+ }
+ }
+ }
+
+ // Default Task should have the lowest OrderIndex number.
+ int32_t orderIndex = GetTask(0u)->GetOrderIndex();
+ uint32_t subTreeCount = renderableData.size();
+ for(uint32_t i = subTreeCount - 1; i < subTreeCount; --i)
+ {
+ auto subTree = renderableData[i];
+ for(auto&& actor : subTree.second)
+ {
+ std::vector<Dali::RenderTask> tasks;
+ actor->GetOffScreenRenderTasks(tasks, false);
+ for(auto&& task : tasks)
+ {
+ GetImplementation(task).SetOrderIndex(orderIndex++);
+ }
+ }
+
+ if(subTree.first && subTree.first->GetOffScreenRenderableType() & OffScreenRenderable::Type::FORWARD)
+ {
+ std::vector<Dali::RenderTask> tasks;
+ subTree.first->GetOffScreenRenderTasks(tasks, true);
+ for(auto&& task : tasks)
+ {
+ GetImplementation(task).SetOrderIndex(orderIndex++);
+ }
+ }
+ }
+
+ SortTasks();
+ }
+ mIsRequestedToReorderTask = false;
+}
+
RenderTaskList::RenderTaskList()
: mEventThreadServices(EventThreadServices::Get()),
mDefaults(*Stage::GetCurrent()),
#include <dali/public-api/object/base-object.h>
#include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/internal/event/actors/layer-list.h>
#include <dali/internal/event/common/complete-notification-interface.h>
#include <dali/internal/event/common/scene-graph-notifier-interface-mapper.h>
#include <dali/internal/event/events/actor-observer.h>
*/
void SortTasks();
+ /**
+ * @brief Requests to reorder the RenderTasks of this RenderTaskList.
+ */
+ void RequestReorder()
+ {
+ mIsRequestedToReorderTask = true;
+ }
+
+ /**
+ * @brief Reorder RenderTasks along the priority of OffScreenRenderableType of each Actor.
+ *
+ * @param[in] layerList layerList that used for tasks reordering.
+ */
+ void ReorderTasks(Dali::Internal::LayerList& layerList);
+
/**
* Provide notification signals for a "Finished" render task.
* This method should be called in the event-thread
RenderTaskPtr mOverlayRenderTask{nullptr};
bool mIsRequestedToSortTask{false};
+ bool mIsRequestedToReorderTask{false};
};
} // namespace Internal
} // namespace LayoutDirection
+/**
+ * @brief Enumeration for the OffScreenRenderable of the Actor
+ * @SINCE_2_3.43
+ */
+namespace OffScreenRenderable
+{
+enum Type
+{
+ NONE = 0, // The Actor has no OffScreenRenderables. @SINCE_2_3.43
+ FORWARD = 1, // The Actor has RenderTasks those need reorder. And the Tasks will draw Actors those placed in front of the Actor. @SINCE_2_3.43
+ BACKWARD = 2, // The Actor has RenderTasks those need reorder, And the Tasks will draw Actors those placed behinde of the Actor. @SINCE_2_3.43
+ BOTH = FORWARD | BACKWARD, // The Actor has RenderTasks for the both of FORWARD and BACKWARD. @SINCE_2_3.43
+};
+} // namespace OffScreenRenderables
+
/**
* @}
*/
{
}
+void CustomActorImpl::SetOffScreenRenderableType(OffScreenRenderable::Type offScreenRenderableType)
+{
+ mOwner->SetOffScreenRenderableType(offScreenRenderableType);
+}
+
+OffScreenRenderable::Type CustomActorImpl::GetOffScreenRenderableType()
+{
+ return mOwner->GetOffScreenRenderableType();
+}
+
+void CustomActorImpl::RequestRenderTaskReorder()
+{
+ mOwner->RequestRenderTaskReorder();
+}
+
CustomActorImpl::CustomActorImpl(ActorFlags flags)
: mOwner(nullptr),
mFlags(flags)
// INTERNAL INCLUDES
#include <dali/public-api/actors/actor-enumerations.h>
+#include <dali/public-api/actors/actor.h>
#include <dali/public-api/math/compile-time-math.h>
#include <dali/public-api/object/property.h>
#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/render-tasks/render-task.h>
namespace Dali
{
class CustomActor;
}
-class Actor;
class Animation;
class CustomActor;
class CustomActorImpl;
*/
virtual void OnSizeAnimation(Animation& animation, const Vector3& targetSize) = 0;
+ /**
+ * @brief Retrieves the off-screen RenderTasks associated with the Actor.
+ * This method returns the internal RenderTasks held by the Actor. This tasks are
+ * used for off-screen rendering, and the system will assign order index to each
+ * tasks based on the render order.
+ *
+ * Actor with a non-NONE OffScreenRenderableType should override this method to
+ * provide their render tasks.
+ *
+ * @SINCE_2_3.43
+ * @param[out] tasks A list of RenderTasks to be populated with the Actor's forward
+ * or backward off-screen RenderTask.
+ * @param[in] isForward Indicates whether to retrieve forward (true) or backward (false)
+ * RenderTasks.
+ */
+ virtual void GetOffScreenRenderTasks(std::vector<Dali::RenderTask>& tasks, bool isForward) = 0;
+
+ /**
+ * @brief Sets OffScreenRenderableType of this Actor.
+ * This method is called by child class to set type itself.
+ *
+ * @SINCE_2_3.43
+ * @param[in] offScreenRenderableType OffScreenRenderableType for this Actor.
+ * It could be one of NONE, FORWARD, BACKWARD, and BOTH.
+ */
+ void SetOffScreenRenderableType(OffScreenRenderable::Type offScreenRenderableType);
+
+ /**
+ * @brief Retrieves OffScreenRenderableType of this Actor.
+ *
+ * @SINCE_2_3.43
+ * @return OffScreenRenderableType for this Actor.
+ */
+ OffScreenRenderable::Type GetOffScreenRenderableType();
+
+ /**
+ * @brief Requests RenderTask reordering when the offscreen properties of this Actor are changed.
+ * @SINCE_2_3.43
+ */
+ void RequestRenderTaskReorder();
+
/**
* @brief Called after the size negotiation has been finished for this control.
*