Merge "Support FastTrackUploading for YUV images" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / texture-manager / texture-manager-impl.h
index 5800e54..59aa9b7 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
 // EXTERNAL INCLUDES
 #include <dali/devel-api/adaptor-framework/animated-image-loading.h>
 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/integration-api/processor-interface.h>
 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
+#include <dali/public-api/adaptor-framework/round-robin-container-view.h>
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/rendering/geometry.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
-#include <dali-toolkit/internal/helpers/round-robin-container-view.h>
 #include <dali-toolkit/internal/texture-manager/texture-cache-manager.h>
 #include <dali-toolkit/internal/texture-manager/texture-manager-type.h>
 #include <dali-toolkit/internal/texture-manager/texture-upload-observer.h>
@@ -51,7 +52,7 @@ class TextureAsyncLoadingHelper;
  * Texture caching is provided and performed by TextureCacheManager.
  * TextureUploadObserver.LoadComplete called when async load completed.
  */
-class TextureManager : public ConnectionTracker
+class TextureManager : public ConnectionTracker, public Integration::Processor
 {
 public:
   // Copy enum and types and const values that TextureManager will use.
@@ -80,6 +81,8 @@ public:
     TextureManager::TextureId mAlphaMaskId;
     float                     mContentScaleFactor;
     bool                      mCropToMask;
+    bool                      mPreappliedMasking;
+    bool                      mMaskImageLoadingFailed;
   };
   using MaskingDataPointer = std::unique_ptr<MaskingData>;
 
@@ -96,8 +99,10 @@ public:
 
   /**
    * Constructor.
+   *
+   * @param[in] loadYuvPlanes Whether we allow to load YuvPlanes or not. Default is false.
    */
-  TextureManager();
+  TextureManager(bool loadYuvPlanes = false);
 
   /**
    * Destructor.
@@ -112,28 +117,33 @@ public:
    * The parameters are used to specify how the animated image is loaded.
    * The observer has the LoadComplete method called when the load is ready.
    *
+   * @param[in]  url                   The URL of the image to load
    * @param[in]  animatedImageLoading  The AnimatedImageLoading that contain the animated image information
    * @param[in]  frameIndex            The frame index to load.
    * @param[out] textureId             The textureId of the frame
    * @param[in, out] maskInfo          Mask info structure
+   * @param[in]  desiredSize           The size the image is likely to appear at. This can be set to 0, 0 for automatic
+   * @param[in]  fittingMode           The FittingMode to use
    * @param[in]  samplingMode          The SamplingMode to use
-   * @param[in]  wrapModeU             Horizontal Wrap mode
-   * @param[in]  wrapModeV             Vertical Wrap mode
    * @param[in]  synchronousLoading    true if the frame should be loaded synchronously
    * @param[in]  textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
    *                                   This is called when an image load completes (or fails).
+   * @param[in,out] preMultiplyOnLoad  True if the image color should be multiplied by it's alpha. Set to false if the
+   *                                   image has no alpha channel
    *
    * @return                           The texture set containing the frame of animated image, or empty if still loading.
    */
-  TextureSet LoadAnimatedImageTexture(Dali::AnimatedImageLoading      animatedImageLoading,
+  TextureSet LoadAnimatedImageTexture(const VisualUrl&                url,
+                                      Dali::AnimatedImageLoading      animatedImageLoading,
                                       const uint32_t&                 frameIndex,
                                       TextureManager::TextureId&      textureId,
                                       MaskingDataPointer&             maskInfo,
+                                      const Dali::ImageDimensions&    desiredSize,
+                                      const Dali::FittingMode::Type&  fittingMode,
                                       const Dali::SamplingMode::Type& samplingMode,
-                                      const Dali::WrapMode::Type&     wrapModeU,
-                                      const Dali::WrapMode::Type&     wrapModeV,
                                       const bool&                     synchronousLoading,
-                                      TextureUploadObserver*          textureObserver);
+                                      TextureUploadObserver*          textureObserver,
+                                      TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
 
   /**
    * @brief Requests an image load of the given URL to get PixelBuffer.
@@ -178,7 +188,8 @@ public:
    * @param[in] samplingMode          The SamplingMode to use
    * @param[in, out] maskInfo         Mask info structure
    * @param[in] synchronousLoading    true if the URL should be loaded synchronously
-   * @param[out] textureId,           The textureId of the URL
+   * @param[in, out] textureId        The textureId of the URL. It is also be used to check the previous textureId
+   *                                  what requestor had. It will be used only ReloadPolicy::FORCED for now.
    * @param[out] textureRect          The rectangle within the texture atlas that this URL occupies,
    *                                  this is the rectangle in normalized coordinates.
    * @param[out] textureRectSize      The rectangle within the texture atlas that this URL occupies,
@@ -187,8 +198,6 @@ public:
    *                                  be loaded, and marked successful, but this will be set to false.
    *                                  If atlasing succeeds, this will be set to true.
    * @param[out] loadingStatus        The loading status of the texture
-   * @param[in] wrapModeU             Horizontal Wrap mode
-   * @param[in] wrapModeV             Vertical Wrap mode
    * @param[in] textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
    *                                  This is called when an image load completes (or fails).
    * @param[in] atlasObserver         This is used if the texture is atlased, and will be called instead of
@@ -213,8 +222,6 @@ public:
     Dali::ImageDimensions&              textureRectSize,
     bool&                               atlasingStatus,
     bool&                               loadingStatus,
-    const Dali::WrapMode::Type&         wrapModeU,
-    const Dali::WrapMode::Type&         wrapModeV,
     TextureUploadObserver*              textureObserver,
     AtlasUploadObserver*                atlasObserver,
     ImageAtlasManagerPtr                imageAtlasManager,
@@ -223,17 +230,6 @@ public:
     TextureManager::MultiplyOnLoad&     preMultiplyOnLoad);
 
   /**
-   * @brief Remove a Texture from the TextureManager.
-   *
-   * Textures are cached and therefore only the removal of the last
-   * occurrence of a Texture will cause its removal internally.
-   *
-   * @param[in] textureId The ID of the Texture to remove.
-   * @param[in] textureObserver The texture observer.
-   */
-  void Remove(const TextureManager::TextureId& textureId, TextureUploadObserver* textureObserver);
-
-  /**
    * Add an observer to the object.
    * @param[in] observer The observer to add.
    */
@@ -255,6 +251,20 @@ public:
    */
   Geometry GetRenderGeometry(const TextureManager::TextureId& textureId, std::uint32_t& frontElements, std::uint32_t& backElements);
 
+  /**
+   * @brief Returns the textureSet in texture manager.
+   * @param[in] textureId Id of the texture
+   * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
+   */
+  TextureSet GetTextureSet(const TextureManager::TextureId& textureId);
+
+  /**
+   * @brief Returns the textureSet in texture manager.
+   * @param[in] textureInfo the information of the texture
+   * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
+   */
+  TextureSet GetTextureSet(const TextureManager::TextureInfo& textureInfo);
+
 public:
   // API list that need to access TextureCacheManager.
 
@@ -267,11 +277,11 @@ public:
   }
 
   /**
-   * @copydoc TextureCacheManager::GetTextureSet
+   * @copydoc TextureCacheManager::GetTexture
    */
-  inline TextureSet GetTextureSet(const TextureManager::TextureId& textureId)
+  inline Texture GetTexture(const TextureManager::TextureId& textureId)
   {
-    return mTextureCacheManager.GetTextureSet(textureId);
+    return mTextureCacheManager.GetTexture(textureId);
   }
 
   /**
@@ -309,9 +319,9 @@ public:
   /**
    * @copydoc TextureCacheManager::AddExternalTexture
    */
-  inline std::string AddExternalTexture(const TextureSet& texture)
+  inline std::string AddExternalTexture(const TextureSet& texture, bool preMultiplied = false)
   {
-    return mTextureCacheManager.AddExternalTexture(texture);
+    return mTextureCacheManager.AddExternalTexture(texture, preMultiplied);
   }
 
   /**
@@ -358,6 +368,7 @@ public: // Load Request API
     TextureManager::MultiplyOnLoad&     preMultiplyOnLoad,
     const bool&                         synchronousLoading = false);
 
+private: // Internal Load Request API
   /**
    * @brief Requests an image load of the given URL, when the texture has
    * have loaded, it will perform a blend with the image mask, and upload
@@ -371,6 +382,7 @@ public: // Load Request API
    * @param[in] url                   The URL of the image to load
    * @param[in] maskTextureId         The texture id of an image to mask this with
    *                                  (can be INVALID if no masking required)
+   * @param[in] previousTextureId     The texture id of an image which the requestor already has before
    * @param[in] contentScale          The scale factor to apply to the image before masking
    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
    * @param[in] fittingMode           The FittingMode to use
@@ -395,6 +407,7 @@ public: // Load Request API
   TextureId RequestLoad(
     const VisualUrl&                    url,
     const TextureManager::TextureId&    maskTextureId,
+    const TextureManager::TextureId&    previousTextureId,
     const float&                        contentScale,
     const ImageDimensions&              desiredSize,
     const Dali::FittingMode::Type&      fittingMode,
@@ -411,15 +424,16 @@ public: // Load Request API
    * @brief Requests a masking image to be loaded. This mask is not uploaded to GL,
    * instead, it is stored in CPU memory, and can be used for CPU blending.
    * @param[in] maskUrl            The URL of the mask image to load
+   * @param[in] storageType,       Whether the pixel data is stored in the cache or uploaded to the GPU
    * @param[in] synchronousLoading True if the frame should be loaded synchronously. If you skip this parameter,
    *                               default is false.
    * @return                       A TextureId to use as a handle to reference this mask Texture
    */
   TextureId RequestMaskLoad(
     const VisualUrl& maskUrl,
+    StorageType      storageType,
     const bool&      synchronousLoading = false);
 
-private:
   /**
    * @brief Requests an image load of the given URL, when the texture has
    * have loaded, if there is a valid maskTextureId, it will perform a
@@ -433,6 +447,8 @@ private:
    * @param[in] url                   The URL of the image to load
    * @param[in] maskTextureId         The texture id of an image to use as a mask. If no mask is required, then set
    *                                  to INVALID_TEXTURE_ID
+   * @param[in] previousTextureId     The texture id of an image which the requestor already has before. It will be used
+   *                                  when reloadPolicy is FORCED.
    * @param[in] contentScale          The scaling factor to apply to the content when masking
    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
    * @param[in] fittingMode           The FittingMode to use
@@ -459,6 +475,7 @@ private:
   TextureId RequestLoadInternal(
     const VisualUrl&                    url,
     const TextureManager::TextureId&    maskTextureId,
+    const TextureManager::TextureId&    previousTextureId,
     const float&                        contentScale,
     const Dali::ImageDimensions&        desiredSize,
     const Dali::FittingMode::Type&      fittingMode,
@@ -483,14 +500,46 @@ private:
    * @param[in] samplingMode          The SamplingMode to use
    * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
    *                                  e.g., from portrait to landscape
+   * @param[in] loadYuvPlanes         True if the image should be loaded as yuv planes
+   * @param[out] pixelBuffers         The image pixelBuffer
    * @return PixelBuffer of loaded image.
    */
-  Devel::PixelBuffer LoadImageSynchronously(
-    const VisualUrl&                url,
-    const Dali::ImageDimensions&    desiredSize,
-    const Dali::FittingMode::Type&  fittingMode,
-    const Dali::SamplingMode::Type& samplingMode,
-    const bool&                     orientationCorrection);
+  void LoadImageSynchronously(
+    const VisualUrl&                 url,
+    const Dali::ImageDimensions&     desiredSize,
+    const Dali::FittingMode::Type&   fittingMode,
+    const Dali::SamplingMode::Type&  samplingMode,
+    const bool&                      orientationCorrection,
+    const bool&                      loadYuvPlanes,
+    std::vector<Devel::PixelBuffer>& pixelBuffers);
+
+public: // Remove Request API
+  /**
+   * @brief Request Remove a Texture from the TextureManager.
+   *
+   * Textures are cached and therefore only the removal of the last
+   * occurrence of a Texture will cause its removal internally.
+   *
+   * @param[in] textureId The ID of the Texture to remove.
+   * @param[in] textureObserver The texture observer.
+   */
+  void RequestRemove(const TextureManager::TextureId& textureId, TextureUploadObserver* textureObserver);
+
+private:
+  /**
+   * @brief Remove a Texture from the TextureManager.
+   *
+   * Textures are cached and therefore only the removal of the last
+   * occurrence of a Texture will cause its removal internally.
+   *
+   * @param[in] textureId The ID of the Texture to remove.
+   */
+  void Remove(const TextureManager::TextureId& textureId);
+
+  /**
+   * @brief Initiate remove of texture queued.
+   */
+  void ProcessRemoveQueue();
 
 private:
   // Load and queue
@@ -498,9 +547,9 @@ private:
   /**
    * Structure to hold info about a texture load queued during NotifyObservers
    */
