/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
{
TestApplication application;
- Dali::Internal::SceneGraph::TransformManagerPropertyQuaternion property;
+ struct S
+ {
+ Dali::Internal::SceneGraph::TransformManagerData txMgrData;
+ Dali::Internal::SceneGraph::TransformManagerPropertyQuaternion<sizeof(txMgrData)> property;
+ } s;
try
{
- property.GetFloatComponent(0u);
+ // There is no float component getter in derived class, only in base class.
+ s.property.GetFloatComponent(0u);
}
- catch(...)
+ catch(Dali::DaliException& e)
{
- DALI_TEST_CHECK(true);
+ DALI_TEST_ASSERT(e, "0 && \"Invalid call\"", TEST_LOCATION);
}
END_TEST;
}
+
+int UtcTransformManagerPropertyUninitializedMgrData(void)
+{
+ TestApplication application;
+
+ struct S
+ {
+ const Vector3 input{1.0f, 2.0f, 3.0f};
+
+ Dali::Internal::SceneGraph::TransformManagerData txMgrData;
+ Dali::Internal::SceneGraph::TransformManagerVector3Input<sizeof(txMgrData)> property{Dali::Internal::SceneGraph::TRANSFORM_PROPERTY_POSITION, input};
+ } s;
+
+ Vector3 output = s.property.GetVector3(0);
+
+ tet_infoline("Test that if input property's transform manager data is not initialized, that getting a value returns the initial value of the property.");
+
+ DALI_TEST_EQUALS(s.input, output, 0.001f, TEST_LOCATION);
+
+ END_TEST;
+}
DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
// Aligned by 16
- clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
- damagedRects.clear();
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
-
// Ensure the damaged rect is empty
DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
application.GetScene().SurfaceRotated(static_cast<float>(TestApplication::DEFAULT_SURFACE_HEIGHT),
static_cast<float>(TestApplication::DEFAULT_SURFACE_WIDTH),
- 90, 0);
+ 90,
+ 0);
// Render and notify
application.SendNotification();
application.Render(16);
std::string viewportParams1("50, 100, 300, 400"); // to match newSize
- std::string viewportParams2("0, 0, 480, 800"); // to match newSize
+ std::string viewportParams2("0, 0, 480, 800"); // to match newSize
// Check that the viewport is handled properly
DALI_TEST_CHECK(callStack.FindIndexFromMethodAndParams("Viewport", viewportParams1) >= 0);
END_TEST;
}
+
+int UtcDaliRenderTaskSetPartialUpdate(void)
+{
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+
+ tet_infoline("Check the damaged rects with render task");
+
+ const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+ Actor actor = CreateRenderableActor();
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+ actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+ actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(actor);
+
+ Actor rootActor = CreateRenderableActor();
+ rootActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ rootActor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+ rootActor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+ rootActor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(rootActor);
+
+ CameraActor cameraActor = CameraActor::New(Size(TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT));
+ cameraActor.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ cameraActor.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ application.GetScene().Add(cameraActor);
+
+ Texture frameBufferTexture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, 16, 16);
+ FrameBuffer frameBuffer = FrameBuffer::New(frameBufferTexture.GetWidth(), frameBufferTexture.GetHeight());
+ frameBuffer.AttachColorTexture(frameBufferTexture);
+
+ // Create a RenderTask and set a framebuffer
+ RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+ RenderTask newTask = taskList.CreateTask();
+ newTask.SetCameraActor(cameraActor);
+ newTask.SetSourceActor(rootActor);
+ newTask.SetInputEnabled(false);
+ newTask.SetClearColor(Vector4(0.f, 0.f, 0.f, 0.f));
+ newTask.SetClearEnabled(true);
+ newTask.SetExclusive(true);
+ newTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
+ newTask.SetFrameBuffer(frameBuffer);
+
+ application.SendNotification();
+
+ std::vector<Rect<int>> damagedRects;
+ Rect<int> clippingRect;
+
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ // Full update if there is off-screen rendering
+ clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ // Remove framebuffer
+ newTask.SetFrameBuffer(FrameBuffer());
+
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ // Full update
+ clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Set invalid viewport of the render task
+ newTask.SetViewportSize(Vector2(-100.0f, -100.0f));
+
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ // Full update because the camera orientation is changed
+ clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ newTask.SetViewportSize(Vector2(0.0f, 0.0f));
+
+ // Change orientation of offscreen camera
+ cameraActor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Degree(90.0f), Vector3::XAXIS));
+
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ // Full update because the camera orientation is changed
+ clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Change camera target
+ cameraActor.SetTargetPosition(Vector3(10.0f, 10.0f, 0.0f));
+
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ // Full update because the camera is moved
+ clippingRect = Rect<int>(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ END_TEST;
+}
RenderItem::RenderItem()
: mModelMatrix(false),
mModelViewMatrix(false),
- mColor(Vector4::ZERO),
mSize(),
mRenderer(nullptr),
mNode(nullptr),
Matrix mModelMatrix;
Matrix mModelViewMatrix;
- Vector4 mColor;
Vector3 mSize;
Vector4 mUpdateArea; ///< Update area hint is provided for damaged area calculation. (x, y, width, height)
Render::Renderer* mRenderer;
if(instruction.mFrameBuffer)
{
- return; // TODO: reset, we don't deal with render tasks with framebuffers (for now)
+ cleanDamagedRect = true;
+ continue; // TODO: reset, we don't deal with render tasks with framebuffers (for now)
}
const Camera* camera = instruction.GetCamera();
orientationAngle != ANGLE_180 ||
scale != Vector3(1.0f, 1.0f, 1.0f))
{
- return;
+ cleanDamagedRect = true;
+ continue;
}
}
else
{
- return;
+ cleanDamagedRect = true;
+ continue;
}
Rect<int32_t> viewportRect;
viewportRect.Set(instruction.mViewport.x, y, instruction.mViewport.width, instruction.mViewport.height);
if(viewportRect.IsEmpty() || !viewportRect.IsValid())
{
- return; // just skip funny use cases for now, empty viewport means it is set somewhere else
+ cleanDamagedRect = true;
+ continue; // just skip funny use cases for now, empty viewport means it is set somewhere else
}
}
else
else
{
// The item is not in the list for some reason. Add it!
+ dirtyRect.rect = surfaceRect;
itemsDirtyRects.insert(dirtyRectPos, dirtyRect);
+ cleanDamagedRect = true; // And make full update at this frame
}
}
}
* Mark an property owner with the updated flag.
* @param[in] updated The updated flag
*/
- virtual void SetUpdated(bool updated)
+ void SetUpdated(bool updated)
{
mUpdated = updated;
}
// Get the next free RenderItem.
RenderItem& item = renderList.GetNextFreeItem();
- item.mNode = node;
- item.mIsOpaque = isOpaque;
- item.mColor = node->GetColor(updateBufferIndex);
-
- item.mDepthIndex = 0;
- if(!isLayer3d)
- {
- item.mDepthIndex = node->GetDepthIndex();
- }
+ item.mNode = node;
+ item.mIsOpaque = isOpaque;
+ item.mDepthIndex = isLayer3d ? 0 : node->GetDepthIndex();
if(DALI_LIKELY(renderable.mRenderer))
{
PartialRenderingData partialRenderingData;
partialRenderingData.color = node->GetWorldColor(updateBufferIndex);
- partialRenderingData.depthIndex = node->GetDepthIndex();
partialRenderingData.matrix = item.mModelViewMatrix;
partialRenderingData.updatedPositionSize = item.mUpdateArea;
partialRenderingData.size = item.mSize;
#define TRANSFORM_MANAGER_PROPERTY_H_
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
}
/**
- * Initializes the property
- * @param[in] transformManager Pointer to the transform manager
- * @param[in] Id of the transformation the property is associated with
- */
- void Initialize(TransformManagerData* data)
- {
- DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr);
- mTxManagerData = data;
- }
-
- /**
* @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty()
*/
bool IsTransformManagerProperty() const override
{
return true;
}
-
- TransformManagerData* mTxManagerData{nullptr};
};
-template<TransformManagerProperty PropertyT>
+template<TransformManagerProperty PropertyT, size_t TxMgrDataOffset>
struct TransformManagerPropertyVector3 final : public TransformManagerPropertyHandler<Vector3>
{
+ enum
+ {
+ TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+ };
+ TransformManagerData* GetTxManagerData()
+ {
+ return reinterpret_cast<TransformManagerData*>(
+ reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+ const TransformManagerData* GetTxManagerData() const
+ {
+ return reinterpret_cast<const TransformManagerData*>(
+ reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+
TransformManagerPropertyVector3() = default;
Dali::Property::Type GetType() const override
Vector3& Get(BufferIndex bufferIndex) override
{
- return mTxManagerData->Manager()->GetVector3PropertyValue(mTxManagerData->Id(), PropertyT);
+ return GetTxManagerData()->Manager()->GetVector3PropertyValue(GetTxManagerData()->Id(), PropertyT);
}
const Vector3& Get(BufferIndex bufferIndex) const override
{
- return mTxManagerData->Manager()->GetVector3PropertyValue(mTxManagerData->Id(), PropertyT);
+ return GetTxManagerData()->Manager()->GetVector3PropertyValue(GetTxManagerData()->Id(), PropertyT);
}
const Vector3& GetVector3(BufferIndex bufferIndex) const override
const float& GetFloatComponent(uint32_t component) const override
{
- return mTxManagerData->Manager()->GetVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, component);
+ return GetTxManagerData()->Manager()->GetVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, component);
}
void Set(BufferIndex bufferIndex, const Vector3& value) override
{
- mTxManagerData->Manager()->SetVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+ GetTxManagerData()->Manager()->SetVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
}
void SetComponent(BufferIndex bufferIndex, float value, uint32_t component)
{
- mTxManagerData->Manager()->SetVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, value, component);
+ GetTxManagerData()->Manager()->SetVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, value, component);
}
void BakeComponent(BufferIndex bufferIndex, float value, uint32_t component)
{
- mTxManagerData->Manager()->BakeVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, value, component);
+ GetTxManagerData()->Manager()->BakeVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, value, component);
}
void Bake(BufferIndex bufferIndex, const Vector3& value) override
{
- mTxManagerData->Manager()->BakeVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+ GetTxManagerData()->Manager()->BakeVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
}
void BakeX(BufferIndex bufferIndex, float value) override
{
- mTxManagerData->Manager()->BakeXVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+ GetTxManagerData()->Manager()->BakeXVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
}
void BakeY(BufferIndex bufferIndex, float value) override
{
- mTxManagerData->Manager()->BakeYVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+ GetTxManagerData()->Manager()->BakeYVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
}
void BakeZ(BufferIndex bufferIndex, float value) override
{
- mTxManagerData->Manager()->BakeZVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+ GetTxManagerData()->Manager()->BakeZVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
}
void SetFloatComponent(float value, uint32_t component) override
{
- mTxManagerData->Manager()->SetVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, value, component);
+ GetTxManagerData()->Manager()->SetVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, value, component);
}
void BakeFloatComponent(float value, uint32_t component) override
{
- mTxManagerData->Manager()->BakeVector3PropertyComponentValue(mTxManagerData->Id(), PropertyT, value, component);
+ GetTxManagerData()->Manager()->BakeVector3PropertyComponentValue(GetTxManagerData()->Id(), PropertyT, value, component);
}
void BakeRelative(BufferIndex bufferIndex, const Vector3& value) override
{
- mTxManagerData->Manager()->BakeRelativeVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+ GetTxManagerData()->Manager()->BakeRelativeVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
}
void BakeRelativeMultiply(BufferIndex bufferIndex, const Vector3& value) override
{
- mTxManagerData->Manager()->BakeMultiplyVector3PropertyValue(mTxManagerData->Id(), PropertyT, value);
+ GetTxManagerData()->Manager()->BakeMultiplyVector3PropertyValue(GetTxManagerData()->Id(), PropertyT, value);
}
};
+template<size_t TxMgrDataOffset>
class TransformManagerPropertyQuaternion final : public TransformManagerPropertyHandler<Quaternion>
{
public:
+ enum
+ {
+ TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+ };
+ TransformManagerData* GetTxManagerData()
+ {
+ return reinterpret_cast<TransformManagerData*>(
+ reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+ const TransformManagerData* GetTxManagerData() const
+ {
+ return reinterpret_cast<const TransformManagerData*>(
+ reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+
TransformManagerPropertyQuaternion() = default;
Dali::Property::Type GetType() const override
Quaternion& Get(BufferIndex bufferIndex) override
{
- return mTxManagerData->Manager()->GetQuaternionPropertyValue(mTxManagerData->Id());
+ return GetTxManagerData()->Manager()->GetQuaternionPropertyValue(GetTxManagerData()->Id());
}
const Quaternion& Get(BufferIndex bufferIndex) const override
{
- return mTxManagerData->Manager()->GetQuaternionPropertyValue(mTxManagerData->Id());
+ return GetTxManagerData()->Manager()->GetQuaternionPropertyValue(GetTxManagerData()->Id());
}
void Set(BufferIndex bufferIndex, const Quaternion& value) override
{
- return mTxManagerData->Manager()->SetQuaternionPropertyValue(mTxManagerData->Id(), value);
+ return GetTxManagerData()->Manager()->SetQuaternionPropertyValue(GetTxManagerData()->Id(), value);
}
void Bake(BufferIndex bufferIndex, const Quaternion& value) override
{
- return mTxManagerData->Manager()->BakeQuaternionPropertyValue(mTxManagerData->Id(), value);
+ return GetTxManagerData()->Manager()->BakeQuaternionPropertyValue(GetTxManagerData()->Id(), value);
}
void BakeRelative(BufferIndex bufferIndex, const Quaternion& value) override
{
- return mTxManagerData->Manager()->BakeRelativeQuaternionPropertyValue(mTxManagerData->Id(), value);
+ return GetTxManagerData()->Manager()->BakeRelativeQuaternionPropertyValue(GetTxManagerData()->Id(), value);
}
const Quaternion& GetQuaternion(BufferIndex bufferIndex) const override
/**
* A Vector3 property used as input.
*/
+template<size_t TxMgrDataOffset>
class TransformManagerVector3Input : public PropertyInputImpl
{
public:
+ enum
+ {
+ TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+ };
+ TransformManagerData* GetTxManagerData()
+ {
+ return reinterpret_cast<TransformManagerData*>(
+ reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+ const TransformManagerData* GetTxManagerData() const
+ {
+ return reinterpret_cast<const TransformManagerData*>(
+ reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+
/**
* Create an TransformManagerVector3Input
*/
*/
void ComputeTransformComponent() const
{
- if(mTxManagerData)
+ auto transformManagerData = GetTxManagerData();
+ auto id = transformManagerData->Id();
+ if(id != INVALID_TRANSFORM_ID)
{
- const Matrix& worldMatrix = mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
-
+ const Matrix& worldMatrix = transformManagerData->Manager()->GetWorldMatrix(id);
if(mProperty == TRANSFORM_PROPERTY_WORLD_POSITION)
{
mValue = worldMatrix.GetTranslation3();
}
/**
- * Initializes the property
- * @param[in] transformManager Pointer to the transform manager
- * @param[in] Id of the transformation the property is associated with
- */
- void Initialize(TransformManagerData* data)
- {
- DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr);
- mTxManagerData = data;
- }
-
- /**
* @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty()
*/
bool IsTransformManagerProperty() const override
}
private:
- // Undefined
- TransformManagerVector3Input(const TransformManagerVector3Input& property);
-
- // Undefined
- TransformManagerVector3Input& operator=(const TransformManagerVector3Input& rhs);
+ TransformManagerVector3Input(const TransformManagerVector3Input& property) = delete;
+ TransformManagerVector3Input& operator=(const TransformManagerVector3Input& rhs) = delete;
public:
- TransformManagerData* mTxManagerData{nullptr};
TransformManagerProperty mProperty;
mutable Vector3 mValue;
};
/**
* A Quaternion property used as input.
*/
+template<size_t TxMgrDataOffset>
class TransformManagerQuaternionInput final : public PropertyInputImpl
{
public:
+ enum
+ {
+ TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+ };
+ TransformManagerData* GetTxManagerData()
+ {
+ return reinterpret_cast<TransformManagerData*>(
+ reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+ const TransformManagerData* GetTxManagerData() const
+ {
+ return reinterpret_cast<const TransformManagerData*>(
+ reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+
/**
* Constructor
*/
*/
void ComputeTransformComponent() const
{
- if(mTxManagerData)
+ auto transformManagerData = GetTxManagerData();
+ auto id = transformManagerData->Id();
+ if(id != INVALID_TRANSFORM_ID)
{
- const Matrix& worldMatrix = mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
+ const Matrix& worldMatrix = transformManagerData->Manager()->GetWorldMatrix(id);
Vector3 position, scale;
worldMatrix.GetTransformComponents(position, mValue, scale);
}
}
/**
- * Initializes the property
- * @param[in] transformManager Pointer to the transform manager
- * @param[in] Id of the transformation the property is associated with
- */
- void Initialize(TransformManagerData* data)
- {
- DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr);
- mTxManagerData = data;
- }
-
- /**
* @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty()
*/
bool IsTransformManagerProperty() const override
}
private:
- // Undefined
- TransformManagerQuaternionInput(const TransformManagerQuaternionInput& property);
-
- // Undefined
- TransformManagerQuaternionInput& operator=(const TransformManagerQuaternionInput& rhs);
+ TransformManagerQuaternionInput(const TransformManagerQuaternionInput& property) = delete;
+ TransformManagerQuaternionInput& operator=(const TransformManagerQuaternionInput& rhs) = delete;
public:
- TransformManagerData* mTxManagerData{nullptr};
- mutable Quaternion mValue;
+ mutable Quaternion mValue;
};
/**
* A Matrix property used as input.
*/
+template<size_t TxMgrDataOffset>
class TransformManagerMatrixInput final : public PropertyInputImpl
{
public:
+ enum
+ {
+ TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset
+ };
+ TransformManagerData* GetTxManagerData()
+ {
+ return reinterpret_cast<TransformManagerData*>(
+ reinterpret_cast<uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+ const TransformManagerData* GetTxManagerData() const
+ {
+ return reinterpret_cast<const TransformManagerData*>(
+ reinterpret_cast<const uint8_t*>(this) - TRANSFORM_MANAGER_DATA_OFFSET);
+ }
+
/**
* Constructor
*/
*/
const Matrix& GetMatrix(BufferIndex bufferIndex) const override
{
- if(mTxManagerData)
+ auto transformManagerData = GetTxManagerData();
+ auto id = transformManagerData->Id();
+ if(id != INVALID_TRANSFORM_ID)
{
- return mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
+ return transformManagerData->Manager()->GetWorldMatrix(id);
}
-
return Matrix::IDENTITY;
}
*/
const Matrix& GetConstraintInputMatrix(BufferIndex bufferIndex) const override
{
- if(mTxManagerData)
+ auto transformManagerData = GetTxManagerData();
+ auto id = transformManagerData->Id();
+ if(id != INVALID_TRANSFORM_ID)
{
- return mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
+ return transformManagerData->Manager()->GetWorldMatrix(id);
}
-
return Matrix::IDENTITY;
}
*/
Matrix& Get(BufferIndex bufferIndex)
{
- DALI_ASSERT_ALWAYS(mTxManagerData != nullptr);
- return mTxManagerData->Manager()->GetWorldMatrix(mTxManagerData->Id());
+ auto transformManagerData = GetTxManagerData();
+ auto id = transformManagerData->Id();
+ DALI_ASSERT_ALWAYS(id != INVALID_TRANSFORM_ID);
+ return transformManagerData->Manager()->GetWorldMatrix(id);
}
/**
return GetMatrix(bufferIndex);
}
- void Initialize(TransformManagerData* data)
- {
- DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr);
- mTxManagerData = data;
- }
-
/**
* @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty()
*/
}
private:
- // Undefined
- TransformManagerMatrixInput(const TransformManagerMatrixInput& property);
-
- // Undefined
- TransformManagerMatrixInput& operator=(const TransformManagerMatrixInput& rhs);
-
-public:
- TransformManagerData* mTxManagerData{nullptr};
+ TransformManagerMatrixInput(const TransformManagerMatrixInput& property) = delete;
+ TransformManagerMatrixInput& operator=(const TransformManagerMatrixInput& rhs) = delete;
};
-} //namespace SceneGraph
-} //namespace Internal
-} //namespace Dali
+} // namespace SceneGraph
+} // namespace Internal
+} // namespace Dali
#endif // TRANSFORM_MANAGER_PROPERTY_H_
--- /dev/null
+#ifndef DALI_INTERNAL_SCENEGRAPH_NODE_HELPER_H
+#define DALI_INTERNAL_SCENEGRAPH_NODE_HELPER_H
+
+/*
+ * Copyright (c) 2022 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Defines the given value, and adds an enumeration that contains it's
+ * size. The enumeration can be used by the wrapper templated types
+ * below during structure definition. ("offsetof" requires the
+ * structure to be completely defined before use, so cannot be
+ * utilized here).
+ */
+#define BASE(_TYPE, _X) \
+ _TYPE _X; \
+ enum \
+ { \
+ OFFSET_##_X = sizeof(_TYPE) \
+ };
+
+/*
+ * Create a property template instance, passing in the previously
+ * stored element, which utilizes that element's OFFSET enumeration to
+ * compute the offset of the BASE element.
+ *
+ * It is expected that _TEMPLATE is a TransformManagerPropertyVector3
+ * which takes a TransformManagerProperty enumeration and an offset
+ * to the BASE TransformManagerData.
+ *
+ * It is assumed that successive elements are aligned, and that no padding
+ * is inserted by the compiler.
+ */
+#define PROPERTY_WRAPPER(_BASE_ELEMENT, _TEMPLATE, _PROPERTY, _ELEMENT) \
+ using _TEMPLATE##_PROPERTY = _TEMPLATE<_PROPERTY, OFFSET_##_BASE_ELEMENT>; \
+ _TEMPLATE##_PROPERTY _ELEMENT; \
+ enum \
+ { \
+ OFFSET_##_ELEMENT = sizeof(_TEMPLATE##_PROPERTY) + OFFSET_##_BASE_ELEMENT \
+ };
+
+/*
+ * Create a template instance, passing in the previously stored
+ * element, utilizing that element's OFFSET enumeration to compute the offset
+ * of the BASE element.
+ *
+ * It is expected that _TEMPLATE is a TransformManagerPropertyNNNN template
+ * which takes an offset to the BASE TransformManagerData.
+ *
+ * It is assumed that successive elements are aligned, and that no padding
+ * is inserted by the compiler.
+ */
+#define TEMPLATE_WRAPPER(_BASE_ELEMENT, _TEMPLATE, _ELEMENT) \
+ using _TEMPLATE##_ELEMENT = _TEMPLATE<OFFSET_##_BASE_ELEMENT>; \
+ _TEMPLATE##_ELEMENT _ELEMENT; \
+ enum \
+ { \
+ OFFSET_##_ELEMENT = sizeof(_TEMPLATE##_ELEMENT) + OFFSET_##_BASE_ELEMENT \
+ };
+
+#endif // DALI_INTERNAL_SCENEGRAPH_NODE_HELPER_H
namespace
{
-//Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies
-// or DALI library is unloaded
+// Memory pool used to allocate new nodes. Memory used by this pool will be released when process dies
+// or DALI library is unloaded
Dali::Internal::MemoryPoolObjectAllocator<Dali::Internal::SceneGraph::Node> gNodeMemoryPool;
#ifdef DEBUG_ENABLED
// keep track of nodes alive, to ensure we have 0 when the process exits or DALi library is unloaded
}
Node::Node()
-: mOrientation(), // Initialized to identity by default
- mVisible(true),
- mCulled(false),
- mColor(Color::WHITE),
- mUpdateAreaHint(Vector4::ZERO),
+: mOrientation(), // Initialized to identity by default
mWorldPosition(TRANSFORM_PROPERTY_WORLD_POSITION, Vector3(0.0f, 0.0f, 0.0f)), // Zero initialized by default
mWorldScale(TRANSFORM_PROPERTY_WORLD_SCALE, Vector3(1.0f, 1.0f, 1.0f)),
mWorldOrientation(), // Initialized to identity by default
mWorldMatrix(),
+ mVisible(true),
+ mCulled(false),
+ mColor(Color::WHITE),
mWorldColor(Color::WHITE),
+ mUpdateAreaHint(Vector4::ZERO),
mClippingSortModifier(0u),
mId(++mNodeCounter),
mParent(nullptr),
void Node::CreateTransform(SceneGraph::TransformManager* transformManager)
{
- //Create a new transform
+ // Create a new transform
mTransformManagerData.mManager = transformManager;
TransformId createdTransformId = transformManager->CreateTransform();
- //Initialize all the animatable properties
- mPosition.Initialize(&mTransformManagerData);
- mScale.Initialize(&mTransformManagerData);
- mOrientation.Initialize(&mTransformManagerData);
- mSize.Initialize(&mTransformManagerData);
- mParentOrigin.Initialize(&mTransformManagerData);
- mAnchorPoint.Initialize(&mTransformManagerData);
-
- //Initialize all the input properties
- mWorldPosition.Initialize(&mTransformManagerData);
- mWorldScale.Initialize(&mTransformManagerData);
- mWorldOrientation.Initialize(&mTransformManagerData);
- mWorldMatrix.Initialize(&mTransformManagerData);
-
- //Set whether the position should use the anchor point
+ // Set whether the position should use the anchor point
transformManager->SetPositionUsesAnchorPoint(createdTransformId, mPositionUsesAnchorPoint);
- //Set TransformId after initialize done.
+ // Set TransformId after initialize done.
mTransformManagerData.mId = createdTransformId;
}
#include <dali/internal/update/manager/transform-manager-property.h>
#include <dali/internal/update/manager/transform-manager.h>
#include <dali/internal/update/nodes/node-declarations.h>
+#include <dali/internal/update/nodes/node-helper.h>
#include <dali/internal/update/nodes/partial-rendering-data.h>
#include <dali/internal/update/rendering/scene-graph-renderer.h>
#include <dali/public-api/actors/actor-enumerations.h>
if(depthIndex != mDepthIndex)
{
SetDirtyFlag(NodePropertyFlags::DEPTH_INDEX);
+ SetUpdated(true);
mDepthIndex = depthIndex;
}
}
void RecursiveDisconnectFromSceneGraph(BufferIndex updateBufferIndex);
public: // Default properties
- using TransformManagerParentsOrigin = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_PARENT_ORIGIN>;
- using TransformManagerAnchorPoint = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_ANCHOR_POINT>;
- using TransformManagerSize = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_SIZE>;
- using TransformManagerPosition = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_POSITION>;
- using TransformManagerScale = TransformManagerPropertyVector3<TRANSFORM_PROPERTY_SCALE>;
-
- TransformManagerData mTransformManagerData;
- TransformManagerParentsOrigin mParentOrigin; ///< Local transform; the position is relative to this. Sets the Transform flag dirty when changed
- TransformManagerAnchorPoint mAnchorPoint; ///< Local transform; local center of rotation. Sets the Transform flag dirty when changed
- TransformManagerSize mSize; ///< Size is provided for layouting
- TransformManagerPosition mPosition; ///< Local transform; distance between parent-origin & anchor-point
- TransformManagerScale mScale; ///< Local transform; scale relative to parent node
- TransformManagerPropertyQuaternion mOrientation; ///< Local transform; rotation relative to parent node
+ // Define a base offset for the following wrappers. The wrapper macros calculate offsets from the previous
+ // element such that each wrapper type generates a compile time offset to the transform manager data.
+ BASE(TransformManagerData, mTransformManagerData);
+ PROPERTY_WRAPPER(mTransformManagerData, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_PARENT_ORIGIN,
+ mParentOrigin); // Local transform; the position is relative to this. Sets the Transform flag dirty when changed
+
+ PROPERTY_WRAPPER(mParentOrigin, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_ANCHOR_POINT,
+ mAnchorPoint); // Local transform; local center of rotation. Sets the Transform flag dirty when changed
+
+ PROPERTY_WRAPPER(mAnchorPoint, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_SIZE,
+ mSize); // Size is provided for layouting
+
+ PROPERTY_WRAPPER(mSize, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_POSITION,
+ mPosition); // Local transform; distance between parent-origin & anchor-point
+ PROPERTY_WRAPPER(mPosition, TransformManagerPropertyVector3, TRANSFORM_PROPERTY_SCALE,
+ mScale); // Local transform; scale relative to parent node
+
+ TEMPLATE_WRAPPER(mScale, TransformManagerPropertyQuaternion,
+ mOrientation); // Local transform; rotation relative to parent node
+
+ // Inherited properties; read-only from public API
+ TEMPLATE_WRAPPER(mOrientation, TransformManagerVector3Input, mWorldPosition); // Full inherited position
+ TEMPLATE_WRAPPER(mWorldPosition, TransformManagerVector3Input, mWorldScale); // Full inherited scale
+ TEMPLATE_WRAPPER(mWorldScale, TransformManagerQuaternionInput, mWorldOrientation); // Full inherited orientation
+ TEMPLATE_WRAPPER(mWorldOrientation, TransformManagerMatrixInput, mWorldMatrix); // Full inherited world matrix
AnimatableProperty<bool> mVisible; ///< Visibility can be inherited from the Node hierachy
AnimatableProperty<bool> mCulled; ///< True if the node is culled. This is not animatable. It is just double-buffered.
AnimatableProperty<Vector4> mColor; ///< Color can be inherited from the Node hierarchy
+ InheritedColor mWorldColor; ///< Full inherited color
AnimatableProperty<Vector4> mUpdateAreaHint; ///< Update area hint is provided for damaged area calculation. (x, y, width, height)
///< This is not animatable. It is just double-buffered. (Because all these bloody properties are).
- // Inherited properties; read-only from public API
-
- TransformManagerVector3Input mWorldPosition; ///< Full inherited position
- TransformManagerVector3Input mWorldScale;
- TransformManagerQuaternionInput mWorldOrientation; ///< Full inherited orientation
- TransformManagerMatrixInput mWorldMatrix; ///< Full inherited world matrix
- InheritedColor mWorldColor; ///< Full inherited color
-
uint64_t mUniformsHash{0u}; ///< Hash of uniform map property values
uint32_t mClippingSortModifier; ///< Contains bit-packed clipping information for quick access when sorting
const uint32_t mId; ///< The Unique ID of the node.
uint32_t mClippingDepth; ///< The number of stencil clipping nodes deep this node is
uint32_t mScissorDepth; ///< The number of scissor clipping nodes deep this node is
-
- uint32_t mDepthIndex; ///< Depth index of the node
+ uint32_t mDepthIndex; ///< Depth index of the node
// flags, compressed to bitfield
NodePropertyFlags mDirtyFlags; ///< Dirty flags for each of the Node properties
Vector4 color{}; /// Color
Vector4 updatedPositionSize{}; /// Updated position/size (x, y, width, height)
Vector3 size{}; /// Size
- uint32_t depthIndex{0u}; /// Depth index
- uint32_t hash; /// Last frame's hash
+ uint32_t hash{0u}; /// Last frame's hash
bool mVisible{true}; /// Visible state (Not hashed)
bool mRendered{false}; /// Rendering state (Not hashed)
AddToHash(hash, &color, sizeof(decltype(color)));
AddToHash(hash, &updatedPositionSize, sizeof(decltype(updatedPositionSize)));
AddToHash(hash, &size, sizeof(decltype(size)));
- AddToHash(hash, &depthIndex, sizeof(decltype(depthIndex)));
}
/**
color != frameCache.color ||
updatedPositionSize != frameCache.updatedPositionSize ||
size != frameCache.size ||
- depthIndex != frameCache.depthIndex ||
!mRendered; // If everything is the same, check if we didn't render last frame.
}
color = frameCache.color;
updatedPositionSize = frameCache.updatedPositionSize;
size = frameCache.size;
- depthIndex = frameCache.depthIndex;
hash = frameCache.hash;
mRendered = true;