Support WebP format 25/237125/1
authorSeungho, Baek <sbsh.baek@samsung.com>
Fri, 12 Jun 2020 12:43:23 +0000 (21:43 +0900)
committerSeungho, Baek <sbsh.baek@samsung.com>
Thu, 25 Jun 2020 05:14:02 +0000 (14:14 +0900)
 - Modified animated-image-visual to support webp amimated image format
 - Added and removed some functions of image-cache to use rolling-animated-image-cache for the both of gif and webp
 - Checked whether mFrameDelayTimer is null or not for the case that Action::PLAY is entered but the system do not support animated webp

Change-Id: I254c4c8e715772acb6c0725c58e64aba1a6dafc4
Signed-off-by: Seungho, Baek <sbsh.baek@samsung.com>
16 files changed:
automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/animated-image/animated-image-visual.h
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h
dali-toolkit/internal/visuals/animated-image/image-cache.h
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h [new file with mode: 0644]
dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp [deleted file]
dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.h [deleted file]
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-url.cpp
dali-toolkit/internal/visuals/visual-url.h

index bb591ddc28e26dfbcaf04326a68e6af229d7acd1..bad5ea05bd544888bac669b3922ac1cf9efeb95d 100644 (file)
@@ -293,7 +293,7 @@ int UtcDaliAnimatedImageVisualStopBehavior(void)
 }
 
 
-int UtcDaliAnimatedImageVisualGif01(void)
+int UtcDaliAnimatedImageVisualAnimatedImage01(void)
 {
   ToolkitTestApplication application;
   TestGlAbstraction& gl = application.GetGlAbstraction();
index 8f3b2f2fef34971de7b9f4382db5a50ddd1ae3f4..246ba89a89807796790e216bf0ee1882a9b2766a 100644 (file)
@@ -17,7 +17,7 @@ SET( toolkit_src_files
    ${toolkit_src_dir}/visuals/animated-image/image-cache.cpp
    ${toolkit_src_dir}/visuals/animated-image/fixed-image-cache.cpp
    ${toolkit_src_dir}/visuals/animated-image/rolling-image-cache.cpp
-   ${toolkit_src_dir}/visuals/animated-image/rolling-gif-image-cache.cpp
+   ${toolkit_src_dir}/visuals/animated-image/rolling-animated-image-cache.cpp
    ${toolkit_src_dir}/visuals/animated-vector-image/animated-vector-image-visual.cpp
    ${toolkit_src_dir}/visuals/animated-vector-image/vector-animation-task.cpp
    ${toolkit_src_dir}/visuals/animated-vector-image/vector-animation-thread.cpp
index 386013a98c470a3349a14861d2ed5a7d99c4fe75..fdde2601f642c57c1d98af98dd346c50a8df8c14 100755 (executable)
@@ -33,7 +33,7 @@
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
 #include <dali-toolkit/internal/visuals/animated-image/fixed-image-cache.h>
 #include <dali-toolkit/internal/visuals/animated-image/rolling-image-cache.h>
-#include <dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.h>
+#include <dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h>
 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
@@ -111,7 +111,7 @@ Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "
 AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties )
 {
   AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) );
-  visual->InitializeGif( imageUrl );
+  visual->InitializeAnimatedImage( imageUrl );
   visual->SetProperties( properties );
 
   if( visual->mFrameCount > 0 )
@@ -149,7 +149,7 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach
 AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl )
 {
   AnimatedImageVisualPtr visual( new AnimatedImageVisual( factoryCache, shaderFactory ) );
-  visual->InitializeGif( imageUrl );
+  visual->InitializeAnimatedImage( imageUrl );
 
   if( visual->mFrameCount > 0 )
   {
@@ -159,12 +159,11 @@ AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCach
   return visual;
 }
 
-void AnimatedImageVisual::InitializeGif( const VisualUrl& imageUrl )
+void AnimatedImageVisual::InitializeAnimatedImage( const VisualUrl& imageUrl )
 {
   mImageUrl = imageUrl;
-  mGifLoading = GifLoading::New( imageUrl.GetUrl(), imageUrl.IsLocalResource() );
-  mFrameCount = mGifLoading->GetImageCount();
-  mGifLoading->LoadFrameDelays( mFrameDelayContainer );
+  mAnimatedImageLoading = AnimatedImageLoading::New( imageUrl.GetUrl(), imageUrl.IsLocalResource() );
+  mFrameCount = mAnimatedImageLoading.GetImageCount();
 }
 
 AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory )
@@ -174,7 +173,7 @@ AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache, Imag
   mImageVisualShaderFactory( shaderFactory ),
   mPixelArea( FULL_TEXTURE_RECT ),
   mImageUrl(),
-  mGifLoading( nullptr ),
+  mAnimatedImageLoading(),
   mCurrentFrameIndex( 0 ),
   mImageUrls( NULL ),
   mImageCache( NULL ),
