From: David Steele Date: Mon, 19 Dec 2022 18:55:26 +0000 (+0000) Subject: Merge "Sync UTC harness" into devel/master X-Git-Tag: dali_2.2.7~6 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-core.git;a=commitdiff_plain;h=5de727a5d6b9ef995c93eff4d4e47a086784a332;hp=0b2088fe1ebf5da886f2f902e928dc0524ff9d10 Merge "Sync UTC harness" into devel/master --- diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-TransformManagerProperty.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-TransformManagerProperty.cpp index d00cea6..0b6a440 100644 --- a/automated-tests/src/dali-internal/utc-Dali-Internal-TransformManagerProperty.cpp +++ b/automated-tests/src/dali-internal/utc-Dali-Internal-TransformManagerProperty.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -22,6 +22,13 @@ // Internal headers are allowed here +namespace +{ +#if defined(DEBUG_ENABLED) +Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Verbose, true, "LOG_UTC_TRANSFORM_MANAGER_PROPERTY"); +#endif +} // namespace + void utc_dali_internal_transform_manager_property_startup() { test_return_value = TET_UNDEF; @@ -36,16 +43,48 @@ int UtcTransformManagerPropertyGetFloatComponentN(void) { TestApplication application; - Dali::Internal::SceneGraph::TransformManagerPropertyQuaternion property; + // For coverage + DALI_LOG_TRACE_METHOD(gLogFilter); + + struct S + { + Dali::Internal::SceneGraph::TransformManagerData txMgrData; + Dali::Internal::SceneGraph::TransformManagerPropertyQuaternion 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); } + // For coverage + DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Test End\n"); + + 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 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; } diff --git a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp index 873b7b3..e4c6078 100644 --- a/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp +++ b/automated-tests/src/dali/dali-test-suite-utils/test-application.cpp @@ -117,13 +117,16 @@ void TestApplication::LogMessage(Dali::Integration::Log::DebugPriority level, st { switch(level) { - case Dali::Integration::Log::DebugInfo: + case Dali::Integration::Log::DEBUG: + fprintf(stderr, "DEBUG: %s", message.c_str()); + break; + case Dali::Integration::Log::INFO: fprintf(stderr, "INFO: %s", message.c_str()); break; - case Dali::Integration::Log::DebugWarning: + case Dali::Integration::Log::WARNING: fprintf(stderr, "WARN: %s", message.c_str()); break; - case Dali::Integration::Log::DebugError: + case Dali::Integration::Log::ERROR: fprintf(stderr, "ERROR: %s", message.c_str()); break; default: diff --git a/automated-tests/src/dali/utc-Dali-Actor.cpp b/automated-tests/src/dali/utc-Dali-Actor.cpp index a4264a4..a528eb3 100644 --- a/automated-tests/src/dali/utc-Dali-Actor.cpp +++ b/automated-tests/src/dali/utc-Dali-Actor.cpp @@ -9353,7 +9353,7 @@ int utcDaliActorPartialUpdateChangeVisibility(void) DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); // Aligned by 16 - clippingRect = Rect(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates + clippingRect = Rect(16, 768, 32, 32); // in screen coordinates DALI_TEST_EQUALS>(clippingRect, damagedRects[0], TEST_LOCATION); application.RenderWithPartialUpdate(damagedRects, clippingRect); DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION); @@ -9365,10 +9365,6 @@ int utcDaliActorPartialUpdateChangeVisibility(void) 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); @@ -11666,6 +11662,76 @@ int UtcDaliActorCalculateWorldTransform07(void) END_TEST; } +int UtcDaliActorCalculateWorldTransform08(void) +{ + TestApplication application; + + tet_infoline("Test that actor inheritance of scale produces right transform matrix"); + + Vector3 solutions[] = {Vector3(250, 0, 0), Vector3(0, 250, 0), Vector3(650, 0, 0), Vector3(0, 250, 0), Vector3(650, 0, 0), Vector3(400, 250, 0), Vector3(200, -50, 0), Vector3(500, 200, 0)}; + + struct TestCase + { + bool translation; + bool rotation; + bool scaling; + }; + TestCase testCases[] = { + {false, false, true}, + {false, true, false}, + {true, false, false}, + {false, true, true}, + {true, false, true}, + {true, true, false}, + {false, false, false}, + {true, true, true}, + }; + + Actor rootActor = Actor::New(); + Actor leafActor = Actor::New(); + + rootActor[Actor::Property::POSITION] = Vector3(0.0f, 0.0f, 0.0f); + rootActor[Actor::Property::SCALE] = Vector3(1.0f, 2.0f, 1.0f); + rootActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + rootActor[Actor::Property::SIZE] = Vector2(200, 400); + rootActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::CENTER; + rootActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER; + + leafActor[Actor::Property::POSITION] = Vector3(0.0f, -50.0f, 0.0f); + leafActor[Actor::Property::SCALE] = Vector3(1.0f, 1.0f, 1.0f); + leafActor[Actor::Property::ORIENTATION] = AngleAxis(Degree(90.0f), Vector3::ZAXIS); + leafActor[Actor::Property::SIZE] = Vector2(200, 400); + leafActor[Actor::Property::ANCHOR_POINT] = AnchorPoint::BOTTOM_CENTER; + leafActor[Actor::Property::PARENT_ORIGIN] = ParentOrigin::TOP_CENTER; + leafActor[Actor::Property::POSITION_USES_ANCHOR_POINT] = true; + + application.GetScene().Add(rootActor); + rootActor.Add(leafActor); + + for(uint32_t i = 0; i< 8; ++i) + { + leafActor[Actor::Property::INHERIT_POSITION] = testCases[i].translation; + leafActor[Actor::Property::INHERIT_ORIENTATION] = testCases[i].rotation; + leafActor[Actor::Property::INHERIT_SCALE] = testCases[i].scaling; + + application.SendNotification(); + application.Render(0); + application.SendNotification(); + application.Render(0); + + Matrix m = DevelActor::GetWorldTransform(leafActor); + Matrix actualMatrix = leafActor.GetCurrentProperty(Actor::Property::WORLD_MATRIX); + + Vector3 worldPosition1 = Vector3(m.GetTranslation()); + Vector3 worldPosition2 = Vector3(actualMatrix.GetTranslation()); + + DALI_TEST_EQUALS(solutions[i], worldPosition1, 0.001f, TEST_LOCATION); + DALI_TEST_EQUALS(solutions[i], worldPosition2, 0.001f, TEST_LOCATION); + } + + END_TEST; +} + int UtcDaliActorCalculateWorldColor01(void) { TestApplication application; diff --git a/automated-tests/src/dali/utc-Dali-Core.cpp b/automated-tests/src/dali/utc-Dali-Core.cpp index 67d14a5..ae881b2 100644 --- a/automated-tests/src/dali/utc-Dali-Core.cpp +++ b/automated-tests/src/dali/utc-Dali-Core.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -50,3 +50,14 @@ int UtcDaliCoreGetObjectRegistry(void) DALI_TEST_CHECK(application.GetCore().GetObjectRegistry()); END_TEST; } + +int UtcDaliCoreCheckMemoryPool(void) +{ + TestApplication application; + + // Calling LogMemoryPools should check capacity across the board. + application.GetCore().LogMemoryPools(); + + tet_result(TET_PASS); + END_TEST; +} diff --git a/automated-tests/src/dali/utc-Dali-RenderTask.cpp b/automated-tests/src/dali/utc-Dali-RenderTask.cpp index e3857dc..af93507 100644 --- a/automated-tests/src/dali/utc-Dali-RenderTask.cpp +++ b/automated-tests/src/dali/utc-Dali-RenderTask.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -3668,14 +3668,15 @@ int UtcDaliRenderTaskViewportGuideActor02(void) application.GetScene().SurfaceRotated(static_cast(TestApplication::DEFAULT_SURFACE_HEIGHT), static_cast(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); @@ -3683,3 +3684,135 @@ int UtcDaliRenderTaskViewportGuideActor02(void) 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> damagedRects; + Rect clippingRect; + + application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects); + + // Full update if there is off-screen rendering + clippingRect = Rect(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(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(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(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(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(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(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(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(0, 0, TestApplication::DEFAULT_SURFACE_WIDTH, TestApplication::DEFAULT_SURFACE_HEIGHT); + DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION); + DALI_TEST_EQUALS>(clippingRect, damagedRects[0], TEST_LOCATION); + + application.RenderWithPartialUpdate(damagedRects, clippingRect); + + END_TEST; +} diff --git a/dali/integration-api/core.cpp b/dali/integration-api/core.cpp index 05f6d52..870861b 100644 --- a/dali/integration-api/core.cpp +++ b/dali/integration-api/core.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -145,6 +145,11 @@ ObjectRegistry Core::GetObjectRegistry() const return ObjectRegistry(&mImpl->GetObjectRegistry()); } +void Core::LogMemoryPools() const +{ + mImpl->LogMemoryPools(); +} + Core::Core() : mImpl(nullptr) { diff --git a/dali/integration-api/core.h b/dali/integration-api/core.h index 0a4ce07..0b44348 100644 --- a/dali/integration-api/core.h +++ b/dali/integration-api/core.h @@ -2,7 +2,7 @@ #define DALI_INTEGRATION_CORE_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. @@ -409,6 +409,11 @@ public: */ ObjectRegistry GetObjectRegistry() const; + /** + * Log core's memory pool's capacities + */ + void LogMemoryPools() const; + private: /** * Private constructor; see also Core::New() diff --git a/dali/integration-api/debug.cpp b/dali/integration-api/debug.cpp index ebbc339..858b4d8 100644 --- a/dali/integration-api/debug.cpp +++ b/dali/integration-api/debug.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -166,14 +166,14 @@ void Filter::Log(LogLevel level, const char* format, ...) if(numChars >= 0) // No error { std::string message = ArgListToString(buffer, arg); - LogMessage(DebugInfo, message.c_str()); + LogMessage(INFO, message.c_str()); free(buffer); } } else { std::string message = ArgListToString(format, arg); - LogMessage(DebugInfo, message.c_str()); + LogMessage(INFO, message.c_str()); } va_end(arg); } @@ -189,7 +189,7 @@ TraceObj::TraceObj(Filter* filter, const char* format, ...) mMessage = ArgListToString(format, arg); va_end(arg); - LogMessage(DebugInfo, "Entr%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str()); + LogMessage(INFO, "Entr%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str()); ++mFilter->mNesting; } } @@ -202,7 +202,7 @@ TraceObj::~TraceObj() { --mFilter->mNesting; } - LogMessage(DebugInfo, "Exit%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str()); + LogMessage(INFO, "Exit%-*c %s\n", mFilter->mNesting, ':', mMessage.c_str()); } } diff --git a/dali/integration-api/debug.h b/dali/integration-api/debug.h index 7daa433..8533270 100644 --- a/dali/integration-api/debug.h +++ b/dali/integration-api/debug.h @@ -2,7 +2,7 @@ #define DALI_INTEGRATION_DEBUG_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. @@ -20,11 +20,11 @@ // EXTERNAL INCLUDES #include +#include #include #include #include #include -#include #include #include @@ -79,9 +79,10 @@ namespace Log { enum DebugPriority { - DebugInfo, - DebugWarning, - DebugError + DEBUG, + INFO, + WARNING, + ERROR }; /** @@ -100,7 +101,7 @@ DALI_CORE_API void LogMessage(enum DebugPriority level, const char* format, ...) #define __MODULE__ (std::strrchr(__FILE__, '/') ? std::strrchr(__FILE__, '/') + 1 : __FILE__) #endif #define DALI_LOG_FORMAT_PREFIX "%s: %s(%d) > " -#define DALI_LOG_FORMAT_PREFIX_ARGS __MODULE__,__func__,__LINE__ +#define DALI_LOG_FORMAT_PREFIX_ARGS __MODULE__, __func__, __LINE__ #endif /** @@ -108,11 +109,11 @@ DALI_CORE_API void LogMessage(enum DebugPriority level, const char* format, ...) * @param level debug level * @param format string format */ -#define LogMessageWithFunctionLine(level, format, ...) \ - LogMessage(level, \ - (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \ - DALI_LOG_FORMAT_PREFIX_ARGS, \ - ##__VA_ARGS__) +#define LogMessageWithFunctionLine(level, format, ...) \ + LogMessage(level, \ + (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \ + DALI_LOG_FORMAT_PREFIX_ARGS, \ + ##__VA_ARGS__) /** * typedef for the logging function. @@ -141,38 +142,43 @@ DALI_CORE_API void UninstallLogFunction(); /** * Provides unfiltered logging for global error level messages */ -#define DALI_LOG_ERROR(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DebugError, format, ##__VA_ARGS__) +#define DALI_LOG_ERROR(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::ERROR, format, ##__VA_ARGS__) -#define DALI_LOG_ERROR_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ##__VA_ARGS__) +#define DALI_LOG_ERROR_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::ERROR, format, ##__VA_ARGS__) -#define DALI_LOG_WARNING_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugWarning, format, ##__VA_ARGS__) +#define DALI_LOG_WARNING_NOFN(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::WARNING, format, ##__VA_ARGS__) /** * Provides unfiltered logging for fps monitor */ -#define DALI_LOG_FPS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ##__VA_ARGS__) +#define DALI_LOG_FPS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__) /** * Provides unfiltered logging for update status */ -#define DALI_LOG_UPDATE_STATUS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ##__VA_ARGS__) +#define DALI_LOG_UPDATE_STATUS(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__) /** * Provides unfiltered logging for render information */ -#define DALI_LOG_RENDER_INFO(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugInfo, format, ##__VA_ARGS__) +#define DALI_LOG_RENDER_INFO(format, ...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::INFO, format, ##__VA_ARGS__) /** * Provides unfiltered logging for release */ -#define DALI_LOG_RELEASE_INFO(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DebugInfo, format, ##__VA_ARGS__) +#define DALI_LOG_RELEASE_INFO(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::INFO, format, ##__VA_ARGS__) + +/** + * Provides unfiltered logging for debuf information + */ +#define DALI_LOG_DEBUG_INFO(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DEBUG, format, ##__VA_ARGS__) #ifdef DEBUG_ENABLED /** * Provides unfiltered logging for global warning level messages */ -#define DALI_LOG_WARNING(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::DebugWarning, "%s " format, ASSERT_LOCATION, ##__VA_ARGS__) +#define DALI_LOG_WARNING(format, ...) Dali::Integration::Log::LogMessageWithFunctionLine(Dali::Integration::Log::WARNING, "%s " format, ASSERT_LOCATION, ##__VA_ARGS__) #else // DEBUG_ENABLED @@ -363,13 +369,13 @@ public: #ifdef DEBUG_ENABLED -#define DALI_LOG_INFO(filter, level, format, ...) \ - if(filter && filter->IsEnabledFor(level)) \ - { \ - filter->Log(level, \ - (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \ - DALI_LOG_FORMAT_PREFIX_ARGS, \ - ##__VA_ARGS__); \ +#define DALI_LOG_INFO(filter, level, format, ...) \ + if(filter && filter->IsEnabledFor(level)) \ + { \ + filter->Log(level, \ + (std::string(DALI_LOG_FORMAT_PREFIX) + std::string(format)).c_str(), \ + DALI_LOG_FORMAT_PREFIX_ARGS, \ + ##__VA_ARGS__); \ } #define DALI_LOG_STREAM(filter, level, stream) \ @@ -393,7 +399,7 @@ public: /* * These macros allow the instrumentation of methods. These translate into calls - * to LogMessage(DebugInfo). + * to LogMessage(INFO). */ #ifdef DEBUG_ENABLED diff --git a/dali/internal/common/core-impl.cpp b/dali/internal/common/core-impl.cpp index 9a5c89e..28b8a6c 100644 --- a/dali/internal/common/core-impl.cpp +++ b/dali/internal/common/core-impl.cpp @@ -138,6 +138,10 @@ Core::Core(RenderController& renderController, mUpdateManager->SetShaderSaver(*mShaderFactory); GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions(); + + DALI_LOG_RELEASE_INFO("Node size: %lu\n", sizeof(Dali::Internal::SceneGraph::Node)); + DALI_LOG_RELEASE_INFO("Renderer size: %lu\n", sizeof(Dali::Internal::SceneGraph::Renderer)); + DALI_LOG_RELEASE_INFO("RenderItem size: %lu\n", sizeof(Dali::Internal::SceneGraph::RenderItem)); } Core::~Core() @@ -484,6 +488,47 @@ ObjectRegistry& Core::GetObjectRegistry() const return *(mObjectRegistry.Get()); } +void Core::LogMemoryPools() const +{ + uint32_t animationPoolCapacity = SceneGraph::Animation::GetMemoryPoolCapacity(); + uint32_t renderItemPoolCapacity = SceneGraph::RenderItem::GetMemoryPoolCapacity(); + uint32_t relayoutItemPoolCapacity = mRelayoutController->GetMemoryPoolCapacity(); + uint32_t rendererPoolCapacity = SceneGraph::Renderer::GetMemoryPoolCapacity(); + uint32_t textureSetPoolCapacity = SceneGraph::TextureSet::GetMemoryPoolCapacity(); + uint32_t renderTaskPoolCapacity = SceneGraph::RenderTaskList::GetMemoryPoolCapacity(); + uint32_t nodePoolCapacity = SceneGraph::Node::GetMemoryPoolCapacity(); + + DALI_LOG_RELEASE_INFO( + "\nMemory Pool capacities:\n" + " Animations: %lu\n" + " RenderItems: %lu\n" + " RelayoutItems: %lu\n" + " Renderers: %lu\n" + " TextureSets: %lu\n" + " RenderTasks: %lu\n" + " Nodes: %lu\n", + animationPoolCapacity, + renderItemPoolCapacity, + relayoutItemPoolCapacity, + rendererPoolCapacity, + textureSetPoolCapacity, + renderTaskPoolCapacity, + nodePoolCapacity); + + uint32_t updateQCapacity = mUpdateManager->GetUpdateMessageQueueCapacity(); + uint32_t renderQCapacity = mUpdateManager->GetRenderMessageQueueCapacity(); + + DALI_LOG_RELEASE_INFO( + "\nMessage Queue capacities:\n" + " UpdateQueue: %lu\n" + " RenderQueue: %lu\n", + updateQCapacity, + renderQCapacity); + + size_t renderInstructionCapacity = mUpdateManager->GetRenderInstructionCapacity(); + DALI_LOG_RELEASE_INFO("\nRenderInstruction capacity: %lu\n", renderInstructionCapacity); +} + EventThreadServices& Core::GetEventThreadServices() { return *this; diff --git a/dali/internal/common/core-impl.h b/dali/internal/common/core-impl.h index 8d218aa..5c21a44 100644 --- a/dali/internal/common/core-impl.h +++ b/dali/internal/common/core-impl.h @@ -198,6 +198,11 @@ public: */ ObjectRegistry& GetObjectRegistry() const; + /** + * Log the capacity of DALi memory pools + */ + void LogMemoryPools() const; + public: // Implementation of EventThreadServices /** * @copydoc EventThreadServices::RegisterObject diff --git a/dali/internal/common/fixed-size-memory-pool.cpp b/dali/internal/common/fixed-size-memory-pool.cpp index 452437c..f225a8d 100644 --- a/dali/internal/common/fixed-size-memory-pool.cpp +++ b/dali/internal/common/fixed-size-memory-pool.cpp @@ -231,6 +231,22 @@ void FixedSizeMemoryPool::FreeThreadSafe(void* memory) } } +uint32_t FixedSizeMemoryPool::GetCapacity() const +{ + // Ignores deleted objects list, just returns currently allocated size + uint32_t totalAllocation = 0; +#ifdef DEBUG_ENABLED + Mutex::ScopedLock lock(mImpl->mMutex); + Impl::Block* block = &mImpl->mMemoryBlocks; + while(block) + { + totalAllocation += block->mBlockSize; + block = block->nextBlock; + } +#endif + return totalAllocation; +} + } // namespace Internal } // namespace Dali diff --git a/dali/internal/common/fixed-size-memory-pool.h b/dali/internal/common/fixed-size-memory-pool.h index ff4138d..6e05ffe 100644 --- a/dali/internal/common/fixed-size-memory-pool.h +++ b/dali/internal/common/fixed-size-memory-pool.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_FIXED_SIZE_MEMORY_POOL_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. @@ -97,6 +97,13 @@ public: */ void FreeThreadSafe(void* memory); + /** + * Get the current capacity of the memory pool + * + * @note in release mode, this returns 0, as the block size isn't defined. + */ + uint32_t GetCapacity() const; + private: // Undefined FixedSizeMemoryPool(const FixedSizeMemoryPool& fixedSizeMemoryPool); diff --git a/dali/internal/common/memory-pool-object-allocator.h b/dali/internal/common/memory-pool-object-allocator.h index 7b6ab96..554ce9a 100644 --- a/dali/internal/common/memory-pool-object-allocator.h +++ b/dali/internal/common/memory-pool-object-allocator.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_MEMORY_POOL_OBJECT_ALLOCATOR_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. @@ -154,6 +154,14 @@ public: mPool = new FixedSizeMemoryPool(TypeSizeWithAlignment::size); } + /** + * @brief Get the capacity of the memory pool + */ + uint32_t GetCapacity() const + { + return mPool->GetCapacity(); + } + private: // Undefined MemoryPoolObjectAllocator(const MemoryPoolObjectAllocator& memoryPoolObjectAllocator); diff --git a/dali/internal/event/actors/actor-coords.cpp b/dali/internal/event/actors/actor-coords.cpp index d1a70db..9f1fefe 100644 --- a/dali/internal/event/actors/actor-coords.cpp +++ b/dali/internal/event/actors/actor-coords.cpp @@ -533,39 +533,60 @@ Matrix CalculateActorWorldTransform(const Actor& actor) } else { - Vector3 parentPosition, parentScale; - Quaternion parentOrientation; - worldMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale); - + // Get Parent information. + Vector3 parentPosition, parentScale; + Quaternion parentOrientation; + const Matrix& parentMatrix = worldMatrix; + parentMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale); + + // Compute intermediate Local information + centerPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, localScale, localOrientation); + Vector3 intermediateLocalPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize; + Matrix intermediateLocalMatrix; + intermediateLocalMatrix.SetTransformComponents(localScale, localOrientation, intermediateLocalPosition); + + // Compute intermediate world information + Matrix intermediateWorldMatrix; + MatrixUtils::Multiply(intermediateWorldMatrix, intermediateLocalMatrix, parentMatrix); + + Vector3 intermediateWorldPosition, intermediateWorldScale; + Quaternion intermediateWorldOrientation; + intermediateWorldMatrix.GetTransformComponents(intermediateWorldPosition, intermediateWorldOrientation, intermediateWorldScale); + + // Compute final world information + Vector3 finalWorldPosition = intermediateWorldPosition; + Vector3 finalWorldScale = intermediateWorldScale; + Quaternion finalWorldOrientation = intermediateWorldOrientation; + // worldScale includes the influence of local scale, local rotation, and parent scale. + // So, for the final world matrix, if this node inherits its parent scale, use worldScale. + // If not, use local scale for the final world matrix. if((inheritanceModeList[i] & INHERIT_SCALE) == 0) { - //Don't inherit scale - localScale /= parentScale; + finalWorldScale = localScale; } + // For the final world matrix, if this node inherits its parent orientation, use worldOrientation. + // If not, use local orientation for the final world matrix. if((inheritanceModeList[i] & INHERIT_ORIENTATION) == 0) { - //Don't inherit orientation - parentOrientation.Invert(); - localOrientation = parentOrientation * localOrientation; + finalWorldOrientation = localOrientation; } - if((inheritanceModeList[i] & INHERIT_POSITION) == 0) - { - localMatrix.SetTransformComponents(localScale, localOrientation, Vector3::ZERO); - Matrix tempMatrix; - MatrixUtils::Multiply(tempMatrix, localMatrix, worldMatrix); - worldMatrix = tempMatrix; - worldMatrix.SetTranslation(actorPosition + centerPosition); - } - else + // The final world position of this node is computed as a sum of + // parent origin position in world space and relative position of center from parent origin. + // If this node doesn't inherit its parent position, simply use the relative position as a final world position. + Vector3 localCenterPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, finalWorldScale, finalWorldOrientation); + finalWorldPosition = actorPosition * finalWorldScale; + finalWorldPosition *= finalWorldOrientation; + finalWorldPosition += localCenterPosition; + if((inheritanceModeList[i] & INHERIT_POSITION) != 0) { - localPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize; - localMatrix.SetTransformComponents(localScale, localOrientation, localPosition); - Matrix tempMatrix; - MatrixUtils::Multiply(tempMatrix, localMatrix, worldMatrix); - worldMatrix = tempMatrix; + Vector4 parentOriginPosition((parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize); + parentOriginPosition.w = 1.0f; + finalWorldPosition += Vector3(parentMatrix * parentOriginPosition); } + + worldMatrix.SetTransformComponents(finalWorldScale, finalWorldOrientation, finalWorldPosition); } } else diff --git a/dali/internal/event/common/thread-local-storage.cpp b/dali/internal/event/common/thread-local-storage.cpp index aca21f4..6ebfc68 100644 --- a/dali/internal/event/common/thread-local-storage.cpp +++ b/dali/internal/event/common/thread-local-storage.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -34,7 +34,7 @@ Debug::Filter* gSingletonServiceLogFilter = Debug::Filter::New(Debug::NoLogging, if(gSingletonServiceLogFilter && gSingletonServiceLogFilter->IsEnabledFor(level)) \ { \ std::string string(message); \ - Dali::TizenPlatform::LogMessage(Debug::DebugInfo, string); \ + Dali::TizenPlatform::LogMessage(Debug::INFO, string); \ } #define DALI_LOG_SINGLETON_SERVICE(level, format, ...) DALI_LOG_INFO(gSingletonServiceLogFilter, level, format, ##__VA_ARGS__) diff --git a/dali/internal/event/images/pixel-data-impl.cpp b/dali/internal/event/images/pixel-data-impl.cpp index 622f867..745896a 100644 --- a/dali/internal/event/images/pixel-data-impl.cpp +++ b/dali/internal/event/images/pixel-data-impl.cpp @@ -18,10 +18,21 @@ // CLASS HEADER #include +#include + +#if defined(DEBUG_ENABLED) +Debug::Filter* gPixelDataLogFilter = Debug::Filter::New(Debug::NoLogging, false, "DALI_LOG_PIXEL_DATA_SIZE"); +#endif + namespace Dali { namespace Internal { +#if defined(DEBUG_ENABLED) +// Only track data allocation if debug is enabled +uint32_t PixelData::gPixelDataAllocationTotal{0}; +#endif + PixelData::PixelData(uint8_t* buffer, uint32_t bufferSize, uint32_t width, @@ -37,6 +48,10 @@ PixelData::PixelData(uint8_t* buffer, mPixelFormat(pixelFormat), mReleaseFunction(releaseFunction) { + DALI_LOG_INFO(gPixelDataLogFilter, Debug::Concise, "Allocated PixelData of size %u\n", bufferSize); +#if defined(DEBUG_ENABLED) + gPixelDataAllocationTotal += mBufferSize; +#endif } PixelData::~PixelData() @@ -51,6 +66,9 @@ PixelData::~PixelData() { delete[] mBuffer; } +#if defined(DEBUG_ENABLED) + gPixelDataAllocationTotal -= mBufferSize; +#endif } } diff --git a/dali/internal/event/images/pixel-data-impl.h b/dali/internal/event/images/pixel-data-impl.h index 5667496..746d347 100644 --- a/dali/internal/event/images/pixel-data-impl.h +++ b/dali/internal/event/images/pixel-data-impl.h @@ -20,6 +20,7 @@ // INTERNAL INCLUDES #include +#include #include #include @@ -121,6 +122,18 @@ public: */ uint32_t GetStride() const; + /** + * Class method to get the total currently allocated size of pixel buffers + */ + static uint32_t GetTotalAllocatedSize() + { +#if defined(DEBUG_ENABLED) + return gPixelDataAllocationTotal; +#else + return 0; +#endif + } + private: /* * Undefined copy constructor. @@ -140,6 +153,10 @@ private: uint32_t mStride; ///< Buffer stride in pixels, 0 means the buffer is tightly packed Pixel::Format mPixelFormat; ///< Pixel format Dali::PixelData::ReleaseFunction mReleaseFunction; ///< Function for releasing memory + +#if defined(DEBUG_ENABLED) + static uint32_t gPixelDataAllocationTotal; +#endif }; } // namespace Internal diff --git a/dali/internal/event/size-negotiation/relayout-controller-impl.cpp b/dali/internal/event/size-negotiation/relayout-controller-impl.cpp index 1589d94..dd0f98d 100644 --- a/dali/internal/event/size-negotiation/relayout-controller-impl.cpp +++ b/dali/internal/event/size-negotiation/relayout-controller-impl.cpp @@ -500,6 +500,11 @@ void RelayoutController::FindAndZero(const RawActorList& list, const Dali::RefOb } } +uint32_t RelayoutController::GetMemoryPoolCapacity() +{ + return mRelayoutInfoAllocator.GetCapacity(); +} + } // namespace Internal } // namespace Dali diff --git a/dali/internal/event/size-negotiation/relayout-controller-impl.h b/dali/internal/event/size-negotiation/relayout-controller-impl.h index 85cb31a..29809ea 100644 --- a/dali/internal/event/size-negotiation/relayout-controller-impl.h +++ b/dali/internal/event/size-negotiation/relayout-controller-impl.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_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. @@ -124,6 +124,12 @@ public: */ void SetProcessingCoreEvents(bool processingEvents); + /** + * Get the capacity of the memory pool containing relayout info + * (It Should be regularly purged!) + */ + uint32_t GetMemoryPoolCapacity(); + public: // CALLBACKS /** * @brief Callback raised after the application creates the scene diff --git a/dali/internal/render/common/render-debug.cpp b/dali/internal/render/common/render-debug.cpp index d4080e5..aa463ac 100644 --- a/dali/internal/render/common/render-debug.cpp +++ b/dali/internal/render/common/render-debug.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -99,7 +99,7 @@ void PrintRendererCount(unsigned int frameCount, unsigned int rendererCount) { if(frameCount % 120 == 30) // Print every 2 seconds reg { - Debug::LogMessage(Debug::DebugInfo, "Renderer Total # renderers: %u\n", rendererCount); + Debug::LogMessage(Debug::INFO, "Renderer Total # renderers: %u\n", rendererCount); } } diff --git a/dali/internal/render/common/render-instruction-container.cpp b/dali/internal/render/common/render-instruction-container.cpp index 6ae3c5b..37900ed 100644 --- a/dali/internal/render/common/render-instruction-container.cpp +++ b/dali/internal/render/common/render-instruction-container.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -62,6 +62,17 @@ void RenderInstructionContainer::PushBack(BufferIndex bufferIndex, RenderInstruc mInstructions.push_back(renderInstruction); } +std::size_t RenderInstructionContainer::GetCapacity() const +{ + std::size_t capacity{0}; + for(auto& el : mInstructions) + { + capacity += el->GetCapacity(); + } + capacity += mInstructions.size() * sizeof(RenderInstruction*); + return capacity; +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/render/common/render-instruction-container.h b/dali/internal/render/common/render-instruction-container.h index 9417afe..f2292c7 100644 --- a/dali/internal/render/common/render-instruction-container.h +++ b/dali/internal/render/common/render-instruction-container.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_CONTAINER_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. @@ -22,6 +22,7 @@ #include #include #include +#include namespace Dali { @@ -75,6 +76,11 @@ public: */ void PushBack(BufferIndex index, RenderInstruction* renderInstruction); + /** + * Get the total memory used by all the render instructions + */ + std::size_t GetCapacity() const; + private: std::vector mInstructions; }; diff --git a/dali/internal/render/common/render-instruction.cpp b/dali/internal/render/common/render-instruction.cpp index acde57b..f42041f 100644 --- a/dali/internal/render/common/render-instruction.cpp +++ b/dali/internal/render/common/render-instruction.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -125,6 +125,20 @@ void RenderInstruction::Reset(Camera* camera, } } +std::size_t RenderInstruction::GetCapacity() +{ + std::size_t capacity{0u}; + RenderListContainer::Iterator iter = mRenderLists.Begin(); + RenderListContainer::ConstIterator end = mRenderLists.End(); + for(; iter != end; ++iter) + { + capacity += ((*iter)->GetCachedItemCount() * (sizeof(RenderItem) + sizeof(RenderItem*))); + capacity += sizeof(RenderList); + } + capacity += sizeof(RenderInstruction); + return capacity; +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/render/common/render-instruction.h b/dali/internal/render/common/render-instruction.h index 52e7e68..f8d24aa 100644 --- a/dali/internal/render/common/render-instruction.h +++ b/dali/internal/render/common/render-instruction.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_RENDER_INSTRUCTION_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. @@ -129,6 +129,11 @@ public: return mCamera; } + /** + * Get the total memory usage of the render instruction + */ + std::size_t GetCapacity(); + public: // Data Render::RenderTracker* mRenderTracker; ///< Pointer to an optional tracker object (not owned) diff --git a/dali/internal/render/common/render-item.cpp b/dali/internal/render/common/render-item.cpp index 9b3ba8c..1aafa37 100644 --- a/dali/internal/render/common/render-item.cpp +++ b/dali/internal/render/common/render-item.cpp @@ -42,7 +42,6 @@ RenderItem* RenderItem::New() RenderItem::RenderItem() : mModelMatrix(false), mModelViewMatrix(false), - mColor(Vector4::ZERO), mSize(), mRenderer(nullptr), mNode(nullptr), @@ -168,6 +167,11 @@ void RenderItem::operator delete(void* ptr) gRenderItemPool.Free(static_cast(ptr)); } +uint32_t RenderItem::GetMemoryPoolCapacity() +{ + return gRenderItemPool.GetCapacity(); +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/render/common/render-item.h b/dali/internal/render/common/render-item.h index d1ca0f4..0a82320 100644 --- a/dali/internal/render/common/render-item.h +++ b/dali/internal/render/common/render-item.h @@ -90,7 +90,6 @@ struct RenderItem 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; @@ -100,6 +99,11 @@ struct RenderItem bool mIsOpaque : 1; bool mIsUpdated : 1; + /** + * Get the capacity of the global pool. + */ + static uint32_t GetMemoryPoolCapacity(); + private: /** * Private constructor. See RenderItem::New diff --git a/dali/internal/render/common/render-manager.cpp b/dali/internal/render/common/render-manager.cpp index c7b88c1..fff4fe8 100644 --- a/dali/internal/render/common/render-manager.cpp +++ b/dali/internal/render/common/render-manager.cpp @@ -543,7 +543,8 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& 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(); @@ -564,12 +565,14 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& orientationAngle != ANGLE_180 || scale != Vector3(1.0f, 1.0f, 1.0f)) { - return; + cleanDamagedRect = true; + continue; } } else { - return; + cleanDamagedRect = true; + continue; } Rect viewportRect; @@ -579,7 +582,8 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& 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 @@ -682,7 +686,9 @@ void RenderManager::PreRender(Integration::Scene& scene, std::vector>& 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 } } } diff --git a/dali/internal/render/queue/render-queue.cpp b/dali/internal/render/queue/render-queue.cpp index 49cd12f..ca582ba 100644 --- a/dali/internal/render/queue/render-queue.cpp +++ b/dali/internal/render/queue/render-queue.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -80,6 +80,9 @@ uint32_t* RenderQueue::ReserveMessageSlot(BufferIndex updateBufferIndex, std::si void RenderQueue::ProcessMessages(BufferIndex bufferIndex) { + std::size_t capacity = container0->GetCapacity() + container1->GetCapacity(); + mCapacity = capacity; // write is atomic. + MessageBuffer* container = GetCurrentContainer(bufferIndex); for(MessageBuffer::Iterator iter = container->Begin(); iter.IsValid(); iter.Next()) diff --git a/dali/internal/render/queue/render-queue.h b/dali/internal/render/queue/render-queue.h index 4739889..0df8060 100644 --- a/dali/internal/render/queue/render-queue.h +++ b/dali/internal/render/queue/render-queue.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_RENDER_QUEUE_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. @@ -21,6 +21,8 @@ // INTERNAL INCLUDES #include #include +#include +#include namespace Dali { @@ -63,6 +65,14 @@ public: */ void ProcessMessages(BufferIndex bufferIndex); + /** + * Return the current capacity total of both buffers. + */ + std::size_t GetCapacity() const + { + return mCapacity; + } + private: /** * Helper to retrieve the current container. @@ -87,6 +97,8 @@ private: private: MessageBuffer* container0; ///< Messages are queued here when the update buffer index == 0 MessageBuffer* container1; ///< Messages are queued here when the update buffer index == 1 + + std::atomic mCapacity{0u}; // Current total capacity of both buffers. }; } // namespace SceneGraph diff --git a/dali/internal/update/animation/scene-graph-animation.cpp b/dali/internal/update/animation/scene-graph-animation.cpp index 49268b6..d75199a 100644 --- a/dali/internal/update/animation/scene-graph-animation.cpp +++ b/dali/internal/update/animation/scene-graph-animation.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -484,6 +484,11 @@ void Animation::UpdateAnimators(BufferIndex bufferIndex, bool bake, bool animati } } +uint32_t Animation::GetMemoryPoolCapacity() +{ + return gAnimationMemoryPool.GetCapacity(); +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/update/animation/scene-graph-animation.h b/dali/internal/update/animation/scene-graph-animation.h index cebcb2e..4119c15 100644 --- a/dali/internal/update/animation/scene-graph-animation.h +++ b/dali/internal/update/animation/scene-graph-animation.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_ANIMATION_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. @@ -292,6 +292,8 @@ public: */ void Update(BufferIndex bufferIndex, float elapsedSeconds, bool& looped, bool& finished, bool& progressReached); + static uint32_t GetMemoryPoolCapacity(); + protected: /** * Protected constructor. See New() diff --git a/dali/internal/update/common/property-owner.h b/dali/internal/update/common/property-owner.h index 1d3fee7..f4329fa 100644 --- a/dali/internal/update/common/property-owner.h +++ b/dali/internal/update/common/property-owner.h @@ -162,7 +162,7 @@ public: * 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; } diff --git a/dali/internal/update/manager/frame-callback-processor.cpp b/dali/internal/update/manager/frame-callback-processor.cpp index 1f54b89..10e7d8d 100644 --- a/dali/internal/update/manager/frame-callback-processor.cpp +++ b/dali/internal/update/manager/frame-callback-processor.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -24,6 +24,12 @@ // INTERNAL INCLUDES #include #include +#include + +namespace +{ +DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false); +} // namespace namespace Dali { @@ -59,12 +65,19 @@ void FrameCallbackProcessor::RemoveFrameCallback(FrameCallbackInterface* frameCa void FrameCallbackProcessor::Update(BufferIndex bufferIndex, float elapsedSeconds) { - // If any of the FrameCallback::Update calls returns false, then they are no longer required & can be removed. - auto iter = std::remove_if( - mFrameCallbacks.begin(), mFrameCallbacks.end(), [&](OwnerPointer& frameCallback) { - return !frameCallback->Update(bufferIndex, elapsedSeconds, mNodeHierarchyChanged); - }); - mFrameCallbacks.erase(iter, mFrameCallbacks.end()); + if(!mFrameCallbacks.empty()) + { + DALI_TRACE_BEGIN(gTraceFilter, "DALI_FRAME_CALLBACK_UPDATE"); + + // If any of the FrameCallback::Update calls returns false, then they are no longer required & can be removed. + auto iter = std::remove_if( + mFrameCallbacks.begin(), mFrameCallbacks.end(), [&](OwnerPointer& frameCallback) { + return !frameCallback->Update(bufferIndex, elapsedSeconds, mNodeHierarchyChanged); + }); + mFrameCallbacks.erase(iter, mFrameCallbacks.end()); + + DALI_TRACE_END(gTraceFilter, "DALI_FRAME_CALLBACK_UPDATE"); + } mNodeHierarchyChanged = false; } diff --git a/dali/internal/update/manager/render-instruction-processor.cpp b/dali/internal/update/manager/render-instruction-processor.cpp index 50bdc0e..e15862a 100644 --- a/dali/internal/update/manager/render-instruction-processor.cpp +++ b/dali/internal/update/manager/render-instruction-processor.cpp @@ -260,15 +260,9 @@ inline void AddRendererToRenderList(BufferIndex updateBufferIndex, // 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)) { @@ -300,7 +294,6 @@ inline void AddRendererToRenderList(BufferIndex updateBufferIndex, PartialRenderingData partialRenderingData; partialRenderingData.color = node->GetWorldColor(updateBufferIndex); - partialRenderingData.depthIndex = node->GetDepthIndex(); partialRenderingData.matrix = item.mModelViewMatrix; partialRenderingData.updatedPositionSize = item.mUpdateArea; partialRenderingData.size = item.mSize; diff --git a/dali/internal/update/manager/transform-manager-property.h b/dali/internal/update/manager/transform-manager-property.h index 619abee..3c11242 100644 --- a/dali/internal/update/manager/transform-manager-property.h +++ b/dali/internal/update/manager/transform-manager-property.h @@ -2,7 +2,7 @@ #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. @@ -148,30 +148,32 @@ struct TransformManagerPropertyHandler : public AnimatablePropertyBase } /** - * 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 +template struct TransformManagerPropertyVector3 final : public TransformManagerPropertyHandler { + enum + { + TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset + }; + TransformManagerData* GetTxManagerData() + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + const TransformManagerData* GetTxManagerData() const + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + TransformManagerPropertyVector3() = default; Dali::Property::Type GetType() const override @@ -181,12 +183,12 @@ struct TransformManagerPropertyVector3 final : public TransformManagerPropertyHa 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 @@ -196,68 +198,84 @@ struct TransformManagerPropertyVector3 final : public TransformManagerPropertyHa 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 class TransformManagerPropertyQuaternion final : public TransformManagerPropertyHandler { public: + enum + { + TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset + }; + TransformManagerData* GetTxManagerData() + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + const TransformManagerData* GetTxManagerData() const + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + TransformManagerPropertyQuaternion() = default; Dali::Property::Type GetType() const override @@ -267,27 +285,27 @@ public: 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 @@ -299,9 +317,25 @@ public: /** * A Vector3 property used as input. */ +template class TransformManagerVector3Input : public PropertyInputImpl { public: + enum + { + TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset + }; + TransformManagerData* GetTxManagerData() + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + const TransformManagerData* GetTxManagerData() const + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + /** * Create an TransformManagerVector3Input */ @@ -355,10 +389,11 @@ public: */ 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(); @@ -420,17 +455,6 @@ public: } /** - * 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 @@ -439,14 +463,10 @@ public: } 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; }; @@ -454,9 +474,25 @@ public: /** * A Quaternion property used as input. */ +template class TransformManagerQuaternionInput final : public PropertyInputImpl { public: + enum + { + TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset + }; + TransformManagerData* GetTxManagerData() + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + const TransformManagerData* GetTxManagerData() const + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + /** * Constructor */ @@ -501,9 +537,11 @@ public: */ 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); } @@ -557,17 +595,6 @@ public: } /** - * 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 @@ -576,23 +603,35 @@ public: } 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 class TransformManagerMatrixInput final : public PropertyInputImpl { public: + enum + { + TRANSFORM_MANAGER_DATA_OFFSET = TxMgrDataOffset + }; + TransformManagerData* GetTxManagerData() + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + const TransformManagerData* GetTxManagerData() const + { + return reinterpret_cast( + reinterpret_cast(this) - TRANSFORM_MANAGER_DATA_OFFSET); + } + /** * Constructor */ @@ -636,11 +675,12 @@ public: */ 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; } @@ -649,11 +689,12 @@ public: */ 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; } @@ -662,8 +703,10 @@ public: */ 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); } /** @@ -684,12 +727,6 @@ public: return GetMatrix(bufferIndex); } - void Initialize(TransformManagerData* data) - { - DALI_ASSERT_ALWAYS(data != nullptr && data->Manager() != nullptr); - mTxManagerData = data; - } - /** * @copydoc Dali::Internal::PropertyInputImpl::IsTransformManagerProperty() */ @@ -699,18 +736,12 @@ public: } 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_ diff --git a/dali/internal/update/manager/transform-manager.cpp b/dali/internal/update/manager/transform-manager.cpp index 342d820..452d272 100644 --- a/dali/internal/update/manager/transform-manager.cpp +++ b/dali/internal/update/manager/transform-manager.cpp @@ -28,6 +28,8 @@ #include #include +#include + namespace Dali { namespace Internal @@ -49,22 +51,24 @@ static_assert(sizeof(gDefaultTransformComponentStaticData) == sizeof(TransformCo * @brief Calculates the center position for the transform component * @param[out] centerPosition The calculated center-position of the transform component * @param[in] transformComponentStatic A const reference to the static component transform struct - * @param[in] transformComponentAnimatable A const reference to the animatable component transform struct + * @param[in] scale scale factor to be applied to the center position. + * @param[in] orientation orientation factor to be applied to the center position. * @param[in] size The size of the current transform component * @param[in] half Halfway point of the transform * @param[in] topLeft The top-left coords of the transform */ inline void CalculateCenterPosition( - Vector3& centerPosition, - const TransformComponentStatic& transformComponentStatic, - const TransformComponentAnimatable& transformComponentAnimatable, - const Vector3& size, - const Vector3& half, - const Vector3& topLeft) + Vector3& centerPosition, + const TransformComponentStatic& transformComponentStatic, + const Vector3& scale, + const Quaternion& orientation, + const Vector3& size, + const Vector3& half, + const Vector3& topLeft) { // Calculate the center-point by applying the scale and rotation on the anchor point. - centerPosition = (half - transformComponentStatic.mAnchorPoint) * size * transformComponentAnimatable.mScale; - centerPosition *= transformComponentAnimatable.mOrientation; + centerPosition = (half - transformComponentStatic.mAnchorPoint) * size * scale; + centerPosition *= orientation; // If the position is ignoring the anchor-point, then remove the anchor-point shift from the position. if(!transformComponentStatic.mPositionUsesAnchorPoint) @@ -255,7 +259,7 @@ bool TransformManager::Update() { //Full transform inherited mLocalMatrixDirty[i] = true; - CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft); + CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, mSize[i], half, topLeft); localPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex]; mLocal[i].SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition); } @@ -265,52 +269,76 @@ bool TransformManager::Update() } else { - //Some components are not inherited + // Keep previous localMatrix for comparison. + Matrix previousLocalMatrix = mLocal[i]; + + // Get Parent information. Vector3 parentPosition, parentScale; Quaternion parentOrientation; const Matrix& parentMatrix = mWorld[parentIndex]; parentMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale); - Vector3 localScale = mTxComponentAnimatable[i].mScale; + // Compute intermediate Local information + CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, mSize[i], half, topLeft); + Vector3 intermediateLocalPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex]; + Matrix intermediateLocalMatrix; + intermediateLocalMatrix.SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, intermediateLocalPosition); + + // Compute intermediate world information + Matrix intermediateWorldMatrix; + MatrixUtils::Multiply(intermediateWorldMatrix, intermediateLocalMatrix, mWorld[parentIndex]); + + Vector3 intermediateWorldPosition, intermediateWorldScale; + Quaternion intermediateWorldOrientation; + intermediateWorldMatrix.GetTransformComponents(intermediateWorldPosition, intermediateWorldOrientation, intermediateWorldScale); + + // Compute final world information + Vector3 finalWorldPosition = intermediateWorldPosition; + Vector3 finalWorldScale = intermediateWorldScale; + Quaternion finalWorldOrientation = intermediateWorldOrientation; + // worldScale includes the influence of local scale, local rotation, and parent scale. + // So, for the final world matrix, if this node inherits its parent scale, use worldScale. + // If not, use local scale for the final world matrix. if((mInheritanceMode[i] & INHERIT_SCALE) == 0) { - //Don't inherit scale - localScale /= parentScale; + finalWorldScale = mTxComponentAnimatable[i].mScale; } - Quaternion localOrientation(mTxComponentAnimatable[i].mOrientation); + // For the final world matrix, if this node inherits its parent orientation, use worldOrientation. + // If not, use local orientation for the final world matrix. if((mInheritanceMode[i] & INHERIT_ORIENTATION) == 0) { - //Don't inherit orientation - parentOrientation.Invert(); - localOrientation = parentOrientation * mTxComponentAnimatable[i].mOrientation; + finalWorldOrientation = mTxComponentAnimatable[i].mOrientation; } - Matrix localMatrix = mLocal[i]; - - if((mInheritanceMode[i] & INHERIT_POSITION) == 0) - { - //Don't inherit position - CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft); - mLocal[i].SetTransformComponents(localScale, localOrientation, Vector3::ZERO); - MatrixUtils::Multiply(mWorld[i], mLocal[i], parentMatrix); - mWorld[i].SetTranslation(mTxComponentAnimatable[i].mPosition + centerPosition); - } - else + // The final world position of this node is computed as a sum of + // parent origin position in world space and relative position of center from parent origin. + // If this node doesn't inherit its parent position, simply use the relative position as a final world position. + Vector3 localCenterPosition; + CalculateCenterPosition(localCenterPosition, mTxComponentStatic[i], finalWorldScale, finalWorldOrientation, mSize[i], half, topLeft); + finalWorldPosition = mTxComponentAnimatable[i].mPosition * finalWorldScale; + finalWorldPosition *= finalWorldOrientation; + finalWorldPosition += localCenterPosition; + if((mInheritanceMode[i] & INHERIT_POSITION) != 0) { - CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft); - localPosition = mTxComponentAnimatable[i].mPosition + centerPosition + (mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex]; - mLocal[i].SetTransformComponents(localScale, localOrientation, localPosition); - MatrixUtils::Multiply(mWorld[i], mLocal[i], parentMatrix); + Vector4 parentOriginPosition((mTxComponentStatic[i].mParentOrigin - half) * mSize[parentIndex]); + parentOriginPosition.w = 1.0f; + finalWorldPosition += Vector3(parentMatrix * parentOriginPosition); } - mLocalMatrixDirty[i] = mComponentDirty[i] || (localMatrix != mLocal[i]); + mWorld[i].SetTransformComponents(finalWorldScale, finalWorldOrientation, finalWorldPosition); + + Matrix inverseParentMatrix; + inverseParentMatrix.SetInverseTransformComponents(parentScale, parentOrientation, parentPosition); + mLocal[i] = inverseParentMatrix * mWorld[i]; + + mLocalMatrixDirty[i] = mComponentDirty[i] || (previousLocalMatrix != mLocal[i]); } } else //Component has no parent or doesn't inherit transform { Matrix localMatrix = mLocal[i]; - CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i], mSize[i], half, topLeft); + CalculateCenterPosition(centerPosition, mTxComponentStatic[i], mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, mSize[i], half, topLeft); localPosition = mTxComponentAnimatable[i].mPosition + centerPosition; mLocal[i].SetTransformComponents(mTxComponentAnimatable[i].mScale, mTxComponentAnimatable[i].mOrientation, localPosition); mWorld[i] = mLocal[i]; diff --git a/dali/internal/update/manager/update-manager.cpp b/dali/internal/update/manager/update-manager.cpp index 1b5c1a3..2873011 100644 --- a/dali/internal/update/manager/update-manager.cpp +++ b/dali/internal/update/manager/update-manager.cpp @@ -112,7 +112,8 @@ inline void EraseUsingDiscardQueue(OwnerContainer& container, T* object, Dis void SortSiblingNodesRecursively(Node& node) { NodeContainer& container = node.GetChildren(); - std::sort(container.Begin(), container.End(), [](Node* a, Node* b) { return a->GetDepthIndex() < b->GetDepthIndex(); }); + std::sort(container.Begin(), container.End(), [](Node* a, Node* b) + { return a->GetDepthIndex() < b->GetDepthIndex(); }); // Descend tree and sort as well for(auto&& iter : container) @@ -136,11 +137,11 @@ struct UpdateManager::Impl { } - ~SceneInfo() = default; ///< Default non-virtual destructor - SceneInfo(SceneInfo&& rhs) = default; ///< Move constructor - SceneInfo& operator=(SceneInfo&& rhs) = default; ///< Move assignment operator - SceneInfo& operator=(const SceneInfo& rhs) = delete; ///< Assignment operator - SceneInfo(const SceneInfo& rhs) = delete; ///< Copy constructor + ~SceneInfo() = default; ///< Default non-virtual destructor + SceneInfo(SceneInfo&& rhs) = default; ///< Move constructor + SceneInfo& operator=(SceneInfo&& rhs) = default; ///< Move assignment operator + SceneInfo& operator=(const SceneInfo& rhs) = delete; ///< Assignment operator + SceneInfo(const SceneInfo& rhs) = delete; ///< Copy constructor Layer* root{nullptr}; ///< Root node (root is a layer). The layer is not stored in the node memory pool. OwnerPointer taskList; ///< Scene graph render task list @@ -288,11 +289,11 @@ struct UpdateManager::Impl OwnerPointer frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required. - float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering - NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame - uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. - - DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior + std::atomic renderInstructionCapacity{0u}; + float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering + NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame + uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore. + DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update() bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out) @@ -338,9 +339,8 @@ void UpdateManager::InstallRoot(OwnerPointer& layer) Layer* rootLayer = layer.Release(); - DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene) { - return scene && scene->root == rootLayer; - }) == mImpl->scenes.end() && + DALI_ASSERT_DEBUG(std::find_if(mImpl->scenes.begin(), mImpl->scenes.end(), [rootLayer](Impl::SceneInfoPtr& scene) + { return scene && scene->root == rootLayer; }) == mImpl->scenes.end() && "Root Node already installed"); rootLayer->CreateTransform(&mImpl->transformManager); @@ -690,6 +690,21 @@ uint32_t* UpdateManager::ReserveMessageSlot(uint32_t size, bool updateScene) return mImpl->messageQueue.ReserveMessageSlot(size, updateScene); } +std::size_t UpdateManager::GetUpdateMessageQueueCapacity() const +{ + return mImpl->messageQueue.GetCapacity(); +} + +std::size_t UpdateManager::GetRenderMessageQueueCapacity() const +{ + return mImpl->renderQueue.GetCapacity(); +} + +std::size_t UpdateManager::GetRenderInstructionCapacity() const +{ + return mImpl->renderInstructionCapacity; +} + void UpdateManager::EventProcessingStarted() { mImpl->messageQueue.EventProcessingStarted(); @@ -817,7 +832,7 @@ bool UpdateManager::Animate(BufferIndex bufferIndex, float elapsedSeconds) void UpdateManager::ConstrainCustomObjects(BufferIndex bufferIndex) { - //Constrain custom objects (in construction order) + // Constrain custom objects (in construction order) for(auto&& object : mImpl->customObjects) { ConstrainPropertyOwner(*object, bufferIndex); @@ -890,7 +905,7 @@ void UpdateManager::UpdateRenderers(BufferIndex bufferIndex) { for(auto&& renderer : mImpl->renderers) { - //Apply constraints + // Apply constraints ConstrainPropertyOwner(*renderer, bufferIndex); mImpl->renderingRequired = renderer->PrepareRender(bufferIndex) || mImpl->renderingRequired; @@ -934,12 +949,12 @@ uint32_t UpdateManager::Update(float elapsedSeconds, { const BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex(); - //Clear nodes/resources which were previously discarded + // Clear nodes/resources which were previously discarded mImpl->discardQueue.Clear(bufferIndex); bool isAnimationRunning = IsAnimationRunning(); - //Process Touches & Gestures + // Process Touches & Gestures const bool gestureUpdated = ProcessGestures(bufferIndex, lastVSyncTimeMilliseconds, nextVSyncTimeMilliseconds); bool updateScene = // The scene-graph requires an update if.. @@ -956,7 +971,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, // values if the scene was updated in the previous frame. if(updateScene || mImpl->previousUpdateScene) { - //Reset properties from the previous update + // Reset properties from the previous update ResetProperties(bufferIndex); mImpl->transformManager.ResetToBaseValue(); } @@ -966,7 +981,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, // be set again updateScene |= mImpl->messageQueue.ProcessMessages(bufferIndex); - //Forward compiled shader programs to event thread for saving + // Forward compiled shader programs to event thread for saving ForwardCompiledShadersToEventThread(); // Although the scene-graph may not require an update, we still need to synchronize double-buffered @@ -974,13 +989,13 @@ uint32_t UpdateManager::Update(float elapsedSeconds, // We should not start skipping update steps or reusing lists until there has been two frames where nothing changes if(updateScene || mImpl->previousUpdateScene) { - //Animate + // Animate bool animationActive = Animate(bufferIndex, elapsedSeconds); - //Constraint custom objects + // Constraint custom objects ConstrainCustomObjects(bufferIndex); - //Clear the lists of renderers from the previous update + // Clear the lists of renderers from the previous update for(auto&& scene : mImpl->scenes) { if(scene) @@ -1001,36 +1016,36 @@ uint32_t UpdateManager::Update(float elapsedSeconds, mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds); } - //Update node hierarchy, apply constraints, + // Update node hierarchy, apply constraints, UpdateNodes(bufferIndex); - //Apply constraints to RenderTasks, shaders + // Apply constraints to RenderTasks, shaders ConstrainRenderTasks(bufferIndex); ConstrainShaders(bufferIndex); - //Update renderers and apply constraints + // Update renderers and apply constraints UpdateRenderers(bufferIndex); - //Update the transformations of all the nodes + // Update the transformations of all the nodes if(mImpl->transformManager.Update()) { mImpl->nodeDirtyFlags |= NodePropertyFlags::TRANSFORM; } - //Initialise layer renderable reuse + // Initialise layer renderable reuse UpdateLayers(bufferIndex); - //Process Property Notifications + // Process Property Notifications ProcessPropertyNotifications(bufferIndex); - //Update cameras + // Update cameras for(auto&& cameraIterator : mImpl->cameras) { cameraIterator->Update(bufferIndex); } - //Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame. - //reset the update buffer index and make sure there is enough room in the instruction container + // Process the RenderTasks if renderers exist. This creates the instructions for rendering the next frame. + // reset the update buffer index and make sure there is enough room in the instruction container if(mImpl->renderersAdded) { // Calculate how many render tasks we have in total @@ -1044,6 +1059,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, } std::size_t numberOfRenderInstructions = 0; + mImpl->renderInstructionCapacity = 0u; for(auto&& scene : mImpl->scenes) { if(scene && scene->root && scene->taskList && scene->scene) @@ -1063,6 +1079,7 @@ uint32_t UpdateManager::Update(float elapsedSeconds, renderToFboEnabled, isRenderingToFbo); + mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity(); scene->scene->SetSkipRendering(false); } else diff --git a/dali/internal/update/manager/update-manager.h b/dali/internal/update/manager/update-manager.h index 3065d34..a8a6683 100644 --- a/dali/internal/update/manager/update-manager.h +++ b/dali/internal/update/manager/update-manager.h @@ -47,6 +47,9 @@ #include // for OwnerPointer< Renderer > #include // for OwnerPointer< TextureSet > +// EXTERNAL INCLUDES +#include + namespace Dali { class FrameCallbackInterface; @@ -660,6 +663,21 @@ public: */ void RemoveFrameCallback(FrameCallbackInterface* frameCallback); + /** + * Get the update message queue capacity (mutex locked) + */ + std::size_t GetUpdateMessageQueueCapacity() const; + + /** + * Get the render message queue capacity + */ + std::size_t GetRenderMessageQueueCapacity() const; + + /** + * Get the render instruction capacity + */ + std::size_t GetRenderInstructionCapacity() const; + private: // Undefined UpdateManager(const UpdateManager&); diff --git a/dali/internal/update/nodes/node-helper.h b/dali/internal/update/nodes/node-helper.h new file mode 100644 index 0000000..4997868 --- /dev/null +++ b/dali/internal/update/nodes/node-helper.h @@ -0,0 +1,73 @@ +#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; \ + _TEMPLATE##_ELEMENT _ELEMENT; \ + enum \ + { \ + OFFSET_##_ELEMENT = sizeof(_TEMPLATE##_ELEMENT) + OFFSET_##_BASE_ELEMENT \ + }; + +#endif // DALI_INTERNAL_SCENEGRAPH_NODE_HELPER_H diff --git a/dali/internal/update/nodes/node.cpp b/dali/internal/update/nodes/node.cpp index f0f4943..87b4603 100644 --- a/dali/internal/update/nodes/node.cpp +++ b/dali/internal/update/nodes/node.cpp @@ -27,8 +27,8 @@ 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 gNodeMemoryPool; #ifdef DEBUG_ENABLED // keep track of nodes alive, to ensure we have 0 when the process exits or DALi library is unloaded @@ -76,16 +76,16 @@ void Node::Delete(Node* node) } 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), @@ -134,28 +134,14 @@ uint32_t Node::GetId() const 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; } @@ -348,6 +334,11 @@ void Node::RecursiveDisconnectFromSceneGraph(BufferIndex updateBufferIndex) } } +uint32_t Node::GetMemoryPoolCapacity() +{ + return gNodeMemoryPool.GetCapacity(); +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/update/nodes/node.h b/dali/internal/update/nodes/node.h index 3e28d7b..be26b7a 100644 --- a/dali/internal/update/nodes/node.h +++ b/dali/internal/update/nodes/node.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -803,6 +804,7 @@ public: if(depthIndex != mDepthIndex) { SetDirtyFlag(NodePropertyFlags::DEPTH_INDEX); + SetUpdated(true); mDepthIndex = depthIndex; } } @@ -850,6 +852,14 @@ public: } /** + * @brief Get the total capacity of the memory pools + * @return The capacity of the memory pools + * + * @note This is different to the node count. + */ + static uint32_t GetMemoryPoolCapacity(); + + /** * @brief Returns partial rendering data associated with the node. * @return The partial rendering data */ @@ -921,10 +931,10 @@ private: // from NodeDataProvider private: // Delete copy and move - Node(const Node&) = delete; - Node(Node&&) = delete; + Node(const Node&) = delete; + Node(Node&&) = delete; Node& operator=(const Node& rhs) = delete; - Node& operator=(Node&& rhs) = delete; + Node& operator=(Node&& rhs) = delete; /** * Recursive helper to disconnect a Node and its children. @@ -934,34 +944,39 @@ private: void RecursiveDisconnectFromSceneGraph(BufferIndex updateBufferIndex); public: // Default properties - using TransformManagerParentsOrigin = TransformManagerPropertyVector3; - using TransformManagerAnchorPoint = TransformManagerPropertyVector3; - using TransformManagerSize = TransformManagerPropertyVector3; - using TransformManagerPosition = TransformManagerPropertyVector3; - using TransformManagerScale = TransformManagerPropertyVector3; - - 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 mVisible; ///< Visibility can be inherited from the Node hierachy AnimatableProperty mCulled; ///< True if the node is culled. This is not animatable. It is just double-buffered. AnimatableProperty mColor; ///< Color can be inherited from the Node hierarchy + InheritedColor mWorldColor; ///< Full inherited color AnimatableProperty 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. @@ -980,8 +995,7 @@ protected: 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 diff --git a/dali/internal/update/nodes/partial-rendering-data.h b/dali/internal/update/nodes/partial-rendering-data.h index cd52c50..5d7f943 100644 --- a/dali/internal/update/nodes/partial-rendering-data.h +++ b/dali/internal/update/nodes/partial-rendering-data.h @@ -37,8 +37,7 @@ struct PartialRenderingData 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) @@ -53,7 +52,6 @@ struct PartialRenderingData AddToHash(hash, &color, sizeof(decltype(color))); AddToHash(hash, &updatedPositionSize, sizeof(decltype(updatedPositionSize))); AddToHash(hash, &size, sizeof(decltype(size))); - AddToHash(hash, &depthIndex, sizeof(decltype(depthIndex))); } /** @@ -69,7 +67,6 @@ struct PartialRenderingData 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. } @@ -79,7 +76,6 @@ struct PartialRenderingData color = frameCache.color; updatedPositionSize = frameCache.updatedPositionSize; size = frameCache.size; - depthIndex = frameCache.depthIndex; hash = frameCache.hash; mRendered = true; diff --git a/dali/internal/update/queue/update-message-queue.cpp b/dali/internal/update/queue/update-message-queue.cpp index 83883a7..8b80412 100644 --- a/dali/internal/update/queue/update-message-queue.cpp +++ b/dali/internal/update/queue/update-message-queue.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -287,6 +287,28 @@ bool MessageQueue::IsSceneUpdateRequired() const return mImpl->sceneUpdate; } +std::size_t MessageQueue::GetCapacity() const +{ + MessageQueueMutex::ScopedLock lock(mImpl->queueMutex); + + uint32_t capacity = 0u; + MessageBufferIter endIter = mImpl->freeQueue.end(); + for(MessageBufferIter iter = mImpl->freeQueue.begin(); iter != endIter; ++iter) + { + capacity += (*iter)->GetCapacity(); + } + endIter = mImpl->processQueue.end(); + for(MessageBufferIter iter = mImpl->processQueue.begin(); iter != endIter; ++iter) + { + capacity += (*iter)->GetCapacity(); + } + if(mImpl->currentMessageBuffer != nullptr) + { + capacity += mImpl->currentMessageBuffer->GetCapacity(); + } + return capacity; +} + } // namespace Update } // namespace Internal diff --git a/dali/internal/update/queue/update-message-queue.h b/dali/internal/update/queue/update-message-queue.h index 6fd1c47..cfc47ba 100644 --- a/dali/internal/update/queue/update-message-queue.h +++ b/dali/internal/update/queue/update-message-queue.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_UPDATE_MESSAGE_QUEUE_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. @@ -22,6 +22,9 @@ #include #include +// EXTERNAL INCLUDES +#include + namespace Dali { namespace Integration @@ -99,6 +102,11 @@ public: */ bool IsSceneUpdateRequired() const; + /** + * Query for the capacity of the current message queue + */ + std::size_t GetCapacity() const; + private: /** * Helper to call Process and destructor on each queued message @@ -108,8 +116,8 @@ private: private: // Not copyable: - MessageQueue() = delete; - MessageQueue(const MessageQueue& rhs) = delete; + MessageQueue() = delete; + MessageQueue(const MessageQueue& rhs) = delete; MessageQueue& operator=(const MessageQueue& rhs) = delete; private: diff --git a/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp b/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp index 8139c2b..03c39fd 100644 --- a/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp +++ b/dali/internal/update/render-tasks/scene-graph-render-task-list.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -107,6 +107,11 @@ CompleteNotificationInterface* RenderTaskList::GetCompleteNotificationInterface( return mNotificationObject; } +uint32_t RenderTaskList::GetMemoryPoolCapacity() +{ + return gRenderTaskListMemoryPool.GetCapacity(); +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/update/render-tasks/scene-graph-render-task-list.h b/dali/internal/update/render-tasks/scene-graph-render-task-list.h index c985491..84058fc 100644 --- a/dali/internal/update/render-tasks/scene-graph-render-task-list.h +++ b/dali/internal/update/render-tasks/scene-graph-render-task-list.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_RENDER_TASK_LIST_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. @@ -107,6 +107,11 @@ public: */ CompleteNotificationInterface* GetCompleteNotificationInterface(); + /** + * Get the capacity of the memory pools + */ + static uint32_t GetMemoryPoolCapacity(); + protected: /** * Protected constructor. See New() diff --git a/dali/internal/update/rendering/scene-graph-renderer.cpp b/dali/internal/update/rendering/scene-graph-renderer.cpp index 6f4b485..1e03ce8 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.cpp +++ b/dali/internal/update/rendering/scene-graph-renderer.cpp @@ -734,6 +734,11 @@ void Renderer::ResetDirtyFlag() SetUpdated(false); } +uint32_t Renderer::GetMemoryPoolCapacity() +{ + return gRendererMemoryPool.GetCapacity(); +} + void Renderer::UniformMappingsChanged(const UniformMap& mappings) { // The mappings are either from PropertyOwner base class, or the Shader diff --git a/dali/internal/update/rendering/scene-graph-renderer.h b/dali/internal/update/rendering/scene-graph-renderer.h index f2a84d6..f49f2fb 100644 --- a/dali/internal/update/rendering/scene-graph-renderer.h +++ b/dali/internal/update/rendering/scene-graph-renderer.h @@ -435,6 +435,12 @@ public: */ void ResetDirtyFlag(); + /** + * Get the capacity of the memory pools + * @return the capacity of the memory pools + */ + static uint32_t GetMemoryPoolCapacity(); + public: // UniformMap::Observer /** * @copydoc UniformMap::Observer::UniformMappingsChanged diff --git a/dali/internal/update/rendering/scene-graph-texture-set.cpp b/dali/internal/update/rendering/scene-graph-texture-set.cpp index 0269286..1e95d3b 100644 --- a/dali/internal/update/rendering/scene-graph-texture-set.cpp +++ b/dali/internal/update/rendering/scene-graph-texture-set.cpp @@ -113,6 +113,11 @@ bool TextureSet::HasAlpha() const return mHasAlpha; } +uint32_t TextureSet::GetMemoryPoolCapacity() +{ + return gTextureSetMemoryPool.GetCapacity(); +} + } // namespace SceneGraph } // namespace Internal diff --git a/dali/internal/update/rendering/scene-graph-texture-set.h b/dali/internal/update/rendering/scene-graph-texture-set.h index 683296a..5e00716 100644 --- a/dali/internal/update/rendering/scene-graph-texture-set.h +++ b/dali/internal/update/rendering/scene-graph-texture-set.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_TEXTURE_SET_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. @@ -91,6 +91,12 @@ public: return mSamplers; } + /** + * Get the capacity of the memory pools + * @return the capacity of the memory pools + */ + static uint32_t GetMemoryPoolCapacity(); + private: /** * Protected constructor; See also TextureSet::New() diff --git a/dali/public-api/dali-core-version.cpp b/dali/public-api/dali-core-version.cpp index d30a059..9ad8470 100644 --- a/dali/public-api/dali-core-version.cpp +++ b/dali/public-api/dali-core-version.cpp @@ -27,7 +27,7 @@ namespace Dali { const uint32_t CORE_MAJOR_VERSION = 2; const uint32_t CORE_MINOR_VERSION = 2; -const uint32_t CORE_MICRO_VERSION = 5; +const uint32_t CORE_MICRO_VERSION = 6; const char* const CORE_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/dali/public-api/images/pixel-data.cpp b/dali/public-api/images/pixel-data.cpp index 2356c4b..c05363a 100644 --- a/dali/public-api/images/pixel-data.cpp +++ b/dali/public-api/images/pixel-data.cpp @@ -83,4 +83,9 @@ uint32_t PixelData::GetStride() const return GetImplementation(*this).GetStride(); } +uint32_t PixelData::GetTotalAllocatedSize() +{ + return Internal::PixelData::GetTotalAllocatedSize(); +} + } // namespace Dali diff --git a/dali/public-api/images/pixel-data.h b/dali/public-api/images/pixel-data.h index b7778d5..70e80da 100644 --- a/dali/public-api/images/pixel-data.h +++ b/dali/public-api/images/pixel-data.h @@ -177,6 +177,11 @@ public: */ uint32_t GetStride() const; + /** + * Class method to get the total currently allocated size of pixel buffers + */ + static uint32_t GetTotalAllocatedSize(); + public: /** * @brief The constructor. @@ -190,6 +195,6 @@ public: /** * @} */ -} //namespace Dali +} // namespace Dali #endif // DALI_PIXEL_DATA_H diff --git a/packaging/dali.spec b/packaging/dali.spec index bdf6375..00c5de2 100644 --- a/packaging/dali.spec +++ b/packaging/dali.spec @@ -1,6 +1,6 @@ Name: dali2 Summary: DALi 3D Engine -Version: 2.2.5 +Version: 2.2.6 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT