[dali_2.3.20] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / texture-manager / texture-manager-impl.h
1 #ifndef DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
2 #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <dali/devel-api/adaptor-framework/animated-image-loading.h>
22 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
23 #include <dali/integration-api/processor-interface.h>
24 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
25 #include <dali/public-api/adaptor-framework/round-robin-container-view.h>
26 #include <dali/public-api/common/dali-vector.h>
27 #include <dali/public-api/rendering/geometry.h>
28
29 // INTERNAL INCLUDES
30 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
31 #include <dali-toolkit/internal/texture-manager/texture-cache-manager.h>
32 #include <dali-toolkit/internal/texture-manager/texture-manager-type.h>
33 #include <dali-toolkit/internal/texture-manager/texture-upload-observer.h>
34 #include <dali-toolkit/internal/visuals/visual-url.h>
35
36 namespace Dali
37 {
38 namespace Toolkit
39 {
40 namespace Internal
41 {
42 class ImageAtlasManager;
43 typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
44 class TextureAsyncLoadingHelper;
45
46 /**
47  * The TextureManager provides a common Image loading API for Visuals.
48  *
49  * The TextureManager is responsible for providing sync, async,
50  * CPU time alpha masking, animated image loads.
51  *
52  * Texture caching is provided and performed by TextureCacheManager.
53  * TextureUploadObserver.LoadComplete called when async load completed.
54  */
55 class TextureManager : public ConnectionTracker, public Integration::Processor
56 {
57 public:
58   // Copy enum and types and const values that TextureManager will use.
59   using TextureId         = TextureManagerType::TextureId;
60   using TextureCacheIndex = TextureManagerType::TextureCacheIndex;
61   using TextureHash       = TextureManagerType::TextureHash;
62
63   static constexpr TextureId         INVALID_TEXTURE_ID  = TextureManagerType::INVALID_TEXTURE_ID;
64   static constexpr TextureCacheIndex INVALID_CACHE_INDEX = TextureManagerType::INVALID_CACHE_INDEX;
65
66   using StorageType    = TextureManagerType::StorageType;
67   using LoadState      = TextureManagerType::LoadState;
68   using ReloadPolicy   = TextureManagerType::ReloadPolicy;
69   using MultiplyOnLoad = TextureManagerType::MultiplyOnLoad;
70   using TextureInfo    = TextureManagerType::TextureInfo;
71
72 public:
73   struct MaskingData
74   {
75     MaskingData();
76     ~MaskingData() = default;
77
78     VisualUrl                 mAlphaMaskUrl;
79     TextureManager::TextureId mAlphaMaskId;
80     float                     mContentScaleFactor;
81     bool                      mCropToMask;
82     bool                      mPreappliedMasking;
83     bool                      mMaskImageLoadingFailed;
84   };
85   using MaskingDataPointer = std::unique_ptr<MaskingData>;
86
87   /**
88    * Class to provide lifecycle event on destruction of texture manager.
89    */
90   struct LifecycleObserver
91   {
92     /**
93      * Called shortly before the texture manager is destroyed.
94      */
95     virtual void TextureManagerDestroyed() = 0;
96   };
97
98   /**
99    * Constructor.
100    *
101    * @param[in] loadYuvPlanes Whether we allow to load YuvPlanes or not. Default is false.
102    */
103   TextureManager(bool loadYuvPlanes = false);
104
105   /**
106    * Destructor.
107    */
108   ~TextureManager() override;
109
110   // TextureManager Main API:
111
112   /**
113    * @brief Requests an frame of animated image load.
114    *
115    * The parameters are used to specify how the animated image is loaded.
116    * The observer has the LoadComplete method called when the load is ready.
117    *
118    * @param[in]  url                   The URL of the image to load
119    * @param[in]  animatedImageLoading  The AnimatedImageLoading that contain the animated image information
120    * @param[in]  frameIndex            The frame index to load.
121    * @param[out] textureId             The textureId of the frame
122    * @param[in, out] maskInfo          Mask info structure
123    * @param[in]  desiredSize           The size the image is likely to appear at. This can be set to 0, 0 for automatic
124    * @param[in]  fittingMode           The FittingMode to use
125    * @param[in]  samplingMode          The SamplingMode to use
126    * @param[in]  synchronousLoading    true if the frame should be loaded synchronously
127    * @param[in]  textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
128    *                                   This is called when an image load completes (or fails).
129    * @param[in,out] preMultiplyOnLoad  True if the image color should be multiplied by it's alpha. Set to false if the
130    *                                   image has no alpha channel
131    *
132    * @return                           The texture set containing the frame of animated image, or empty if still loading.
133    */
134   TextureSet LoadAnimatedImageTexture(const VisualUrl&                url,
135                                       Dali::AnimatedImageLoading      animatedImageLoading,
136                                       const uint32_t                  frameIndex,
137                                       TextureManager::TextureId&      textureId,
138                                       MaskingDataPointer&             maskInfo,
139                                       const Dali::ImageDimensions&    desiredSize,
140                                       const Dali::FittingMode::Type   fittingMode,
141                                       const Dali::SamplingMode::Type  samplingMode,
142                                       const bool                      synchronousLoading,
143                                       TextureUploadObserver*          textureObserver,
144                                       TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
145
146   /**
147    * @brief Requests an image load of the given URL to get PixelBuffer.
148    *
149    * The parameters are used to specify how the image is loaded.
150    * The observer has the LoadComplete method called when the load is ready.
151    *
152    * @param[in] url                   The URL of the image to load
153    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
154    * @param[in] fittingMode           The FittingMode to use
155    * @param[in] samplingMode          The SamplingMode to use
156    * @param[in] synchronousLoading    true if the URL should be loaded synchronously
157    * @param[in] textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
158    *                                  This is called when an image load completes (or fails).
159    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
160    * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
161    *                                  image has no alpha channel
162    *
163    * @return                          The pixel buffer containing the image, or empty if still loading.
164    */
165   Devel::PixelBuffer LoadPixelBuffer(
166     const VisualUrl&                url,
167     const Dali::ImageDimensions&    desiredSize,
168     const Dali::FittingMode::Type   fittingMode,
169     const Dali::SamplingMode::Type  samplingMode,
170     const bool                      synchronousLoading,
171     TextureUploadObserver*          textureObserver,
172     const bool                      orientationCorrection,
173     TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
174
175   /**
176    * @brief Requests an image load of the given URL.
177    *
178    * The parameters are used to specify how the image is loaded.
179    * The observer has the LoadComplete method called when the load is ready.
180    *
181    * When the client has finished with the Texture, Remove() should be called.
182    *
183    * @param[in] url                   The URL of the image to load
184    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
185    * @param[in] fittingMode           The FittingMode to use
186    * @param[in] samplingMode          The SamplingMode to use
187    * @param[in, out] maskInfo         Mask info structure
188    * @param[in] synchronousLoading    true if the URL should be loaded synchronously
189    * @param[in, out] textureId        The textureId of the URL. It is also be used to check the previous textureId
190    *                                  what requestor had. It will be used only ReloadPolicy::FORCED for now.
191    * @param[out] textureRect          The rectangle within the texture atlas that this URL occupies,
192    *                                  this is the rectangle in normalized coordinates.
193    * @param[out] textureRectSize      The rectangle within the texture atlas that this URL occupies,
194    *                                  this is the same rectangle in pixels.
195    * @param[in,out] atlasingStatus    Set to true to attempt atlasing. If atlasing fails, the image will still
196    *                                  be loaded, and marked successful, but this will be set to false.
197    *                                  If atlasing succeeds, this will be set to true.
198    * @param[out] loadingStatus        The loading status of the texture
199    * @param[in] textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
200    *                                  This is called when an image load completes (or fails).
201    * @param[in] atlasObserver         This is used if the texture is atlased, and will be called instead of
202    *                                  textureObserver.LoadCompleted
203    * @param[in] imageAtlasManager     The atlas manager to use for atlasing textures
204    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
205    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
206    * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
207    *                                  image has no alpha channel
208    *
209    * @return                          The texture set containing the image, or empty if still loading.
210    */
211   TextureSet LoadTexture(
212     const VisualUrl&                   url,
213     const Dali::ImageDimensions&       desiredSize,
214     const Dali::FittingMode::Type      fittingMode,
215     const Dali::SamplingMode::Type     samplingMode,
216     MaskingDataPointer&                maskInfo,
217     const bool                         synchronousLoading,
218     TextureManager::TextureId&         textureId,
219     Dali::Vector4&                     textureRect,
220     Dali::ImageDimensions&             textureRectSize,
221     bool&                              atlasingStatus,
222     bool&                              loadingStatus,
223     TextureUploadObserver*             textureObserver,
224     AtlasUploadObserver*               atlasObserver,
225     ImageAtlasManagerPtr               imageAtlasManager,
226     const bool                         orientationCorrection,
227     const TextureManager::ReloadPolicy reloadPolicy,
228     TextureManager::MultiplyOnLoad&    preMultiplyOnLoad);
229
230   /**
231    * Add an observer to the object.
232    * @param[in] observer The observer to add.
233    */
234   void AddObserver(TextureManager::LifecycleObserver& observer);
235
236   /**
237    * Remove an observer from the object
238    * @pre The observer has already been added.
239    * @param[in] observer The observer to remove.
240    */
241   void RemoveObserver(TextureManager::LifecycleObserver& observer);
242
243   /**
244    * @brief Returns the geometry associated with texture.
245    * @param[in] textureId Id of the texture
246    * @param[out] frontElements number of front elements
247    * @param[out] backElements number of back elements
248    * @return Returns valid geometry object
249    */
250   Geometry GetRenderGeometry(const TextureManager::TextureId textureId, uint32_t& frontElements, uint32_t& backElements);
251
252   /**
253    * @brief Returns the textureSet in texture manager.
254    * @param[in] textureId Id of the texture
255    * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
256    */
257   TextureSet GetTextureSet(const TextureManager::TextureId textureId);
258
259   /**
260    * @brief Returns the textureSet in texture manager.
261    * @param[in] textureInfo the information of the texture
262    * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
263    */
264   TextureSet GetTextureSet(const TextureManager::TextureInfo& textureInfo);
265
266 public:
267   // API list that need to access TextureCacheManager.
268
269   /**
270    * @copydoc TextureCacheManager::GetVisualUrl
271    */
272   inline VisualUrl GetVisualUrl(const TextureManager::TextureId textureId)
273   {
274     return mTextureCacheManager.GetVisualUrl(textureId);
275   }
276
277   /**
278    * @copydoc TextureCacheManager::GetTexture
279    */
280   inline Texture GetTexture(const TextureManager::TextureId textureId)
281   {
282     return mTextureCacheManager.GetTexture(textureId);
283   }
284
285   /**
286    * @copydoc TextureCacheManager::RemoveExternalTexture
287    */
288   inline TextureSet RemoveExternalTexture(const std::string& url)
289   {
290     return mTextureCacheManager.RemoveExternalTexture(url);
291   }
292
293   /**
294    * @copydoc TextureCacheManager::RemoveEncodedImageBuffer
295    */
296   inline EncodedImageBuffer RemoveEncodedImageBuffer(const std::string& url)
297   {
298     return mTextureCacheManager.RemoveEncodedImageBuffer(url);
299   }
300
301   /**
302    * @copydoc TextureCacheManager::UseExternalResource
303    */
304   inline void UseExternalResource(const VisualUrl& url)
305   {
306     mTextureCacheManager.UseExternalResource(url);
307   }
308
309   /**
310    * @copydoc TextureCacheManager::GetEncodedImageBuffer
311    */
312   inline EncodedImageBuffer GetEncodedImageBuffer(const std::string& url)
313   {
314     return mTextureCacheManager.GetEncodedImageBuffer(url);
315   }
316
317   /**
318    * @copydoc TextureCacheManager::AddExternalTexture
319    */
320   inline std::string AddExternalTexture(const TextureSet& texture, const bool preMultiplied = false)
321   {
322     return mTextureCacheManager.AddExternalTexture(texture, preMultiplied);
323   }
324
325   /**
326    * @copydoc TextureCacheManager::AddEncodedImageBuffer
327    */
328   inline std::string AddEncodedImageBuffer(const EncodedImageBuffer& encodedImageBuffer)
329   {
330     return mTextureCacheManager.AddEncodedImageBuffer(encodedImageBuffer);
331   }
332
333 public: // Load Request API
334   /**
335    * @brief Requests an image load of the given URL.
336    *
337    * The parameters are used to specify how the image is loaded.
338    * The observer has the LoadComplete method called when the load is ready.
339    *
340    * When the client has finished with the Texture, Remove() should be called.
341    *
342    * @param[in] url                   The URL of the image to load
343    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
344    * @param[in] fittingMode           The FittingMode to use
345    * @param[in] samplingMode          The SamplingMode to use
346    * @param[in] observer              The client object should inherit from this and provide the "LoadCompleted" virtual.
347    *                                  This is called when an image load completes (or fails).
348    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
349    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
350    * @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
351    * @param[in] synchronousLoading    True if the frame should be loaded synchronously. If you skip this parameter,
352    *                                  default is false.
353    * @return                          A TextureId to use as a handle to reference this Texture
354    */
355   TextureId RequestLoad(
356     const VisualUrl&                   url,
357     const ImageDimensions&             desiredSize,
358     const Dali::FittingMode::Type      fittingMode,
359     const Dali::SamplingMode::Type     samplingMode,
360     TextureUploadObserver*             observer,
361     const bool                         orientationCorrection,
362     const TextureManager::ReloadPolicy reloadPolicy,
363     TextureManager::MultiplyOnLoad&    preMultiplyOnLoad,
364     const bool                         synchronousLoading = false);
365
366 private: // Internal Load Request API
367   /**
368    * @brief Requests an image load of the given URL, when the texture has
369    * have loaded, it will perform a blend with the image mask, and upload
370    * the blended texture.
371    *
372    * The parameters are used to specify how the image is loaded.
373    * The observer has the LoadComplete method called when the load is ready.
374    *
375    * When the client has finished with the Texture, Remove() should be called.
376    *
377    * @param[in] url                   The URL of the image to load
378    * @param[in] maskTextureId         The texture id of an image to mask this with
379    *                                  (can be INVALID if no masking required)
380    * @param[in] previousTextureId     The texture id of an image which the requestor already has before
381    * @param[in] contentScale          The scale factor to apply to the image before masking
382    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
383    * @param[in] fittingMode           The FittingMode to use
384    * @param[in] samplingMode          The SamplingMode to use
385    * @param[in] cropToMask            Only used with masking, this will crop the scaled image to the mask size.
386    *                                  If false, then the mask will be scaled to fit the image before being applied.
387    * @param[in] observer              The client object should inherit from this and provide the "LoadCompleted"
388    *                                  virtual.
389    *                                  This is called when an image load completes (or fails).
390    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
391    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
392    * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
393    *                                  image has no alpha channel
394    * @param[in] synchronousLoading    True if the frame should be loaded synchronously. If you skip this parameter,
395    *                                  default is false.
396    * @return                          A TextureId to use as a handle to reference this Texture
397    */
398   TextureId RequestLoad(
399     const VisualUrl&                   url,
400     const TextureManager::TextureId    maskTextureId,
401     const TextureManager::TextureId    previousTextureId,
402     const float                        contentScale,
403     const ImageDimensions&             desiredSize,
404     const Dali::FittingMode::Type      fittingMode,
405     const Dali::SamplingMode::Type     samplingMode,
406     const bool                         cropToMask,
407     TextureUploadObserver*             observer,
408     const bool                         orientationCorrection,
409     const TextureManager::ReloadPolicy reloadPolicy,
410     TextureManager::MultiplyOnLoad&    preMultiplyOnLoad,
411     const bool                         synchronousLoading = false);
412
413   /**
414    * @brief Requests a masking image to be loaded. This mask is not uploaded to GL,
415    * instead, it is stored in CPU memory, and can be used for CPU blending.
416    * @param[in] maskUrl            The URL of the mask image to load
417    * @param[in] storageType        Whether the pixel data is stored in the cache or uploaded to the GPU
418    * @param[in] synchronousLoading True if the frame should be loaded synchronously. If you skip this parameter,
419    *                               default is false.
420    * @return                       A TextureId to use as a handle to reference this mask Texture
421    */
422   TextureId RequestMaskLoad(
423     const VisualUrl&                  maskUrl,
424     const TextureManager::StorageType storageType,
425     const bool                        synchronousLoading = false);
426
427   /**
428    * @brief Requests an image load of the given URL, when the texture has
429    * have loaded, if there is a valid maskTextureId, it will perform a
430    * CPU blend with the mask, and upload the blend texture.
431    *
432    * The parameters are used to specify how the image is loaded.
433    * The observer has the LoadComplete method called when the load is ready.
434    *
435    * When the client has finished with the Texture, Remove() should be called.
436    *
437    * @param[in] url                   The URL of the image to load
438    * @param[in] maskTextureId         The texture id of an image to use as a mask. If no mask is required, then set
439    *                                  to INVALID_TEXTURE_ID
440    * @param[in] previousTextureId     The texture id of an image which the requestor already has before. It will be used
441    *                                  when reloadPolicy is FORCED.
442    * @param[in] contentScale          The scaling factor to apply to the content when masking
443    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
444    * @param[in] fittingMode           The FittingMode to use
445    * @param[in] samplingMode          The SamplingMode to use
446    * @param[in] cropToMask            Whether to crop the target after masking, or scale the mask to the image before
447    *                                  masking.
448    * @param[in] storageType           Whether the pixel data is stored in the cache or uploaded to the GPU
449    * @param[in] observer              The client object should inherit from this and provide the "LoadCompleted"
450    *                                  virtual.
451    *                                  This is called when an image load completes (or fails).
452    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
453    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
454    * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if
455    *                                  there is no alpha
456    * @param[in] animatedImageLoading  The AnimatedImageLoading to load animated image
457    * @param[in] frameIndex            The frame index of a frame to be loaded frame
458    * @param[in] synchronousLoading    True if the frame should be loaded synchronously. If you skip this parameter,
459    *                                  default is false.
460    * @return                          A TextureId to use as a handle to reference this Texture
461    */
462   TextureId RequestLoadInternal(
463     const VisualUrl&                   url,
464     const TextureManager::TextureId    maskTextureId,
465     const TextureManager::TextureId    previousTextureId,
466     const float                        contentScale,
467     const Dali::ImageDimensions&       desiredSize,
468     const Dali::FittingMode::Type      fittingMode,
469     const Dali::SamplingMode::Type     samplingMode,
470     const bool                         cropToMask,
471     const TextureManager::StorageType  storageType,
472     TextureUploadObserver*             observer,
473     const bool                         orientationCorrection,
474     const TextureManager::ReloadPolicy reloadPolicy,
475     TextureManager::MultiplyOnLoad&    preMultiplyOnLoad,
476     Dali::AnimatedImageLoading         animatedImageLoading,
477     const uint32_t                     frameIndex,
478     const bool                         synchronousLoading);
479
480   /**
481    * @brief Load a new image synchronously.
482    * @param[in] url                   The URL of the image to load
483    * @param[in] desiredSize           The size the image is likely to appear at.
484    *                                  This can be set to 0,0 for automatic
485    * @param[in] fittingMode           The FittingMode to use
486    * @param[in] samplingMode          The SamplingMode to use
487    * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
488    *                                  e.g., from portrait to landscape
489    * @param[in] loadYuvPlanes         True if the image should be loaded as yuv planes
490    * @param[out] pixelBuffers         The image pixelBuffer
491    * @return PixelBuffer of loaded image.
492    */
493   void LoadImageSynchronously(
494     const VisualUrl&                 url,
495     const Dali::ImageDimensions&     desiredSize,
496     const Dali::FittingMode::Type    fittingMode,
497     const Dali::SamplingMode::Type   samplingMode,
498     const bool                       orientationCorrection,
499     const bool                       loadYuvPlanes,
500     std::vector<Devel::PixelBuffer>& pixelBuffers);
501
502 public: // Remove Request API
503   /**
504    * @brief Request Remove a Texture from the TextureManager.
505    *
506    * Textures are cached and therefore only the removal of the last
507    * occurrence of a Texture will cause its removal internally.
508    *
509    * @param[in] textureId The ID of the Texture to remove.
510    * @param[in] textureObserver The texture observer.
511    */
512   void RequestRemove(const TextureManager::TextureId textureId, TextureUploadObserver* textureObserver);
513
514 private:
515   /**
516    * @brief Remove a Texture from the TextureManager.
517    *
518    * Textures are cached and therefore only the removal of the last
519    * occurrence of a Texture will cause its removal internally.
520    *
521    * @param[in] textureId The ID of the Texture to remove.
522    */
523   void Remove(const TextureManager::TextureId textureId);
524
525   /**
526    * @brief Initiate remove of texture queued.
527    */
528   void ProcessRemoveQueue();
529
530 private:
531   // Load and queue
532
533   /**
534    * Structure to hold info about a texture load queued during NotifyObservers
535    */
536   struct QueueElement
537   {
538     QueueElement(const TextureManager::TextureId textureId, TextureUploadObserver* observer)
539     : mTextureId(textureId),
540       mObserver(observer)
541     {
542     }
543
544     TextureManager::TextureId mTextureId; ///< The texture id of the requested load.
545     TextureUploadObserver*    mObserver;  ///< Observer of texture load.
546   };
547
548   /**
549    * @brief Initiate a load or queue load if NotifyObservers is invoking callbacks
550    * @param[in] textureInfo The TextureInfo struct associated with the Texture
551    * @param[in] observer The observer wishing to observe the texture upload
552    */
553   void LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
554
555   /**
556    * @brief Queue a texture load to be subsequently handled by ProcessLoadQueue.
557    * @param[in] textureInfo The TextureInfo struct associated with the Texture
558    * @param[in] observer The observer wishing to observe the texture upload
559    */
560   void QueueLoadTexture(const TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
561
562   /**
563    * @brief Used internally to initiate a load.
564    * @param[in] textureInfo The TextureInfo struct associated with the Texture
565    * @param[in] observer The observer wishing to observe the texture upload
566    */
567   void LoadTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
568
569   /**
570    * @brief Initiate load of textures queued whilst NotifyObservers invoking callbacks.
571    */
572   void ProcessLoadQueue();
573
574   /**
575    * Add the observer to the observer list
576    * @param[in] textureInfo The TextureInfo struct associated with the texture
577    * @param[in] observer The observer wishing to observe the texture upload
578    */
579   void ObserveTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
580
581   /**
582    * @brief Performs Post-Load steps.
583    * @param[in] textureInfo  The struct associated with this Texture
584    * @param[in] pixelBuffers The image pixelBuffer
585    * @return    True if successful
586    */
587   void PostLoad(TextureManager::TextureInfo& textureInfo, std::vector<Devel::PixelBuffer>& pixelBuffers);
588
589   /**
590    * Check if there is a texture waiting to be masked. If there
591    * is then apply this mask and upload it.
592    * @param[in] maskTextureInfo The texture info of the mask that has just loaded.
593    */
594   void CheckForWaitingTexture(TextureManager::TextureInfo& maskTextureInfo);
595
596   /**
597    * Apply the mask to the pixelBuffer.
598    * @param[in] textureInfo The information of texture to apply the mask to
599    * @param[in] maskTextureId The texture id of the mask.
600    */
601   void ApplyMask(TextureManager::TextureInfo& textureInfo, const TextureManager::TextureId maskTextureId);
602
603   /**
604    * Upload the texture specified in pixelBuffer to the appropriate location
605    * @param[in] pixelBuffers The image data to upload
606    * @param[in] textureInfo  The texture info containing the location to store the data to.
607    */
608   void UploadTextures(std::vector<Devel::PixelBuffer>& pixelBuffers, TextureManager::TextureInfo& textureInfo);
609
610   /**
611    * Notify the current observers that the texture upload is complete,
612    * then remove the observers from the list.
613    * @param[in] textureInfo The struct associated with this Texture
614    * @param[in] success If the pixel data was retrieved successfully and uploaded to GPU
615    */
616   void NotifyObservers(TextureManager::TextureInfo& textureInfo, const bool success);
617
618   /**
619    * Call LoadComplete to the observer.
620    * @param[in] observer    The client object should inherit from this and provide the "LoadCompleted"
621    * @param[in] textureInfo The struct associated with this Texture
622    * @param[in] success     If the pixel data was retrieved successfully and uploaded to GPU
623    */
624   void EmitLoadComplete(TextureUploadObserver* observer, TextureManager::TextureInfo& textureInfo, const bool success);
625
626   /**
627    * @brief Remove observer in textureInfo
628    *
629    * @param textureInfo The struct associated with this Texture.
630    * @param observer The observer wishing to remove.
631    */
632   void RemoveTextureObserver(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
633
634 public:
635   /**
636    * @brief Common method to handle loading completion.
637    * TextureAsyncLoadingHelper will call this API After async loading finished.
638    * @param[in] textureId    The ID of the texture load complete.
639    * @param[in] pixelBuffers The loaded image data
640    */
641   void AsyncLoadComplete(const TextureManager::TextureId textureId, std::vector<Devel::PixelBuffer>& pixelBuffers);
642
643 protected: // Implementation of Processor
644   /**
645    * @copydoc Dali::Integration::Processor::Process()
646    */
647   void Process(bool postProcessor) override;
648
649   /**
650    * @copydoc Dali::Integration::Processor::GetProcessorName()
651    */
652   std::string_view GetProcessorName() const override
653   {
654     return "TextureManager";
655   }
656
657 private:
658   /**
659    * Deleted copy constructor.
660    */
661   TextureManager(const TextureManager&) = delete;
662
663   /**
664    * Deleted assignment operator.
665    */
666   TextureManager& operator=(const TextureManager& rhs) = delete;
667
668   /**
669    * This is called by the TextureManagerUploadObserver when an observer is destroyed.
670    * We use the callback to know when to remove an observer from our notify list.
671    * @param[in] observer The observer that generated the callback
672    */
673   void ObserverDestroyed(TextureUploadObserver* observer);
674
675 private:                                    // Member Variables:
676   TextureCacheManager mTextureCacheManager; ///< Manager the life-cycle and caching of Textures
677
678   std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader;        ///< The Asynchronous image loader used to provide all local async loads
679   Dali::Vector<LifecycleObserver*>           mLifecycleObservers; ///< Lifecycle observers of texture manager
680
681   Dali::Vector<QueueElement> mLoadQueue;             ///< Queue of textures to load after NotifyObservers
682   TextureManager::TextureId  mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued.
683
684   Dali::Vector<TextureManager::TextureId> mRemoveQueue; ///< Queue of textures to remove at PostProcess. It will be cleared after PostProcess.
685
686   const bool mLoadYuvPlanes;             ///< A global flag to specify if the image should be loaded as yuv planes
687   bool       mRemoveProcessorRegistered; ///< Flag if remove processor registered or not.
688 };
689
690 } // namespace Internal
691
692 } // namespace Toolkit
693
694 } // namespace Dali
695
696 #endif // DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H