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