2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-extension/vector-animation-renderer/vector-animation-renderer.h>
22 #include <dali/devel-api/common/hash.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/integration-api/texture-integ.h>
25 #include <dali/public-api/object/property-array.h>
27 #include <cstring> // for strlen()
30 #include <dali-extension/vector-animation-renderer/vector-animation-plugin-manager.h>
38 const char* const PIXEL_AREA_UNIFORM_NAME("pixelArea");
39 const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
41 #if defined(DEBUG_ENABLED)
42 Debug::Filter* gVectorAnimationLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_VECTOR_ANIMATION");
44 } // unnamed namespace
46 VectorAnimationRenderer::VectorAnimationRenderer()
52 mUploadCompletedSignal(),
60 mResourceReady(false),
61 mShaderChanged(false),
62 mResourceReadyTriggered(false),
63 mEnableFixedCache(false)
65 VectorAnimationPluginManager::Get().AddEventHandler(*this);
68 VectorAnimationRenderer::~VectorAnimationRenderer()
72 void VectorAnimationRenderer::Finalize()
74 Dali::Mutex::ScopedLock lock(mMutex);
76 VectorAnimationPluginManager::Get().RemoveEventHandler(*this);
80 mVectorRenderer.reset();
81 mPropertyCallbacks.clear();
85 DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "[%p]\n", this);
88 bool VectorAnimationRenderer::Load(const std::string& url)
90 Dali::Mutex::ScopedLock lock(mMutex);
94 mVectorRenderer = rlottie::Animation::loadFromFile(mUrl);
97 DALI_LOG_ERROR("Failed to load a Lottie file [%s] [%p]\n", mUrl.c_str(), this);
102 mTotalFrameNumber = static_cast<uint32_t>(mVectorRenderer->totalFrame());
103 mFrameRate = static_cast<float>(mVectorRenderer->frameRate());
106 mVectorRenderer->size(w, h);
107 mDefaultWidth = static_cast<uint32_t>(w);
108 mDefaultHeight = static_cast<uint32_t>(h);
110 DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "file [%s] [%p]\n", url.c_str(), this);
115 bool VectorAnimationRenderer::Load(const Dali::Vector<uint8_t>& data)
117 Dali::Mutex::ScopedLock lock(mMutex);
119 std::string jsonData(data.Begin(), data.End()); ///< Convert from raw buffer to string.
120 auto hashValue = Dali::CalculateHash(data); ///< Will be used for rlottie internal cache system.
122 mVectorRenderer = rlottie::Animation::loadFromData(std::move(jsonData), std::to_string(hashValue));
125 DALI_LOG_ERROR("Failed to load a Lottie data [data size : %zu byte] [%p]\n", data.Size(), this);
130 mTotalFrameNumber = static_cast<uint32_t>(mVectorRenderer->totalFrame());
131 mFrameRate = static_cast<float>(mVectorRenderer->frameRate());
134 mVectorRenderer->size(w, h);
135 mDefaultWidth = static_cast<uint32_t>(w);
136 mDefaultHeight = static_cast<uint32_t>(h);
138 DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "data [data size : %zu byte] [%p]\n", data.Size(), this);
143 void VectorAnimationRenderer::SetRenderer(Renderer renderer)
145 mRenderer = renderer;
146 mShaderChanged = false;
148 if(IsTargetPrepared())
150 Dali::Mutex::ScopedLock lock(mMutex);
154 TextureSet textureSet = renderer.GetTextures();
156 textureSet.SetTexture(0, GetTargetTexture());
158 mUploadCompletedSignal.Emit();
165 void VectorAnimationRenderer::SetSize(uint32_t width, uint32_t height)
167 Dali::Mutex::ScopedLock lock(mMutex);
169 if(mWidth == width && mHeight == height)
171 DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "Same size (%d, %d) [%p]\n", mWidth, mHeight, this);
177 DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "Load is failed. Do not make texture [%p]\n", this);
191 mResourceReady = false;
195 DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "width = %d, height = %d [%p]\n", mWidth, mHeight, this);
198 uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
200 return mTotalFrameNumber;
203 float VectorAnimationRenderer::GetFrameRate() const
208 void VectorAnimationRenderer::GetDefaultSize(uint32_t& width, uint32_t& height) const
210 width = mDefaultWidth;
211 height = mDefaultHeight;
214 void VectorAnimationRenderer::GetLayerInfo(Property::Map& map) const
216 Dali::Mutex::ScopedLock lock(mMutex);
220 auto layerInfo = mVectorRenderer->layers();
222 for(auto&& iter : layerInfo)
224 Property::Array frames;
225 frames.PushBack(std::get<1>(iter));
226 frames.PushBack(std::get<2>(iter));
227 map.Add(std::get<0>(iter), frames);
232 bool VectorAnimationRenderer::GetMarkerInfo(const std::string& marker, uint32_t& startFrame, uint32_t& endFrame) const
234 Dali::Mutex::ScopedLock lock(mMutex);
238 auto markerList = mVectorRenderer->markers();
239 for(auto&& iter : markerList)
241 if(std::get<0>(iter).compare(marker) == 0)
243 startFrame = static_cast<uint32_t>(std::get<1>(iter));
244 endFrame = static_cast<uint32_t>(std::get<2>(iter));
252 void VectorAnimationRenderer::GetMarkerInfo(Property::Map& map) const
254 Dali::Mutex::ScopedLock lock(mMutex);
258 auto markerList = mVectorRenderer->markers();
259 for(auto&& iter : markerList)
261 Property::Array frames;
262 frames.PushBack(std::get<1>(iter));
263 frames.PushBack(std::get<2>(iter));
264 map.Add(std::get<0>(iter), frames);
269 void VectorAnimationRenderer::InvalidateBuffer()
271 Dali::Mutex::ScopedLock lock(mMutex);
272 mResourceReady = false;
275 void VectorAnimationRenderer::AddPropertyValueCallback(const std::string& keyPath, VectorProperty property, CallbackBase* callback, int32_t id)
277 Dali::Mutex::ScopedLock lock(mMutex);
279 mPropertyCallbacks.push_back(std::unique_ptr<CallbackBase>(callback));
283 case VectorProperty::FILL_COLOR:
285 mVectorRenderer->setValue<rlottie::Property::FillColor>(keyPath,
286 [property, callback, id](const rlottie::FrameInfo& info) {
287 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
291 return rlottie::Color(color.r, color.g, color.b);
293 return rlottie::Color(1.0f, 1.0f, 1.0f);
297 case VectorProperty::FILL_OPACITY:
299 mVectorRenderer->setValue<rlottie::Property::FillOpacity>(keyPath,
300 [property, callback, id](const rlottie::FrameInfo& info) {
301 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
303 if(value.Get(opacity))
305 return opacity * 100;
311 case VectorProperty::STROKE_COLOR:
313 mVectorRenderer->setValue<rlottie::Property::StrokeColor>(keyPath,
314 [property, callback, id](const rlottie::FrameInfo& info) {
315 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
319 return rlottie::Color(color.r, color.g, color.b);
321 return rlottie::Color(1.0f, 1.0f, 1.0f);
325 case VectorProperty::STROKE_OPACITY:
327 mVectorRenderer->setValue<rlottie::Property::StrokeOpacity>(keyPath,
328 [property, callback, id](const rlottie::FrameInfo& info) {
329 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
331 if(value.Get(opacity))
333 return opacity * 100;
339 case VectorProperty::STROKE_WIDTH:
341 mVectorRenderer->setValue<rlottie::Property::StrokeWidth>(keyPath,
342 [property, callback, id](const rlottie::FrameInfo& info) {
343 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
353 case VectorProperty::TRANSFORM_ANCHOR:
355 mVectorRenderer->setValue<rlottie::Property::TrAnchor>(keyPath,
356 [property, callback, id](const rlottie::FrameInfo& info) {
357 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
361 return rlottie::Point(point.x, point.y);
363 return rlottie::Point(0.0f, 0.0f);
367 case VectorProperty::TRANSFORM_POSITION:
369 mVectorRenderer->setValue<rlottie::Property::TrPosition>(keyPath,
370 [property, callback, id](const rlottie::FrameInfo& info) {
371 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
373 if(value.Get(position))
375 return rlottie::Point(position.x, position.y);
377 return rlottie::Point(0.0f, 0.0f);
381 case VectorProperty::TRANSFORM_SCALE:
383 mVectorRenderer->setValue<rlottie::Property::TrScale>(keyPath,
384 [property, callback, id](const rlottie::FrameInfo& info) {
385 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
389 return rlottie::Size(scale.x, scale.y);
391 return rlottie::Size(100.0f, 100.0f);
395 case VectorProperty::TRANSFORM_ROTATION:
397 mVectorRenderer->setValue<rlottie::Property::TrRotation>(keyPath,
398 [property, callback, id](const rlottie::FrameInfo& info) {
399 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
401 if(value.Get(rotation))
409 case VectorProperty::TRANSFORM_OPACITY:
411 mVectorRenderer->setValue<rlottie::Property::TrOpacity>(keyPath,
412 [property, callback, id](const rlottie::FrameInfo& info) {
413 Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
415 if(value.Get(opacity))
417 return opacity * 100;
426 void VectorAnimationRenderer::KeepRasterizedBuffer()
428 Dali::Mutex::ScopedLock lock(mMutex);
429 mEnableFixedCache = true;
430 mDecodedBuffers.clear();
433 VectorAnimationRendererPlugin::UploadCompletedSignalType& VectorAnimationRenderer::UploadCompletedSignal()
435 return mUploadCompletedSignal;
438 void VectorAnimationRenderer::NotifyEvent()
440 bool emitSignal = false;
442 Dali::Mutex::ScopedLock lock(mMutex);
444 if(mResourceReadyTriggered)
446 DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "Set Texture [%p]\n", this);
449 if(mRenderer && GetTargetTexture())
451 TextureSet textureSet = mRenderer.GetTextures();
452 textureSet.SetTexture(0, GetTargetTexture());
455 mResourceReadyTriggered = false;
463 mUploadCompletedSignal.Emit();
467 } // namespace Plugin