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