mRenderedTexture(),
mPreviousTextures()
{
- mRenderingDataImpl[0] = std::make_shared<RenderingDataImpl>();
- mRenderingDataImpl[1] = std::make_shared<RenderingDataImpl>();
- mRenderingData[0] = mRenderingDataImpl[0];
- mRenderingData[1] = mRenderingDataImpl[1];
}
VectorAnimationRendererTizen::~VectorAnimationRendererTizen()
// Called by VectorAnimationTaskThread
bool VectorAnimationRendererTizen::Render(uint32_t frameNumber)
{
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl;
{
Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
- mCurrentRenderingData = mRenderingDataImpl[mCurrentDataIndex];
- if(IsRenderingDataUpdated())
+ if(mPreparedRenderingData)
{
+ mPreviousRenderingData.push_back(mCurrentRenderingData);
+ mCurrentRenderingData = mPreparedRenderingData;
+ mPreparedRenderingData.reset();
mResourceReady = false;
- mIsDataActivated = true;
}
+ renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(mCurrentRenderingData);
+ }
+
+ if(!renderingDataImpl)
+ {
+ return false;
}
Dali::Mutex::ScopedLock lock(mMutex);
}
}
- if(!mCurrentRenderingData->mTbmQueue || !mVectorRenderer || !mCurrentRenderingData->mTargetSurface)
+ if(!renderingDataImpl->mTbmQueue || !mVectorRenderer || !renderingDataImpl->mTargetSurface)
{
return false;
}
- int canDequeue = tbm_surface_queue_can_dequeue(mCurrentRenderingData->mTbmQueue, 0);
+ int canDequeue = tbm_surface_queue_can_dequeue(renderingDataImpl->mTbmQueue, 0);
if(!canDequeue)
{
// Ignore the previous image which is inserted to the queue.
- mCurrentRenderingData->mTargetSurface->IgnoreSourceImage();
+ renderingDataImpl->mTargetSurface->IgnoreSourceImage();
// Check again
- canDequeue = tbm_surface_queue_can_dequeue(mCurrentRenderingData->mTbmQueue, 0);
+ canDequeue = tbm_surface_queue_can_dequeue(renderingDataImpl->mTbmQueue, 0);
if(!canDequeue)
{
return false;
tbm_surface_h tbmSurface;
- if(tbm_surface_queue_dequeue(mCurrentRenderingData->mTbmQueue, &tbmSurface) != TBM_SURFACE_QUEUE_ERROR_NONE)
+ if(tbm_surface_queue_dequeue(renderingDataImpl->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(mCurrentRenderingData->mTbmQueue, tbmSurface);
+ tbm_surface_queue_cancel_dequeue(renderingDataImpl->mTbmQueue, tbmSurface);
return false;
}
unsigned char* buffer = info.planes[0].ptr;
- if(info.width != mCurrentRenderingData->mWidth || info.height != mCurrentRenderingData->mHeight || !buffer)
+ if(info.width != renderingDataImpl->mWidth || info.height != renderingDataImpl->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(mCurrentRenderingData->mTbmQueue, tbmSurface);
+ tbm_surface_queue_cancel_dequeue(renderingDataImpl->mTbmQueue, tbmSurface);
return false;
}
if(mEnableFixedCache && (frameNumber < mDecodedBuffers.size()) && mDecodedBuffers[frameNumber].second)
{
- const int bufferSize = mCurrentRenderingData->mWidth * mCurrentRenderingData->mHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888);
+ const int bufferSize = renderingDataImpl->mWidth * renderingDataImpl->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), mCurrentRenderingData->mWidth, mCurrentRenderingData->mHeight, static_cast<size_t>(info.planes[0].stride));
+ surface = rlottie::Surface(reinterpret_cast<uint32_t*>(buffer), renderingDataImpl->mWidth, renderingDataImpl->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 = mCurrentRenderingData->mWidth * mCurrentRenderingData->mHeight * Dali::Pixel::GetBytesPerPixel(Dali::Pixel::RGBA8888);
+ const uint32_t bufferSize = renderingDataImpl->mWidth * renderingDataImpl->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(mCurrentRenderingData->mTbmQueue, tbmSurface);
+ tbm_surface_queue_enqueue(renderingDataImpl->mTbmQueue, tbmSurface);
if(!mResourceReady)
{
mPreviousTextures.push_back(mRenderedTexture); // It is used to destroy the object in the main thread.
- mRenderedTexture = mCurrentRenderingData->mTexture;
+ mRenderedTexture = renderingDataImpl->mTexture;
mResourceReady = true;
mResourceReadyTriggered = true;
void VectorAnimationRendererTizen::RenderStopped()
{
- if(mCurrentRenderingData->mTargetSurface)
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl;
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(mCurrentRenderingData);
+ }
+
+ if(renderingDataImpl && renderingDataImpl->mTargetSurface)
{
// Animation is stopped. Free empty buffers
- mCurrentRenderingData->mTargetSurface->FreeReleasedBuffers();
+ renderingDataImpl->mTargetSurface->FreeReleasedBuffers();
{
Dali::Mutex::ScopedLock lock(mMutex);
}
}
+// This Method is called inside mMutex
void VectorAnimationRendererTizen::ResetBuffers()
{
for(auto&& iter : mBuffers)
mBuffers.clear();
}
+// This Method is called inside mRenderingDataMutex
void VectorAnimationRendererTizen::OnFinalize()
{
mRenderedTexture.Reset();
mPreviousTextures.clear();
-
- for(auto&& renderingData : mRenderingDataImpl)
- {
- renderingData->mTargetSurface = nullptr;
- renderingData->mTbmQueue = nullptr;
- }
}
+// This Method is called inside mMutex
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)
+// This Method is called inside mRenderingDataMutex
+void VectorAnimationRendererTizen::PrepareTarget(std::shared_ptr<RenderingData> renderingData)
{
- mRenderingDataImpl[updatedDataIndex]->mTargetSurface = NativeImageSourceQueue::New(mRenderingDataImpl[updatedDataIndex]->mWidth, mRenderingDataImpl[updatedDataIndex]->mHeight, NativeImageSourceQueue::ColorFormat::RGBA8888);
- mRenderingDataImpl[updatedDataIndex]->mTexture = Texture::New(*mRenderingDataImpl[updatedDataIndex]->mTargetSurface);
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(renderingData);
+ renderingDataImpl->mTargetSurface = NativeImageSourceQueue::New(renderingDataImpl->mWidth, renderingDataImpl->mHeight, NativeImageSourceQueue::ColorFormat::BGRA8888);
+ renderingDataImpl->mTexture = Texture::New(*renderingDataImpl->mTargetSurface);
}
-void VectorAnimationRendererTizen::SetShader(uint32_t updatedDataIndex)
+// This Method is called inside mRenderingDataMutex
+void VectorAnimationRendererTizen::SetShader(std::shared_ptr<RenderingData> renderingData)
{
if(mShaderChanged)
{
}
// Get custom fragment shader prefix
- mRenderingDataImpl[updatedDataIndex]->mTargetSurface->ApplyNativeFragmentShader(fragmentShader);
+ if(!renderingData)
+ {
+ DALI_LOG_ERROR("Target Surface is not yet prepared.\n");
+ }
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(renderingData);
+ renderingDataImpl->mTargetSurface->ApplyNativeFragmentShader(fragmentShader);
// Set the modified shader again
Shader newShader = Shader::New(vertexShader, fragmentShader);
mShaderChanged = true;
}
-void VectorAnimationRendererTizen::OnSetSize(uint32_t updatedDataIndex)
+// This Method is called inside mRenderingDataMutex
+void VectorAnimationRendererTizen::OnSetSize(std::shared_ptr<RenderingData> renderingData)
{
- std::shared_ptr<RenderingDataImpl> renderingData = mRenderingDataImpl[updatedDataIndex];
- renderingData->mTbmQueue = AnyCast<tbm_surface_queue_h>(renderingData->mTargetSurface->GetNativeImageSourceQueue());
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(renderingData);
+ renderingDataImpl->mTbmQueue = AnyCast<tbm_surface_queue_h>(renderingDataImpl->mTargetSurface->GetNativeImageSourceQueue());
}
bool VectorAnimationRendererTizen::IsTargetPrepared()
{
- return (mCurrentRenderingData) ? !!mCurrentRenderingData->mTargetSurface : false;
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl;
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(mPreparedRenderingData ? mPreparedRenderingData : mCurrentRenderingData);
+ }
+ return (renderingDataImpl) ? !!renderingDataImpl->mTargetSurface : false;
}
+// This Method is called inside mMutex
bool VectorAnimationRendererTizen::IsRenderReady()
{
return (mResourceReady && mRenderedTexture);
}
+// This Method is called inside mMutex
Dali::Texture VectorAnimationRendererTizen::GetTargetTexture()
{
return mRenderedTexture;
}
+// This Method is called inside mRenderingDataMutex
+std::shared_ptr<VectorAnimationRenderer::RenderingData> VectorAnimationRendererTizen::CreateRenderingData()
+{
+ return std::make_shared<RenderingDataImpl>();
+}
+
} // namespace Plugin
} // namespace Dali
/**
* @copydoc VectorAnimationRenderer::PrepareTarget()
*/
- void PrepareTarget(uint32_t updatedDataIndex) override;
+ void PrepareTarget(std::shared_ptr<RenderingData> renderingData) override;
/**
* @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
*/
- void SetShader(uint32_t updatedDataIndex) override;
+ void SetShader(std::shared_ptr<RenderingData> renderingData) override;
/**
* @copydoc VectorAnimationRenderer::OnSetSize()
*/
- void OnSetSize(uint32_t updatedDataIndex) override;
+ void OnSetSize(std::shared_ptr<RenderingData> renderingData) override;
/**
* @copydoc VectorAnimationRenderer::IsTargetPrepared()
*/
Dali::Texture GetTargetTexture() override;
+ /**
+ * @copydoc VectorAnimationRenderer::CreateRenderingData()
+ */
+ std::shared_ptr<RenderingData> CreateRenderingData() override;
+
private:
using SurfacePair = std::pair<tbm_surface_h, rlottie::Surface>;
std::vector<SurfacePair> mBuffers; ///< EGL Image vector
- std::shared_ptr<RenderingDataImpl> mRenderingDataImpl[2];
- std::shared_ptr<RenderingDataImpl> mCurrentRenderingData;
Dali::Texture mRenderedTexture; ///< Rendered Texture
std::vector<Dali::Texture> mPreviousTextures; ///< Previous rendered texture
};
VectorAnimationRendererX::VectorAnimationRendererX()
: 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)
{
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl;
{
Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
- mCurrentRenderingData = mRenderingDataImpl[mCurrentDataIndex];
- if(IsRenderingDataUpdated())
+ if(mPreparedRenderingData)
{
+ mPreviousRenderingData.push_back(mCurrentRenderingData);
+ mCurrentRenderingData = mPreparedRenderingData;
+ mPreparedRenderingData.reset();
mResourceReady = false;
- mIsDataActivated = true;
}
+ renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(mCurrentRenderingData);
+ }
+
+ if(!renderingDataImpl)
+ {
+ return false;
}
Dali::Mutex::ScopedLock lock(mMutex);
- if(!mVectorRenderer || !mCurrentRenderingData->mPixelBuffer)
+ if(!mVectorRenderer || !renderingDataImpl->mPixelBuffer)
{
return false;
}
- mVectorRenderer->renderSync(frameNumber, mCurrentRenderingData->mLottieSurface);
+ mVectorRenderer->renderSync(frameNumber, renderingDataImpl->mLottieSurface);
mRenderCallback->Trigger();
if(!mResourceReady)
{
}
+// This Method is called inside mMutex
void VectorAnimationRendererX::ResetBuffers()
{
- for(auto&& renderingData : mRenderingDataImpl)
- {
- if(renderingData->mPixelBuffer)
- {
- uint32_t bufferSize = renderingData->mPixelBuffer.GetWidth() * renderingData->mPixelBuffer.GetHeight() * Dali::Pixel::GetBytesPerPixel(renderingData->mPixelBuffer.GetPixelFormat());
- memset(renderingData->mPixelBuffer.GetBuffer(), 0, bufferSize);
- }
- }
}
+// This Method is called inside mRenderingDataMutex
void VectorAnimationRendererX::OnFinalize()
{
}
void VectorAnimationRendererX::OnLottieRendered()
{
- Dali::Mutex::ScopedLock lock(mMutex);
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl;
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(mCurrentRenderingData);
+ }
- if(mCurrentRenderingData->mPixelBuffer && mCurrentRenderingData->mTexture)
+ Dali::Mutex::ScopedLock lock(mMutex);
+ if(renderingDataImpl && renderingDataImpl->mPixelBuffer && renderingDataImpl->mTexture)
{
- PixelData pixelData = mCurrentRenderingData->mPixelBuffer.CreatePixelData();
- mCurrentRenderingData->mTexture.Upload(pixelData);
+ PixelData pixelData = renderingDataImpl->mPixelBuffer.CreatePixelData();
+ renderingDataImpl->mTexture.Upload(pixelData);
}
}
+// This Method is called inside mMutex
void VectorAnimationRendererX::OnNotify()
{
- // If RenderingData is updated, then clear previous renderingData
- if(IsRenderingDataUpdated())
- {
- std::shared_ptr<RenderingDataImpl> oldRenderingData = mRenderingDataImpl[1u - mCurrentDataIndex];
- SetRenderingDataUpdated(false);
- }
}
-void VectorAnimationRendererX::PrepareTarget(uint32_t updatedDataIndex)
+// This Method is called inside mRenderingDataMutex
+void VectorAnimationRendererX::PrepareTarget(std::shared_ptr<RenderingData> renderingData)
{
- 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));
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(renderingData);
+ renderingDataImpl->mTexture = Texture::New(Dali::TextureType::TEXTURE_2D, Dali::Pixel::BGRA8888, renderingDataImpl->mWidth, renderingDataImpl->mHeight);
+ renderingDataImpl->mPixelBuffer = Dali::Devel::PixelBuffer::New(renderingDataImpl->mWidth, renderingDataImpl->mHeight, Dali::Pixel::BGRA8888);
+ renderingDataImpl->mLottieSurface = rlottie::Surface(reinterpret_cast<uint32_t*>(renderingDataImpl->mPixelBuffer.GetBuffer()), renderingDataImpl->mWidth, renderingDataImpl->mHeight, static_cast<size_t>(renderingDataImpl->mPixelBuffer.GetStride() * 4));
}
-void VectorAnimationRendererX::SetShader(uint32_t updatedDataIndex)
+// This Method is called inside mRenderingDataMutex
+void VectorAnimationRendererX::SetShader(std::shared_ptr<RenderingData> renderingData)
{
- std::shared_ptr<RenderingDataImpl> renderingData = mRenderingDataImpl[updatedDataIndex];
- if(mShaderChanged || !renderingData->mTexture)
+ if(!renderingData)
+ {
+ DALI_LOG_ERROR("Target Surface is not yet prepared.\n");
+ return;
+ }
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(renderingData);
+
+ if(mShaderChanged || !renderingDataImpl->mTexture)
{
return;
}
bool VectorAnimationRendererX::IsTargetPrepared()
{
- return (mCurrentRenderingData) ? !!mCurrentRenderingData->mPixelBuffer : false;
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl;
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(mPreparedRenderingData ? mPreparedRenderingData : mCurrentRenderingData);
+ }
+ return (renderingDataImpl) ? !!renderingDataImpl->mPixelBuffer : false;
}
+// This Method is called inside mMutex
bool VectorAnimationRendererX::IsRenderReady()
{
- return mResourceReady && ((mCurrentRenderingData) ? !!mCurrentRenderingData->mTexture : false);
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl;
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(mCurrentRenderingData);
+ }
+ return mResourceReady && ((renderingDataImpl) ? !!renderingDataImpl->mTexture : false);
}
+// This Method is called inside mMutex
Dali::Texture VectorAnimationRendererX::GetTargetTexture()
{
- return (mCurrentRenderingData) ? mCurrentRenderingData->mTexture : Texture();
+ std::shared_ptr<RenderingDataImpl> renderingDataImpl;
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ renderingDataImpl = std::static_pointer_cast<RenderingDataImpl>(mCurrentRenderingData);
+ }
+ return (renderingDataImpl) ? renderingDataImpl->mTexture : Texture();
+}
+
+// This Method is called inside mRenderingDataMutex
+std::shared_ptr<VectorAnimationRenderer::RenderingData> VectorAnimationRendererX::CreateRenderingData()
+{
+ return std::make_shared<RenderingDataImpl>();
}
} // namespace Plugin
/**
* @copydoc VectorAnimationRenderer::PrepareTarget()
*/
- void PrepareTarget(uint32_t updatedDataIndex) override;
+ void PrepareTarget(std::shared_ptr<RenderingData> renderingData) override;
/**
* @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
*/
- void SetShader(uint32_t updatedDataIndex) override;
+ void SetShader(std::shared_ptr<RenderingData> renderingData) override;
/**
* @copydoc VectorAnimationRenderer::OnSetSize()
+ * @note This Method is called inside mRenderingDataMutex
*/
- void OnSetSize(uint32_t updatedDataIndex) override
+ void OnSetSize(std::shared_ptr<RenderingData> renderingData) override
{}
/**
*/
Dali::Texture GetTargetTexture() override;
+ /**
+ * @copydoc VectorAnimationRenderer::CreateRenderingData()
+ */
+ std::shared_ptr<RenderingData> CreateRenderingData() override;
+
private:
- std::shared_ptr<RenderingDataImpl> mRenderingDataImpl[2];
- std::shared_ptr<RenderingDataImpl> mCurrentRenderingData;
std::unique_ptr<EventThreadCallback> mRenderCallback; ///
};
{
}
+// This Method is called inside mRenderingDataMutex
+void VectorAnimationRenderer::ClearPreviousRenderingData()
+{
+ mPreviousRenderingData.clear();
+}
+
void VectorAnimationRenderer::Finalize()
{
- VectorAnimationPluginManager::Get().RemoveEventHandler(*this);
+ Dali::Mutex::ScopedLock lock(mMutex);
- {
- Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
- mRenderingData[0]->mTexture.Reset();
- mRenderingData[1]->mTexture.Reset();
+ VectorAnimationPluginManager::Get().RemoveEventHandler(*this);
- OnFinalize();
- }
+ mVectorRenderer.reset();
+ mPropertyCallbacks.clear();
mRenderer.Reset();
- Dali::Mutex::ScopedLock lock(mMutex);
+ mPreparedRenderingData.reset();
+ mCurrentRenderingData.reset();
+ ClearPreviousRenderingData();
- mVectorRenderer.reset();
- mPropertyCallbacks.clear();
+ OnFinalize();
DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "[%p]\n", this);
}
if(IsTargetPrepared())
{
- Dali::Mutex::ScopedLock lock(mMutex);
-
- if(IsRenderReady())
{
- TextureSet textureSet = renderer.GetTextures();
+ Dali::Mutex::ScopedLock lock(mMutex);
+
+ if(IsRenderReady())
+ {
+ TextureSet textureSet = renderer.GetTextures();
- textureSet.SetTexture(0, GetTargetTexture());
+ textureSet.SetTexture(0, GetTargetTexture());
- mUploadCompletedSignal.Emit();
+ mUploadCompletedSignal.Emit();
+ }
}
- SetShader(mCurrentDataIndex);
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ SetShader(mPreparedRenderingData ? mPreparedRenderingData : mCurrentRenderingData);
+ }
}
}
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);
- if(mRenderingData[mCurrentDataIndex]->mWidth == width && mRenderingData[mCurrentDataIndex]->mHeight == height)
+ if(!mPreparedRenderingData && mCurrentRenderingData && (mCurrentRenderingData->mWidth == width && mCurrentRenderingData->mHeight == height))
{
return;
}
- // If updated data is not used yet, do not change current data index.
- if(mIsDataActivated)
+ if(mPreparedRenderingData && (mPreparedRenderingData->mWidth == width && mPreparedRenderingData->mHeight == height))
{
- mCurrentDataIndex = 1u - mCurrentDataIndex;
+ return;
}
- std::shared_ptr<RenderingData> updatedData = mRenderingData[mCurrentDataIndex];
+ mPreparedRenderingData.reset();
+ }
- updatedData->mWidth = width;
- updatedData->mHeight = height;
+ std::shared_ptr<RenderingData> preparedRenderingData = CreateRenderingData();
- PrepareTarget(mCurrentDataIndex);
+ // If updated data is not used yet, do not change current data index.
+ preparedRenderingData->mWidth = width;
+ preparedRenderingData->mHeight = height;
- if(mRenderer)
- {
- SetShader(mCurrentDataIndex);
- }
+ PrepareTarget(preparedRenderingData);
- OnSetSize(mCurrentDataIndex);
+ if(mRenderer)
+ {
+ SetShader(preparedRenderingData);
+ }
- mIsDataActivated = false;
- SetRenderingDataUpdated(true);
+ OnSetSize(preparedRenderingData);
- DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "width = %d, height = %d [%p]\n", updatedData->mWidth, updatedData->mHeight, this);
+ {
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ mPreparedRenderingData = preparedRenderingData;
}
+
+ DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "width = %d, height = %d [%p]\n", preparedRenderingData->mWidth, preparedRenderingData->mHeight, this);
}
uint32_t VectorAnimationRenderer::GetTotalFrameNumber() const
mPropertyCallbacks.push_back(std::unique_ptr<CallbackBase>(callback));
- switch(property)
+ if(mVectorRenderer)
{
- case VectorProperty::FILL_COLOR:
- {
- mVectorRenderer->setValue<rlottie::Property::FillColor>(keyPath,
- [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))
- {
- return rlottie::Color(color.r, color.g, color.b);
- }
- return rlottie::Color(1.0f, 1.0f, 1.0f);
- });
- break;
- }
- case VectorProperty::FILL_OPACITY:
- {
- mVectorRenderer->setValue<rlottie::Property::FillOpacity>(keyPath,
- [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))
- {
- return opacity * 100;
- }
- return 100.0f;
- });
- break;
- }
- case VectorProperty::STROKE_COLOR:
+ switch(property)
{
- mVectorRenderer->setValue<rlottie::Property::StrokeColor>(keyPath,
+ case VectorProperty::FILL_COLOR:
+ {
+ mVectorRenderer->setValue<rlottie::Property::FillColor>(keyPath,
[property, callback, id](const rlottie::FrameInfo& info)
{
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
}
return rlottie::Color(1.0f, 1.0f, 1.0f);
});
- break;
- }
- case VectorProperty::STROKE_OPACITY:
- {
- mVectorRenderer->setValue<rlottie::Property::StrokeOpacity>(keyPath,
+ break;
+ }
+ case VectorProperty::FILL_OPACITY:
+ {
+ mVectorRenderer->setValue<rlottie::Property::FillOpacity>(keyPath,
[property, callback, id](const rlottie::FrameInfo& info)
{
Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
}
return 100.0f;
});
- break;
- }
- case VectorProperty::STROKE_WIDTH:
- {
- mVectorRenderer->setValue<rlottie::Property::StrokeWidth>(keyPath,
- [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))
+ break;
+ }
+ case VectorProperty::STROKE_COLOR:
+ {
+ mVectorRenderer->setValue<rlottie::Property::StrokeColor>(keyPath,
+ [property, callback, id](const rlottie::FrameInfo& info)
{
- return width;
- }
- return 1.0f;
- });
- break;
- }
- case VectorProperty::TRANSFORM_ANCHOR:
- {
- mVectorRenderer->setValue<rlottie::Property::TrAnchor>(keyPath,
- [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))
- {
- return rlottie::Point(point.x, point.y);
- }
- return rlottie::Point(0.0f, 0.0f);
- });
- break;
- }
- case VectorProperty::TRANSFORM_POSITION:
- {
- mVectorRenderer->setValue<rlottie::Property::TrPosition>(keyPath,
+ Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
+ Vector3 color;
+ if(value.Get(color))
+ {
+ return rlottie::Color(color.r, color.g, color.b);
+ }
+ return rlottie::Color(1.0f, 1.0f, 1.0f);
+ });
+ break;
+ }
+ case VectorProperty::STROKE_OPACITY:
+ {
+ mVectorRenderer->setValue<rlottie::Property::StrokeOpacity>(keyPath,
+ [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))
+ {
+ return opacity * 100;
+ }
+ return 100.0f;
+ });
+ break;
+ }
+ case VectorProperty::STROKE_WIDTH:
+ {
+ mVectorRenderer->setValue<rlottie::Property::StrokeWidth>(keyPath,
+ [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))
+ {
+ return width;
+ }
+ return 1.0f;
+ });
+ break;
+ }
+ case VectorProperty::TRANSFORM_ANCHOR:
+ {
+ mVectorRenderer->setValue<rlottie::Property::TrAnchor>(keyPath,
[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))
+ Vector2 point;
+ if(value.Get(point))
{
- return rlottie::Point(position.x, position.y);
+ return rlottie::Point(point.x, point.y);
}
return rlottie::Point(0.0f, 0.0f);
});
- break;
- }
- case VectorProperty::TRANSFORM_SCALE:
- {
- mVectorRenderer->setValue<rlottie::Property::TrScale>(keyPath,
- [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))
- {
- return rlottie::Size(scale.x, scale.y);
- }
- return rlottie::Size(100.0f, 100.0f);
- });
- break;
- }
- case VectorProperty::TRANSFORM_ROTATION:
- {
- mVectorRenderer->setValue<rlottie::Property::TrRotation>(keyPath,
- [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))
+ break;
+ }
+ case VectorProperty::TRANSFORM_POSITION:
+ {
+ mVectorRenderer->setValue<rlottie::Property::TrPosition>(keyPath,
+ [property, callback, id](const rlottie::FrameInfo& info)
{
- return rotation;
- }
- return 0.0f;
- });
- break;
- }
- case VectorProperty::TRANSFORM_OPACITY:
- {
- mVectorRenderer->setValue<rlottie::Property::TrOpacity>(keyPath,
+ Property::Value value = CallbackBase::ExecuteReturn<Property::Value>(*callback, id, property, info.curFrame());
+ Vector2 position;
+ if(value.Get(position))
+ {
+ return rlottie::Point(position.x, position.y);
+ }
+ return rlottie::Point(0.0f, 0.0f);
+ });
+ break;
+ }
+ case VectorProperty::TRANSFORM_SCALE:
+ {
+ mVectorRenderer->setValue<rlottie::Property::TrScale>(keyPath,
[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))
+ Vector2 scale;
+ if(value.Get(scale))
{
- return opacity * 100;
+ return rlottie::Size(scale.x, scale.y);
}
- return 100.0f;
+ return rlottie::Size(100.0f, 100.0f);
});
- break;
+ break;
+ }
+ case VectorProperty::TRANSFORM_ROTATION:
+ {
+ mVectorRenderer->setValue<rlottie::Property::TrRotation>(keyPath,
+ [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))
+ {
+ return rotation;
+ }
+ return 0.0f;
+ });
+ break;
+ }
+ case VectorProperty::TRANSFORM_OPACITY:
+ {
+ mVectorRenderer->setValue<rlottie::Property::TrOpacity>(keyPath,
+ [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))
+ {
+ return opacity * 100;
+ }
+ return 100.0f;
+ });
+ break;
+ }
}
}
}
}
OnNotify();
- mRenderingData[1u - mCurrentDataIndex]->mTexture.Reset();
}
- if(emitSignal)
+
{
- mUploadCompletedSignal.Emit();
+ Dali::Mutex::ScopedLock lock(mRenderingDataMutex);
+ ClearPreviousRenderingData();
}
-}
-
-void VectorAnimationRenderer::SetRenderingDataUpdated(bool renderingDataUpdated)
-{
- if(!Stage::IsCoreThread())
+ if(emitSignal)
{
- DALI_LOG_ERROR("SetRenderingDataUpdated should be called by Core Thread.\n");
- return;
+ mUploadCompletedSignal.Emit();
}
- mIsRenderingDataUpdated = renderingDataUpdated;
}
} // namespace Plugin
void NotifyEvent() override;
protected:
+
+ 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
+ };
+
/**
* @brief Reset buffer list.
*/
/**
* @brief Prepare target
*/
- virtual void PrepareTarget(uint32_t updatedDataIndex) = 0;
+ virtual void PrepareTarget(std::shared_ptr<RenderingData> renderingData) = 0;
/**
* @brief Set shader for NativeImageSourceQueue with custom sampler type and prefix.
*/
- virtual void SetShader(uint32_t updatedDataIndex) = 0;
+ virtual void SetShader(std::shared_ptr<RenderingData> renderingData) = 0;
/**
* @brief Apply the changes of Size
*/
- virtual void OnSetSize(uint32_t updatedDataIndex) = 0;
+ virtual void OnSetSize(std::shared_ptr<RenderingData> renderingData) = 0;
/**
* @brief Retrieve whether the target is prepared or not.
*/
virtual Dali::Texture GetTargetTexture() = 0;
- void SetRenderingDataUpdated(bool renderingDataUpdated);
-
- bool IsRenderingDataUpdated() const
- {
- return mIsRenderingDataUpdated;
- }
+ /**
+ * @brief Clear Previous RenderingData
+ */
+ void ClearPreviousRenderingData();
- 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
- };
+ /**
+ * @brief Create RenderingData
+ */
+ virtual std::shared_ptr<RenderingData> CreateRenderingData() = 0;
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];
+ std::shared_ptr<RenderingData> mPreparedRenderingData;
+ std::shared_ptr<RenderingData> mCurrentRenderingData;
+ std::vector<std::shared_ptr<RenderingData>> mPreviousRenderingData;
+
mutable Dali::Mutex mMutex; ///< Mutex
mutable Dali::Mutex mRenderingDataMutex; ///< Mutex
Dali::Renderer mRenderer; ///< Renderer