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