@@ -206,7 +205,7 @@ void AnimatedImageVisual::GetNaturalSize( Vector2& naturalSize )
   {
     if( mImageUrl.IsValid() )
     {
-      mImageSize = mGifLoading->GetImageSize();
+      mImageSize = mAnimatedImageLoading.GetImageSize();
     }
     else if( mImageUrls && mImageUrls->size() > 0 )
     {
@@ -270,7 +269,7 @@ void AnimatedImageVisual::OnDoAction( const Dali::Property::Index actionId, cons
     }
     case DevelAnimatedImageVisual::Action::PLAY:
     {
-      if( IsOnStage() && mActionStatus != DevelAnimatedImageVisual::Action::PLAY )
+      if( mFrameDelayTimer && IsOnStage() && mActionStatus != DevelAnimatedImageVisual::Action::PLAY )
       {
         mFrameDelayTimer.Start();
       }
@@ -542,9 +541,9 @@ void AnimatedImageVisual::LoadFirstBatch()
   mUrlIndex = 0;
   TextureManager& textureManager = mFactoryCache.GetTextureManager();
 
-  if( mGifLoading != nullptr )
+  if( mAnimatedImageLoading )
   {
-    mImageCache = new RollingGifImageCache( textureManager, *mGifLoading, mFrameCount, *this, cacheSize, batchSize );
+    mImageCache = new RollingAnimatedImageCache( textureManager, mAnimatedImageLoading, mFrameCount, *this, cacheSize, batchSize );
   }
   else if( mImageUrls )
   {
@@ -592,11 +591,10 @@ void AnimatedImageVisual::StartFirstFrame( TextureSet& textureSet )
   if( mFrameCount > 1 )
   {
     int frameDelay = mFrameDelay; // from URL array
-    if( mFrameDelayContainer.Count() > 0 ) // from GIF
+    if( mAnimatedImageLoading && mImageCache )
     {
-      frameDelay = mFrameDelayContainer[0];
+      frameDelay = mImageCache->GetFrameInterval( 0 );
     }
-
     mFrameDelayTimer = Timer::New( frameDelay );
     mFrameDelayTimer.TickSignal().Connect( this, &AnimatedImageVisual::DisplayNextFrame );
     mFrameDelayTimer.Start();
@@ -706,11 +704,10 @@ bool AnimatedImageVisual::DisplayNextFrame()
         return DisplayNextFrame();
       }
     }
-
-    if( mFrameDelayContainer.Count() > 0 )
+    // TODO : newly added one.
+    if( mAnimatedImageLoading && mImageCache )
     {
-      unsigned int delay = mFrameDelayContainer[mCurrentFrameIndex];
-
+      unsigned int delay = mImageCache->GetFrameInterval( mCurrentFrameIndex );
       if( mFrameDelayTimer.GetInterval() != delay )
       {
         mFrameDelayTimer.SetInterval( delay );
index 0d21f97f22eb42f063447dc22a8b1daee8338fef..7c0764e94ce440fde29d505171ed22bd2e6784f9 100755 (executable)
@@ -24,7 +24,7 @@
 #include <dali/public-api/math/vector4.h>
 #include <dali/public-api/object/weak-handle.h>
 #include <dali/public-api/adaptor-framework/timer.h>
-#include <dali/devel-api/adaptor-framework/gif-loading.h>
+#include <dali/devel-api/adaptor-framework/animated-image-loading.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
@@ -92,7 +92,7 @@ public:
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
    * @param[in] shaderFactory The ImageVisualShaderFactory object
-   * @param[in] imageUrl The URL to gif resource to use
+   * @param[in] imageUrl The URL to animated image resource to use
    * @param[in] properties A Property::Map containing settings for this visual
    * @return A smart-pointer to the newly allocated visual.
    */
@@ -224,10 +224,10 @@ private:
   bool DisplayNextFrame();
 
   /**
-   * Initialize the gif variables.
-   * @param[in] imageUrl The url of the animated gif
+   * Initialize the animated image variables.
+   * @param[in] imageUrl The url of the animated image
    */
-  void InitializeGif( const VisualUrl& imageUrl );
+  void InitializeAnimatedImage( const VisualUrl& imageUrl );
 
   // Undefined
   AnimatedImageVisual( const AnimatedImageVisual& animatedImageVisual );
@@ -241,11 +241,10 @@ private:
   WeakHandle<Actor> mPlacementActor;
   ImageVisualShaderFactory& mImageVisualShaderFactory;
 
-  // Variables for GIF player
-  Dali::Vector<uint32_t> mFrameDelayContainer;
+  // Variables for Animated Image player
   Vector4 mPixelArea;
   VisualUrl mImageUrl;
-  std::unique_ptr<Dali::GifLoading> mGifLoading; // Only needed for animated gifs
+  Dali::AnimatedImageLoading mAnimatedImageLoading; // Only needed for animated image
   uint32_t mCurrentFrameIndex; // Frame index into textureRects
 
   // Variables for Multi-Image player
index d71ee9469debb1487aaad2190373073076955c7a..726cd39fd13810702282217caa3b729e80c60e41 100644 (file)
@@ -58,8 +58,14 @@ TextureSet FixedImageCache::Frame( uint32_t frameIndex )
 {
   while( frameIndex > mFront )
   {
-    NextFrame();
+    ++mFront;
+    if( mFront >= mImageUrls.size() )
+    {
+      mFront = 0;
+    }
+    LoadBatch();
   }
+
   mFront = frameIndex;
 
   TextureSet textureSet;
@@ -87,23 +93,9 @@ TextureSet FixedImageCache::FirstFrame()
   return textureSet;
 }
 
-TextureSet FixedImageCache::NextFrame()
+uint32_t FixedImageCache::GetFrameInterval( uint32_t frameIndex )
 {
-  TextureSet textureSet;
-  ++mFront;
-  mFront %= mImageUrls.size();
-
-  if( IsFrontReady() == true )
-  {
-    textureSet = GetFrontTextureSet();
-  }
-  else
-  {
-    mWaitingForReadyFrame = true;
-  }
-  LoadBatch();
-
-  return textureSet;
+  return 0u;
 }
 
 bool FixedImageCache::IsFrontReady() const
index d884e283fe6bb9968eecaca7962de5d4c343d325..50632321634aa13c185a1a28fcf8a522ce030433 100644 (file)
@@ -61,11 +61,9 @@ public:
   TextureSet FirstFrame() override;
 
   /**
-   * Get the next frame. If it's not ready, this will trigger the
-   * sending of FrameReady() when the image becomes ready.
-   * This will trigger the loading of the next batch.
+   * Get the interval of Nth frame.
    */
-  TextureSet NextFrame() override;
+  uint32_t GetFrameInterval( uint32_t frameIndex ) override;
 
 private:
   /**
index 7354992ce7d7b9db088d01a6c2f59141599ee05a..1d385c8ea00261a26d320e9bb4a542efed1057d1 100644 (file)
@@ -79,17 +79,15 @@ public:
   virtual TextureSet FirstFrame() = 0;
 
   /**
-   * Get the next frame. If it's not ready, this will trigger the
+   * Get the Nth frame. If it's not ready, this will trigger the
    * sending of FrameReady() when the image becomes ready.
-   * This will trigger the loading of the next batch.
    */
-  virtual TextureSet NextFrame() = 0;
+  virtual TextureSet Frame( uint32_t frameIndex ) = 0;
 
   /**
-   * Get the Nth frame. If it's not ready, this will trigger the
-   * sending of FrameReady() when the image becomes ready.
+   * Get the interval of Nth frame.
    */
-  virtual TextureSet Frame( uint32_t frameIndex ) = 0;
+  virtual uint32_t GetFrameInterval( uint32_t frameIndex ) = 0;
 
 private:
 
diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp
new file mode 100644 (file)
index 0000000..c421678
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2020 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 "rolling-animated-image-cache.h"
+
+// EXTERNAL HEADERS
+
+// INTERNAL HEADERS
+#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
+#include <dali-toolkit/internal/visuals/image-atlas-manager.h> // For ImageAtlasManagerPtr
+#include <dali/integration-api/debug.h>
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ANIMATED_IMAGE");
+
+#define LOG_CACHE                                                       \
+  {                                                                     \
+    std::ostringstream oss;                                             \
+    oss<<"Size:"<<mQueue.Count()<<" [ ";                                \
+    for(std::size_t _i=0; _i<mQueue.Count(); ++_i)                      \
+    {                                                                   \
+      oss<<_i<<                                                         \
+        "={ frm#: " << mQueue[_i].mFrameNumber <<                        \
+           " tex: " << mImageUrls[mQueue[_i].mFrameNumber].mTextureId<<"}, ";  \
+    }                                                                   \
+    oss<<" ]"<<std::endl;                                               \
+    DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"%s",oss.str().c_str()); \
+  }
+
+#else
+  #define LOG_CACHE
+#endif
+
+const bool ENABLE_ORIENTATION_CORRECTION( true );
+
+}
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+RollingAnimatedImageCache::RollingAnimatedImageCache(
+  TextureManager& textureManager, AnimatedImageLoading& animatedImageLoading, uint32_t frameCount, ImageCache::FrameReadyObserver& observer,
+  uint16_t cacheSize, uint16_t batchSize )
+: ImageCache( textureManager, observer, batchSize ),
+  mAnimatedImageLoading( animatedImageLoading ),
+  mFrameCount( frameCount ),
+  mFrameIndex( 0 ),
+  mCacheSize( cacheSize ),
+  mQueue( cacheSize )
+{
+  mImageUrls.resize( mFrameCount );
+  LoadBatch();
+}
+
+RollingAnimatedImageCache::~RollingAnimatedImageCache()
+{
+  if( mTextureManagerAlive )
+  {
+    while( IsFrontReady() )
+    {
+      ImageFrame imageFrame = mQueue.PopFront();
+      Dali::Toolkit::TextureManager::RemoveTexture( mImageUrls[ imageFrame.mFrameNumber ].mUrl );
+    }
+  }
+}
+
+TextureSet RollingAnimatedImageCache::Frame( uint32_t frameIndex )
+{
+  bool popExist = false;
+  while( IsFrontReady() && mQueue.Front().mFrameNumber != frameIndex )
+  {
+    ImageFrame imageFrame = mQueue.PopFront();
+    Dali::Toolkit::TextureManager::RemoveTexture( mImageUrls[ imageFrame.mFrameNumber ].mUrl );
+    mImageUrls[ imageFrame.mFrameNumber ].mTextureId = TextureManager::INVALID_TEXTURE_ID;
+    popExist = true;
+  }
+  if( popExist || mImageUrls[ frameIndex ].mTextureId == TextureManager::INVALID_TEXTURE_ID )
+  {
+    // If the frame of frameIndex was already loaded, load batch from the last frame of queue
+    if( IsFrontReady() )
+    {
+      mFrameIndex = ( mQueue.Back().mFrameNumber + 1 ) % mFrameCount;
+    }
+    // If the queue is empty, load batch from the frame of frameIndex
+    else
+    {
+      mFrameIndex = frameIndex;
+    }
+    LoadBatch();
+  }
+
+  return GetFrontTextureSet();
+}
+
+TextureSet RollingAnimatedImageCache::FirstFrame()
+{
+  return Frame( 0u );
+}
+
+uint32_t RollingAnimatedImageCache::GetFrameInterval( uint32_t frameIndex )
+{
+  Frame( frameIndex );
+  return mAnimatedImageLoading.GetFrameInterval( frameIndex );
+}
+
+bool RollingAnimatedImageCache::IsFrontReady() const
+{
+  return ( !mQueue.IsEmpty() );
+}
+
+void RollingAnimatedImageCache::LoadBatch()
+{
+  // Try and load up to mBatchSize images, until the cache is filled.
+  // Once the cache is filled, as frames progress, the old frame is
+  // removed, and another frame is loaded
+
+  std::vector<Dali::PixelData> pixelDataList;
+
+  // Get the smallest number of frames we need to load
+  int batchSize = std::min( std::size_t(mBatchSize), mCacheSize - mQueue.Count() );
+  DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "RollingAnimatedImageCache::LoadBatch() mFrameIndex:%d  batchSize:%d\n", mFrameIndex, batchSize );
+  if( mAnimatedImageLoading.LoadNextNFrames( mFrameIndex, batchSize, pixelDataList) )
+  {
+    unsigned int pixelDataListCount = pixelDataList.size();
+
+    for( unsigned int i = 0; i < pixelDataListCount && !mQueue.IsFull(); ++i )
+    {
+      ImageFrame imageFrame;
+
+      // create the texture for uploading the pixel data
+      Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
+                                      pixelDataList[i].GetPixelFormat(),
+                                      pixelDataList[i].GetWidth(),
+                                      pixelDataList[i].GetHeight() );
+
+      texture.Upload( pixelDataList[i] );
+
+      mImageUrls[ mUrlIndex ].mUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
+      imageFrame.mFrameNumber = mUrlIndex;
+
+      ++mUrlIndex;
+      mUrlIndex %= mImageUrls.size();
+
+      mQueue.PushBack( imageFrame );
+
+      bool synchronousLoading = false;
+      bool atlasingStatus = false;
+      bool loadingStatus = false;
+      TextureManager::MaskingDataPointer maskInfo = nullptr;
+      AtlasUploadObserver* atlasObserver = nullptr;
+      ImageAtlasManagerPtr imageAtlasManager = nullptr;
+      Vector4 textureRect;
+      Dali::ImageDimensions textureRectSize;
+      auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+      mTextureManager.LoadTexture(
+        mImageUrls[ imageFrame.mFrameNumber ].mUrl, ImageDimensions(), FittingMode::SCALE_TO_FILL,
+        SamplingMode::BOX_THEN_LINEAR, maskInfo,
+        synchronousLoading, mImageUrls[ imageFrame.mFrameNumber ].mTextureId, textureRect, textureRectSize,
+        atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
+        Dali::WrapMode::Type::DEFAULT, NULL,
+        atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply );
+    }
+
+    mFrameIndex += batchSize;
+    mFrameIndex %= mFrameCount;
+  }
+
+  LOG_CACHE;
+}
+
+TextureSet RollingAnimatedImageCache::GetFrontTextureSet() const
+{
+  DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "RollingAnimatedImageCache::GetFrontTextureSet() FrameNumber:%d\n", mQueue[ 0 ].mFrameNumber );
+
+  TextureManager::TextureId textureId = GetCachedTextureId( 0 );
+  return mTextureManager.GetTextureSet( textureId );
+}
+
+TextureManager::TextureId RollingAnimatedImageCache::GetCachedTextureId( int index ) const
+{
+  return mImageUrls[ mQueue[ index ].mFrameNumber ].mTextureId;
+}
+
+} //namespace Internal
+} //namespace Toolkit
+} //namespace Dali
diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h b/dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h
new file mode 100644 (file)
index 0000000..503f65e
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef DALI_TOOLKIT_INTERNAL_ROLLING_ANIMATED_IMAGE_CACHE_H
+#define DALI_TOOLKIT_INTERNAL_ROLLING_ANIMATED_IMAGE_CACHE_H
+
+/*
+ * Copyright (c) 2020 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.
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/animated-image-loading.h>
+#include <dali/devel-api/common/circular-queue.h>
+#include <dali-toolkit/internal/visuals/animated-image/image-cache.h>
+#include <dali-toolkit/internal/visuals/texture-manager-impl.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+/**
+ * Class to manage a rolling cache of Animated images, where the cache size
+ * is smaller than the total number of images.
+ *
+ * Frames are always ready, so the observer.FrameReady callback is never triggered;
+ * the FirstFrame and NextFrame APIs will always return a texture.
+ */
+class RollingAnimatedImageCache : public ImageCache
+{
+public:
+  /**
+   * Constructor.
+   * @param[in] textureManager The texture manager
+   * @param[in] animatedImageLoader The loaded animated image
+   * @param[in] frameCount The number of frames in the animated image
+   * @param[in] observer FrameReady observer
+   * @param[in] cacheSize The size of the cache
+   * @param[in] batchSize The size of a batch to load
+   *
+   * This will start loading textures immediately, according to the
+   * batch and cache sizes.
+   */
+  RollingAnimatedImageCache( TextureManager&                 textureManager,
+                        AnimatedImageLoading&           animatedImageLoader,
+                        uint32_t                        frameCount,
+                        ImageCache::FrameReadyObserver& observer,
+                        uint16_t                        cacheSize,
+                        uint16_t                        batchSize );
+
+  /**
+   * Destructor
+   */
+  virtual ~RollingAnimatedImageCache();
+
+  /**
+   * Get the Nth frame. If it's not ready, this will trigger the
+   * sending of FrameReady() when the image becomes ready.
+   */
+  TextureSet Frame( uint32_t frameIndex ) override;
+
+  /**
+   * Get the first frame. If it's not ready, this will trigger the
+   * sending of FrameReady() when the image becomes ready.
+   */
+  TextureSet FirstFrame() override;
+
+  /**
+   * Get the interval of Nth frame.
+   */
+  uint32_t GetFrameInterval( uint32_t frameIndex ) override;
+
+private:
+  /**
+   * @return true if the front frame is ready
+   */
+  bool IsFrontReady() const;
+
+  /**
+   * Load the next batch of images
+   */
+  void LoadBatch();
+
+  /**
+   * Get the texture set of the front frame.
+   * @return the texture set
+   */
+  TextureSet GetFrontTextureSet() const;
+
+  /**
+   * Get the texture id of the given index
+   */
+  TextureManager::TextureId GetCachedTextureId( int index ) const;
+
+private:
+  /**
+   * Secondary class to hold readiness and index into url
+   */
+  struct ImageFrame
+  {
+    unsigned int mFrameNumber = 0u;
+  };
+
+  Dali::AnimatedImageLoading& mAnimatedImageLoading;
+  uint32_t                   mFrameCount;
+  int                        mFrameIndex;
+  std::vector<UrlStore>      mImageUrls;
+  uint16_t                   mCacheSize;
+  CircularQueue<ImageFrame>  mQueue;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif //DALI_TOOLKIT_INTERNAL_ROLLING_ANIMATED_IMAGE_CACHE_H
diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp b/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.cpp
deleted file mode 100644 (file)
index 04f0f1d..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (c) 2020 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 "rolling-gif-image-cache.h"
-
-// EXTERNAL HEADERS
-
-// INTERNAL HEADERS
-#include <dali-toolkit/devel-api/image-loader/texture-manager.h>
-#include <dali-toolkit/internal/visuals/image-atlas-manager.h> // For ImageAtlasManagerPtr
-#include <dali/integration-api/debug.h>
-
-namespace
-{
-#if defined(DEBUG_ENABLED)
-Debug::Filter* gAnimImgLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_ANIMATED_IMAGE");
-
-#define LOG_CACHE                                                       \
-  {                                                                     \
-    std::ostringstream oss;                                             \
-    oss<<"Size:"<<mQueue.Count()<<" [ ";                                \
-    for(std::size_t _i=0; _i<mQueue.Count(); ++_i)                      \
-    {                                                                   \
-      oss<<_i<<                                                         \
-        "={ frm#: " << mQueue[_i].mFrameNumber <<                        \
-           " tex: " << mImageUrls[mQueue[_i].mFrameNumber].mTextureId<<"}, ";  \
-    }                                                                   \
-    oss<<" ]"<<std::endl;                                               \
-    DALI_LOG_INFO(gAnimImgLogFilter,Debug::Concise,"%s",oss.str().c_str()); \
-  }
-
-#else
-  #define LOG_CACHE
-#endif
-
-const bool ENABLE_ORIENTATION_CORRECTION( true );
-
-}
-
-namespace Dali
-{
-namespace Toolkit
-{
-namespace Internal
-{
-
-RollingGifImageCache::RollingGifImageCache(
-  TextureManager& textureManager, GifLoading& gifLoading, uint32_t frameCount, ImageCache::FrameReadyObserver& observer,
-  uint16_t cacheSize, uint16_t batchSize )
-: ImageCache( textureManager, observer, batchSize ),
-  mGifLoading( gifLoading ),
-  mFrameCount( frameCount ),
-  mFrameIndex( 0 ),
-  mCacheSize( cacheSize ),
-  mQueue( cacheSize )
-{
-  mImageUrls.resize( mFrameCount );
-  LoadBatch();
-}
-
-RollingGifImageCache::~RollingGifImageCache()
-{
-  if( mTextureManagerAlive )
-  {
-    while( !mQueue.IsEmpty() )
-    {
-      ImageFrame imageFrame = mQueue.PopFront();
-      Dali::Toolkit::TextureManager::RemoveTexture( mImageUrls[ imageFrame.mFrameNumber ].mUrl );
-    }
-  }
-}
-
-TextureSet RollingGifImageCache::Frame( uint32_t frameIndex )
-{
-  // If a frame of frameIndex is not loaded, clear the queue and remove all loaded textures.
-  if( mImageUrls[ frameIndex ].mTextureId == TextureManager::INVALID_TEXTURE_ID )
-  {
-    mFrameIndex = frameIndex;
-    while( !mQueue.IsEmpty() )
-    {
-      ImageFrame imageFrame = mQueue.PopFront();
-      Dali::Toolkit::TextureManager::RemoveTexture( mImageUrls[ imageFrame.mFrameNumber ].mUrl );
-      mImageUrls[ imageFrame.mFrameNumber ].mTextureId = TextureManager::INVALID_TEXTURE_ID;
-    }
-    LoadBatch();
-  }
-  // If the frame is already loaded, remove previous frames of the frame in the queue
-  // and load new frames amount of removed frames.
-  else
-  {
-    bool popExist = false;
-    while( !mQueue.IsEmpty() && mQueue.Front().mFrameNumber != frameIndex )
-    {
-      ImageFrame imageFrame = mQueue.PopFront();
-      Dali::Toolkit::TextureManager::RemoveTexture( mImageUrls[ imageFrame.mFrameNumber ].mUrl );
-      mImageUrls[ imageFrame.mFrameNumber ].mTextureId = TextureManager::INVALID_TEXTURE_ID;
-      popExist = true;
-    }
-    if( popExist )
-    {
-      mFrameIndex = ( mQueue.Back().mFrameNumber + 1 ) % mFrameCount;
-      LoadBatch();
-    }
-  }
-
-  return GetFrontTextureSet();
-}
-
-TextureSet RollingGifImageCache::FirstFrame()
-{
-  return Frame( 0u );
-}
-
-TextureSet RollingGifImageCache::NextFrame()
-{
-  ImageFrame imageFrame = mQueue.PopFront();
-  Dali::Toolkit::TextureManager::RemoveTexture( mImageUrls[ imageFrame.mFrameNumber ].mUrl );
-  mImageUrls[ imageFrame.mFrameNumber ].mTextureId = TextureManager::INVALID_TEXTURE_ID;
-
-  LoadBatch();
-
-  return GetFrontTextureSet();
-}
-
-bool RollingGifImageCache::IsFrontReady() const
-{
-  return ( !mQueue.IsEmpty() );
-}
-
-void RollingGifImageCache::LoadBatch()
-{
-  // Try and load up to mBatchSize images, until the cache is filled.
-  // Once the cache is filled, as frames progress, the old frame is
-  // removed, and another frame is loaded
-
-  std::vector<Dali::PixelData> pixelDataList;
-
-  // Get the smallest number of frames we need to load
-  int batchSize = std::min( std::size_t(mBatchSize), mCacheSize - mQueue.Count() );
-  DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "RollingGifImageCache::LoadBatch() mFrameIndex:%d  batchSize:%d\n", mFrameIndex, batchSize );
-
-  if( mGifLoading.LoadNextNFrames( mFrameIndex, batchSize, pixelDataList) )
-  {
-    unsigned int pixelDataListCount = pixelDataList.size();
-
-    for( unsigned int i = 0; i < pixelDataListCount && !mQueue.IsFull(); ++i )
-    {
-      ImageFrame imageFrame;
-
-      // create the texture for uploading the pixel data
-      Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D,
-                                      pixelDataList[i].GetPixelFormat(),
-                                      pixelDataList[i].GetWidth(),
-                                      pixelDataList[i].GetHeight() );
-
-      texture.Upload( pixelDataList[i] );
-
-      mImageUrls[ mUrlIndex ].mUrl = Dali::Toolkit::TextureManager::AddTexture(texture);
-      imageFrame.mFrameNumber = mUrlIndex;
-
-      ++mUrlIndex;
-      mUrlIndex %= mImageUrls.size();
-
-      mQueue.PushBack( imageFrame );
-
-      bool synchronousLoading = false;
-      bool atlasingStatus = false;
-      bool loadingStatus = false;
-      TextureManager::MaskingDataPointer maskInfo = nullptr;
-      AtlasUploadObserver* atlasObserver = nullptr;
-      ImageAtlasManagerPtr imageAtlasManager = nullptr;
-      Vector4 textureRect;
-      Dali::ImageDimensions textureRectSize;
-      auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
-
-      mTextureManager.LoadTexture(
-        mImageUrls[ imageFrame.mFrameNumber ].mUrl, ImageDimensions(), FittingMode::SCALE_TO_FILL,
-        SamplingMode::BOX_THEN_LINEAR, maskInfo,
-        synchronousLoading, mImageUrls[ imageFrame.mFrameNumber ].mTextureId, textureRect, textureRectSize,
-        atlasingStatus, loadingStatus, Dali::WrapMode::Type::DEFAULT,
-        Dali::WrapMode::Type::DEFAULT, NULL,
-        atlasObserver, imageAtlasManager, ENABLE_ORIENTATION_CORRECTION, TextureManager::ReloadPolicy::CACHED, preMultiply );
-    }
-
-    mFrameIndex += batchSize;
-    mFrameIndex %= mFrameCount;
-  }
-
-  LOG_CACHE;
-}
-
-TextureSet RollingGifImageCache::GetFrontTextureSet() const
-{
-  DALI_LOG_INFO( gAnimImgLogFilter, Debug::Concise, "RollingGifImageCache::GetFrontTextureSet() FrameNumber:%d\n", mQueue[ 0 ].mFrameNumber );
-
-  TextureManager::TextureId textureId = GetCachedTextureId( 0 );
-  return mTextureManager.GetTextureSet( textureId );
-}
-
-TextureManager::TextureId RollingGifImageCache::GetCachedTextureId( int index ) const
-{
-  return mImageUrls[ mQueue[ index ].mFrameNumber ].mTextureId;
-}
-
-} //namespace Internal
-} //namespace Toolkit
-} //namespace Dali
diff --git a/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.h b/dali-toolkit/internal/visuals/animated-image/rolling-gif-image-cache.h
deleted file mode 100644 (file)
index 91a1210..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-#ifndef DALI_TOOLKIT_INTERNAL_ROLLING_GIF_IMAGE_CACHE_H
-#define DALI_TOOLKIT_INTERNAL_ROLLING_GIF_IMAGE_CACHE_H
-
-/*
- * Copyright (c) 2020 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.
- */
-
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/gif-loading.h>
-#include <dali/devel-api/common/circular-queue.h>
-#include <dali-toolkit/internal/visuals/animated-image/image-cache.h>
-#include <dali-toolkit/internal/visuals/texture-manager-impl.h>
-
-namespace Dali
-{
-namespace Toolkit
-{
-namespace Internal
-{
-
-/**
- * Class to manage a rolling cache of GIF images, where the cache size
- * is smaller than the total number of images.
- *
- * Frames are always ready, so the observer.FrameReady callback is never triggered;
- * the FirstFrame and NextFrame APIs will always return a texture.
- */
-class RollingGifImageCache : public ImageCache
-{
-public:
-  /**
-   * Constructor.
-   * @param[in] textureManager The texture manager
-   * @param[in] gifLoader The loaded gif image
-   * @param[in] frameCount The number of frames in the gif
-   * @param[in] observer FrameReady observer
-   * @param[in] cacheSize The size of the cache
-   * @param[in] batchSize The size of a batch to load
-   *
-   * This will start loading textures immediately, according to the
-   * batch and cache sizes.
-   */
-  RollingGifImageCache( TextureManager&                 textureManager,
-                        GifLoading&                     gifLoader,
-                        uint32_t                        frameCount,
-                        ImageCache::FrameReadyObserver& observer,
-                        uint16_t                        cacheSize,
-                        uint16_t                        batchSize );
-
-  /**
-   * Destructor
-   */
-  virtual ~RollingGifImageCache();
-
-  /**
-   * Get the Nth frame. If it's not ready, this will trigger the
-   * sending of FrameReady() when the image becomes ready.
-   */
-  TextureSet Frame( uint32_t frameIndex ) override;
-
-  /**
-   * Get the first frame. If it's not ready, this will trigger the
-   * sending of FrameReady() when the image becomes ready.
-   */
-  TextureSet FirstFrame() override;
-
-  /**
-   * Get the next frame. If it's not ready, this will trigger the
-   * sending of FrameReady() when the image becomes ready.
-   * This will trigger the loading of the next batch.
-   */
-  TextureSet NextFrame() override;
-
-private:
-  /**
-   * @return true if the front frame is ready
-   */
-  bool IsFrontReady() const;
-
-  /**
-   * Load the next batch of images
-   */
-  void LoadBatch();
-
-  /**
-   * Get the texture set of the front frame.
-   * @return the texture set
-   */
-  TextureSet GetFrontTextureSet() const;
-
-  /**
-   * Get the texture id of the given index
-   */
-  TextureManager::TextureId GetCachedTextureId( int index ) const;
-
-private:
-  /**
-   * Secondary class to hold readiness and index into url
-   */
-  struct ImageFrame
-  {
-    unsigned int mFrameNumber = 0u;
-  };
-
-  GifLoading&               mGifLoading;
-  uint32_t                  mFrameCount;
-  int                       mFrameIndex;
-  std::vector<UrlStore>     mImageUrls;
-  uint16_t                  mCacheSize;
-  CircularQueue<ImageFrame> mQueue;
-};
-
-} // namespace Internal
-} // namespace Toolkit
-} // namespace Dali
-
-#endif
index 21f81b7f50ddabe41979680dfece1fc28794901c..22847786182817da7e95696af100d898a6a33831 100644 (file)
@@ -131,26 +131,9 @@ TextureSet RollingImageCache::FirstFrame()
   return Frame( 0u );
 }
 
