8d46f04185ddba83a959c35921a596ee7b3161e0
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / 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) 2017 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 <deque>
22 #include <functional>
23 #include <string>
24 #include <memory>
25 #include <dali/public-api/common/dali-vector.h>
26 #include <dali/public-api/object/ref-object.h>
27 #include <dali/public-api/rendering/texture-set.h>
28 #include <dali/devel-api/common/owner-container.h>
29 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
30
31 // INTERNAL INCLUDES
32 #include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
33 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
34 #include <dali-toolkit/public-api/image-loader/async-image-loader.h>
35 #include <dali-toolkit/internal/visuals/texture-upload-observer.h>
36 #include <dali-toolkit/internal/visuals/visual-url.h>
37 #include <dali-toolkit/internal/helpers/round-robin-container-view.h>
38 #include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
39
40
41 namespace Dali
42 {
43
44 namespace Toolkit
45 {
46
47 namespace Internal
48 {
49 class ImageAtlasManager;
50 typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
51
52 /**
53  * The TextureManager provides a common Image loading API for Visuals.
54  *
55  * The TextureManager is responsible for providing sync, async, atlased and non-atlased loads.
56  * Texture caching is provided and performed when possible.
57  * Broken Images are automatically provided on load failure.
58  */
59 class TextureManager : public ConnectionTracker
60 {
61 public:
62
63   typedef int32_t TextureId;       ///< The TextureId type. This is used as a handle to refer to a particular Texture.
64   static const int INVALID_TEXTURE_ID = -1; ///< Used to represent a null TextureId or error
65
66   /**
67    * Whether the texture should be atlased or uploaded into it's own GPU texture
68    */
69   enum UseAtlas
70   {
71     NO_ATLAS,
72     USE_ATLAS
73   };
74
75   /**
76    * Whether the pixel data should be kept in TextureManager, or uploaded for rendering
77    */
78   enum StorageType
79   {
80     KEEP_PIXEL_BUFFER,
81     UPLOAD_TO_TEXTURE
82   };
83
84   /**
85    * Whether the texture should be loaded synchronously or asynchronously.
86    */
87   enum LoadType
88   {
89     LOAD_ASYNCHRONOUSLY,
90     LOAD_SYNCHRONOUSLY
91   };
92
93   /**
94    * @brief The LoadState Enumeration represents the current state of a particular Texture's life-cycle.
95    */
96   enum LoadState
97   {
98     NOT_STARTED,     ///< Default
99     LOADING,         ///< Loading has been started, but not finished.
100     LOAD_FINISHED,   ///< Loading has finished. (for CPU storage only)
101     WAITING_FOR_MASK,///< Loading has finished, but waiting for mask image
102     UPLOADED,        ///< Uploaded and ready. (For GPU upload only)
103     CANCELLED,       ///< Removed before loading completed
104     LOAD_FAILED      ///< Async loading failed, e.g. connection problem
105   };
106
107   /**
108   * @breif Types of reloading policies
109   */
110   enum class ReloadPolicy
111   {
112     CACHED = 0,             ///< Loads cached texture if it exists.
113     FORCED                  ///< Forces reloading of texture.
114   };
115
116 public:
117
118   struct MaskingData
119   {
120     MaskingData();
121     ~MaskingData() = default;
122
123     VisualUrl mAlphaMaskUrl;
124     TextureManager::TextureId mAlphaMaskId;
125     float mContentScaleFactor;
126     bool mCropToMask;
127   };
128   using MaskingDataPointer = std::unique_ptr<MaskingData>;
129
130   /**
131    * Constructor.
132    */
133   TextureManager();
134
135   /**
136    * Destructor.
137    */
138   ~TextureManager() = default;
139
140
141   // TextureManager Main API:
142
143   TextureSet LoadTexture(const VisualUrl& url, Dali::ImageDimensions desiredSize,
144                          Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode,
145                          const MaskingDataPointer& maskInfo, bool synchronousLoading,
146                          TextureManager::TextureId& textureId, Vector4& textureRect,
147                          bool& atlasingStatus, bool& loadingStatus, Dali::WrapMode::Type wrapModeU,
148                          Dali::WrapMode::Type wrapModeV, TextureUploadObserver* textureObserver,
149                          AtlasUploadObserver* atlasObserver,
150                          ImageAtlasManagerPtr imageAtlasManager,
151                          bool orientationCorrection,
152                          TextureManager::ReloadPolicy reloadPolicy );
153
154   /**
155    * @brief Requests an image load of the given URL.
156    *
157    * The parameters are used to specify how the image is loaded.
158    * The observer has the UploadComplete method called when the load is ready.
159    *
160    * When the client has finished with the Texture, Remove() should be called.
161    *
162    * @param[in] url                   The URL of the image to load
163    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
164    * @param[in] fittingMode           The FittingMode to use
165    * @param[in] samplingMode          The SamplingMode to use
166    * @param[in] useAtlasing           Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
167    *                                  but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
168    * @param[in] observer              The client object should inherit from this and provide the "UploadCompleted" virtual.
169    *                                  This is called when an image load completes (or fails).
170    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
171    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
172    * @return                          A TextureId to use as a handle to reference this Texture
173    */
174   TextureId RequestLoad( const VisualUrl&                   url,
175                          const ImageDimensions              desiredSize,
176                          FittingMode::Type                  fittingMode,
177                          Dali::SamplingMode::Type           samplingMode,
178                          const UseAtlas                     useAtlasing,
179                          TextureUploadObserver*             observer,
180                          bool                               orientationCorrection,
181                          TextureManager::ReloadPolicy       reloadPolicy );
182
183   /**
184    * @brief Requests an image load of the given URL, when the texture has
185    * have loaded, it will perform a blend with the image mask, and upload
186    * the blended texture.
187    *
188    * The parameters are used to specify how the image is loaded.
189    * The observer has the UploadComplete method called when the load is ready.
190    *
191    * When the client has finished with the Texture, Remove() should be called.
192    *
193    * @param[in] url                   The URL of the image to load
194    * @param[in] maskTextureId         The texture id of an image to mask this with
195    *                                  (can be INVALID if no masking required)
196    * @param[in] contentScale          The scale factor to apply to the image before masking
197    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
198    * @param[in] fittingMode           The FittingMode to use
199    * @param[in] samplingMode          The SamplingMode to use
200    * @param[in] useAtlasing           Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
201    *                                  be loaded, and marked successful,
202    *                                  but "useAtlasing" will be set to false in the "UploadCompleted" callback from
203    *                                  the TextureManagerUploadObserver.
204    * @param[in] cropToMask            Only used with masking, this will crop the scaled image to the mask size.
205    *                                  If false, then the mask will be scaled to fit the image before being applied.
206    * @param[in] observer              The client object should inherit from this and provide the "UploadCompleted"
207    *                                  virtual.
208    *                                  This is called when an image load completes (or fails).
209    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
210    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
211    * @return                          A TextureId to use as a handle to reference this Texture
212    */
213   TextureId RequestLoad( const VisualUrl&                   url,
214                          TextureId                          maskTextureId,
215                          float                              contentScale,
216                          const ImageDimensions              desiredSize,
217                          FittingMode::Type                  fittingMode,
218                          Dali::SamplingMode::Type           samplingMode,
219                          const UseAtlas                     useAtlasing,
220                          bool                               cropToMask,
221                          TextureUploadObserver*             observer,
222                          bool                               orientationCorrection,
223                          TextureManager::ReloadPolicy       reloadPolicy );
224
225   /**
226    * Requests a masking image to be loaded. This mask is not uploaded to GL,
227    * instead, it is stored in CPU memory, and can be used for CPU blending.
228    */
229   TextureId RequestMaskLoad( const VisualUrl& maskUrl );
230
231   /**
232    * @brief Remove a Texture from the TextureManager.
233    *
234    * Textures are cached and therefore only the removal of the last
235    * occurrence of a Texture will cause its removal internally.
236    *
237    * @param[in] textureId The ID of the Texture to remove.
238    */
239   void Remove( const TextureManager::TextureId textureId );
240
241   /**
242    * Get the visualUrl associated with the texture id
243    */
244   const VisualUrl& GetVisualUrl( TextureId textureId );
245
246   /**
247    * @brief Get the current state of a texture
248    * @param[in] textureId The texture id to query
249    * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
250    * is not valid.
251    */
252   LoadState GetTextureState( TextureId textureId );
253
254   /**
255    * @brief Get the associated texture set if the texture id is valid
256    * @param[in] textureId The texture Id to look up
257    * @return the associated texture set, or an empty handle if textureId is not valid
258    */
259   TextureSet GetTextureSet( TextureId textureId );
260
261   /**
262    * Adds an external texture to the texture manager
263    * @param[in] texture The texture to add
264    * @return string containing the URL for the texture
265    */
266   std::string AddExternalTexture( TextureSet& texture );
267
268   /**
269    * Removes an external texture from texture manager
270    * @param[in] url The string containing the texture to remove
271    * @return handle to the texture
272    */
273   TextureSet RemoveExternalTexture( const std::string& url );
274
275 private:
276
277   /**
278    * @brief Requests an image load of the given URL, when the texture has
279    * have loaded, if there is a valid maskTextureId, it will perform a
280    * CPU blend with the mask, and upload the blend texture.
281    *
282    * The parameters are used to specify how the image is loaded.
283    * The observer has the UploadComplete method called when the load is ready.
284    *
285    * When the client has finished with the Texture, Remove() should be called.
286    *
287    * @param[in] url                   The URL of the image to load
288    * @param[in] maskTextureId         The texture id of an image to use as a mask. If no mask is required, then set
289    *                                  to INVALID_TEXTURE_ID
290    * @param[in] contentScale          The scaling factor to apply to the content when masking
291    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
292    * @param[in] fittingMode           The FittingMode to use
293    * @param[in] samplingMode          The SamplingMode to use
294    * @param[in] useAtlasing           Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be
295    *                                  loaded, and marked successful, but "useAtlasing" will be set to false in the
296    *                                  "UploadCompleted" callback from the TextureManagerUploadObserver.
297    * @param[in] cropToMask            Whether to crop the target after masking, or scale the mask to the image before
298    *                                  masking.
299    * @param[in] storageType,          Whether the pixel data is stored in the cache or uploaded to the GPU
300    * @param[in] observer              The client object should inherit from this and provide the "UploadCompleted"
301    *                                  virtual.
302    *                                  This is called when an image load completes (or fails).
303    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
304    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
305    * @return                          A TextureId to use as a handle to reference this Texture
306    */
307   TextureId RequestLoadInternal(
308     const VisualUrl&                    url,
309     TextureId                           maskTextureId,
310     float                               contentScale,
311     const ImageDimensions               desiredSize,
312     FittingMode::Type                   fittingMode,
313     Dali::SamplingMode::Type            samplingMode,
314     UseAtlas                            useAtlas,
315     bool                                cropToMask,
316     StorageType                         storageType,
317     TextureUploadObserver*              observer,
318     bool                                orientationCorrection,
319     TextureManager::ReloadPolicy        reloadPolicy );
320
321   /**
322    * @brief Get the current state of a texture
323    * @param[in] textureId The texture id to query
324    * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
325    * is not valid.
326    */
327   LoadState GetTextureStateInternal( TextureId textureId );
328
329   typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
330
331   /**
332    * @brief This struct is used to manage the life-cycle of Texture loading and caching.
333    */
334   struct TextureInfo
335   {
336     TextureInfo( TextureId textureId,
337                  TextureId maskTextureId,
338                  const VisualUrl& url,
339                  ImageDimensions desiredSize,
340                  float scaleFactor,
341                  FittingMode::Type fittingMode,
342                  Dali::SamplingMode::Type samplingMode,
343                  bool loadSynchronously,
344                  bool cropToMask,
345                  UseAtlas useAtlas,
346                  TextureManager::TextureHash hash,
347                  bool orientationCorrection )
348     : url( url ),
349       desiredSize( desiredSize ),
350       useSize( desiredSize ),
351       atlasRect( 0.0f, 0.0f, 1.0f, 1.0f ), // Full atlas rectangle
352       textureId( textureId ),
353       maskTextureId( maskTextureId ),
354       hash( hash ),
355       scaleFactor( scaleFactor ),
356       referenceCount( 1u ),
357       loadState( NOT_STARTED ),
358       fittingMode( fittingMode ),
359       samplingMode( samplingMode ),
360       storageType( UPLOAD_TO_TEXTURE ),
361       loadSynchronously( loadSynchronously ),
362       useAtlas( useAtlas ),
363       cropToMask( cropToMask ),
364       orientationCorrection( true )
365     {
366     }
367
368     /**
369      * Container type used to store all observer clients of this Texture
370      */
371     typedef Dali::Vector< TextureUploadObserver* > ObserverListType;
372
373     ObserverListType observerList; ///< Container used to store all observer clients of this Texture
374     Toolkit::ImageAtlas atlas;     ///< The atlas this Texture lays within (if any)
375     Devel::PixelBuffer pixelBuffer;///< The PixelBuffer holding the image data (May be empty after upload)
376     TextureSet textureSet;         ///< The TextureSet holding the Texture
377     VisualUrl url;                 ///< The URL of the image
378     ImageDimensions desiredSize;   ///< The size requested
379     ImageDimensions useSize;       ///< The size used
380     Vector4 atlasRect;             ///< The atlas rect used if atlased
381     TextureId textureId;           ///< The TextureId associated with this Texture
382     TextureId maskTextureId;       ///< The mask TextureId to be applied on load
383     TextureManager::TextureHash hash; ///< The hash used to cache this Texture
384     float scaleFactor;             ///< The scale factor to apply to the Texture when masking
385     int16_t referenceCount;        ///< The reference count of clients using this Texture
386     LoadState loadState:3;         ///< The load state showing the load progress of the Texture
387     FittingMode::Type fittingMode:2; ///< The requested FittingMode
388     Dali::SamplingMode::Type samplingMode:3; ///< The requested SamplingMode
389     StorageType storageType:1;     ///< CPU storage / GPU upload;
390     bool loadSynchronously:1;      ///< True if synchronous loading was requested
391     UseAtlas useAtlas:1;           ///< USE_ATLAS if an atlas was requested.
392                                    ///< This is updated to false if atlas is not used
393     bool cropToMask:1;             ///< true if the image should be cropped to the mask size.
394     bool orientationCorrection:1;  ///< true if the image should be rotated to match exif orientation data
395   };
396
397   // Structs:
398
399   /**
400    * Struct to hold information about a requested Async load.
401    * This is used to look up a TextureManager::TextureId from the returned AsyncLoad Id.
402    */
403   struct AsyncLoadingInfo
404   {
405     AsyncLoadingInfo( TextureId textureId )
406     : textureId( textureId ),
407       loadId( 0 )
408     {
409     }
410
411     TextureId           textureId;   ///< The external Texture Id assigned to this load
412     uint32_t            loadId;      ///< The load Id used by the async loader to reference this load
413   };
414
415   // Private typedefs:
416
417   typedef std::deque<AsyncLoadingInfo>  AsyncLoadingInfoContainerType;  ///< The container type used to manage Asynchronous loads in progress
418   typedef std::vector<TextureInfo>      TextureInfoContainerType;       ///< The container type used to manage the life-cycle and caching of Textures
419
420   /**
421    * @brief Used internally to initiate a load.
422    * @param[in] textureInfo The TextureInfo struct associated with the Texture
423    * @return                True if the load was initiated
424    */
425   bool LoadTexture( TextureInfo& textureInfo );
426
427   /**
428    * Add the observer to the observer list
429    * @param[in] textureInfo The TextureInfo struct associated with the texture
430    * observer The observer wishing to observe the texture upload
431    */
432   void ObserveTexture( TextureInfo & textureInfo, TextureUploadObserver* observer );
433
434   /**
435    * @brief This signal handler is called when the async local loader finishes loading.
436    * @param[in] id        This is the async image loaders Id
437    * @param[in] pixelBuffer The loaded image data
438    */
439   void AsyncLocalLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer );
440
441   /**
442    * @brief This signal handler is called when the async local loader finishes loading.
443    * @param[in] id        This is the async image loaders Id
444    * @param[in] pixelBuffer The loaded image data
445    */
446   void AsyncRemoteLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer );
447
448   /**
449    * Common method to handle loading completion
450    * @param[in] container The Async loading container
451    * @param[in] id        This is the async image loaders Id
452    * @param[in] pixelBuffer The loaded image data
453    */
454   void AsyncLoadComplete( AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer );
455
456   /**
457    * @brief Performs Post-Load steps including atlasing.
458    * @param[in] textureInfo The struct associated with this Texture
459    * @param[in] pixelBuffer The image pixelBuffer
460    * @return    True if successful
461    */
462   void PostLoad( TextureManager::TextureInfo& textureInfo, Devel::PixelBuffer& pixelBuffer );
463
464   /**
465    * Check if there is a texture waiting to be masked. If there
466    * is then apply this mask and upload it.
467    * @param[in] maskTextureInfo The texture info of the mask that has just loaded.
468    */
469   void CheckForWaitingTexture( TextureInfo& maskTextureInfo );
470
471   /**
472    * Apply the mask to the pixelBuffer.
473    * @param[in] pixelBuffer The pixelBuffer to apply the mask to
474    * @param[in] maskTextureId The texture id of the mask.
475    * @param[in] contentScale The factor to scale the content
476    * @param[in] cropToMask Whether to crop the content to the mask size
477    */
478   void ApplyMask( Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId,
479                   float contentScale, bool cropToMask );
480
481   /**
482    * Upload the texture specified in pixelBuffer to the appropriate location
483    * @param[in] pixelBuffer The image data to upload
484    * @param[in] textureInfo The texture info containing the location to
485    * store the data to.
486    */
487   void UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo );
488
489   /**
490    * Mark the texture as complete, and inform observers
491    * @param[in] textureInfo The struct associated with this Texture
492    */
493   void UploadComplete( TextureInfo& textureInfo );
494
495   /**
496    * Notify the current observers that the texture upload is complete,
497    * then remove the observers from the list.
498    * @param[in] textureInfo The struct associated with this Texture
499    * @param[in] success If the pixel data was retrieved successfully and uploaded to GPU
500    */
501   void NotifyObservers( TextureInfo& textureInfo, bool success );
502
503   /**
504    * @brief Generates a new, unique TextureId
505    * @return A unique TextureId
506    */
507   TextureManager::TextureId GenerateUniqueTextureId();
508
509   /**
510    * @brief Used to lookup an index into the TextureInfoContainer from a TextureId
511    * @param[in] textureId The TextureId to look up
512    * @return              The cache index
513    */
514   int GetCacheIndexFromId( TextureId textureId );
515
516
517   /**
518    * @brief Generates a hash for caching based on the input parameters.
519    * Only applies size, fitting mode andsampling mode if the size is specified.
520    * Only applies maskTextureId if it isn't INVALID_TEXTURE_ID
521    * Always applies useAtlas.
522    * @param[in] url          The URL of the image to load
523    * @param[in] size         The image size
524    * @param[in] fittingMode  The FittingMode to use
525    * @param[in] samplingMode The SamplingMode to use
526    * @param[in] useAtlas     True if atlased
527    * @param[in] maskTextureId The masking texture id (or INVALID_TEXTURE_ID)
528    * @return                 A hash of the provided data for caching.
529    */
530   TextureHash GenerateHash( const std::string& url, const ImageDimensions size,
531                             const FittingMode::Type fittingMode,
532                             const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas,
533                             TextureId maskTextureId );
534   /**
535    * @brief Looks up a cached texture by its hash.
536    * If found, the given parameters are used to check there is no hash-collision.
537    * @param[in] hash          The hash to look up
538    * @param[in] url           The URL of the image to load
539    * @param[in] size          The image size
540    * @param[in] fittingMode   The FittingMode to use
541    * @param[in] samplingMode  The SamplingMode to use
542    * @param[in] useAtlas      True if atlased
543    * @param[in] maskTextureId Optional texture ID to use to mask this image
544    * @return A TextureId of a cached Texture if found. Or INVALID_TEXTURE_ID if not found.
545    */
546   TextureManager::TextureId FindCachedTexture(
547     const TextureManager::TextureHash hash,
548     const std::string& url,
549     const ImageDimensions size,
550     const FittingMode::Type fittingMode,
551     const Dali::SamplingMode::Type samplingMode,
552     const bool useAtlas,
553     TextureId maskTextureId );
554
555 private:
556
557   /**
558    * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container
559    */
560   class AsyncLoadingHelper : public ConnectionTracker
561   {
562   public:
563     /**
564      * @brief Create an AsyncLoadingHelper.
565      * @param[in] textureManager Reference to the texture manager
566      */
567     AsyncLoadingHelper(TextureManager& textureManager);
568
569     /**
570      * @brief Load a new texture.
571      * @param[in] textureId             TextureId to reference the texture that will be loaded
572      * @param[in] url                   The URL of the image to load
573      * @param[in] desiredSize           The size the image is likely to appear at.
574      *                                  This can be set to 0,0 for automatic
575      * @param[in] fittingMode           The FittingMode to use
576      * @param[in] samplingMode          The SamplingMode to use
577      * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
578      *                                  e.g., from portrait to landscape
579      */
580     void Load(TextureId textureId,
581               const VisualUrl& url,
582               ImageDimensions desiredSize,
583               FittingMode::Type fittingMode,
584               SamplingMode::Type samplingMode,
585               bool orientationCorrection);
586
587   public:
588     AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
589     AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete;
590
591     AsyncLoadingHelper(AsyncLoadingHelper&& rhs);
592     AsyncLoadingHelper& operator=(AsyncLoadingHelper&&rhs) = delete;
593
594   private:
595     /**
596      * @brief Main constructor that used by all other constructors
597      */
598     AsyncLoadingHelper(Toolkit::AsyncImageLoader loader,
599                        TextureManager& textureManager,
600                        AsyncLoadingInfoContainerType&& loadingInfoContainer);
601
602     /**
603      * @brief Callback to be called when texture loading is complete, it passes the pixel buffer on to texture manager.
604      * @param[in] id          Loader id
605      * @param[in] pixelBuffer Image data
606      */
607     void AsyncLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
608
609   private:
610     Toolkit::AsyncImageLoader     mLoader;
611     TextureManager&               mTextureManager;
612     AsyncLoadingInfoContainerType mLoadingInfoContainer;
613   };
614
615   struct ExternalTextureInfo
616   {
617     TextureId textureId;
618     TextureSet textureSet;
619   };
620
621 private:
622
623   /**
624    * Deleted copy constructor.
625    */
626   TextureManager( const TextureManager& ) = delete;
627
628   /**
629    * Deleted assignment operator.
630    */
631   TextureManager& operator=( const TextureManager& rhs ) = delete;
632
633   /**
634    * This is called by the TextureManagerUploadObserver when an observer is destroyed.
635    * We use the callback to know when to remove an observer from our notify list.
636    * @param[in] observer The observer that generated the callback
637    */
638   void ObserverDestroyed( TextureUploadObserver* observer );
639
640 private:  // Member Variables:
641
642   TextureInfoContainerType                      mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
643   RoundRobinContainerView< AsyncLoadingHelper > mAsyncLocalLoaders;    ///< The Asynchronous image loaders used to provide all local async loads
644   RoundRobinContainerView< AsyncLoadingHelper > mAsyncRemoteLoaders;   ///< The Asynchronous image loaders used to provide all remote async loads
645   std::vector< ExternalTextureInfo >            mExternalTextures;     ///< Externally provided textures
646   TextureId                                     mCurrentTextureId;     ///< The current value used for the unique Texture Id generation
647
648 };
649
650
651 } // name Internal
652
653 } // namespace Toolkit
654
655 } // namespace Dali
656
657 #endif // DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H