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