From: Richard Huang Date: Fri, 29 Jul 2022 11:13:05 +0000 (+0100) Subject: [dali_2.1.33] Merge branch 'devel/master' X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=1f5f10ff81ed70d033cbc236216dda5ea5a1b8e4;hp=c9838bbf5eb41f8475bcef2198b338f7020b0397 [dali_2.1.33] Merge branch 'devel/master' Change-Id: Ie6ceafed11dd2c4b56ba111d237ce17ff98d0be9 --- diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp index e6456ec..a8f3ab8 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-vector-animation-renderer.cpp @@ -129,6 +129,11 @@ public: mNeedDroppedFrames = false; } + if(mDynamicPropertyCallback) + { + CallbackBase::ExecuteReturn(*mDynamicPropertyCallback, 0, 0, frameNumber); + } + if(mNeedTrigger) { mEventThreadCallback->Trigger(); @@ -190,6 +195,11 @@ public: } } + void AddPropertyValueCallback(const std::string& keyPath, Dali::VectorAnimationRenderer::VectorProperty property, CallbackBase* callback, int32_t id) + { + mDynamicPropertyCallback = std::unique_ptr(callback); + } + Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal() { return mUploadCompletedSignal; @@ -216,23 +226,25 @@ public: public: static uint32_t mCount; - std::string mUrl; - Dali::Renderer mRenderer; - Dali::Mutex mMutex; - uint32_t mWidth; - uint32_t mHeight; - uint32_t mDefaultWidth; - uint32_t mDefaultHeight; - uint32_t mTotalFrameNumber; - uint32_t mPreviousFrame; - uint32_t mDelayTime; - uint32_t mDroppedFrames; - float mFrameRate; - bool mTestFrameDrop; - bool mNeedDroppedFrames; - bool mLoadFailed{false}; - bool mResourceReady{false}; - bool mNeedTrigger{true}; + std::string mUrl; + Dali::Renderer mRenderer; + Dali::Mutex mMutex; + std::unique_ptr mDynamicPropertyCallback{nullptr}; + + uint32_t mWidth; + uint32_t mHeight; + uint32_t mDefaultWidth; + uint32_t mDefaultHeight; + uint32_t mTotalFrameNumber; + uint32_t mPreviousFrame; + uint32_t mDelayTime; + uint32_t mDroppedFrames; + float mFrameRate; + bool mTestFrameDrop; + bool mNeedDroppedFrames; + bool mLoadFailed{false}; + bool mResourceReady{false}; + bool mNeedTrigger{true}; Dali::VectorAnimationRenderer::UploadCompletedSignalType mUploadCompletedSignal; std::unique_ptr mEventThreadCallback; @@ -348,6 +360,11 @@ void VectorAnimationRenderer::InvalidateBuffer() return Internal::Adaptor::GetImplementation(*this).InvalidateBuffer(); } +void VectorAnimationRenderer::AddPropertyValueCallback(const std::string& keyPath, VectorProperty property, CallbackBase* callback, int32_t id) +{ + Internal::Adaptor::GetImplementation(*this).AddPropertyValueCallback(keyPath, property, callback, id); +} + VectorAnimationRenderer::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal() { return Internal::Adaptor::GetImplementation(*this).UploadCompletedSignal(); diff --git a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp index 0529655..4ca6308 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp @@ -34,6 +34,8 @@ #include #include #include + +#include #include #include @@ -709,8 +711,9 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void) Renderer renderer = actor.GetRendererAt(0u); DALI_TEST_CHECK(renderer); - Property::Map map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); - Property::Value* value = map.Find(DevelImageVisual::Property::PLAY_RANGE); + Property::Map map = actor.GetProperty(DummyControl::Property::TEST_VISUAL); + Property::Value* value = map.Find(DevelImageVisual::Property::PLAY_RANGE); + int totalFrameNumber = map.Find(DevelImageVisual::Property::TOTAL_FRAME_NUMBER)->Get(); int resultStartFrame, resultEndFrame; Property::Array* result = value->GetArray(); @@ -744,8 +747,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void) result->GetElementAt(0).Get(resultStartFrame); result->GetElementAt(1).Get(resultEndFrame); - DALI_TEST_EQUALS(startFrame, resultStartFrame, TEST_LOCATION); // Should not be changed - DALI_TEST_EQUALS(endFrame, resultEndFrame, TEST_LOCATION); + DALI_TEST_EQUALS(resultStartFrame, 1, TEST_LOCATION); + DALI_TEST_EQUALS(resultEndFrame, totalFrameNumber - 1, TEST_LOCATION); // Should be clamped DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, Property::Map()); @@ -1854,8 +1857,14 @@ int UtcDaliAnimatedVectorImageVisualSize(void) application.SendNotification(); - // Trigger count is 2 - load, resource ready - DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + // Trigger count is 1 - load + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); + + application.SendNotification(); + application.Render(); + + // Trigger count is 1 - resource ready + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION); textureTrace.Enable(true); @@ -1891,3 +1900,63 @@ int UtcDaliAnimatedVectorImageVisualSize(void) END_TEST; } + +namespace +{ +bool gDynamicPropertyCallbackFired = false; + +Property::Value FillColorCallback(int32_t id, VectorAnimationRenderer::VectorProperty property, uint32_t frameNumber) +{ + gDynamicPropertyCallbackFired = true; + + if(frameNumber < 3) + { + return Vector3(0, 0, 1); + } + else + { + return Vector3(1, 0, 0); + } +} +} // namespace + +int UtcDaliAnimatedVectorImageVisualDynamicProperty(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliAnimatedVectorImageVisualDynamicProperty"); + + VisualFactory factory = VisualFactory::Get(); + Visual::Base visual = factory.CreateVisual(TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions()); + DALI_TEST_CHECK(visual); + + DummyControl actor = DummyControl::New(true); + DummyControlImpl& dummyImpl = static_cast(actor.GetImplementation()); + dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual); + + application.GetScene().Add(actor); + + gDynamicPropertyCallbackFired = false; + + // Set dynamic property + DevelAnimatedVectorImageVisual::DynamicPropertyInfo info; + info.id = 1; + info.keyPath = "Test.Path"; + info.property = static_cast(VectorAnimationRenderer::VectorProperty::FILL_COLOR); + info.callback = MakeCallback(FillColorCallback); + + DevelControl::DoActionExtension(actor, DummyControl::Property::TEST_VISUAL, DevelAnimatedVectorImageVisual::Action::SET_DYNAMIC_PROPERTY, Any(info)); + + Property::Map attributes; + DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes); + + application.SendNotification(); + application.Render(); + + // Trigger count is 2 - load & render a frame + DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION); + + // Test whether the property callback is called + DALI_TEST_EQUALS(gDynamicPropertyCallbackFired, true, TEST_LOCATION); + + END_TEST; +} diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 6609ae5..6313fc9 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -630,7 +630,7 @@ MESSAGE( STATUS "Use pkg configure: " ${ENABLE_PKG_CONFIGURE} ) MESSAGE( STATUS "Vector Based Text Rendering: " ${ENABLE_VECTOR_BASED_TEXT_RENDERING} ) MESSAGE( STATUS "Enable link test: " ${ENABLE_LINK_TEST} ) MESSAGE( STATUS "Configure automated tests: " ${CONFIGURE_AUTOMATED_TESTS} ) -MESSAGE( STATUS "Build Dali Scene3D: " ${BUILD_SCENE3D} ) +MESSAGE( STATUS "Build Dali Scene3D: " ${BUILD_SCENE3D} ) MESSAGE( STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS} ) MESSAGE( STATUS "LDFLAGS: " ${CMAKE_SHARED_LINKER_FLAGS_INIT}${CMAKE_SHARED_LINKER_FLAGS} ) diff --git a/dali-toolkit/devel-api/controls/control-devel.cpp b/dali-toolkit/devel-api/controls/control-devel.cpp index 51e0564..ef1265b 100644 --- a/dali-toolkit/devel-api/controls/control-devel.cpp +++ b/dali-toolkit/devel-api/controls/control-devel.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. @@ -114,6 +114,13 @@ void DoAction(Control& control, Dali::Property::Index visualIndex, Dali::Propert controlDataImpl.DoAction(visualIndex, actionId, attributes); } +void DoActionExtension(Control& control, Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes) +{ + Internal::Control& controlInternal = Toolkit::Internal::GetImplementation(control); + Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(controlInternal); + controlDataImpl.DoActionExtension(visualIndex, actionId, attributes); +} + void SetInputMethodContext(Internal::Control& control, InputMethodContext& inputMethodContext) { Internal::Control::Impl::Get(control).SetInputMethodContext(inputMethodContext); diff --git a/dali-toolkit/devel-api/controls/control-devel.h b/dali-toolkit/devel-api/controls/control-devel.h index 3a94e1b..fe95c70 100644 --- a/dali-toolkit/devel-api/controls/control-devel.h +++ b/dali-toolkit/devel-api/controls/control-devel.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_CONTROL_DEVEL_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. @@ -368,6 +368,18 @@ DALI_TOOLKIT_API Dali::Animation CreateTransition(Internal::Control& DALI_TOOLKIT_API void DoAction(Control& control, Dali::Property::Index visualIndex, Dali::Property::Index actionId, const Dali::Property::Value attributes); /** + * @brief Perform an action on a visual registered to this control. + * + * Visuals will have actions, this API is used to perform one of these actions with the given attributes. + * + * @param[in] control The control. + * @param[in] visualIndex The Property index of the visual. + * @param[in] actionId The action to perform. See Visual to find supported actions. + * @param[in] attributes Optional attributes for the action. + */ +DALI_TOOLKIT_API void DoActionExtension(Control& control, Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes); + +/** * @brief Set input method context. * * @param[in] control The control. diff --git a/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h b/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h index ecb91ae..33c88e0 100644 --- a/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h +++ b/dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_DEVEL_API_VISUALS_ANIMATED_VECTOR_IMAGE_VISUAL_ACTIONS_DEVEL_H /* - * 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. @@ -17,7 +17,11 @@ * limitations under the License. * */ + +// EXTERNAL INCLUDES #include +#include +#include namespace Dali { @@ -39,10 +43,35 @@ enum Type PAUSE, ///< Pause the animated vector image. STOP, ///< Stop the animated vector image. This is also Default playback mode. JUMP_TO, ///< Jump to the specified frame. Property::INTEGER value should be passed. + SET_DYNAMIC_PROPERTY ///< Set the dynamic property. }; } // namespace Action +/** + * @brief The dynamic property info + * + * @note A callback of the following type may be used: + * @code + * Property::Value MyFunction(int32_t id, VectorAnimationRenderer::VectorProperty property, uint32_t frameNumber); + * @endcode + * + * id The id to specify the callback. + * property The property that represent what you are trying to change. + * frameNumber The current frame number. + * It returns a Property::Value to set according to the property type. + * + * The callback will be called on the worker thread. You MUST not call other DALi methods in the callback. + * And the object must still be alive when the callback occurs if you make the callback from a class member function. + */ +struct DynamicPropertyInfo +{ + int32_t id; ///< The Id to specify the callback. It should be unique and will be passed when the callback is called. + std::string keyPath; ///< The key path used to target a specific content or a set of contents that will be updated. + int32_t property; ///< The property to set. + CallbackBase* callback; ///< The callback that gets called every time the animation is rendered. Ownership of the callback is passed onto the visual. +}; + } // namespace DevelAnimatedVectorImageVisual } // namespace Toolkit diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index b967d14..4c74704 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -1096,6 +1096,15 @@ void Control::Impl::DoAction(Dali::Property::Index visualIndex, Dali::Property:: } } +void Control::Impl::DoActionExtension(Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes) +{ + RegisteredVisualContainer::Iterator iter; + if(FindVisual(visualIndex, mVisuals, iter)) + { + Toolkit::GetImplementation((*iter)->visual).DoActionExtension(actionId, attributes); + } +} + void Control::Impl::AppendAccessibilityAttribute(const std::string& key, const std::string value) { Property::Value* checkedValue = mAccessibilityAttributes.Find(key); diff --git a/dali-toolkit/internal/controls/control/control-data-impl.h b/dali-toolkit/internal/controls/control/control-data-impl.h index 793fc22..46cc97b 100644 --- a/dali-toolkit/internal/controls/control/control-data-impl.h +++ b/dali-toolkit/internal/controls/control/control-data-impl.h @@ -224,6 +224,11 @@ public: void DoAction(Dali::Property::Index visualIndex, Dali::Property::Index actionId, const Dali::Property::Value attributes); /** + * @copydoc Dali::Toolkit::DevelControl::DoActionExtension() + */ + void DoActionExtension(Dali::Property::Index visualIndex, Dali::Property::Index actionId, Dali::Any attributes); + + /** * @brief Function used to set control properties. * @param[in] object The object whose property to set * @param[in] index The index of the property to set diff --git a/dali-toolkit/internal/controls/scene3d-view/gltf-loader.h b/dali-toolkit/internal/controls/scene3d-view/gltf-loader.h index 7303324..9672929 100644 --- a/dali-toolkit/internal/controls/scene3d-view/gltf-loader.h +++ b/dali-toolkit/internal/controls/scene3d-view/gltf-loader.h @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include #include #include diff --git a/dali-toolkit/internal/transition/transition-impl.h b/dali-toolkit/internal/transition/transition-impl.h index 7230e2b..22cc01f 100644 --- a/dali-toolkit/internal/transition/transition-impl.h +++ b/dali-toolkit/internal/transition/transition-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_TRANSITION_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. @@ -24,6 +24,7 @@ #include // EXTERNAL INCLUDES +#include #include namespace Dali diff --git a/dali-toolkit/internal/transition/transition-set-impl.h b/dali-toolkit/internal/transition/transition-set-impl.h index eb9962d..b980a46 100644 --- a/dali-toolkit/internal/transition/transition-set-impl.h +++ b/dali-toolkit/internal/transition/transition-set-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_TRANSITION_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. @@ -24,6 +24,7 @@ // EXTERNAL INCLUDES #include +#include #include #include diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp index 4b547b4..1f73f80 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp @@ -489,6 +489,22 @@ void AnimatedVectorImageVisual::OnDoAction(const Property::Index actionId, const TriggerVectorRasterization(); } +void AnimatedVectorImageVisual::OnDoActionExtension(const Property::Index actionId, Dali::Any attributes) +{ + switch(actionId) + { + case DevelAnimatedVectorImageVisual::Action::SET_DYNAMIC_PROPERTY: + { + DevelAnimatedVectorImageVisual::DynamicPropertyInfo info = AnyCast(attributes); + mAnimationData.dynamicProperties.push_back(info); + mAnimationData.resendFlag |= VectorAnimationTask::RESEND_DYNAMIC_PROPERTY; + break; + } + } + + TriggerVectorRasterization(); +} + void AnimatedVectorImageVisual::OnResourceReady(VectorAnimationTask::ResourceStatus status) { if(status == VectorAnimationTask::ResourceStatus::LOADED) diff --git a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h index 221cf23..72c8e60 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h @@ -159,6 +159,11 @@ protected: */ void OnDoAction(const Property::Index actionId, const Property::Value& attributes) override; + /** + * @copydoc Visual::Base::OnDoActionExtension + */ + void OnDoActionExtension(const Property::Index actionId, Dali::Any attributes) override; + private: /** * Helper method to set individual values by index key. diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp index b79f422..a202747 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp @@ -95,6 +95,10 @@ void VectorAnimationTask::Finalize() { mAnimationFinishedTrigger.reset(); } + if(mLoadCompletedTrigger) + { + mLoadCompletedTrigger.reset(); + } mVectorRenderer.Finalize(); @@ -144,6 +148,11 @@ void VectorAnimationTask::RequestLoad(const std::string& url) mVectorAnimationThread.AddTask(this); } +bool VectorAnimationTask::IsLoadRequested() const +{ + return mLoadRequest; +} + void VectorAnimationTask::SetAnimationData(const AnimationData& data) { ConditionalWait::ScopedLock lock(mConditionalWait); @@ -280,38 +289,33 @@ void VectorAnimationTask::SetPlayRange(const Property::Array& playRange) } // Make sure the range specified is between 0 and the total frame number - if(startFrame < mTotalFrame && endFrame < mTotalFrame) + startFrame = std::min(startFrame, mTotalFrame - 1); + endFrame = std::min(endFrame, mTotalFrame - 1); + + // If the range is not in order swap values + if(startFrame > endFrame) + { + uint32_t temp = startFrame; + startFrame = endFrame; + endFrame = temp; + } + + if(startFrame != mStartFrame || endFrame != mEndFrame) { - // If the range is not in order swap values - if(startFrame > endFrame) + mStartFrame = startFrame; + mEndFrame = endFrame; + + // If the current frame is out of the range, change the current frame also. + if(mStartFrame > mCurrentFrame) { - uint32_t temp = startFrame; - startFrame = endFrame; - endFrame = temp; + mCurrentFrame = mStartFrame; } - - if(startFrame != mStartFrame || endFrame != mEndFrame) + else if(mEndFrame < mCurrentFrame) { - mStartFrame = startFrame; - mEndFrame = endFrame; - - // If the current frame is out of the range, change the current frame also. - if(mStartFrame > mCurrentFrame) - { - mCurrentFrame = mStartFrame; - } - else if(mEndFrame < mCurrentFrame) - { - mCurrentFrame = mEndFrame; - } - - DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetPlayRange: [%d, %d] [%s] [%p]\n", mStartFrame, mEndFrame, mUrl.c_str(), this); + mCurrentFrame = mEndFrame; } - } - else - { - DALI_LOG_ERROR("VectorAnimationTask::SetPlayRange: Invalid range (%d, %d) [%s] [%p]\n", startFrame, endFrame, mUrl.c_str(), this); - return; + + DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetPlayRange: [%d, %d] [%s] [%p]\n", mStartFrame, mEndFrame, mUrl.c_str(), this); } } @@ -627,6 +631,14 @@ void VectorAnimationTask::ApplyAnimationData() mVectorRenderer.InvalidateBuffer(); } + if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_DYNAMIC_PROPERTY) + { + for(auto&& iter : mAnimationData[index].dynamicProperties) + { + mVectorRenderer.AddPropertyValueCallback(iter.keyPath, static_cast(iter.property), iter.callback, iter.id); + } + } + if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_STATE) { if(mAnimationData[index].playState == DevelImageVisual::PlayState::PLAYING) @@ -643,6 +655,8 @@ void VectorAnimationTask::ApplyAnimationData() } } + // reset data + mAnimationData[index].dynamicProperties.clear(); mAnimationData[index].resendFlag = 0; } diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h index 1e4ff4c..42d13f8 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h @@ -21,11 +21,13 @@ #include #include #include +#include #include #include #include // INTERNAL INCLUDES +#include #include namespace Dali @@ -54,7 +56,8 @@ public: using ResourceReadySignalType = Signal; - using TimePoint = std::chrono::time_point; + using TimePoint = std::chrono::time_point; + using DynamicPropertyType = std::vector; /** * Flags for re-sending data to the vector animation thread @@ -68,7 +71,8 @@ public: RESEND_CURRENT_FRAME = 1 << 4, RESEND_SIZE = 1 << 5, RESEND_PLAY_STATE = 1 << 6, - RESEND_NEED_RESOURCE_READY = 1 << 7 + RESEND_NEED_RESOURCE_READY = 1 << 7, + RESEND_DYNAMIC_PROPERTY = 1 << 8 }; /** @@ -79,6 +83,7 @@ public: AnimationData() : resendFlag(0), playRange(), + dynamicProperties(), playState(), stopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME), loopingMode(DevelImageVisual::LoopingMode::RESTART), @@ -100,11 +105,13 @@ public: width = rhs.width; height = rhs.height; loopCount = rhs.loopCount; + dynamicProperties.insert(dynamicProperties.end(), rhs.dynamicProperties.begin(), rhs.dynamicProperties.end()); return *this; } uint32_t resendFlag; Property::Array playRange; + DynamicPropertyType dynamicProperties; DevelImageVisual::PlayState::Type playState; DevelImageVisual::StopBehavior::Type stopBehavior; DevelImageVisual::LoopingMode::Type loopingMode; @@ -139,13 +146,19 @@ public: void SetRenderer(Renderer renderer); /** - * @brief Request to load the animation file. + * @brief Requests to load the animation file. * * @param[in] url The url of the vector animation file */ void RequestLoad(const std::string& url); /** + * @brief Queries whether loading is requested. + * @return True if loading is requested. + */ + bool IsLoadRequested() const; + + /** * @brief Sets data to specify animation playback. * @param[in] data The animation data */ diff --git a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp index 7e505c9..c6dbdb6 100644 --- a/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp +++ b/dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp @@ -85,7 +85,9 @@ void VectorAnimationThread::AddTask(VectorAnimationTaskPtr task) { ConditionalWait::ScopedLock lock(mConditionalWait); - if(mAnimationTasks.end() == std::find(mAnimationTasks.begin(), mAnimationTasks.end(), task)) + // Find if the task is already in the list except loading task + auto iter = std::find_if(mAnimationTasks.begin(), mAnimationTasks.end(), [task](VectorAnimationTaskPtr& element) { return (element == task && !element->IsLoadRequested()); }); + if(iter == mAnimationTasks.end()) { auto currentTime = task->CalculateNextFrameTime(true); // Rasterize as soon as possible diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp index aa205cf..14e1ce3 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -569,8 +570,8 @@ void TextVisual::UpdateRenderer() const bool markupStrikethroughEnabled = markupProcessorEnabled && mController->GetTextModel()->IsMarkupStrikethroughSet(); const bool underlineEnabled = mController->GetTextModel()->IsUnderlineEnabled() || markupUnderlineEnabled; const bool strikethroughEnabled = mController->GetTextModel()->IsStrikethroughEnabled() || markupStrikethroughEnabled; - const bool styleEnabled = (shadowEnabled || outlineEnabled || backgroundEnabled || markupProcessorEnabled); - const bool isOverlayStyle = underlineEnabled || strikethroughEnabled; + const bool styleEnabled = (shadowEnabled || outlineEnabled || backgroundEnabled || markupProcessorEnabled); + const bool isOverlayStyle = underlineEnabled || strikethroughEnabled; AddRenderer(control, relayoutSize, hasMultipleTextColors, containsColorGlyph, styleEnabled, isOverlayStyle); @@ -592,53 +593,47 @@ void TextVisual::AddTexture(TextureSet& textureSet, PixelData& data, Sampler& sa textureSet.SetSampler(textureSetIndex, sampler); } -PixelData TextVisual::ConvertToPixelData(unsigned char* buffer, int width, int height, int offsetPosition, const Pixel::Format textPixelFormat) +void TextVisual::AddTilingTexture(TextureSet& textureSet, TilingInfo& tilingInfo, PixelData& data, Sampler& sampler, unsigned int textureSetIndex) { - int bpp = Pixel::GetBytesPerPixel(textPixelFormat); - unsigned int bufferSize = width * height * bpp; - unsigned char* dstBuffer = static_cast(malloc(bufferSize)); - memcpy(dstBuffer, buffer + offsetPosition * bpp, bufferSize); - PixelData pixelData = Dali::PixelData::New(dstBuffer, - bufferSize, - width, - height, - textPixelFormat, - Dali::PixelData::FREE); - return pixelData; + Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, + tilingInfo.textPixelFormat, + tilingInfo.width, + tilingInfo.height); + DevelTexture::UploadSubPixelData(texture, data, 0u, tilingInfo.offsetHeight, tilingInfo.width, tilingInfo.height); + + textureSet.SetTexture(textureSetIndex, texture); + textureSet.SetSampler(textureSetIndex, sampler); } void TextVisual::CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sampler& sampler) { - TextureSet textureSet = TextureSet::New(); - unsigned int textureSetIndex = 0u; + TextureSet textureSet = TextureSet::New(); + uint32_t textureSetIndex = 0u; // Convert the buffer to pixel data to make it a texture. - if(info.textBuffer) + if(info.textPixelData) { - PixelData data = ConvertToPixelData(info.textBuffer, info.width, info.height, info.offsetPosition, info.textPixelFormat); - AddTexture(textureSet, data, sampler, textureSetIndex); + AddTilingTexture(textureSet, info, info.textPixelData, sampler, textureSetIndex); ++textureSetIndex; } - if(mTextShaderFeatureCache.IsEnabledStyle() && info.styleBuffer) + if(mTextShaderFeatureCache.IsEnabledStyle() && info.stylePixelData) { - PixelData styleData = ConvertToPixelData(info.styleBuffer, info.width, info.height, info.offsetPosition, Pixel::RGBA8888); - AddTexture(textureSet, styleData, sampler, textureSetIndex); + AddTilingTexture(textureSet, info, info.stylePixelData, sampler, textureSetIndex); ++textureSetIndex; } - if(mTextShaderFeatureCache.IsEnabledOverlay() && info.overlayStyleBuffer) + if(mTextShaderFeatureCache.IsEnabledOverlay() && info.overlayStylePixelData) { - PixelData overlayStyleData = ConvertToPixelData(info.overlayStyleBuffer, info.width, info.height, info.offsetPosition, Pixel::RGBA8888); - AddTexture(textureSet, overlayStyleData, sampler, textureSetIndex); + AddTilingTexture(textureSet, info, info.overlayStylePixelData, sampler, textureSetIndex); ++textureSetIndex; } - if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor() && info.maskBuffer) + if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor() && info.maskPixelData) { - PixelData maskData = ConvertToPixelData(info.maskBuffer, info.width, info.height, info.offsetPosition, Pixel::L8); - AddTexture(textureSet, maskData, sampler, textureSetIndex); + AddTilingTexture(textureSet, info, info.maskPixelData, sampler, textureSetIndex); + ++textureSetIndex; } renderer.SetTextures(textureSet); @@ -652,7 +647,7 @@ void TextVisual::CreateTextureSet(TilingInfo& info, VisualRenderer& renderer, Sa // Set size and offset for the tiling. renderer.SetProperty(VisualRenderer::Property::TRANSFORM_SIZE, Vector2(info.width, info.height)); - renderer.SetProperty(VisualRenderer::Property::TRANSFORM_OFFSET, Vector2(info.offSet.x, info.offSet.y)); + renderer.SetProperty(VisualRenderer::Property::TRANSFORM_OFFSET, info.transformOffset); renderer.SetProperty(Renderer::Property::BLEND_MODE, BlendMode::ON); renderer.RegisterProperty("uHasMultipleTextColors", static_cast(mTextShaderFeatureCache.IsEnabledMultiColor())); @@ -702,32 +697,25 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple // Set information for creating textures. TilingInfo info(verifiedWidth, maxTextureSize, textPixelFormat); - // Get the buffer of text. - Dali::DevelPixelData::PixelDataBuffer textPixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(data); - info.textBuffer = textPixelData.buffer; + // Get the pixel data of text. + info.textPixelData = data; if(mTextShaderFeatureCache.IsEnabledStyle()) { // Create RGBA texture for all the text styles (without the text itself) - PixelData styleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888); - Dali::DevelPixelData::PixelDataBuffer stylePixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(styleData); - info.styleBuffer = stylePixelData.buffer; + info.stylePixelData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_NO_TEXT, false, Pixel::RGBA8888); } if(mTextShaderFeatureCache.IsEnabledOverlay()) { // Create RGBA texture for all the overlay styles - PixelData overlayStyleData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_OVERLAY_STYLE, false, Pixel::RGBA8888); - Dali::DevelPixelData::PixelDataBuffer overlayStylePixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(overlayStyleData); - info.overlayStyleBuffer = overlayStylePixelData.buffer; + info.overlayStylePixelData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_OVERLAY_STYLE, false, Pixel::RGBA8888); } if(mTextShaderFeatureCache.IsEnabledEmoji() && !mTextShaderFeatureCache.IsEnabledMultiColor()) { // Create a L8 texture as a mask to avoid color glyphs (e.g. emojis) to be affected by text color animation - PixelData maskData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_MASK, false, Pixel::L8); - Dali::DevelPixelData::PixelDataBuffer maskPixelData = Dali::DevelPixelData::ReleasePixelDataBuffer(maskData); - info.maskBuffer = maskPixelData.buffer; + info.maskPixelData = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_MASK, false, Pixel::L8); } // Get the current offset for recalculate the offset when tiling. @@ -736,7 +724,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple Property::Value* offsetValue = retMap.Find(Dali::Toolkit::Visual::Transform::Property::OFFSET); if(offsetValue) { - offsetValue->Get(info.offSet); + offsetValue->Get(info.transformOffset); } // Create a textureset in the default renderer. @@ -746,18 +734,17 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY); - int offsetPosition = verifiedWidth * maxTextureSize; // Create a renderer by cutting maxTextureSize. while(verifiedHeight > 0) { VisualRenderer tilingRenderer = VisualRenderer::New(geometry, shader); tilingRenderer.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, Toolkit::DepthIndex::CONTENT); // New offset position of buffer for tiling. - info.offsetPosition += offsetPosition; + info.offsetHeight += maxTextureSize; // New height for tiling. info.height = (verifiedHeight - maxTextureSize) > 0 ? maxTextureSize : verifiedHeight; // New offset for tiling. - info.offSet.y += maxTextureSize; + info.transformOffset.y += maxTextureSize; // Create a textureset int the new tiling renderer. CreateTextureSet(info, tilingRenderer, sampler); @@ -820,9 +807,7 @@ TextureSet TextVisual::GetTextTexture(const Vector2& size) // Create a texture for the text without any styles PixelData data = mTypesetter->Render(size, textDirection, Text::Typesetter::RENDER_NO_STYLES, false, textPixelFormat); - // It may happen the image atlas can't handle a pixel data it exceeds the maximum size. - // In that case, create a texture. TODO: should tile the text. - unsigned int textureSetIndex = 0u; + uint32_t textureSetIndex = 0u; AddTexture(textureSet, data, sampler, textureSetIndex); ++textureSetIndex; diff --git a/dali-toolkit/internal/visuals/text/text-visual.h b/dali-toolkit/internal/visuals/text/text-visual.h index c81fbce..1b1930d 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.h +++ b/dali-toolkit/internal/visuals/text/text-visual.h @@ -194,47 +194,31 @@ protected: private: struct TilingInfo { - unsigned char* textBuffer; - unsigned char* styleBuffer; - unsigned char* overlayStyleBuffer; - unsigned char* maskBuffer; - int width; - int height; - Pixel::Format textPixelFormat; - int offsetPosition; - Vector2 offSet; - - TilingInfo(int width, int height, Pixel::Format textPixelFormat) - : textBuffer(NULL), - styleBuffer(NULL), - overlayStyleBuffer(NULL), - maskBuffer(NULL), + PixelData textPixelData; + PixelData stylePixelData; + PixelData overlayStylePixelData; + PixelData maskPixelData; + int32_t width; + int32_t height; + Pixel::Format textPixelFormat; + uint32_t offsetHeight; + Vector2 transformOffset; + + TilingInfo(int32_t width, int32_t height, Pixel::Format textPixelFormat) + : textPixelData(), + stylePixelData(), + overlayStylePixelData(), + maskPixelData(), width(width), height(height), textPixelFormat(textPixelFormat), - offsetPosition(0), - offSet(0.f, 0.f) + offsetHeight(0u), + transformOffset(0.f, 0.f) { } ~TilingInfo() { - if(textBuffer) - { - free(textBuffer); - } - if(styleBuffer) - { - free(styleBuffer); - } - if(overlayStyleBuffer) - { - free(overlayStyleBuffer); - } - if(maskBuffer) - { - free(maskBuffer); - } } }; @@ -260,21 +244,21 @@ private: /** * @brief Create a texture in textureSet and add it. * @param[in] textureSet The textureSet to which the texture will be added. - * @param[in] data The PixelData to be uploaded to texture + * @param[in] data The PixelData to be uploaded to texture. * @param[in] sampler The sampler. * @param[in] textureSetIndex The Index of TextureSet. */ void AddTexture(TextureSet& textureSet, PixelData& data, Sampler& sampler, unsigned int textureSetIndex); /** - * @brief Convert the buffer to pixelData. - * @param[in] buffer The Buffer to be converted to pixelData. - * @param[in] width The width of pixel data. - * @param[in] height The height of pixel data. - * @param[in] offsetPosition The The buffer's start position. - * @param[in] textPixelFormat The PixelForma of text. + * @brief Create a texture in textureSet and add it. + * @param[in] textureSet The textureSet to which the texture will be added. + * @param[in] tilingInfo The tiling infomation to be uploaded to texture. + * @param[in] data The PixelData to be uploaded to texture. + * @param[in] sampler The sampler. + * @param[in] textureSetIndex The Index of TextureSet. */ - PixelData ConvertToPixelData(unsigned char* buffer, int width, int height, int offsetPosition, const Pixel::Format textPixelFormat); + void AddTilingTexture(TextureSet& textureSet, TilingInfo& tilingInfo, PixelData& data, Sampler& sampler, unsigned int textureSetIndex); /** * @brief Create the text's texture. It will use cached shader feature for text visual. diff --git a/dali-toolkit/internal/visuals/visual-base-impl.cpp b/dali-toolkit/internal/visuals/visual-base-impl.cpp index 99b6c38..ce78b7e 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.cpp +++ b/dali-toolkit/internal/visuals/visual-base-impl.cpp @@ -517,6 +517,11 @@ void Visual::Base::DoAction(const Property::Index actionId, const Property::Valu } } +void Visual::Base::DoActionExtension(const Dali::Property::Index actionId, const Dali::Any attributes) +{ + OnDoActionExtension(actionId, attributes); +} + void Visual::Base::SetDepthIndex(int index) { mImpl->mDepthIndex = index; @@ -698,6 +703,11 @@ void Visual::Base::OnDoAction(const Property::Index actionId, const Property::Va // May be overriden by derived class } +void Visual::Base::OnDoActionExtension(const Property::Index actionId, const Dali::Any attributes) +{ + // May be overriden by derived class +} + void Visual::Base::RegisterMixColor() { if(mImpl->mRenderer) diff --git a/dali-toolkit/internal/visuals/visual-base-impl.h b/dali-toolkit/internal/visuals/visual-base-impl.h index bdcb193..7ebf239 100644 --- a/dali-toolkit/internal/visuals/visual-base-impl.h +++ b/dali-toolkit/internal/visuals/visual-base-impl.h @@ -100,6 +100,14 @@ public: void DoAction(const Dali::Property::Index actionId, const Dali::Property::Value attributes); /** + * @brief Performs an action on the visual with the given action id and attributes. + * + * @param[in] actionId The id of the action to perform this API only takes an Index + * @param[in] attributes The list of attributes for the action. ( optional for this data structure to have content ) + */ + void DoActionExtension(const Dali::Property::Index actionId, const Dali::Any attributes); + + /** * @copydoc Toolkit::Visual::Base::GetHeightForWidth */ virtual float GetHeightForWidth(float width); @@ -363,6 +371,14 @@ protected: virtual void OnDoAction(const Property::Index actionId, const Property::Value& attributes); /** + * @brief Called by DoActionExtension() allowing sub classes to do the given action. + * + * @param[in] actionId The action to perform + * @param[in] attributes The list of attributes for the action. ( optional for this data structure to have content ) + */ + virtual void OnDoActionExtension(const Property::Index actionId, Dali::Any attributes); + + /** * @brief Update the shader when some properties are changed. */ virtual void UpdateShader() diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 9ae5216..45b6e51 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -29,7 +29,7 @@ namespace Toolkit { const unsigned int TOOLKIT_MAJOR_VERSION = 2; const unsigned int TOOLKIT_MINOR_VERSION = 1; -const unsigned int TOOLKIT_MICRO_VERSION = 32; +const unsigned int TOOLKIT_MICRO_VERSION = 33; const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/dali-toolkit/shader-generator/shader-generator.cpp b/dali-toolkit/shader-generator/shader-generator.cpp index d386fb3..a88333c 100644 --- a/dali-toolkit/shader-generator/shader-generator.cpp +++ b/dali-toolkit/shader-generator/shader-generator.cpp @@ -144,11 +144,13 @@ void GenerateHeaderFile( << endl; outFile << "const std::string_view " << shaderVariableName << endl; outFile << "{" << endl; + outFile << "R\"(" << endl; string line; while(getline(shaderFile, line)) { - outFile << "\"" << line << "\\n\"" << endl; + outFile << line << endl; } + outFile << ")\"" << endl; outFile << "};" << endl; cout << " [OK]" << endl; } diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 5caa1e1..8f10bbd 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali2-toolkit Summary: Dali 3D engine Toolkit -Version: 2.1.32 +Version: 2.1.33 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-3-Clause and MIT