#endif
} // unnamed namespace
+class VectorAnimationRendererTizen::RenderingDataImpl : public VectorAnimationRenderer::RenderingData
+{
+public:
+ NativeImageSourceQueuePtr mTargetSurface;
+ tbm_surface_queue_h mTbmQueue;
+};
+
VectorAnimationRendererTizen::VectorAnimationRendererTizen()
: mBuffers(),
mRenderedTexture(),
- mPreviousTextures(),
- mTargetSurface(),
- mTbmQueue(NULL)
+ mPreviousTextures()
{
+ mRenderingDataImpl[0] = std::make_shared<RenderingDataImpl>();
+ mRenderingDataImpl[1] = std::make_shared<RenderingDataImpl>();
+ mRenderingData[0] = mRenderingDataImpl[0];
+ mRenderingData[1] = mRenderingDataImpl[1];
}
VectorAnimationRendererTizen::~VectorAnimationRendererTizen()
DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "this = %p\n", this);
}
+// Called by VectorAnimationTaskThread
bool VectorAnimationRendererTizen::Render(uint32_t frameNumber)
{
- Dali::Mutex::ScopedLock lock(mMutex);
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ mCurrentRenderingData = mRenderingDataImpl[mCurrentDataIndex];
+ if(IsRenderingDataUpdated())
+ {
+ mResourceReady = false;
+ mIsDataActivated = true;
+ }
+ }
+ Dali::Mutex::ScopedLock lock(mMutex);
if(mEnableFixedCache)
{
if(mDecodedBuffers.size() < mTotalFrameNumber)
}
}
- if(!mTbmQueue || !mVectorRenderer || !mTargetSurface)
+ if(!mCurrentRenderingData->mTbmQueue || !mVectorRenderer || !mCurrentRenderingData->mTargetSurface)
{
return false;
}
- int canDequeue = tbm_surface_queue_can_dequeue(mTbmQueue, 0);
+ int canDequeue = tbm_surface_queue_can_dequeue(mCurrentRenderingData->mTbmQueue, 0);
if(!canDequeue)
{
// Ignore the previous image which is inserted to the queue.
- mTargetSurface->IgnoreSourceImage();
+ mCurrentRenderingData->mTargetSurface->IgnoreSourceImage();
// Check again
- canDequeue = tbm_surface_queue_can_dequeue(mTbmQueue, 0);
+ canDequeue = tbm_surface_queue_can_dequeue(mCurrentRenderingData->mTbmQueue, 0);
if(!canDequeue)
{
return false;
tbm_surface_h tbmSurface;
- if(tbm_surface_queue_dequeue(mTbmQueue, &tbmSurface) != TBM_SURFACE_QUEUE_ERROR_NONE)
+ if(tbm_surface_queue_dequeue(mCurrentRenderingData->mTbmQueue, &tbmSurface) != TBM_SURFACE_QUEUE_ERROR_NONE)
{
DALI_LOG_ERROR("Failed to dequeue a tbm_surface [%p]\n", this);
return false;
if(ret != TBM_SURFACE_ERROR_NONE)
{
DALI_LOG_ERROR("VectorAnimationRendererTizen::Render: tbm_surface_map is failed! [%d] [%p]\n", ret, this);
- tbm_surface_queue_cancel_dequeue(mTbmQueue, tbmSurface);
+ tbm_surface_queue_cancel_dequeue(mCurrentRenderingData->mTbmQueue, tbmSurface);
return false;
}
unsigned char* buffer = info.planes[0].ptr;
- if(info.width != mWidth || info.height != mHeight || !buffer)
+ if(info.width != mCurrentRenderingData->mWidth || info.height != mCurrentRenderingData->mHeight || !buffer)
{
DALI_LOG_ERROR("VectorAnimationRendererTizen::Render: Invalid tbm surface! [%d, %d, %p] [%p]\n", info.width, info.height, buffer, this);
tbm_surface_unmap(tbmSurface);
- tbm_surface_queue_cancel_dequeue(mTbmQueue, tbmSurface);
+ tbm_surface_queue_cancel_dequeue(mCurrentRenderingData->mTbmQueue, tbmSurface);
return false;
}
if(mEnableFixedCache && (frameNumber < mDecodedBuffers.size()) && mDecodedBuffers[frameNumber].second)
{
- const int bufferSize = mWidth * mHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888);
+ const int bufferSize = mCurrentRenderingData->mWidth * mCurrentRenderingData->mHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888);
memcpy(buffer, &mDecodedBuffers[frameNumber].first[0], bufferSize);
}
else
tbm_surface_internal_ref(tbmSurface);
// Create Surface object
- surface = rlottie::Surface(reinterpret_cast<uint32_t*>(buffer), mWidth, mHeight, static_cast<size_t>(info.planes[0].stride));
+ surface = rlottie::Surface(reinterpret_cast<uint32_t*>(buffer), mCurrentRenderingData->mWidth, mCurrentRenderingData->mHeight, static_cast<size_t>(info.planes[0].stride));
// Push the buffer
mBuffers.push_back(SurfacePair(tbmSurface, surface));
if(mEnableFixedCache && (frameNumber < mDecodedBuffers.size()))
{
- const uint32_t bufferSize = mWidth * mHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888);
+ const uint32_t bufferSize = mCurrentRenderingData->mWidth * mCurrentRenderingData->mHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888);
std::vector<uint8_t> rasterizeBuffer(buffer, buffer + bufferSize);
mDecodedBuffers[frameNumber].first = std::move(rasterizeBuffer);
mDecodedBuffers[frameNumber].second = true;
tbm_surface_unmap(tbmSurface);
- tbm_surface_queue_enqueue(mTbmQueue, tbmSurface);
+ tbm_surface_queue_enqueue(mCurrentRenderingData->mTbmQueue, tbmSurface);
if(!mResourceReady)
{
mPreviousTextures.push_back(mRenderedTexture); // It is used to destroy the object in the main thread.
- mRenderedTexture = mTexture;
+ mRenderedTexture = mCurrentRenderingData->mTexture;
mResourceReady = true;
mResourceReadyTriggered = true;
void VectorAnimationRendererTizen::RenderStopped()
{
- if(mTargetSurface)
+ if(mCurrentRenderingData->mTargetSurface)
{
// Animation is stopped. Free empty buffers
- mTargetSurface->FreeReleasedBuffers();
+ mCurrentRenderingData->mTargetSurface->FreeReleasedBuffers();
{
Dali::Mutex::ScopedLock lock(mMutex);
}
}
-void VectorAnimationRendererTizen::SetShader()
+void VectorAnimationRendererTizen::ResetBuffers()
+{
+ for(auto&& iter : mBuffers)
+ {
+ tbm_surface_internal_unref(iter.first);
+ }
+ mBuffers.clear();
+}
+
+void VectorAnimationRendererTizen::OnFinalize()
+{
+ mRenderedTexture.Reset();
+ mPreviousTextures.clear();
+
+ for(auto&& renderingData : mRenderingDataImpl)
+ {
+ renderingData->mTargetSurface = nullptr;
+ renderingData->mTbmQueue = nullptr;
+ }
+}
+
+void VectorAnimationRendererTizen::OnNotify()
+{
+ // Reset the previous texture to destroy it in the main thread
+ mPreviousTextures.clear();
+
+ // If RenderingData is updated, then clear previous renderingData
+ if(IsRenderingDataUpdated())
+ {
+ std::shared_ptr<RenderingDataImpl> oldRenderingData = mRenderingDataImpl[1u - mCurrentDataIndex];
+ oldRenderingData->mTargetSurface = nullptr;
+ oldRenderingData->mTbmQueue = nullptr;
+ SetRenderingDataUpdated(false);
+ }
+}
+
+void VectorAnimationRendererTizen::PrepareTarget(uint32_t updatedDataIndex)
+{
+ mRenderingDataImpl[updatedDataIndex]->mTargetSurface = NativeImageSourceQueue::New(mRenderingDataImpl[updatedDataIndex]->mWidth, mRenderingDataImpl[updatedDataIndex]->mHeight, NativeImageSourceQueue::ColorFormat::RGBA8888);
+ mRenderingDataImpl[updatedDataIndex]->mTexture = Texture::New(*mRenderingDataImpl[updatedDataIndex]->mTargetSurface);
+}
+
+void VectorAnimationRendererTizen::SetShader(uint32_t updatedDataIndex)
{
if(mShaderChanged)
{
}
// Get custom fragment shader prefix
- mTargetSurface->ApplyNativeFragmentShader(fragmentShader);
+ mRenderingDataImpl[updatedDataIndex]->mTargetSurface->ApplyNativeFragmentShader(fragmentShader);
// Set the modified shader again
Shader newShader = Shader::New(vertexShader, fragmentShader);
mShaderChanged = true;
}
-void VectorAnimationRendererTizen::ResetBuffers()
+void VectorAnimationRendererTizen::OnSetSize(uint32_t updatedDataIndex)
{
- for(auto&& iter : mBuffers)
- {
- tbm_surface_internal_unref(iter.first);
- }
- mBuffers.clear();
-}
-
-void VectorAnimationRendererTizen::OnFinalize()
-{
- mRenderedTexture.Reset();
- mPreviousTextures.clear();
-
- mTargetSurface = nullptr;
- mTbmQueue = NULL;
-}
-
-void VectorAnimationRendererTizen::OnSetSize()
-{
- mTbmQueue = AnyCast<tbm_surface_queue_h>(mTargetSurface->GetNativeImageSourceQueue());
-
- // Reset the previous texture to destroy it in the main thread
- mPreviousTextures.clear();
-}
-
-void VectorAnimationRendererTizen::OnNotify()
-{
- // Reset the previous texture to destroy it in the main thread
- mPreviousTextures.clear();
-}
-
-void VectorAnimationRendererTizen::PrepareTarget()
-{
- mTargetSurface = NativeImageSourceQueue::New(mWidth, mHeight, NativeImageSourceQueue::ColorFormat::RGBA8888);
-
- mTexture = Texture::New(*mTargetSurface);
+ std::shared_ptr<RenderingDataImpl> renderingData = mRenderingDataImpl[updatedDataIndex];
+ renderingData->mTbmQueue = AnyCast<tbm_surface_queue_h>(renderingData->mTargetSurface->GetNativeImageSourceQueue());
}
bool VectorAnimationRendererTizen::IsTargetPrepared()
{
- return !!mTargetSurface;
+ return (mCurrentRenderingData) ? !!mCurrentRenderingData->mTargetSurface : false;
}
bool VectorAnimationRendererTizen::IsRenderReady()
*/
class VectorAnimationRendererTizen : public VectorAnimationRenderer
{
+ class RenderingDataImpl;
+
public:
/**
* @brief Constructor.
private:
/**
- * @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
- */
- void SetShader() override;
-
- /**
* @brief Reset buffer list.
*/
void ResetBuffers() override;
void OnFinalize() override;
/**
- * @copydoc VectorAnimationRenderer::OnSetSize()
- */
- void OnSetSize() override;
-
- /**
* @brief Event callback to process events.
*/
void OnLottieRendered() override
- {}
+ {
+ }
/**
* @copydoc VectorAnimationRenderer::OnNotify()
/**
* @copydoc VectorAnimationRenderer::PrepareTarget()
*/
- void PrepareTarget() override;
+ void PrepareTarget(uint32_t updatedDataIndex) override;
+
+ /**
+ * @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
+ */
+ void SetShader(uint32_t updatedDataIndex) override;
+
+ /**
+ * @copydoc VectorAnimationRenderer::OnSetSize()
+ */
+ void OnSetSize(uint32_t updatedDataIndex) override;
/**
* @copydoc VectorAnimationRenderer::IsTargetPrepared()
std::vector<SurfacePair> mBuffers; ///< EGL Image vector
- Dali::Texture mRenderedTexture; ///< Rendered Texture
- std::vector<Dali::Texture> mPreviousTextures; ///< Previous rendered texture
- NativeImageSourceQueuePtr mTargetSurface; ///< The target surface
- tbm_surface_queue_h mTbmQueue; ///< Tbm surface queue handle
+ std::shared_ptr<RenderingDataImpl> mRenderingDataImpl[2];
+ std::shared_ptr<RenderingDataImpl> mCurrentRenderingData;
+ Dali::Texture mRenderedTexture; ///< Rendered Texture
+ std::vector<Dali::Texture> mPreviousTextures; ///< Previous rendered texture
};
} // namespace Plugin
#endif
} // unnamed namespace
+class VectorAnimationRendererX::RenderingDataImpl : public VectorAnimationRenderer::RenderingData
+{
+public:
+ rlottie::Surface mLottieSurface;
+ Dali::Devel::PixelBuffer mPixelBuffer;
+};
+
VectorAnimationRendererX::VectorAnimationRendererX()
-: mLottieSurface(),
- mRenderCallback(std::unique_ptr<EventThreadCallback>(new EventThreadCallback(MakeCallback(this, &VectorAnimationRendererX::OnLottieRendered))))
+: mRenderCallback(std::unique_ptr<EventThreadCallback>(new EventThreadCallback(MakeCallback(this, &VectorAnimationRendererX::OnLottieRendered))))
{
+ mRenderingDataImpl[0] = std::make_shared<RenderingDataImpl>();
+ mRenderingDataImpl[1] = std::make_shared<RenderingDataImpl>();
+ mRenderingData[0] = mRenderingDataImpl[0];
+ mRenderingData[1] = mRenderingDataImpl[1];
}
VectorAnimationRendererX::~VectorAnimationRendererX()
bool VectorAnimationRendererX::Render(uint32_t frameNumber)
{
- Dali::Mutex::ScopedLock lock(mMutex);
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ mCurrentRenderingData = mRenderingDataImpl[mCurrentDataIndex];
+ if(IsRenderingDataUpdated())
+ {
+ mResourceReady = false;
+ mIsDataActivated = true;
+ }
+ }
- if(!mVectorRenderer || !mPixelBuffer)
+ Dali::Mutex::ScopedLock lock(mMutex);
+ if(!mVectorRenderer || !mCurrentRenderingData->mPixelBuffer)
{
return false;
}
- mVectorRenderer->renderSync(frameNumber, mLottieSurface);
+ mVectorRenderer->renderSync(frameNumber, mCurrentRenderingData->mLottieSurface);
mRenderCallback->Trigger();
if(!mResourceReady)
{
}
-
-void VectorAnimationRendererX::SetShader()
-{
- if(mShaderChanged || !mTexture)
- {
- return;
- }
-
- // Not implemented
-
- mShaderChanged = true;
-}
-
void VectorAnimationRendererX::ResetBuffers()
{
- if(mPixelBuffer)
+ for(auto&& renderingData : mRenderingDataImpl)
{
- uint32_t bufferSize = mPixelBuffer.GetWidth() * mPixelBuffer.GetHeight() * Dali::Pixel::GetBytesPerPixel(mPixelBuffer.GetPixelFormat());
- memset(mPixelBuffer.GetBuffer(), 0, bufferSize);
+ if(renderingData->mPixelBuffer)
+ {
+ uint32_t bufferSize = renderingData->mPixelBuffer.GetWidth() * renderingData->mPixelBuffer.GetHeight() * Dali::Pixel::GetBytesPerPixel(renderingData->mPixelBuffer.GetPixelFormat());
+ memset(renderingData->mPixelBuffer.GetBuffer(), 0, bufferSize);
+ }
}
}
{
Dali::Mutex::ScopedLock lock(mMutex);
- if(mPixelBuffer && mTexture)
+ if(mCurrentRenderingData->mPixelBuffer && mCurrentRenderingData->mTexture)
+ {
+ PixelData pixelData = mCurrentRenderingData->mPixelBuffer.CreatePixelData();
+ mCurrentRenderingData->mTexture.Upload(pixelData);
+ }
+}
+
+void VectorAnimationRendererX::OnNotify()
+{
+ // If RenderingData is updated, then clear previous renderingData
+ if(IsRenderingDataUpdated())
{
- PixelData pixelData = mPixelBuffer.CreatePixelData();
- mTexture.Upload(pixelData);
+ std::shared_ptr<RenderingDataImpl> oldRenderingData = mRenderingDataImpl[1u - mCurrentDataIndex];
+ SetRenderingDataUpdated(false);
}
}
-void VectorAnimationRendererX::PrepareTarget()
+void VectorAnimationRendererX::PrepareTarget(uint32_t updatedDataIndex)
+{
+ mRenderingDataImpl[updatedDataIndex]->mTexture = Texture::New(Dali::TextureType::TEXTURE_2D, Dali::Pixel::BGRA8888, mRenderingDataImpl[updatedDataIndex]->mWidth, mRenderingDataImpl[updatedDataIndex]->mHeight);
+
+ mRenderingDataImpl[updatedDataIndex]->mPixelBuffer = Dali::Devel::PixelBuffer::New(mRenderingDataImpl[updatedDataIndex]->mWidth, mRenderingDataImpl[updatedDataIndex]->mHeight, Dali::Pixel::BGRA8888);
+ mRenderingDataImpl[updatedDataIndex]->mLottieSurface = rlottie::Surface(reinterpret_cast<uint32_t*>(mRenderingDataImpl[updatedDataIndex]->mPixelBuffer.GetBuffer()), mRenderingDataImpl[updatedDataIndex]->mWidth, mRenderingDataImpl[updatedDataIndex]->mHeight, static_cast<size_t>(mRenderingDataImpl[updatedDataIndex]->mPixelBuffer.GetStride() * 4));
+}
+
+void VectorAnimationRendererX::SetShader(uint32_t updatedDataIndex)
{
- mTexture = Texture::New(Dali::TextureType::TEXTURE_2D, Dali::Pixel::BGRA8888, mWidth, mHeight);
+ std::shared_ptr<RenderingDataImpl> renderingData = mRenderingDataImpl[updatedDataIndex];
+ if(mShaderChanged || !renderingData->mTexture)
+ {
+ return;
+ }
+
+ // Not implemented
- mPixelBuffer = Dali::Devel::PixelBuffer::New(mWidth, mHeight, Dali::Pixel::BGRA8888);
- mLottieSurface = rlottie::Surface(reinterpret_cast<uint32_t*>(mPixelBuffer.GetBuffer()), mWidth, mHeight, static_cast<size_t>(mPixelBuffer.GetStride() * 4));
+ mShaderChanged = true;
}
bool VectorAnimationRendererX::IsTargetPrepared()
{
- return !!mPixelBuffer;
+ return (mCurrentRenderingData) ? !!mCurrentRenderingData->mPixelBuffer : false;
}
bool VectorAnimationRendererX::IsRenderReady()
{
- return mResourceReady && mTexture;
+ return mResourceReady && ((mCurrentRenderingData) ? !!mCurrentRenderingData->mTexture : false);
}
Dali::Texture VectorAnimationRendererX::GetTargetTexture()
{
- return mTexture;
+ return (mCurrentRenderingData) ? mCurrentRenderingData->mTexture : Texture();
}
} // namespace Plugin
*/
class VectorAnimationRendererX : public VectorAnimationRenderer
{
+ class RenderingDataImpl;
+
public:
/**
* @brief Constructor.
private:
/**
- * @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
- */
- void SetShader() override;
-
- /**
* @brief Reset buffer list.
*/
void ResetBuffers() override;
void OnFinalize() override;
/**
- * @copydoc VectorAnimationRenderer::OnSetSize()
- */
- void OnSetSize() override
- {}
-
- /**
* @brief Event callback to process events.
*/
void OnLottieRendered() override;
/**
* @copydoc VectorAnimationRenderer::OnNotify()
*/
- void OnNotify() override
- {}
+ void OnNotify() override;
/**
* @copydoc VectorAnimationRenderer::PrepareTarget()
*/
- void PrepareTarget() override;
+ void PrepareTarget(uint32_t updatedDataIndex) override;
+
+ /**
+ * @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
+ */
+ void SetShader(uint32_t updatedDataIndex) override;
+
+ /**
+ * @copydoc VectorAnimationRenderer::OnSetSize()
+ */
+ void OnSetSize(uint32_t updatedDataIndex) override
+ {}
/**
* @copydoc VectorAnimationRenderer::IsTargetPrepared()
Dali::Texture GetTargetTexture() override;
private:
- rlottie::Surface mLottieSurface; ///
- Dali::Devel::PixelBuffer mPixelBuffer; ///
+ std::shared_ptr<RenderingDataImpl> mRenderingDataImpl[2];
+ std::shared_ptr<RenderingDataImpl> mCurrentRenderingData;
std::unique_ptr<EventThreadCallback> mRenderCallback; ///
};
// EXTERNAL INCLUDES
#include <dali/devel-api/common/hash.h>
+#include <dali/devel-api/common/stage.h>
#include <dali/integration-api/debug.h>
#include <dali/integration-api/texture-integ.h>
#include <dali/public-api/object/property-array.h>
VectorAnimationRenderer::VectorAnimationRenderer()
: mUrl(),
mMutex(),
+ mRenderingDataMutex(),
mRenderer(),
- mTexture(),
mVectorRenderer(),
mUploadCompletedSignal(),
mTotalFrameNumber(0),
- mWidth(0),
- mHeight(0),
mDefaultWidth(0),
mDefaultHeight(0),
mFrameRate(60.0f),
void VectorAnimationRenderer::Finalize()
{
- Dali::Mutex::ScopedLock lock(mMutex);
-
VectorAnimationPluginManager::Get().RemoveEventHandler(*this);
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ mRenderingData[0]->mTexture.Reset();
+ mRenderingData[1]->mTexture.Reset();
+
+ OnFinalize();
+ }
+
mRenderer.Reset();
- mTexture.Reset();
+
+ Dali::Mutex::ScopedLock lock(mMutex);
+
mVectorRenderer.reset();
mPropertyCallbacks.clear();
- OnFinalize();
-
DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "[%p]\n", this);
}
+// Called by VectorAnimationTaskThread
bool VectorAnimationRenderer::Load(const std::string& url)
{
Dali::Mutex::ScopedLock lock(mMutex);
return true;
}
+// Called by VectorAnimationTaskThread
bool VectorAnimationRenderer::Load(const Dali::Vector<uint8_t>& data)
{
Dali::Mutex::ScopedLock lock(mMutex);
mUploadCompletedSignal.Emit();
}
- SetShader();
+ SetShader(mCurrentDataIndex);
}
}
void VectorAnimationRenderer::SetSize(uint32_t width, uint32_t height)
{
- Dali::Mutex::ScopedLock lock(mMutex);
-
- if(mWidth == width && mHeight == height)
+ if(!Stage::IsCoreThread())
{
- DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "Same size (%d, %d) [%p]\n", mWidth, mHeight, this);
+ DALI_LOG_ERROR("SetSize should be called by Core Thread.\n");
return;
}
- if(mLoadFailed)
{
- DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "Load is failed. Do not make texture [%p]\n", this);
- return;
- }
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
- mWidth = width;
- mHeight = height;
+ if(mRenderingData[mCurrentDataIndex]->mWidth == width && mRenderingData[mCurrentDataIndex]->mHeight == height)
+ {
+ return;
+ }
- PrepareTarget();
+ // If updated data is not used yet, do not change current data index.
+ if(mIsDataActivated)
+ {
+ mCurrentDataIndex = 1u - mCurrentDataIndex;
+ }
+ std::shared_ptr<RenderingData> updatedData = mRenderingData[mCurrentDataIndex];
- if(mRenderer)
- {
- SetShader();
- }
+ updatedData->mWidth = width;
+ updatedData->mHeight = height;
- mResourceReady = false;
+ PrepareTarget(mCurrentDataIndex);
+
+ if(mRenderer)
+ {
+ SetShader(mCurrentDataIndex);
+ }
+
+ OnSetSize(mCurrentDataIndex);
- OnSetSize();
+ mIsDataActivated = false;
+ SetRenderingDataUpdated(true);
- DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "width = %d, height = %d [%p]\n", mWidth, mHeight, this);
+ DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "width = %d, height = %d [%p]\n", updatedData->mWidth, updatedData->mHeight, this);
+ }
}
uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
case VectorProperty::FILL_COLOR:
{
mVectorRenderer->setValue<rlottie::Property::FillColor>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
Vector3 color;
if(value.Get(color))
case VectorProperty::FILL_OPACITY:
{
mVectorRenderer->setValue<rlottie::Property::FillOpacity>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
float opacity;
if(value.Get(opacity))
case VectorProperty::STROKE_COLOR:
{
mVectorRenderer->setValue<rlottie::Property::StrokeColor>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
Vector3 color;
if(value.Get(color))
case VectorProperty::STROKE_OPACITY:
{
mVectorRenderer->setValue<rlottie::Property::StrokeOpacity>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
float opacity;
if(value.Get(opacity))
case VectorProperty::STROKE_WIDTH:
{
mVectorRenderer->setValue<rlottie::Property::StrokeWidth>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
float width;
if(value.Get(width))
case VectorProperty::TRANSFORM_ANCHOR:
{
mVectorRenderer->setValue<rlottie::Property::TrAnchor>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
Vector2 point;
if(value.Get(point))
case VectorProperty::TRANSFORM_POSITION:
{
mVectorRenderer->setValue<rlottie::Property::TrPosition>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
Vector2 position;
if(value.Get(position))
case VectorProperty::TRANSFORM_SCALE:
{
mVectorRenderer->setValue<rlottie::Property::TrScale>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
Vector2 scale;
if(value.Get(scale))
case VectorProperty::TRANSFORM_ROTATION:
{
mVectorRenderer->setValue<rlottie::Property::TrRotation>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
float rotation;
if(value.Get(rotation))
case VectorProperty::TRANSFORM_OPACITY:
{
mVectorRenderer->setValue<rlottie::Property::TrOpacity>(keyPath,
- [property, callback, id](const rlottie::FrameInfo& info) {
+ [property, callback, id](const rlottie::FrameInfo& info)
+ {
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
float opacity;
if(value.Get(opacity))
}
OnNotify();
+ mRenderingData[1u - mCurrentDataIndex]->mTexture.Reset();
}
if(emitSignal)
{
}
}
+void VectorAnimationRenderer::SetRenderingDataUpdated(bool renderingDataUpdated)
+{
+ if(!Stage::IsCoreThread())
+ {
+ DALI_LOG_ERROR("SetRenderingDataUpdated should be called by Core Thread.\n");
+ return;
+ }
+ mIsRenderingDataUpdated = renderingDataUpdated;
+}
+
} // namespace Plugin
} // namespace Dali
protected:
/**
- * @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
- */
- virtual void SetShader() = 0;
-
- /**
* @brief Reset buffer list.
*/
virtual void ResetBuffers() = 0;
virtual void OnFinalize() = 0;
/**
- * @brief Apply the changes of Size
- */
- virtual void OnSetSize() = 0;
-
- /**
* @brief Event callback to process events.
*/
virtual void OnLottieRendered() = 0;
/**
* @brief Prepare target
*/
- virtual void PrepareTarget() = 0;
+ virtual void PrepareTarget(uint32_t updatedDataIndex) = 0;
+
+ /**
+ * @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
+ */
+ virtual void SetShader(uint32_t updatedDataIndex) = 0;
+
+ /**
+ * @brief Apply the changes of Size
+ */
+ virtual void OnSetSize(uint32_t updatedDataIndex) = 0;
/**
* @brief Retrieve whether the target is prepared or not.
*/
virtual Dali::Texture GetTargetTexture() = 0;
+ void SetRenderingDataUpdated(bool renderingDataUpdated);
+
+ bool IsRenderingDataUpdated() const
+ {
+ return mIsRenderingDataUpdated;
+ }
+
+ class RenderingData
+ {
+ public:
+ Dali::Texture mTexture; ///< Texture
+ uint32_t mWidth{0}; ///< The width of the surface
+ uint32_t mHeight{0}; ///< The height of the surface
+ };
+
protected:
std::string mUrl; ///< The content file path
std::vector<std::unique_ptr<CallbackBase>> mPropertyCallbacks; ///< Property callback list
std::vector<std::pair<std::vector<uint8_t>, bool>> mDecodedBuffers;
+ bool mIsRenderingDataUpdated{false};
+ bool mIsDataActivated{false};
+ uint32_t mCurrentDataIndex{0};
+ std::shared_ptr<RenderingData> mRenderingData[2];
mutable Dali::Mutex mMutex; ///< Mutex
+ mutable Dali::Mutex mRenderingDataMutex; ///< Mutex
Dali::Renderer mRenderer; ///< Renderer
- Dali::Texture mTexture; ///< Texture
std::unique_ptr<rlottie::Animation> mVectorRenderer; ///< The vector animation renderer
UploadCompletedSignalType mUploadCompletedSignal; ///< Upload completed signal
uint32_t mTotalFrameNumber; ///< The total frame number
- uint32_t mWidth; ///< The width of the surface
- uint32_t mHeight; ///< The height of the surface
uint32_t mDefaultWidth; ///< The width of the surface
uint32_t mDefaultHeight; ///< The height of the surface
float mFrameRate; ///< The frame rate of the content