(Webp) Do not load file again if we know size and frame count 55/319655/1
authorEunki, Hong <eunkiki.hong@samsung.com>
Fri, 14 Feb 2025 07:19:53 +0000 (16:19 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Fri, 14 Feb 2025 07:27:28 +0000 (16:27 +0900)
For single webp case, we release the buffer data after load finished.
But user can request the GetImageSize() and GetImageCount().
In this case, we re-load the webp buffer again, and
fail to release the buffers until loader desturcted.

Change-Id: I04817b9e8c589937b36f821e7653b0257c54e067
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
dali/internal/imaging/common/webp-loading.cpp

index 1a550bfd2e0f2b4a3144717b15b2b1e5163ce433..90af1eef629cbaf3dc230b7a5994689756b5bebb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 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.
@@ -94,10 +94,10 @@ public:
   {
   }
 
+  /// Worker thread and Event thread called. Mutex mMutex is locked
   bool LoadWebPInformation()
   {
     // Block to do not load this file again.
-    Mutex::ScopedLock lock(mMutex);
     if(DALI_UNLIKELY(mLoadSucceeded))
     {
       return mLoadSucceeded;
@@ -160,6 +160,7 @@ public:
     return mLoadSucceeded;
   }
 
+  /// Worker thread and Event thread called. Mutex mMutex is locked
   bool ReadWebPInformation()
   {
     mBufferSize = 0;
@@ -221,7 +222,11 @@ public:
           DALI_LOG_ERROR("malloc is failed. request malloc size : %zu\n", sizeof(WebPByteType) * mBufferSize);
           return false;
         }
-        mBufferSize = fread(mBuffer, sizeof(WebPByteType), mBufferSize, fp);
+        if(DALI_UNLIKELY(fread(mBuffer, sizeof(WebPByteType), mBufferSize, fp) != mBufferSize))
+        {
+          DALI_LOG_ERROR("Error read file\n");
+          return false;
+        }
         return true;
       }
       else
@@ -236,6 +241,7 @@ public:
     return false;
   }
 
+  /// Worker thread called, and Event thread called when destruction. Mutex mMutex is locked
   void ReleaseResource()
   {
 #ifdef DALI_WEBP_AVAILABLE
@@ -258,6 +264,7 @@ public:
       mBuffer = nullptr;
     }
 
+    // Make to load this file again.
     mLoadSucceeded = false;
   }
 
@@ -270,6 +277,7 @@ public:
 
   ~Impl()
   {
+    Mutex::ScopedLock lock(mMutex);
     ReleaseResource();
   }
 
@@ -279,11 +287,12 @@ public:
   int32_t               mLatestLoadedFrame{INITIAL_INDEX};
   uint32_t              mFrameCount;
   Mutex                 mMutex;
+
   // For the case the system doesn't support DALI_ANIMATED_WEBP_ENABLED
   unsigned char*  mBuffer;
   uint32_t        mBufferSize;
   ImageDimensions mImageSize;
-  bool            mLoadSucceeded;
+  bool            mLoadSucceeded; ///< Should be changed under mMutex
   bool            mIsAnimatedImage;
   bool            mIsLocalResource;
 
@@ -334,12 +343,15 @@ Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex, ImageDimens
   Dali::Devel::PixelBuffer pixelBuffer;
 
   // If WebP file is still not loaded, Load the information.
-  if(DALI_UNLIKELY(!mImpl->mLoadSucceeded))
   {
-    if(DALI_UNLIKELY(!mImpl->LoadWebPInformation()))
+    Mutex::ScopedLock lock(mImpl->mMutex);
+    if(DALI_UNLIKELY(!mImpl->mLoadSucceeded))
     {
-      mImpl->ReleaseResource();
-      return pixelBuffer;
+      if(DALI_UNLIKELY(!mImpl->LoadWebPInformation()))
+      {
+        mImpl->ReleaseResource();
+        return pixelBuffer;
+      }
     }
   }
 
@@ -424,7 +436,10 @@ Dali::Devel::PixelBuffer WebPLoading::LoadFrame(uint32_t frameIndex, ImageDimens
       }
     }
     // The single frame resource should be released after loading.
-    mImpl->ReleaseResource();
+    {
+      Mutex::ScopedLock lock(mImpl->mMutex);
+      mImpl->ReleaseResource();
+    }
   }
 #endif
 
@@ -492,18 +507,26 @@ Dali::Devel::PixelBuffer WebPLoading::DecodeFrame(uint32_t frameIndex)
 
 ImageDimensions WebPLoading::GetImageSize() const
 {
-  if(DALI_UNLIKELY(!mImpl->mLoadSucceeded))
+  if(mImpl->mImageSize == ImageDimensions())
   {
-    mImpl->LoadWebPInformation();
+    Mutex::ScopedLock lock(mImpl->mMutex);
+    if(DALI_UNLIKELY(!mImpl->mLoadSucceeded))
+    {
+      mImpl->LoadWebPInformation();
+    }
   }
   return mImpl->mImageSize;
 }
 
 uint32_t WebPLoading::GetImageCount() const
 {
-  if(DALI_UNLIKELY(!mImpl->mLoadSucceeded))
+  if(mImpl->mFrameCount == 0u)
   {
-    mImpl->LoadWebPInformation();
+    Mutex::ScopedLock lock(mImpl->mMutex);
+    if(DALI_UNLIKELY(!mImpl->mLoadSucceeded))
+    {
+      mImpl->LoadWebPInformation();
+    }
   }
   return mImpl->mFrameCount;
 }
@@ -522,11 +545,11 @@ uint32_t WebPLoading::GetFrameInterval(uint32_t frameIndex) const
   else
   {
     int32_t interval = 0u;
-    if(GetImageCount() == 1u)
+    if(mImpl->mFrameCount == 1u)
     {
       return 0u;
     }
-    else if(frameIndex + 1 == GetImageCount())
+    else if(frameIndex + 1 == mImpl->mFrameCount)
     {
       // For the interval between last frame and first frame, use last interval again.
       interval = mImpl->mTimeStamp[frameIndex] - mImpl->mTimeStamp[frameIndex - 1];