mNeedDroppedFrames = false;
}
+ if(mDynamicPropertyCallback)
+ {
+ CallbackBase::ExecuteReturn<Property::Value>(*mDynamicPropertyCallback, 0, 0, frameNumber);
+ }
+
if(mNeedTrigger)
{
mEventThreadCallback->Trigger();
}
}
+ void AddPropertyValueCallback(const std::string& keyPath, Dali::VectorAnimationRenderer::VectorProperty property, CallbackBase* callback, int32_t id)
+ {
+ mDynamicPropertyCallback = std::unique_ptr<CallbackBase>(callback);
+ }
+
Dali::VectorAnimationRenderer::UploadCompletedSignalType& UploadCompletedSignal()
{
return mUploadCompletedSignal;
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<CallbackBase> 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<EventThreadCallback> mEventThreadCallback;
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();
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+
+#include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
#include <dali/devel-api/adaptor-framework/window-devel.h>
#include <dali/devel-api/rendering/renderer-devel.h>
Renderer renderer = actor.GetRendererAt(0u);
DALI_TEST_CHECK(renderer);
- Property::Map map = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
- Property::Value* value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
+ Property::Map map = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+ Property::Value* value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
+ int totalFrameNumber = map.Find(DevelImageVisual::Property::TOTAL_FRAME_NUMBER)->Get<int>();
int resultStartFrame, resultEndFrame;
Property::Array* result = value->GetArray();
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());
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);
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<DummyControlImpl&>(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<int>(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;
+}
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} )
/*
- * 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.
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);
#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.
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.
#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.
* limitations under the License.
*
*/
+
+// EXTERNAL INCLUDES
#include <dali-toolkit/devel-api/toolkit-action-index-ranges.h>
+#include <dali/public-api/signals/callback.h>
+#include <string>
namespace Dali
{
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
}
}
+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);
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
// EXTERNAL INCLUDES\r
#include <dali/public-api/actors/layer.h>\r
#include <dali/public-api/animation/animation.h>\r
+#include <dali/public-api/common/vector-wrapper.h>\r
#include <dali/public-api/rendering/renderer.h>\r
#include <dali/public-api/rendering/shader.h>\r
\r
#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.
#include <dali-toolkit/public-api/transition/transition.h>
// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/weak-handle.h>
namespace Dali
#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.
// EXTERNAL INCLUDES
#include <dali/integration-api/processor-interface.h>
+#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/base-object.h>
#include <dali/public-api/signals/connection-tracker.h>
TriggerVectorRasterization();
}
+void AnimatedVectorImageVisual::OnDoActionExtension(const Property::Index actionId, Dali::Any attributes)
+{
+ switch(actionId)
+ {
+ case DevelAnimatedVectorImageVisual::Action::SET_DYNAMIC_PROPERTY:
+ {
+ DevelAnimatedVectorImageVisual::DynamicPropertyInfo info = AnyCast<DevelAnimatedVectorImageVisual::DynamicPropertyInfo>(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)
*/
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.
{
mAnimationFinishedTrigger.reset();
}
+ if(mLoadCompletedTrigger)
+ {
+ mLoadCompletedTrigger.reset();
+ }
mVectorRenderer.Finalize();
mVectorAnimationThread.AddTask(this);
}
+bool VectorAnimationTask::IsLoadRequested() const
+{
+ return mLoadRequest;
+}
+
void VectorAnimationTask::SetAnimationData(const AnimationData& data)
{
ConditionalWait::ScopedLock lock(mConditionalWait);
}
// 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);
}
}
mVectorRenderer.InvalidateBuffer();
}
+ if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_DYNAMIC_PROPERTY)
+ {
+ for(auto&& iter : mAnimationData[index].dynamicProperties)
+ {
+ mVectorRenderer.AddPropertyValueCallback(iter.keyPath, static_cast<VectorAnimationRenderer::VectorProperty>(iter.property), iter.callback, iter.id);
+ }
+ }
+
if(mAnimationData[index].resendFlag & VectorAnimationTask::RESEND_PLAY_STATE)
{
if(mAnimationData[index].playState == DevelImageVisual::PlayState::PLAYING)
}
}
+ // reset data
+ mAnimationData[index].dynamicProperties.clear();
mAnimationData[index].resendFlag = 0;
}
#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
#include <dali/devel-api/adaptor-framework/vector-animation-renderer.h>
#include <dali/devel-api/threading/conditional-wait.h>
+#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/property-array.h>
#include <chrono>
#include <memory>
// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
namespace Dali
using ResourceReadySignalType = Signal<void(ResourceStatus)>;
- using TimePoint = std::chrono::time_point<std::chrono::steady_clock>;
+ using TimePoint = std::chrono::time_point<std::chrono::steady_clock>;
+ using DynamicPropertyType = std::vector<DevelAnimatedVectorImageVisual::DynamicPropertyInfo>;
/**
* Flags for re-sending data to the vector animation thread
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
};
/**
AnimationData()
: resendFlag(0),
playRange(),
+ dynamicProperties(),
playState(),
stopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
loopingMode(DevelImageVisual::LoopingMode::RESTART),
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;
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
*/
{
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
#include <dali/devel-api/adaptor-framework/image-loading.h>
#include <dali/devel-api/images/pixel-data-devel.h>
#include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/devel-api/rendering/texture-devel.h>
#include <dali/devel-api/text-abstraction/text-abstraction-definitions.h>
#include <dali/integration-api/debug.h>
#include <string.h>
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);
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<unsigned char*>(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);
// 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<float>(mTextShaderFeatureCache.IsEnabledMultiColor()));
// 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.
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.
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);
// 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;
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);
- }
}
};
/**
* @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.
}
}
+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;
// 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)
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);
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()
{
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
<< 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;
}
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