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