-  struct LoadQueueElement
+  struct QueueElement
   {
-    LoadQueueElement(TextureManager::TextureId textureId, TextureUploadObserver* observer)
+    QueueElement(TextureManager::TextureId textureId, TextureUploadObserver* observer)
     : mTextureId(textureId),
       mObserver(observer)
     {
@@ -518,7 +567,7 @@ private:
   void LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
 
   /**
-   * @brief Queue a texture load to be subsequently handled by ProcessQueuedTextures.
+   * @brief Queue a texture load to be subsequently handled by ProcessLoadQueue.
    * @param[in] textureInfo The TextureInfo struct associated with the Texture
    * @param[in] observer The observer wishing to observe the texture upload
    */
@@ -537,11 +586,6 @@ private:
   void ProcessLoadQueue();
 
   /**
-   * @brief Initiate remove of texture queued whilst NotifyObservers invoking callbacks.
-   */
-  void ProcessRemoveQueue();
-
-  /**
    * Add the observer to the observer list
    * @param[in] textureInfo The TextureInfo struct associated with the texture
    * @param[in] observer The observer wishing to observe the texture upload
@@ -550,11 +594,11 @@ private:
 
   /**
    * @brief Performs Post-Load steps including atlasing.
-   * @param[in] textureInfo The struct associated with this Texture
-   * @param[in] pixelBuffer The image pixelBuffer
+   * @param[in] textureInfo  The struct associated with this Texture
+   * @param[in] pixelBuffers The image pixelBuffer
    * @return    True if successful
    */
-  void PostLoad(TextureManager::TextureInfo& textureInfo, Devel::PixelBuffer& pixelBuffer);
+  void PostLoad(TextureManager::TextureInfo& textureInfo, std::vector<Devel::PixelBuffer>& pixelBuffers);
 
   /**
    * Check if there is a texture waiting to be masked. If there
@@ -572,11 +616,10 @@ private:
 
   /**
    * Upload the texture specified in pixelBuffer to the appropriate location
-   * @param[in] pixelBuffer The image data to upload
-   * @param[in] textureInfo The texture info containing the location to
-   * store the data to.
+   * @param[in] pixelBuffers The image data to upload
+   * @param[in] textureInfo  The texture info containing the location to store the data to.
    */
-  void UploadTexture(Devel::PixelBuffer& pixelBuffer, TextureManager::TextureInfo& textureInfo);
+  void UploadTextures(std::vector<Devel::PixelBuffer>& pixelBuffers, TextureManager::TextureInfo& textureInfo);
 
   /**
    * Notify the current observers that the texture upload is complete,
@@ -594,14 +637,28 @@ private:
    */
   void EmitLoadComplete(TextureUploadObserver* observer, TextureManager::TextureInfo& textureInfo, const bool& success);
 
+  /**
+   * @brief Remove observer in textureInfo
+   *
+   * @param textureInfo The struct associated with this Texture.
+   * @param observer The observer wishing to remove.
+   */
+  void RemoveTextureObserver(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
+
 public:
   /**
    * @brief Common method to handle loading completion.
    * TextureAsyncLoadingHelper will call this API After async loading finished.
-   * @param[in] textureId   The ID of the texture load complete.
-   * @param[in] pixelBuffer The loaded image data
+   * @param[in] textureId    The ID of the texture load complete.
+   * @param[in] pixelBuffers The loaded image data
    */
-  void AsyncLoadComplete(const TextureManager::TextureId& textureId, Devel::PixelBuffer pixelBuffer);
+  void AsyncLoadComplete(const TextureManager::TextureId& textureId, std::vector<Devel::PixelBuffer>& pixelBuffers);
+
+protected: // Implementation of Processor
+  /**
+   * @copydoc Dali::Integration::Processor::Process()
+   */
+  void Process(bool postProcessor) override;
 
 private:
   /**
@@ -624,13 +681,16 @@ private:
 private:                                    // Member Variables:
   TextureCacheManager mTextureCacheManager; ///< Manager the life-cycle and caching of Textures
 
-  RoundRobinContainerView<TextureAsyncLoadingHelper> mAsyncLocalLoaders;  ///< The Asynchronous image loaders used to provide all local async loads
-  RoundRobinContainerView<TextureAsyncLoadingHelper> mAsyncRemoteLoaders; ///< The Asynchronous image loaders used to provide all remote async loads
+  std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader;        ///< The Asynchronous image loader used to provide all local async loads
+  Dali::Vector<LifecycleObserver*>           mLifecycleObservers; ///< Lifecycle observers of texture manager
+
+  Dali::Vector<QueueElement> mLoadQueue;             ///< Queue of textures to load after NotifyObservers
+  TextureManager::TextureId  mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued.
+
+  Dali::Vector<TextureManager::TextureId> mRemoveQueue; ///< Queue of textures to remove at PostProcess. It will be cleared after PostProcess.
 
-  Dali::Vector<LifecycleObserver*>        mLifecycleObservers; ///< Lifecycle observers of texture manager
-  Dali::Vector<LoadQueueElement>          mLoadQueue;          ///< Queue of textures to load after NotifyObservers
-  Dali::Vector<TextureManager::TextureId> mRemoveQueue;        ///< Queue of textures to remove after NotifyObservers
-  bool                                    mQueueLoadFlag;      ///< Flag that causes Load Textures to be queued.
+  const bool mLoadYuvPlanes;             ///< A global flag to specify if the image should be loaded as yuv planes
+  bool       mRemoveProcessorRegistered; ///< Flag if remove processor registered or not.
 };
 
 } // namespace Internal