-TextureSet RollingImageCache::NextFrame()
+uint32_t RollingImageCache::GetFrameInterval( uint32_t frameIndex )
 {
-  TextureSet textureSet;
-
-  ImageFrame imageFrame = mQueue.PopFront();
-  mTextureManager.Remove( mImageUrls[ imageFrame.mUrlIndex ].mTextureId, this );
-  mImageUrls[ imageFrame.mUrlIndex ].mTextureId = TextureManager::INVALID_TEXTURE_ID;
-
-  LoadBatch();
-
-  if( IsFrontReady() == true )
-  {
-    textureSet = GetFrontTextureSet();
-  }
-  else
-  {
-    mWaitingForReadyFrame = true;
-  }
-
-  return textureSet;
+  return 0u;
 }
 
 bool RollingImageCache::IsFrontReady() const
index 47a5155bbce4dae22309f75373839bc45d621ed1..f57b5c2ec65c94f06bc9a7e4f27bcba2146f796c 100644 (file)
@@ -72,11 +72,9 @@ public:
   TextureSet FirstFrame() override;
 
   /**
-   * Get the next frame. If it's not ready, this will trigger the
-   * sending of FrameReady() when the image becomes ready.
-   * This will trigger the loading of the next batch.
+   * Get the interval of Nth frame.
    */
