return 320;
}
+ void FrameStart() override
+ {
+ }
+
+ void LogMemoryPools() override
+ {
+ }
+
/**
* Store cached configurations
*/
END_TEST;
}
+int UtcDaliApplicationNew06P(void)
+{
+ int argc(1);
+ const char* argList[1] = {"program"};
+ char** argv = const_cast<char**>(argList);
+
+ Application application = Application::New(&argc, &argv, "stylesheet", Application::WINDOW_MODE::OPAQUE, PositionSize(), true);
+
+ MyTestApp testApp(application);
+
+ DALI_TEST_CHECK(application);
+
+ END_TEST;
+}
+
+int UtcDaliApplicationNew07P(void)
+{
+ int argc(1);
+ const char* argList[1] = {"program"};
+ char** argv = const_cast<char**>(argList);
+
+ Application application = Application::New(&argc, &argv, "stylesheet", Application::WINDOW_MODE::OPAQUE, PositionSize());
+
+ MyTestApp testApp(application);
+
+ DALI_TEST_CHECK(application);
+
+ END_TEST;
+}
+
int UtcDaliApplicationCopyAndAssignment(void)
{
Application application = Application::New();
/*
- * 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.
END_TEST;
}
+
+int UtcDaliTimerPauseN(void)
+{
+ Timer timer;
+
+ try
+ {
+ timer.Pause();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+ END_TEST;
+}
+
+int UtcDaliTimerResumeN(void)
+{
+ Timer timer;
+
+ try
+ {
+ timer.Resume();
+ DALI_TEST_CHECK(false); // Should not get here
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+ END_TEST;
+}
/*
- * 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.
END_TEST;
}
+int UtcDaliTtsPlayerMoveConstructorP(void)
+{
+ Dali::TtsPlayer player;
+ Dali::TtsPlayer copy(std::move(player));
+ DALI_TEST_CHECK(player == copy);
+
+ END_TEST;
+}
+
int UtcDaliTtsPlayerAssignmentOperatorP(void)
{
Dali::TtsPlayer player;
END_TEST;
}
+int UtcDaliTtsPlayerMoveAssignmentOperatorP(void)
+{
+ Dali::TtsPlayer player;
+ Dali::TtsPlayer copy;
+ DALI_TEST_CHECK(!copy);
+ copy = std::move(player);
+ DALI_TEST_CHECK(copy == player);
+
+ END_TEST;
+}
+
int UtcDaliTtsPlayerDestructorP(void)
{
Dali::TtsPlayer* player = new Dali::TtsPlayer();
END_TEST;
}
+
+int UtcDaliTtsPlayerStateChangedSignalN(void)
+{
+ Dali::TtsPlayer player = Dali::TtsPlayer::Get();
+
+ try
+ {
+ player.StateChangedSignal();
+ DALI_TEST_CHECK(false); // Should not reach here!
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(true);
+ }
+
+ END_TEST;
+}
\ No newline at end of file
END_TEST;
}
+
+int UtcDaliWidgetApplicationNewP(void)
+{
+ WidgetApplication widget1 = WidgetApplication::New(nullptr, nullptr, std::string());
+ DALI_TEST_CHECK(widget1);
+
+ END_TEST;
+}
SET(CAPI_LIB "dali-graphics")
SET(TC_SOURCES
+ utc-Dali-GlesImplementation.cpp
utc-Dali-GraphicsFramebuffer.cpp
utc-Dali-GraphicsGeometry.cpp
utc-Dali-GraphicsNativeImage.cpp
PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
dali2-core
dali2-adaptor
+ glesv2
ecore
ecore-x
)
--- /dev/null
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#include <dali-test-suite-utils.h>
+
+#include <dali/internal/graphics/gles/gles2-implementation.h>
+#include <dali/internal/graphics/gles/gles3-implementation.h>
+
+void gles_implementation_startup(void)
+{
+}
+
+void gles_implementation_cleanup(void)
+{
+}
+
+using namespace Dali::Internal::Adaptor;
+
+namespace
+{
+void CallAllMethods(GlesAbstraction& implementation)
+{
+ // These tests are purely for coverage, they don't really test anything!
+ try
+ {
+ implementation.ReadBuffer(0);
+ implementation.DrawRangeElements(0, 0, 0, 0, 0, nullptr);
+ implementation.TexImage3D(0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr);
+ implementation.TexSubImage3D(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr);
+ implementation.CopyTexSubImage3D(0, 0, 0, 0, 0, 0, 0, 0, 0);
+ implementation.CompressedTexImage3D(0, 0, 0, 0, 0, 0, 0, 0, nullptr);
+ implementation.CompressedTexSubImage3D(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nullptr);
+ implementation.GenQueries(0, nullptr);
+ implementation.DeleteQueries(0, nullptr);
+ implementation.IsQuery(0);
+ implementation.BeginQuery(0, 0);
+ implementation.EndQuery(0);
+ implementation.GetQueryiv(0, 0, nullptr);
+ implementation.GetQueryObjectuiv(0, 0, nullptr);
+ implementation.UnmapBuffer(0);
+ implementation.GetBufferPointerv(0, 0, nullptr);
+ implementation.DrawBuffers(0, nullptr);
+ implementation.UniformMatrix2x3fv(0, 0, 0, nullptr);
+ implementation.UniformMatrix3x2fv(0, 0, 0, nullptr);
+ implementation.UniformMatrix2x4fv(0, 0, 0, nullptr);
+ implementation.UniformMatrix4x2fv(0, 0, 0, nullptr);
+ implementation.UniformMatrix3x4fv(0, 0, 0, nullptr);
+ implementation.UniformMatrix4x3fv(0, 0, 0, nullptr);
+ implementation.BlitFramebuffer(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ implementation.RenderbufferStorageMultisample(0, 0, 0, 0, 0);
+ implementation.FramebufferTexture2DMultisample(0, 0, 0, 0, 0, 0);
+ implementation.FramebufferTextureLayer(0, 0, 0, 0, 0);
+ implementation.MapBufferRange(0, 0, 0, 0);
+ implementation.FlushMappedBufferRange(0, 0, 0);
+ implementation.BindVertexArray(0);
+ implementation.DeleteVertexArrays(0, nullptr);
+ implementation.GenVertexArrays(0, nullptr);
+ implementation.IsVertexArray(0);
+ implementation.GetIntegeri_v(0, 0, nullptr);
+ implementation.BeginTransformFeedback(0);
+ implementation.EndTransformFeedback();
+ implementation.BindBufferRange(0, 0, 0, 0, 0);
+ implementation.BindBufferBase(0, 0, 0);
+ implementation.TransformFeedbackVaryings(0, 0, nullptr, 0);
+ implementation.GetTransformFeedbackVarying(0, 0, 0, nullptr, nullptr, nullptr, nullptr);
+ implementation.VertexAttribIPointer(0, 0, 0, 0, nullptr);
+ implementation.GetVertexAttribIiv(0, 0, nullptr);
+ implementation.GetVertexAttribIuiv(0, 0, nullptr);
+ implementation.VertexAttribI4i(0, 0, 0, 0, 0);
+ implementation.VertexAttribI4ui(0, 0, 0, 0, 0);
+ implementation.VertexAttribI4iv(0, nullptr);
+ implementation.VertexAttribI4uiv(0, nullptr);
+ implementation.GetUniformuiv(0, 0, nullptr);
+ implementation.GetFragDataLocation(0, nullptr);
+ implementation.Uniform1ui(0, 0);
+ implementation.Uniform2ui(0, 0, 0);
+ implementation.Uniform3ui(0, 0, 0, 0);
+ implementation.Uniform4ui(0, 0, 0, 0, 0);
+ implementation.Uniform1uiv(0, 0, nullptr);
+ implementation.Uniform2uiv(0, 0, nullptr);
+ implementation.Uniform3uiv(0, 0, nullptr);
+ implementation.Uniform4uiv(0, 0, nullptr);
+ implementation.ClearBufferiv(0, 0, nullptr);
+ implementation.ClearBufferuiv(0, 0, nullptr);
+ implementation.ClearBufferfv(0, 0, nullptr);
+ implementation.ClearBufferfi(0, 0, 0, 0);
+ implementation.GetStringi(0, 0);
+ implementation.CopyBufferSubData(0, 0, 0, 0, 0);
+ implementation.GetUniformIndices(0, 0, nullptr, nullptr);
+ implementation.GetActiveUniformsiv(0, 0, nullptr, 0, nullptr);
+ implementation.GetUniformBlockIndex(0, nullptr);
+ implementation.GetActiveUniformBlockiv(0, 0, 0, nullptr);
+ implementation.GetActiveUniformBlockName(0, 0, 0, nullptr, nullptr);
+ implementation.UniformBlockBinding(0, 0, 0);
+ implementation.DrawArraysInstanced(0, 0, 0, 0);
+ implementation.DrawElementsInstanced(0, 0, 0, nullptr, 0);
+ implementation.FenceSync(0, 0);
+ implementation.IsSync(0);
+ implementation.DeleteSync(0);
+ implementation.ClientWaitSync(0, 0, 0);
+ implementation.WaitSync(0, 0, 0);
+ implementation.GetInteger64v(0, nullptr);
+ implementation.GetSynciv(0, 0, 0, nullptr, nullptr);
+ implementation.GetInteger64i_v(0, 0, nullptr);
+ implementation.GetBufferParameteri64v(0, 0, nullptr);
+ implementation.GenSamplers(0, nullptr);
+ implementation.DeleteSamplers(0, nullptr);
+ implementation.IsSampler(0);
+ implementation.BindSampler(0, 0);
+ implementation.SamplerParameteri(0, 0, 0);
+ implementation.SamplerParameteriv(0, 0, nullptr);
+ implementation.SamplerParameterf(0, 0, 0);
+ implementation.SamplerParameterfv(0, 0, nullptr);
+ implementation.GetSamplerParameteriv(0, 0, nullptr);
+ implementation.GetSamplerParameterfv(0, 0, nullptr);
+ implementation.VertexAttribDivisor(0, 0);
+ implementation.BindTransformFeedback(0, 0);
+ implementation.DeleteTransformFeedbacks(0, nullptr);
+ implementation.GenTransformFeedbacks(0, nullptr);
+ implementation.IsTransformFeedback(0);
+ implementation.PauseTransformFeedback();
+ implementation.ResumeTransformFeedback();
+ implementation.GetProgramBinary(0, 0, nullptr, nullptr, nullptr);
+ implementation.ProgramBinary(0, 0, nullptr, 0);
+ implementation.ProgramParameteri(0, 0, 0);
+ implementation.InvalidateFramebuffer(0, 0, nullptr);
+ implementation.InvalidateSubFramebuffer(0, 0, nullptr, 0, 0, 0, 0);
+ implementation.TexStorage2D(0, 0, 0, 0, 0);
+ implementation.TexStorage3D(0, 0, 0, 0, 0, 0);
+ implementation.GetInternalformativ(0, 0, 0, 0, nullptr);
+ implementation.BlendBarrier();
+ DALI_TEST_CHECK(true); // Should get here!
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(false); // Should not get here!
+ }
+}
+
+template<typename Impl>
+void CreateWithBaseClassPtr()
+{
+ // This derived destructor of the class is called which is purely for increasing function coverage
+ GlesAbstraction* abstraction = new Impl;
+ try
+ {
+ abstraction->ReadBuffer(0);
+ DALI_TEST_CHECK(true);
+ }
+ catch(...)
+ {
+ DALI_TEST_CHECK(false);
+ }
+ delete abstraction;
+}
+
+} // unnamed namespace
+
+int UtcDaliGles2ImplementationConstruction(void)
+{
+ CreateWithBaseClassPtr<Gles2Implementation>();
+ END_TEST;
+}
+
+int UtcDaliGles3ImplementationConstruction(void)
+{
+ CreateWithBaseClassPtr<Gles3Implementation>();
+ END_TEST;
+}
+
+int UtcDaliGles2ImplementationMethods(void)
+{
+ Gles2Implementation implementation;
+ CallAllMethods(implementation);
+ END_TEST;
+}
+
+int UtcDaliGles3ImplementationMethods(void)
+{
+ Gles3Implementation implementation;
+ CallAllMethods(implementation);
+ END_TEST;
+}
\ No newline at end of file
struct Error
{
std::string message;
- ErrorType errorType{ErrorType::DEFAULT};
+ ErrorType errorType{ErrorType::DEFAULT};
Error() = default;
Error(std::string msg, ErrorType errorType = ErrorType::DEFAULT)
constexpr char* xcopy_n(const char* src, size_t n, char* dst)
{
for(std::size_t i = 0; i < n; ++i)
+ {
dst[i] = src[i];
+ }
return dst + n;
}
-template<std::size_t N>
-constexpr std::size_t xlen(const char (&)[N])
+template<std::size_t L, std::size_t R>
+constexpr char_array<L + R - 1> concat_internal(const char_array<L> lhs, const char_array<R> rhs)
{
- return N - 1;
-}
+ char_array<L + R - 1> arr{};
+ char* ptr = arr.data();
-template<std::size_t N>
-constexpr std::size_t xlen(const char_array<N>&)
-{
- return N - 1;
-}
+ if constexpr(!arr.empty())
+ {
+ ptr = xcopy_n(std::data(lhs), L - 1, ptr);
+ ptr = xcopy_n(std::data(rhs), R - 1, ptr);
+ *ptr = 0;
+ }
-template<typename... Args>
-constexpr auto concat(const Args&... args)
+ return arr;
+}
+template<std::size_t L>
+constexpr char_array<L> convert_internal(const char (&str)[L])
{
- char_array<(1U + ... + xlen(args))> arr{};
- char* ptr = arr.data();
+ char_array<L> arr{};
+ char* ptr = arr.data();
if constexpr(!arr.empty())
- ((ptr = xcopy_n(std::data(args), xlen(args), ptr)), ...);
+ {
+ ptr = xcopy_n(std::data(str), L, ptr);
+ }
return arr;
}
+template<std::size_t L, std::size_t R>
+constexpr char_array<L + R - 1> concat(const char_array<L> lhs, const char_array<R> rhs)
+{
+ return concat_internal(lhs, rhs);
+}
+template<std::size_t L, std::size_t R>
+constexpr char_array<L + R - 1> concat(const char (&lhs)[L], const char_array<R> rhs)
+{
+ return concat_internal(convert_internal(lhs), rhs);
+}
+template<std::size_t L, std::size_t R>
+constexpr char_array<L + R - 1> concat(const char_array<L> lhs, const char (&rhs)[R])
+{
+ return concat_internal(lhs, convert_internal(rhs));
+}
+template<std::size_t L, std::size_t R>
+constexpr char_array<L + R - 1> concat(const char (&lhs)[L], const char (&rhs)[R])
+{
+ return concat_internal(convert_internal(lhs), convert_internal(rhs));
+}
+template<std::size_t L>
+constexpr char_array<L> concat(const char (&str)[L])
+{
+ return convert_internal(str);
+}
+template<std::size_t L>
+constexpr char_array<L> concat(const char_array<L> str)
+{
+ return str;
+}
template<std::size_t... Digits>
struct to_chars
struct signature<float> : signature_helper<signature<float>>
{
static constexpr auto name_v = concat("float");
- static constexpr auto sig_v = concat("d");
+ static constexpr auto sig_v = concat("f");
/**
* @brief Marshals value v as marshalled type into message
{
using current_type = typename signature_tuple_element_type_helper<INDEX, ARGS...>::type;
- static constexpr auto name_v = concat(signature<current_type>::name_v, ", ", signature_tuple_helper<INDEX + 1, SIZE, ARGS...>::name_v);
+ static constexpr auto name_v = concat(signature<current_type>::name_v, concat(", ", signature_tuple_helper<INDEX + 1, SIZE, ARGS...>::name_v));
static constexpr auto sig_v = concat(signature<current_type>::sig_v, signature_tuple_helper<INDEX + 1, SIZE, ARGS...>::sig_v);
/**
template<typename... ARGS>
struct signature<std::tuple<ARGS...>> : signature_helper<signature<std::tuple<ARGS...>>>
{
- static constexpr auto name_v = concat("tuple<", signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::name_v, ">");
- static constexpr auto sig_v = concat("(", signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::sig_v, ")");
+ static constexpr auto name_v = concat("tuple<", concat(signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::name_v, ">"));
+ static constexpr auto sig_v = concat("(", concat(signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::sig_v, ")"));
/**
* @brief Marshals value v as marshalled type into message
template<typename... ARGS>
struct signature<ValueOrError<ARGS...>> : signature_helper<signature<ValueOrError<ARGS...>>>
{
- static constexpr auto name_v = concat("ValueOrError<", signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::name_v, ">");
+ static constexpr auto name_v = concat("ValueOrError<", concat(signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::name_v, ">"));
static constexpr auto sig_v = signature_tuple_helper<0, sizeof...(ARGS), ARGS...>::sig_v;
/**
template<typename A, typename B>
struct signature<std::pair<A, B>> : signature_helper<signature<std::pair<A, B>>>
{
- static constexpr auto name_v = concat("pair<", signature_tuple_helper<0, 2, A, B>::name_v, ">");
- static constexpr auto sig_v = concat("(", signature_tuple_helper<0, 2, A, B>::sig_v, ")");
+ static constexpr auto name_v = concat("pair<", concat(signature_tuple_helper<0, 2, A, B>::name_v, ">"));
+ static constexpr auto sig_v = concat("(", concat(signature_tuple_helper<0, 2, A, B>::sig_v, ")"));
/**
* @brief Marshals value v as marshalled type into message
template<typename A>
struct signature<std::vector<A>> : signature_helper<signature<std::vector<A>>>
{
- static constexpr auto name_v = concat("vector<", signature<A>::name_v, ">");
+ static constexpr auto name_v = concat("vector<", concat(signature<A>::name_v, ">"));
static constexpr auto sig_v = concat("a", signature<A>::sig_v);
/**
template<typename A, size_t N>
struct signature<std::array<A, N>> : signature_helper<signature<std::array<A, N>>>
{
- static constexpr auto name_v = concat("array<", signature<A>::name_v, ", ", to_string<N>::value, ">");
+ static constexpr auto name_v = concat("array<", concat(signature<A>::name_v, concat(", ", concat(to_string<N>::value, ">"))));
static constexpr auto sig_v = concat("a", signature<A>::sig_v);
/**
template<typename A>
struct signature<EldbusVariant<A>> : signature_helper<signature<EldbusVariant<A>>>
{
- static constexpr auto name_v = concat("variant<", signature<A>::name_v, ">");
+ static constexpr auto name_v = concat("variant<", concat(signature<A>::name_v, ">"));
static constexpr auto sig_v = concat("v");
/**
template<typename A, typename B>
struct signature<std::unordered_map<A, B>> : signature_helper<signature<std::unordered_map<A, B>>>
{
- static constexpr auto name_v = concat("unordered_map<", signature<A>::name_v, ", ", signature<B>::name_v, ">");
- static constexpr auto sig_v = concat("a{", signature_tuple_helper<0, 2, A, B>::sig_v, "}");
+ static constexpr auto name_v = concat("unordered_map<", concat(signature<A>::name_v, concat(", ", concat(signature<B>::name_v, ">"))));
+ static constexpr auto sig_v = concat("a{", concat(signature_tuple_helper<0, 2, A, B>::sig_v, "}"));
/**
* @brief Marshals value v as marshalled type into message
template<typename A, typename B>
struct signature<std::map<A, B>> : signature_helper<signature<std::map<A, B>>>
{
- static constexpr auto name_v = concat("map<", signature<A>::name_v, ", ", signature<B>::name_v, ">");
- static constexpr auto sig_v = concat("a{", signature_tuple_helper<0, 2, A, B>::sig_v, "}");
+ static constexpr auto name_v = concat("map<", concat(signature<A>::name_v, concat(", ", concat(signature<B>::name_v, ">"))));
+ static constexpr auto sig_v = concat("a{", concat(signature_tuple_helper<0, 2, A, B>::sig_v, "}"));
/**
* @brief Marshals value v as marshalled type into message
template<typename A>
struct signature<const A&> : signature_helper<signature<const A&>>
{
- static constexpr auto name_v = concat("const ", signature<A>::name_v, "&");
+ static constexpr auto name_v = concat("const ", concat(signature<A>::name_v, "&"));
static constexpr auto sig_v = signature<A>::sig_v;
/**
mObjectProfiler = new ObjectProfiler(mCore->GetObjectRegistry(), timeInterval);
}
+ const uint32_t poolTimeInterval = mEnvironmentOptions->GetMemoryPoolInterval();
+ if(0u < poolTimeInterval)
+ {
+ mMemoryPoolTimer = Dali::Timer::New(poolTimeInterval * 1000);
+ mMemoryPoolTimer.TickSignal().Connect(mMemoryPoolTimerSlotDelegate, &Adaptor::MemoryPoolTimeout);
+ mMemoryPoolTimer.Start();
+ }
+
mNotificationTrigger = TriggerEventFactory::CreateTriggerEvent(MakeCallback(this, &Adaptor::ProcessCoreEvents), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER);
mDisplayConnection = Dali::DisplayConnection::New(*mGraphics, defaultWindow->GetSurface()->GetSurfaceType());
mKernelTracer(),
mSystemTracer(),
mObjectProfiler(nullptr),
+ mMemoryPoolTimerSlotDelegate(this),
mSocketFactory(),
mMutex(),
mThreadMode(threadMode),
mCallbackManager->RemoveIdleEntererCallback(callback);
}
+bool Adaptor::MemoryPoolTimeout()
+{
+ mCore->LogMemoryPools();
+ return true; // Keep logging forever
+}
+
} // namespace Adaptor
} // namespace Internal
#define DALI_INTERNAL_ADAPTOR_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.
// EXTERNAL INCLUDES
#include <dali/devel-api/threading/mutex.h>
#include <dali/integration-api/render-controller.h>
+#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/math/rect.h>
#include <dali/public-api/math/uint-16-pair.h>
*/
void RemoveIdleEnterer(CallbackBase* callback);
+ /**
+ * Trigger to log the memory pools from Core and Adaptor
+ */
+ bool MemoryPoolTimeout();
+
private:
/**
* Constructor
KernelTrace mKernelTracer; ///< Kernel tracer
SystemTrace mSystemTracer; ///< System tracer
ObjectProfiler* mObjectProfiler; ///< Tracks object lifetime for profiling
- SocketFactory mSocketFactory; ///< Socket factory
- Mutex mMutex; ///< Mutex
- ThreadMode mThreadMode; ///< The thread mode
- const bool mEnvironmentOptionsOwned : 1; ///< Whether we own the EnvironmentOptions (and thus, need to delete it)
- bool mUseRemoteSurface : 1; ///< whether the remoteSurface is used or not
- Dali::LayoutDirection::Type mRootLayoutDirection; ///< LayoutDirection of window
+ Dali::Timer mMemoryPoolTimer; ///< Logs memory pool capacity
+ SlotDelegate<Adaptor> mMemoryPoolTimerSlotDelegate;
+ SocketFactory mSocketFactory; ///< Socket factory
+ Mutex mMutex; ///< Mutex
+ ThreadMode mThreadMode; ///< The thread mode
+ const bool mEnvironmentOptionsOwned : 1; ///< Whether we own the EnvironmentOptions (and thus, need to delete it)
+ bool mUseRemoteSurface : 1; ///< whether the remoteSurface is used or not
+ Dali::LayoutDirection::Type mRootLayoutDirection; ///< LayoutDirection of window
std::unique_ptr<Integration::AddOnManager> mAddOnManager; ///< Pointer to the addon manager
#include <dali/internal/adaptor/common/combined-update-render-controller-debug.h>
#include <dali/internal/graphics/common/graphics-interface.h>
#include <dali/internal/graphics/gles/egl-graphics.h>
-#include <dali/internal/graphics/gles/egl-implementation.h>
#include <dali/internal/system/common/environment-options.h>
#include <dali/internal/system/common/time-service.h>
#include <dali/internal/window-system/common/window-impl.h>
// Update time
uint64_t lastFrameTime;
TimeService::GetNanoseconds(lastFrameTime);
+ uint64_t lastMemPoolLogTime = lastFrameTime;
LOG_UPDATE_RENDER("THREAD INITIALISED");
uint64_t timeToSleepUntil = 0;
int extraFramesDropped = 0;
+ const uint64_t memPoolInterval = mEnvironmentOptions.GetMemoryPoolInterval() * NANOSECONDS_PER_SECOND;
+
const unsigned int renderToFboInterval = mEnvironmentOptions.GetRenderToFboInterval();
const bool renderToFboEnabled = 0u != renderToFboInterval;
unsigned int frameCount = 0u;
// RENDER
//////////////////////////////
+ graphics.FrameStart();
mAdaptorInterfaces.GetDisplayConnectionInterface().ConsumeEvents();
if(mPreRenderCallback != NULL)
TRACE_UPDATE_RENDER_END("DALI_RENDER");
AddPerformanceMarker(PerformanceInterface::RENDER_END);
+ // if the memory pool interval is set and has elapsed, log the graphics memory pools
+ if(0 < memPoolInterval && memPoolInterval < lastFrameTime - lastMemPoolLogTime)
+ {
+ lastMemPoolLogTime = lastFrameTime;
+ graphics.LogMemoryPools();
+ }
+
mForceClear = false;
// Trigger event thread to request Update/Render thread to sleep if update not required
*/
virtual void CacheConfigurations(ConfigurationManager& configurationManager) = 0;
+ /**
+ * Initialize data for logging frame info
+ */
+ virtual void FrameStart() = 0;
+
+ /**
+ * Log total capacity of memory pools during this frame
+ */
+ virtual void LogMemoryPools() = 0;
+
protected:
Integration::DepthBufferAvailable mDepthBufferRequired; ///< Whether the depth buffer is required
Integration::StencilBufferAvailable mStencilBufferRequired; ///< Whether the stencil buffer is required
void EglGraphicsController::InitializeGLES(Integration::GlAbstraction& glAbstraction)
{
- DALI_LOG_RELEASE_INFO("Initializing New Graphics Controller #1\n");
+ DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 1\n");
mGlAbstraction = &glAbstraction;
mContext = std::make_unique<GLES::Context>(*this);
mCurrentContext = mContext.get();
Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
Internal::Adaptor::GraphicsInterface& graphicsInterface)
{
- DALI_LOG_RELEASE_INFO("Initializing New Graphics Controller #2\n");
+ DALI_LOG_RELEASE_INFO("Initializing Graphics Controller Phase 2\n");
auto* syncImplPtr = static_cast<Internal::Adaptor::EglSyncImplementation*>(&syncImplementation);
mEglSyncImplementation = syncImplPtr;
mGraphics = &graphicsInterface;
}
+void EglGraphicsController::FrameStart()
+{
+ mCapacity = 0; // Reset the command buffer capacity at the start of the frame.
+}
+
void EglGraphicsController::SubmitCommandBuffers(const SubmitInfo& submitInfo)
{
for(auto& cmdbuf : submitInfo.cmdBuffer)
{
// Push command buffers
- mCommandQueue.push(static_cast<GLES::CommandBuffer*>(cmdbuf));
+ auto* commandBuffer = static_cast<GLES::CommandBuffer*>(cmdbuf);
+ mCapacity += commandBuffer->GetCapacity();
+ mCommandQueue.push(commandBuffer);
}
// If flush bit set, flush all pending tasks
properties.compressed = glesTexture->IsCompressed();
properties.extent2D = createInfo.size;
properties.nativeHandle = glesTexture->GetGLTexture();
- //TODO: Skip format1, emulated, packed, directWriteAccessEnabled of TextureProperties for now
+ // TODO: Skip format1, emulated, packed, directWriteAccessEnabled of TextureProperties for now
return properties;
}
void EglGraphicsController::DeleteSurfaceContext(Dali::RenderSurfaceInterface* surface)
{
mSurfaceContexts.erase(std::remove_if(
- mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter) { return surface == iter.first; }),
+ mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter)
+ { return surface == iter.first; }),
mSurfaceContexts.end());
}
{
mCurrentContext = mContext.get();
mCurrentContext->GlContextCreated();
-
if(!mSharedContext)
{
auto eglGraphics = dynamic_cast<Dali::Internal::Adaptor::EglGraphics*>(mGraphics);
{
if(surface && mGraphics->IsResourceContextSupported())
{
- auto iter = std::find_if(mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter) {
- return (iter.first == surface);
- });
+ auto iter = std::find_if(mSurfaceContexts.begin(), mSurfaceContexts.end(), [surface](SurfaceContextPair& iter)
+ { return (iter.first == surface); });
if(iter != mSurfaceContexts.end())
{
Internal::Adaptor::EglSyncImplementation& GetEglSyncImplementation();
/**
+ * Mark the start of the frame.
+ *
+ * Note, this is used for logging & debugging, so is not part of the main Graphics API.
+ */
+ void FrameStart();
+
+ /**
* @copydoc Dali::Graphics::SubmitCommandBuffers()
*/
void SubmitCommandBuffers(const SubmitInfo& submitInfo) override;
return mSyncPool;
}
+ std::size_t GetCapacity() const
+ {
+ return mCapacity;
+ }
+
private:
Integration::GlAbstraction* mGlAbstraction{nullptr};
Integration::GlContextHelperAbstraction* mGlContextHelperAbstraction{nullptr};
GLES::TextureDependencyChecker mTextureDependencyChecker; // Checks if FBO textures need syncing
GLES::SyncPool mSyncPool;
+ std::size_t mCapacity; ///< Memory Usage (of command buffers)
};
} // namespace Graphics
} // namespace Dali
-#endif //DALI_EGL_GRAPHICS_CONTROLLER_H
+#endif // DALI_EGL_GRAPHICS_CONTROLLER_H
inline void resize(int newSize)
{
ptr = reinterpret_cast<T*>(realloc(ptr, newSize * sizeof(T)));
- capacity = newSize;
+ capacity = newSize * sizeof(T);
dataSize = newSize;
}
size = commandPool.size;
return commandPool.data.ptr;
}
+
+ std::size_t GetTotalCapacity() const
+ {
+ return commandPool.data.capacity + memoryPool.data.capacity;
+ }
};
CommandBuffer::CommandBuffer(const Graphics::CommandBufferCreateInfo& createInfo, EglGraphicsController& controller)
GetController().DiscardResource(this);
}
+std::size_t CommandBuffer::GetCapacity()
+{
+ std::size_t total{0u};
+ if(mCommandPool)
+ {
+ total = mCommandPool->GetTotalCapacity();
+ }
+ return total;
+}
+
} // namespace Dali::Graphics::GLES
*/
void DiscardResource() override;
+ // Get the total memory usage of this command buffer
+ std::size_t GetCapacity();
+
private:
std::unique_ptr<CommandPool> mCommandPool; ///< Pool of commands and transient memory
};
// INTERNAL INCLUDES
#include <dali/integration-api/adaptor-framework/render-surface-interface.h>
+#include <dali/integration-api/debug.h>
#include <dali/internal/system/common/configuration-manager.h>
#include <dali/internal/system/common/environment-options.h>
#include <dali/internal/window-system/common/display-utils.h> // For Utils::MakeUnique
mGLES->SetShadingLanguageVersion(configurationManager.GetShadingLanguageVersion());
}
+void EglGraphics::FrameStart()
+{
+ mGraphicsController.FrameStart();
+}
+
+void EglGraphics::LogMemoryPools()
+{
+ std::size_t graphicsCapacity = mGraphicsController.GetCapacity();
+ DALI_LOG_RELEASE_INFO(
+ "EglGraphics:\n"
+ " GraphicsController Capacity: %lu\n",
+ graphicsCapacity);
+}
+
} // namespace Adaptor
} // namespace Internal
} // namespace Dali
void CacheConfigurations(ConfigurationManager& configurationManager) override;
+ /**
+ * @copydoc Dali::Internal::Adaptor::GraphicsInterface::FrameStart()
+ */
+ void FrameStart() override;
+
+ /**
+ * @copydoc Dali::Internal::Adaptor::GraphicsInterface::LogMemoryPools()
+ */
+ void LogMemoryPools() override;
+
private:
// Eliminate copy and assigned operations
- EglGraphics(const EglGraphics& rhs) = delete;
+ EglGraphics(const EglGraphics& rhs) = delete;
EglGraphics& operator=(const EglGraphics& rhs) = delete;
/**
#include <cstring>
// INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
#include <dali/internal/imaging/common/alpha-mask.h>
#include <dali/internal/imaging/common/gaussian-blur.h>
#include <dali/internal/imaging/common/image-operations.h>
{
namespace
{
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gPixelBufferFilter = Debug::Filter::New(Debug::NoLogging, false, "DALI_LOG_PIXEL_BUFFER_SIZE");
+#endif
+
const float TWO_PI = 2.f * Math::PI; ///< 360 degrees in radians
// based on W3C Recommendations (https://www.w3.org/TR/AERT/#color-contrast)
constexpr uint32_t BRIGHTNESS_CONSTANT_R = 299;
constexpr uint32_t BRIGHTNESS_CONSTANT_B = 114;
} // namespace
+#if defined(DEBUG_ENABLED)
+uint32_t PixelBuffer::gPixelBufferAllocationTotal{0};
+#endif
+
PixelBuffer::PixelBuffer(uint8_t* buffer,
uint32_t bufferSize,
uint32_t width,
if(bufferSize > 0)
{
buffer = static_cast<uint8_t*>(malloc(bufferSize));
+#if defined(DEBUG_ENABLED)
+ gPixelBufferAllocationTotal += bufferSize;
+#endif
}
+ DALI_LOG_INFO(gPixelBufferFilter, Debug::Concise, "Allocated PixelBuffer of size %u\n", bufferSize);
+
return new PixelBuffer(buffer, bufferSize, width, height, width, pixelFormat);
}
Dali::PixelData PixelBuffer::Convert(PixelBuffer& pixelBuffer)
{
+#if defined(DEBUG_ENABLED)
+ gPixelBufferAllocationTotal -= pixelBuffer.mBufferSize;
+#endif
Dali::PixelData pixelData = Dali::PixelData::New(pixelBuffer.mBuffer,
pixelBuffer.mBufferSize,
pixelBuffer.mWidth,
{
if(mBuffer)
{
+#if defined(DEBUG_ENABLED)
+ gPixelBufferAllocationTotal -= mBufferSize;
+#endif
free(mBuffer);
}
}
ReleaseBuffer();
mBuffer = reinterpret_cast<unsigned char*>(malloc(size));
mBufferSize = size;
+#if defined(DEBUG_ENABLED)
+ gPixelBufferAllocationTotal += size;
+#endif
}
bool PixelBuffer::Rotate(Degree angle)
// INTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/integration-api/debug.h>
#include <dali/public-api/images/image-operations.h> // For ImageDimensions
#include <dali/public-api/images/pixel-data.h>
#include <dali/public-api/object/base-object.h>
public:
/**
+ * Get the total allocated size of current pixel buffers
+ */
+ static uint32_t GetTotalAllocatedSize()
+ {
+#if defined(DEBUG_ENABLED)
+ return gPixelBufferAllocationTotal;
+#else
+ return 0;
+#endif
+ }
+
+ /**
* Get the width of the buffer in pixels.
* @return The width of the buffer in pixels
*/
uint32_t mStride; ///< Buffer stride in bytes, 0 means the buffer is tightly packed
Pixel::Format mPixelFormat; ///< Pixel format
bool mPreMultiplied; ///< PreMultiplied
+
+#if defined(DEBUG_ENABLED)
+ static uint32_t gPixelBufferAllocationTotal;
+#endif
};
} // namespace Adaptor
/*
- * 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.
mFpsFrequency(0),
mUpdateStatusFrequency(0),
mObjectProfilerInterval(0),
+ mMemoryPoolInterval(0),
mPerformanceStatsLevel(0),
mPerformanceStatsFrequency(DEFAULT_STATISTICS_LOG_FREQUENCY),
mPerformanceTimeStampOutput(0),
{
return mObjectProfilerInterval;
}
-
+unsigned int EnvironmentOptions::GetMemoryPoolInterval() const
+{
+ return mMemoryPoolInterval;
+}
unsigned int EnvironmentOptions::GetPerformanceStatsLoggingOptions() const
{
return mPerformanceStatsLevel;
mFpsFrequency = GetEnvironmentVariable(DALI_ENV_FPS_TRACKING, 0);
mUpdateStatusFrequency = GetEnvironmentVariable(DALI_ENV_UPDATE_STATUS_INTERVAL, 0);
mObjectProfilerInterval = GetEnvironmentVariable(DALI_ENV_OBJECT_PROFILER_INTERVAL, 0);
+ mMemoryPoolInterval = GetEnvironmentVariable(DALI_ENV_MEMORY_POOL_INTERVAL, 0);
mPerformanceStatsLevel = GetEnvironmentVariable(DALI_ENV_LOG_PERFORMANCE_STATS, 0);
mPerformanceStatsFrequency = GetEnvironmentVariable(DALI_ENV_LOG_PERFORMANCE_STATS_FREQUENCY, 0);
mPerformanceTimeStampOutput = GetEnvironmentVariable(DALI_ENV_PERFORMANCE_TIMESTAMP_OUTPUT, 0);
#define DALI_INTERNAL_ADAPTOR_ENVIRONMENT_OPTIONS_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.
unsigned int GetObjectProfilerInterval() const;
/**
+ * @return memory pool status interval (0==off)
+ */
+ unsigned int GetMemoryPoolInterval() const;
+
+ /**
* @return performance statistics log level ( 0 == off )
*/
unsigned int GetPerformanceStatsLoggingOptions() const;
unsigned int mFpsFrequency; ///< how often fps is logged out in seconds
unsigned int mUpdateStatusFrequency; ///< how often update status is logged out in frames
unsigned int mObjectProfilerInterval; ///< how often object counts are logged out in seconds
+ uint32_t mMemoryPoolInterval; ///< how often memory pool capacities are logged out in seconds
unsigned int mPerformanceStatsLevel; ///< performance statistics logging bitmask
unsigned int mPerformanceStatsFrequency; ///< performance statistics logging frequency (seconds)
unsigned int mPerformanceTimeStampOutput; ///< performance time stamp output ( bitmask)
#define DALI_INTERNAL_ADAPTOR_ENVIRONMENT_VARIABLES_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.
#define DALI_ENV_UPDATE_STATUS_INTERVAL "DALI_UPDATE_STATUS_INTERVAL"
#define DALI_ENV_OBJECT_PROFILER_INTERVAL "DALI_OBJECT_PROFILER_INTERVAL"
+#define DALI_ENV_MEMORY_POOL_INTERVAL "DALI_MEMORY_POOL_INTERVAL"
// Pan-Gesture configuration:
// Prediction Modes 1 & 2:
/*
- * Copyright (c) 20217 Samsung Electronics Co., Ltd.
+ * Copyright (c) 20227 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.
// EXTERNAL INCLUDES
#include <dali/integration-api/debug.h>
#include <dali/integration-api/profiling.h>
+#include <dali/internal/imaging/common/pixel-buffer-impl.h>
+#include <dali/public-api/images/pixel-data.h>
#include <dali/public-api/object/base-object.h>
#include <dali/public-api/object/ref-object.h>
#include <dali/public-api/object/type-registry.h>
+
#include <stdlib.h>
using std::string;
bool ObjectProfiler::OnTimeout()
{
+ uint32_t pixelDataSize = Dali::PixelData::GetTotalAllocatedSize();
+ uint32_t pixelBufferSize = Dali::Internal::Adaptor::PixelBuffer::GetTotalAllocatedSize();
+ LogMessage(Debug::DebugInfo, "Total PixelData: %9.1fkb\n", ((float)pixelDataSize) / 1024.0f);
+ LogMessage(Debug::DebugInfo, "Total PixelBuffer: %9.1fkb\n", ((float)pixelBufferSize) / 1024.0f);
+
DisplayInstanceCounts();
return true;
}
{
auto&& countIter = std::find_if(mInstanceCountContainer.begin(),
mInstanceCountContainer.end(),
- [theType](const InstanceCountPair& instance) { return instance.first == theType; });
+ [theType](const InstanceCountPair& instance)
+ { return instance.first == theType; });
if(countIter != mInstanceCountContainer.end())
{
(*countIter).second--;