mMutex(),
mRenderer(),
mTexture(),
+ mRenderedTexture(),
mTargetSurface(),
mVectorRenderer(),
+ mResourceReadyTrigger( new EventThreadCallback( MakeCallback( this, &TizenVectorAnimationRenderer::OnResourceReady ) ) ),
+ mUploadCompletedSignal(),
mTbmQueue( NULL ),
mTotalFrameNumber( 0 ),
mWidth( 0 ),
mHeight( 0 ),
- mFrameRate( 60.0f )
+ mDefaultWidth( 0 ),
+ mDefaultHeight( 0 ),
+ mFrameRate( 60.0f ),
+ mResourceReady( false )
{
}
{
Dali::Mutex::ScopedLock lock( mMutex );
- for( auto&& iter : mBuffers )
- {
- tbm_surface_internal_unref( iter.first );
- }
- mBuffers.clear();
+ ResetBuffers();
}
bool TizenVectorAnimationRenderer::Initialize( const std::string& url )
mTotalFrameNumber = mVectorRenderer->totalFrame();
mFrameRate = static_cast< float >( mVectorRenderer->frameRate() );
+ size_t w, h;
+ mVectorRenderer->size( w, h );
+ mDefaultWidth = static_cast< uint32_t >( w );
+ mDefaultHeight = static_cast< uint32_t >( h );
+
DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::Initialize: file [%s] [%p]\n", url.c_str(), this );
return true;
if( mTargetSurface )
{
- TextureSet textureSet = renderer.GetTextures();
+ Dali::Mutex::ScopedLock lock( mMutex );
+
+ if( mResourceReady && mRenderedTexture )
+ {
+ TextureSet textureSet = renderer.GetTextures();
- textureSet.SetTexture( 0, mTexture );
+ textureSet.SetTexture( 0, mRenderedTexture );
+
+ mUploadCompletedSignal.Emit();
+ }
SetShader();
}
return;
}
- if( !mTargetSurface )
- {
- mTargetSurface = NativeImageSourceQueue::New( width, height, NativeImageSourceQueue::COLOR_DEPTH_DEFAULT );
-
- mTexture = Texture::New( *mTargetSurface );
+ mTargetSurface = NativeImageSourceQueue::New( width, height, NativeImageSourceQueue::COLOR_DEPTH_DEFAULT );
- if( mRenderer )
- {
- TextureSet textureSet = mRenderer.GetTextures();
-
- textureSet.SetTexture( 0, mTexture );
-
- SetShader();
- }
+ mTexture = Texture::New( *mTargetSurface );
- mTbmQueue = AnyCast< tbm_surface_queue_h >( mTargetSurface->GetNativeImageSourceQueue() );
- }
- else
+ if( mRenderer )
{
- mTargetSurface->SetSize( width, height );
+ SetShader();
}
+ mTbmQueue = AnyCast< tbm_surface_queue_h >( mTargetSurface->GetNativeImageSourceQueue() );
+
mWidth = width;
mHeight = height;
- // Reset the buffer list
- for( auto&& iter : mBuffers )
- {
- tbm_surface_internal_unref( iter.first );
- }
- mBuffers.clear();
+ mResourceReady = false;
DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::SetSize: width = %d, height = %d [%p]\n", mWidth, mHeight, this );
}
tbm_surface_info_s info;
tbm_surface_map( tbmSurface, TBM_OPTION_WRITE, &info );
+ rlottie::Surface surface;
bool existing = false;
- for( auto&& iter : mBuffers )
+
+ if( !mResourceReady )
{
- if( iter.first == tbmSurface )
+ // Need to reset buffer list
+ ResetBuffers();
+ }
+ else
+ {
+ for( auto&& iter : mBuffers )
{
- // Find the buffer in the existing list
- existing = true;
-
- // Render the frame
- mVectorRenderer->renderSync( frameNumber, iter.second );
- break;
+ if( iter.first == tbmSurface )
+ {
+ // Find the buffer in the existing list
+ existing = true;
+ surface = iter.second;
+ break;
+ }
}
}
unsigned char* buffer = info.planes[0].ptr;
// Create Surface object
- rlottie::Surface surface( reinterpret_cast< uint32_t* >( buffer ), mWidth, mHeight, static_cast< size_t >( info.planes[0].stride ) );
+ surface = rlottie::Surface( reinterpret_cast< uint32_t* >( buffer ), mWidth, mHeight, static_cast< size_t >( info.planes[0].stride ) );
// Push the buffer
mBuffers.push_back( SurfacePair( tbmSurface, surface ) );
-
- // Render the frame
- mVectorRenderer->renderSync( frameNumber, surface );
}
+ // Render the frame
+ mVectorRenderer->renderSync( frameNumber, surface );
+
tbm_surface_unmap( tbmSurface );
tbm_surface_queue_enqueue( mTbmQueue, tbmSurface );
+
+ if( !mResourceReady )
+ {
+ mRenderedTexture = mTexture;
+ mResourceReady = true;
+
+ mResourceReadyTrigger->Trigger();
+
+ DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::Render: Resource ready [current = %d] [%p]\n", frameNumber, this );
+ }
}
else
{
- DALI_LOG_ERROR( "Cannot dequeue a tbm_surface [%d] [%p]\n", frameNumber, this );
return false;
}
void TizenVectorAnimationRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const
{
- size_t w, h;
- mVectorRenderer->size( w, h );
- width = static_cast< uint32_t >( w );
- height = static_cast< uint32_t >( h );
+ width = mDefaultWidth;
+ height = mDefaultHeight;
DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::GetDefaultSize: width = %d, height = %d [%p]\n", width, height, this );
}
+VectorAnimationRendererPlugin::UploadCompletedSignalType& TizenVectorAnimationRenderer::UploadCompletedSignal()
+{
+ return mUploadCompletedSignal;
+}
+
void TizenVectorAnimationRenderer::SetShader()
{
NativeImageInterface::Extension* extension = static_cast< NativeImageInterface* >( mTargetSurface.Get() )->GetExtension();
}
}
+void TizenVectorAnimationRenderer::ResetBuffers()
+{
+ for( auto&& iter : mBuffers )
+ {
+ tbm_surface_internal_unref( iter.first );
+ }
+ mBuffers.clear();
+}
+
+void TizenVectorAnimationRenderer::OnResourceReady()
+{
+ DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::OnResourceReady: Set Texture [%p]\n", this );
+
+ // Set texture
+ if( mRenderer )
+ {
+ TextureSet textureSet = mRenderer.GetTextures();
+ textureSet.SetTexture( 0, mRenderedTexture );
+ }
+
+ mUploadCompletedSignal.Emit();
+}
+
} // namespace Plugin
} // namespace Dali;
#include <dali/public-api/math/uint-16-pair.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/devel-api/threading/mutex.h>
+#include <dali/devel-api/adaptor-framework/event-thread-callback.h>
#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
#include <dali/devel-api/adaptor-framework/vector-animation-renderer-plugin.h>
#include <memory>
*/
void GetDefaultSize( uint32_t& width, uint32_t& height ) const override;
+ /**
+ * @copydoc Dali::VectorAnimationRendererPlugin::UploadCompletedSignal()
+ */
+ UploadCompletedSignalType& UploadCompletedSignal() override;
+
private:
/**
*/
void SetShader();
+ /**
+ * @brief Reset buffer list.
+ */
+ void ResetBuffers();
+
+ /**
+ * @brief Event callback from rasterize thread. This is called after the first frame is ready.
+ */
+ void OnResourceReady();
+
private:
using SurfacePair = std::pair< tbm_surface_h, rlottie::Surface >;
- std::string mUrl; ///< The content file path
- std::vector< SurfacePair > mBuffers; ///< EGL Image vector
- Dali::Mutex mMutex; ///< Mutex
- Dali::Renderer mRenderer; ///< Renderer
- Dali::Texture mTexture; ///< Texture
- NativeImageSourceQueuePtr mTargetSurface; ///< The target surface
- std::unique_ptr< rlottie::Animation > mVectorRenderer; ///< The vector animation renderer
- tbm_surface_queue_h mTbmQueue; ///< Tbm surface queue handle
- uint32_t mTotalFrameNumber; ///< The total frame number
- uint32_t mWidth; ///< The width of the surface
- uint32_t mHeight; ///< The height of the surface
- float mFrameRate; ///< The frame rate of the content
+ std::string mUrl; ///< The content file path
+ std::vector< SurfacePair > mBuffers; ///< EGL Image vector
+ Dali::Mutex mMutex; ///< Mutex
+ Dali::Renderer mRenderer; ///< Renderer
+ Dali::Texture mTexture; ///< Texture
+ Dali::Texture mRenderedTexture; ///< Rendered Texture
+ NativeImageSourceQueuePtr mTargetSurface; ///< The target surface
+ std::unique_ptr< rlottie::Animation > mVectorRenderer; ///< The vector animation renderer
+ std::unique_ptr< EventThreadCallback > mResourceReadyTrigger; ///< Resource ready trigger
+ UploadCompletedSignalType mUploadCompletedSignal; ///< Upload completed signal
+ tbm_surface_queue_h mTbmQueue; ///< Tbm surface queue handle
+ 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
+ bool mResourceReady; ///< Whether the resource is ready
};
} // namespace Plugin