Merge branch 'devel/master' into tizen
authorWonsik Jung <sidein@samsung.com>
Thu, 19 Dec 2019 07:57:42 +0000 (16:57 +0900)
committerWonsik Jung <sidein@samsung.com>
Thu, 19 Dec 2019 07:57:42 +0000 (16:57 +0900)
1  2 
dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.cpp.orig

index 0000000,0000000..0efe707
new file mode 100755 (executable)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,426 @@@
++/*
++ * Copyright (c) 2019 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.
++ * You may obtain a copy of the License at
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ *
++ */
++
++// CLASS HEADER
++#include <dali-extension/vector-animation-renderer/tizen-vector-animation-renderer.h>
++
++// EXTERNAL INCLUDES
++#include <dali/public-api/object/property-array.h>
++#include <dali/integration-api/debug.h>
++#include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
++#include <dali/devel-api/images/native-image-interface-extension.h>
++#include <cstring> // for strlen()
++#include <tbm_surface_internal.h>
++
++// INTERNAL INCLUDES
++#include <dali-extension/vector-animation-renderer/tizen-vector-animation-manager.h>
++
++// The plugin factories
++extern "C" DALI_EXPORT_API Dali::VectorAnimationRendererPlugin* CreateVectorAnimationRendererPlugin( void )
++{
++  return new Dali::Plugin::TizenVectorAnimationRenderer;
++}
++
++namespace Dali
++{
++
++namespace Plugin
++{
++
++namespace
++{
++
++const char* const DEFAULT_SAMPLER_TYPENAME( "sampler2D" );
++const char* const PIXEL_AREA_UNIFORM_NAME( "pixelArea" );
++
++const Vector4 FULL_TEXTURE_RECT( 0.f, 0.f, 1.f, 1.f );
++
++} // unnamed namespace
++
++TizenVectorAnimationRenderer::TizenVectorAnimationRenderer()
++: mUrl(),
++  mBuffers(),
++  mMutex(),
++  mRenderer(),
++  mTexture(),
++  mRenderedTexture(),
++  mTargetSurface(),
++  mVectorRenderer(),
++  mUploadCompletedSignal(),
++  mTbmQueue( NULL ),
++  mTotalFrameNumber( 0 ),
++  mWidth( 0 ),
++  mHeight( 0 ),
++  mDefaultWidth( 0 ),
++  mDefaultHeight( 0 ),
++  mFrameRate( 60.0f ),
++  mResourceReady( false ),
++  mShaderChanged( false ),
++  mResourceReadyTriggered( false )
++{
++}
++
++TizenVectorAnimationRenderer::~TizenVectorAnimationRenderer()
++{
++  Dali::Mutex::ScopedLock lock( mMutex );
++
++  ResetBuffers();
++}
++
++bool TizenVectorAnimationRenderer::Initialize( const std::string& url )
++{
++  mUrl = url;
++
++  mVectorRenderer = rlottie::Animation::loadFromFile( mUrl );
++  if( !mVectorRenderer )
++  {
++    DALI_LOG_ERROR( "Failed to load a Lottie file [%s]\n", mUrl.c_str() );
++    return false;
++  }
++
++  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 );
++
++  TizenVectorAnimationManager::Get().AddEventHandler( *this );
++
++  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::Initialize: file [%s] [%p]\n", url.c_str(), this );
++
++  return true;
++}
++
++void TizenVectorAnimationRenderer::Finalize()
++{
++  Dali::Mutex::ScopedLock lock( mMutex );
++
++  TizenVectorAnimationManager::Get().RemoveEventHandler( *this );
++
++  mRenderer.Reset();
++  mTexture.Reset();
++  mRenderedTexture.Reset();
++  mVectorRenderer.reset();
++
++  mTargetSurface = nullptr;
++  mTbmQueue = NULL;
++}
++
++void TizenVectorAnimationRenderer::SetRenderer( Renderer renderer )
++{
++  mRenderer = renderer;
++  mShaderChanged = false;
++
++  if( mTargetSurface )
++  {
++    Dali::Mutex::ScopedLock lock( mMutex );
++
++    if( mResourceReady && mRenderedTexture )
++    {
++      TextureSet textureSet = renderer.GetTextures();
++
++      textureSet.SetTexture( 0, mRenderedTexture );
++
++      mUploadCompletedSignal.Emit();
++    }
++
++    SetShader();
++  }
++
++  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::SetRenderer [%p]\n", this );
++}
++
++void TizenVectorAnimationRenderer::SetSize( uint32_t width, uint32_t height )
++{
++  Dali::Mutex::ScopedLock lock( mMutex );
++
++  if( mWidth == width && mHeight == height )
++  {
++    DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::SetSize: Same size (%d, %d) [%p]\n", mWidth, mHeight, this );
++    return;
++  }
++
++  mTargetSurface = NativeImageSourceQueue::New( width, height, NativeImageSourceQueue::COLOR_DEPTH_DEFAULT );
++
++  mTexture = Texture::New( *mTargetSurface );
++
++  if( mRenderer )
++  {
++    SetShader();
++  }
++
++  mTbmQueue = AnyCast< tbm_surface_queue_h >( mTargetSurface->GetNativeImageSourceQueue() );
++
++  mWidth = width;
++  mHeight = height;
++
++  mResourceReady = false;
++
++  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::SetSize: width = %d, height = %d [%p]\n", mWidth, mHeight, this );
++}
++
++bool TizenVectorAnimationRenderer::Render( uint32_t frameNumber )
++{
++  Dali::Mutex::ScopedLock lock( mMutex );
++
++  if( !mTbmQueue || !mVectorRenderer )
++  {
++    return false;
++  }
++
++  if( tbm_surface_queue_can_dequeue( mTbmQueue, 0 ) )
++  {
++    tbm_surface_h tbmSurface;
++
++    if( tbm_surface_queue_dequeue( mTbmQueue, &tbmSurface ) != TBM_SURFACE_QUEUE_ERROR_NONE )
++    {
++      DALI_LOG_ERROR( "Failed to dequeue a tbm_surface [%p]\n", this );
++      return false;
++    }
++
++    tbm_surface_info_s info;
++    tbm_surface_map( tbmSurface, TBM_OPTION_WRITE, &info );
++
++    rlottie::Surface surface;
++    bool existing = false;
++
++    if( !mResourceReady )
++    {
++      // Need to reset buffer list
++      ResetBuffers();
++    }
++    else
++    {
++      for( auto&& iter : mBuffers )
++      {
++        if( iter.first == tbmSurface )
++        {
++          // Find the buffer in the existing list
++          existing = true;
++          surface = iter.second;
++          break;
++        }
++      }
++    }
++
++    if( !existing )
++    {
++      tbm_surface_internal_ref( tbmSurface );
++
++      unsigned char* buffer = info.planes[0].ptr;
++
++      // Create Surface object
++      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 );
++
++    tbm_surface_unmap( tbmSurface );
++
++    tbm_surface_queue_enqueue( mTbmQueue, tbmSurface );
++
++    if( !mResourceReady )
++    {
++      mRenderedTexture = mTexture;
++      mResourceReady = true;
++      mResourceReadyTriggered = true;
++
++      TizenVectorAnimationManager::Get().TriggerEvent( *this );
++
++      DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::Render: Resource ready [current = %d] [%p]\n", frameNumber, this );
++    }
++
++    return true;
++  }
++
++  return false;
++}
++
++uint32_t TizenVectorAnimationRenderer::GetTotalFrameNumber() const
++{
++  return mTotalFrameNumber;
++}
++
++float TizenVectorAnimationRenderer::GetFrameRate() const
++{
++  return mFrameRate;
++}
++
++void TizenVectorAnimationRenderer::GetDefaultSize( uint32_t& width, uint32_t& height ) const
++{
++  width = mDefaultWidth;
++  height = mDefaultHeight;
++
++  DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::GetDefaultSize: width = %d, height = %d [%p]\n", width, height, this );
++}
++
++void TizenVectorAnimationRenderer::GetLayerInfo( Property::Map& map ) const
++{
++  Dali::Mutex::ScopedLock lock( mMutex );
++
++  if( mVectorRenderer )
++<<<<<<< HEAD
++  {
++    auto layerInfo = mVectorRenderer->layers();
++
++    for( auto&& iter : layerInfo )
++    {
++      Property::Array frames;
++      frames.PushBack( std::get< 1 >( iter ) );
++      frames.PushBack( std::get< 2 >( iter ) );
++      map.Add( std::get< 0 >( iter ), frames );
++=======
++  {
++    auto layerInfo = mVectorRenderer->layers();
++
++    for( auto&& iter : layerInfo )
++    {
++      Property::Array frames;
++      frames.PushBack( std::get< 1 >( iter ) );
++      frames.PushBack( std::get< 2 >( iter ) );
++      map.Add( std::get< 0 >( iter ), frames );
++    }
++  }
++}
++
++bool TizenVectorAnimationRenderer::GetMarkerInfo( const std::string& marker, uint32_t& startFrame, uint32_t& endFrame ) const
++{
++  Dali::Mutex::ScopedLock lock( mMutex );
++
++  if( mVectorRenderer )
++  {
++    auto markerList = mVectorRenderer->markers();
++    for( auto&& iter : markerList )
++    {
++      if( std::get< 0 >( iter ).compare( marker ) == 0 )
++      {
++        startFrame = static_cast< uint32_t >( std::get< 1 >( iter ) );
++        endFrame = static_cast< uint32_t >( std::get< 2 >( iter ) );
++        return true;
++      }
++>>>>>>> devel/master
++    }
++  }
++  return false;
++}
++
++VectorAnimationRendererPlugin::UploadCompletedSignalType& TizenVectorAnimationRenderer::UploadCompletedSignal()
++{
++  return mUploadCompletedSignal;
++}
++
++void TizenVectorAnimationRenderer::NotifyEvent()
++{
++  Dali::Mutex::ScopedLock lock( mMutex );
++
++  if( mResourceReadyTriggered )
++  {
++    DALI_LOG_RELEASE_INFO( "TizenVectorAnimationRenderer::NotifyEvent: Set Texture [%p]\n", this );
++
++    // Set texture
++    if( mRenderer && mRenderedTexture )
++    {
++      TextureSet textureSet = mRenderer.GetTextures();
++      textureSet.SetTexture( 0, mRenderedTexture );
++    }
++
++    mResourceReadyTriggered = false;
++
++    mUploadCompletedSignal.Emit();
++  }
++}
++
++void TizenVectorAnimationRenderer::SetShader()
++{
++  if( mShaderChanged )
++  {
++    return;
++  }
++
++  NativeImageInterface::Extension* extension = static_cast< NativeImageInterface* >( mTargetSurface.Get() )->GetExtension();
++  if( extension )
++  {
++    Shader shader = mRenderer.GetShader();
++
++    std::string fragmentShader;
++    std::string vertexShader;
++
++    // Get custom fragment shader prefix
++    const char* fragmentPreFix = extension->GetCustomFragmentPreFix();
++    if( fragmentPreFix )
++    {
++      fragmentShader = fragmentPreFix;
++      fragmentShader += "\n";
++    }
++
++    // Get the current fragment shader source
++    Property::Value program = shader.GetProperty( Shader::Property::PROGRAM );
++    Property::Map* map = program.GetMap();
++    if( map )
++    {
++      Property::Value* fragment = map->Find( "fragment" );
++      if( fragment )
++      {
++        fragmentShader += fragment->Get< std::string >();
++      }
++
++      Property::Value* vertex = map->Find( "vertex" );
++      if( vertex )
++      {
++        vertexShader = vertex->Get< std::string >();
++      }
++    }
++
++    // Get custom sampler type name
++    const char* customSamplerTypename = extension->GetCustomSamplerTypename();
++    if( customSamplerTypename )
++    {
++      size_t position = fragmentShader.find( DEFAULT_SAMPLER_TYPENAME );
++      if( position != std::string::npos )
++      {
++        fragmentShader.replace( position, strlen( DEFAULT_SAMPLER_TYPENAME ), customSamplerTypename );
++      }
++    }
++
++    // Set the modified shader again
++    Shader newShader = Shader::New( vertexShader, fragmentShader );
++    newShader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
++
++    mRenderer.SetShader( newShader );
++
++    mShaderChanged = true;
++  }
++}
++
++void TizenVectorAnimationRenderer::ResetBuffers()
++{
++  for( auto&& iter : mBuffers )
++  {
++    tbm_surface_internal_unref( iter.first );
++  }
++  mBuffers.clear();
++}
++
++} // namespace Plugin
++
++} // namespace Dali;