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