-  TextureSet NextFrame() override;
+  uint32_t GetFrameInterval( uint32_t frameIndex ) override;
 
 private:
   /**
index dc35220642843148aab619ca8ef78e541be05856..d753ddb822300e8cc884dfb7388d7b4f9ae2b0f2 100644 (file)
@@ -165,6 +165,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
                 break;
               }
               case VisualUrl::GIF:
+              case VisualUrl::WEBP:
               {
                 visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap );
                 break;
@@ -361,6 +362,7 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const std::string& url, Image
         break;
       }
       case VisualUrl::GIF:
+      case VisualUrl::WEBP:
       {
         visualPtr = AnimatedImageVisual::New( GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl );
         break;
index 731ed2024425e26ee54092baca18b6de59991a3a..451ac06fdad8212328f03803588a4175added098 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -99,9 +99,11 @@ VisualUrl::Type ResolveType( const std::string& url )
     enum { SUFFIX, HASH, HASH_DOT } state = SUFFIX;
     char SVG[ 4 ] = { 'g', 'v', 's', '.' };
     char GIF[ 4 ] = { 'f', 'i', 'g', '.' };
+    char WEBP[ 5 ] = { 'p', 'b', 'e', 'w', '.' };
     char JSON[ 5 ] = { 'n', 'o', 's', 'j', '.' };
     unsigned int svgScore = 0;
     unsigned int gifScore = 0;
+    unsigned int webpScore = 0;
     unsigned int jsonScore = 0;
     int index = count;
     while( --index >= 0 )
@@ -124,6 +126,14 @@ VisualUrl::Type ResolveType( const std::string& url )
           return VisualUrl::GIF;
         }
       }
+      if( ( offsetFromEnd < sizeof(WEBP) )&&( currentChar == WEBP[ offsetFromEnd ] ) )
+      {
+        // early out if WEBP as can't be used in N patch for now
+        if( ++webpScore == sizeof(WEBP) )
+        {
+          return VisualUrl::WEBP;
+        }
+      }
       if( ( offsetFromEnd < sizeof(JSON) )&&( currentChar == JSON[ offsetFromEnd ] ) )
       {
         // early out if JSON as can't be used in N patch for now
index f3af2e0b9752a61ba1cf5d74b065ed1a5ea4f7ab..63ad5e47e22af4f0ad406b431f9fc062b5f0c9b7 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_VISUAL_URL_H
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 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.
@@ -41,6 +41,7 @@ public:
     N_PATCH,
     SVG,
     GIF,
+    WEBP,
     JSON
   };