Merge "Let we allow to change AnimationDefinition property" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / texture-manager / 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) 2023 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 <dali/devel-api/adaptor-framework/animated-image-loading.h>
22 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
23 #include <dali/integration-api/processor-interface.h>
24 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
25 #include <dali/public-api/adaptor-framework/round-robin-container-view.h>
26 #include <dali/public-api/common/dali-vector.h>
27 #include <dali/public-api/rendering/geometry.h>
28
29 // INTERNAL INCLUDES
30 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
31 #include <dali-toolkit/internal/texture-manager/texture-cache-manager.h>
32 #include <dali-toolkit/internal/texture-manager/texture-manager-type.h>
33 #include <dali-toolkit/internal/texture-manager/texture-upload-observer.h>
34 #include <dali-toolkit/internal/visuals/visual-url.h>
35
36 namespace Dali
37 {
38 namespace Toolkit
39 {
40 namespace Internal
41 {
42 class ImageAtlasManager;
43 typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
44 class TextureAsyncLoadingHelper;
45
46 /**
47  * The TextureManager provides a common Image loading API for Visuals.
48  *
49  * The TextureManager is responsible for providing sync, async, atlased and non-atlased
50  * CPU time alpha masking, animated image loads.
51  *
52  * Texture caching is provided and performed by TextureCacheManager.
53  * TextureUploadObserver.LoadComplete called when async load completed.
54  */
55 class TextureManager : public ConnectionTracker, public Integration::Processor
56 {
57 public:
58   // Copy enum and types and const values that TextureManager will use.
59   using TextureId         = TextureManagerType::TextureId;
60   using TextureCacheIndex = TextureManagerType::TextureCacheIndex;
61   using TextureHash       = TextureManagerType::TextureHash;
62
63   static constexpr TextureId         INVALID_TEXTURE_ID  = TextureManagerType::INVALID_TEXTURE_ID;
64   static constexpr TextureCacheIndex INVALID_CACHE_INDEX = TextureManagerType::INVALID_CACHE_INDEX;
65
66   using UseAtlas       = TextureManagerType::UseAtlas;
67   using StorageType    = TextureManagerType::StorageType;
68   using LoadType       = TextureManagerType::LoadType;
69   using LoadState      = TextureManagerType::LoadState;
70   using ReloadPolicy   = TextureManagerType::ReloadPolicy;
71   using MultiplyOnLoad = TextureManagerType::MultiplyOnLoad;
72   using TextureInfo    = TextureManagerType::TextureInfo;
73
74 public:
75   struct MaskingData
76   {
77     MaskingData();
78     ~MaskingData() = default;
79
80     VisualUrl                 mAlphaMaskUrl;
81     TextureManager::TextureId mAlphaMaskId;
82     float                     mContentScaleFactor;
83     bool                      mCropToMask;
84     bool                      mPreappliedMasking;
85     bool                      mMaskImageLoadingFailed;
86   };
87   using MaskingDataPointer = std::unique_ptr<MaskingData>;
88
89   /**
90    * Class to provide lifecycle event on destruction of texture manager.
91    */
92   struct LifecycleObserver
93   {
94     /**
95      * Called shortly before the texture manager is destroyed.
96      */
97     virtual void TextureManagerDestroyed() = 0;
98   };
99
100   /**
101    * Constructor.
102    */
103   TextureManager();
104
105   /**
106    * Destructor.
107    */
108   ~TextureManager() override;
109
110   // TextureManager Main API:
111
112   /**
113    * @brief Requests an frame of animated image load.
114    *
115    * The parameters are used to specify how the animated image is loaded.
116    * The observer has the LoadComplete method called when the load is ready.
117    *
118    * @param[in]  url                   The URL of the image to load
119    * @param[in]  animatedImageLoading  The AnimatedImageLoading that contain the animated image information
120    * @param[in]  frameIndex            The frame index to load.
121    * @param[out] textureId             The textureId of the frame
122    * @param[in, out] maskInfo          Mask info structure
123    * @param[in]  desiredSize           The size the image is likely to appear at. This can be set to 0, 0 for automatic
124    * @param[in]  fittingMode           The FittingMode to use
125    * @param[in]  samplingMode          The SamplingMode to use
126    * @param[in]  synchronousLoading    true if the frame should be loaded synchronously
127    * @param[in]  textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
128    *                                   This is called when an image load completes (or fails).
129    * @param[in,out] preMultiplyOnLoad  True if the image color should be multiplied by it's alpha. Set to false if the
130    *                                   image has no alpha channel
131    *
132    * @return                           The texture set containing the frame of animated image, or empty if still loading.
133    */
134   TextureSet LoadAnimatedImageTexture(const VisualUrl&                url,
135                                       Dali::AnimatedImageLoading      animatedImageLoading,
136                                       const uint32_t&                 frameIndex,
137                                       TextureManager::TextureId&      textureId,
138                                       MaskingDataPointer&             maskInfo,
139                                       const Dali::ImageDimensions&    desiredSize,
140                                       const Dali::FittingMode::Type&  fittingMode,
141                                       const Dali::SamplingMode::Type& samplingMode,
142                                       const bool&                     synchronousLoading,
143                                       TextureUploadObserver*          textureObserver,
144                                       TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
145
146   /**
147    * @brief Requests an image load of the given URL to get PixelBuffer.
148    *
149    * The parameters are used to specify how the image is loaded.
150    * The observer has the LoadComplete method called when the load is ready.
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] synchronousLoading    true if the URL should be loaded synchronously
157    * @param[in] textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
158    *                                  This is called when an image load completes (or fails).
159    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
160    * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
161    *                                  image has no alpha channel
162    *
163    * @return                          The pixel buffer containing the image, or empty if still loading.
164    */
165   Devel::PixelBuffer LoadPixelBuffer(
166     const VisualUrl&                url,
167     const Dali::ImageDimensions&    desiredSize,
168     const Dali::FittingMode::Type&  fittingMode,
169     const Dali::SamplingMode::Type& samplingMode,
170     const bool&                     synchronousLoading,
171     TextureUploadObserver*          textureObserver,
172     const bool&                     orientationCorrection,
173     TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
174
175   /**
176    * @brief Requests an image load of the given URL.
177    *
178    * The parameters are used to specify how the image is loaded.
179    * The observer has the LoadComplete method called when the load is ready.
180    *
181    * When the client has finished with the Texture, Remove() should be called.
182    *
183    * @param[in] url                   The URL of the image to load
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, out] maskInfo         Mask info structure
188    * @param[in] synchronousLoading    true if the URL should be loaded synchronously
189    * @param[out] textureId,           The textureId of the URL
190    * @param[out] textureRect          The rectangle within the texture atlas that this URL occupies,
191    *                                  this is the rectangle in normalized coordinates.
192    * @param[out] textureRectSize      The rectangle within the texture atlas that this URL occupies,
193    *                                  this is the same rectangle in pixels.
194    * @param[in,out] atlasingStatus    Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
195    *                                  be loaded, and marked successful, but this will be set to false.
196    *                                  If atlasing succeeds, this will be set to true.
197    * @param[out] loadingStatus        The loading status of the texture
198    * @param[in] textureObserver       The client object should inherit from this and provide the "LoadCompleted" virtual.
199    *                                  This is called when an image load completes (or fails).
200    * @param[in] atlasObserver         This is used if the texture is atlased, and will be called instead of
201    *                                  textureObserver.LoadCompleted
202    * @param[in] imageAtlasManager     The atlas manager to use for atlasing textures
203    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
204    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
205    * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
206    *                                  image has no alpha channel
207    *
208    * @return                          The texture set containing the image, or empty if still loading.
209    */
210   TextureSet LoadTexture(
211     const VisualUrl&                    url,
212     const Dali::ImageDimensions&        desiredSize,
213     const Dali::FittingMode::Type&      fittingMode,
214     const Dali::SamplingMode::Type&     samplingMode,
215     MaskingDataPointer&                 maskInfo,
216     const bool&                         synchronousLoading,
217     TextureManager::TextureId&          textureId,
218     Dali::Vector4&                      textureRect,
219     Dali::ImageDimensions&              textureRectSize,
220     bool&                               atlasingStatus,
221     bool&                               loadingStatus,
222     TextureUploadObserver*              textureObserver,
223     AtlasUploadObserver*                atlasObserver,
224     ImageAtlasManagerPtr                imageAtlasManager,
225     const bool&                         orientationCorrection,
226     const TextureManager::ReloadPolicy& reloadPolicy,
227     TextureManager::MultiplyOnLoad&     preMultiplyOnLoad);
228
229   /**
230    * Add an observer to the object.
231    * @param[in] observer The observer to add.
232    */
233   void AddObserver(TextureManager::LifecycleObserver& observer);
234
235   /**
236    * Remove an observer from the object
237    * @pre The observer has already been added.
238    * @param[in] observer The observer to remove.
239    */
240   void RemoveObserver(TextureManager::LifecycleObserver& observer);
241
242   /**
243    * @brief Returns the geometry associated with texture.
244    * @param[in] textureId Id of the texture
245    * @param[out] frontElements number of front elements
246    * @param[out] backElements number of back elements
247    * @return Returns valid geometry object
248    */
249   Geometry GetRenderGeometry(const TextureManager::TextureId& textureId, std::uint32_t& frontElements, std::uint32_t& backElements);
250
251   /**
252    * @brief Returns the textureSet in texture manager.
253    * @param[in] textureId Id of the texture
254    * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
255    */
256   TextureSet GetTextureSet(const TextureManager::TextureId& textureId);
257
258   /**
259    * @brief Returns the textureSet in texture manager.
260    * @param[in] textureInfo the information of the texture
261    * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
262    */
263   TextureSet GetTextureSet(const TextureManager::TextureInfo& textureInfo);
264
265 public:
266   // API list that need to access TextureCacheManager.
267
268   /**
269    * @copydoc TextureCacheManager::GetVisualUrl
270    */
271   inline VisualUrl GetVisualUrl(const TextureManager::TextureId& textureId)
272   {
273     return mTextureCacheManager.GetVisualUrl(textureId);
274   }
275
276   /**
277    * @copydoc TextureCacheManager::GetTexture
278    */
279   inline Texture GetTexture(const TextureManager::TextureId& textureId)
280   {
281     return mTextureCacheManager.GetTexture(textureId);
282   }
283
284   /**
285    * @copydoc TextureCacheManager::RemoveExternalTexture
286    */
287   inline TextureSet RemoveExternalTexture(const std::string& url)
288   {
289     return mTextureCacheManager.RemoveExternalTexture(url);
290   }
291
292   /**
293    * @copydoc TextureCacheManager::RemoveEncodedImageBuffer
294    */
295   inline EncodedImageBuffer RemoveEncodedImageBuffer(const std::string& url)
296   {
297     return mTextureCacheManager.RemoveEncodedImageBuffer(url);
298   }
299
300   /**
301    * @copydoc TextureCacheManager::UseExternalResource
302    */
303   inline void UseExternalResource(const VisualUrl& url)
304   {
305     mTextureCacheManager.UseExternalResource(url);
306   }
307
308   /**
309    * @copydoc TextureCacheManager::GetEncodedImageBuffer
310    */
311   inline EncodedImageBuffer GetEncodedImageBuffer(const std::string& url)
312   {
313     return mTextureCacheManager.GetEncodedImageBuffer(url);
314   }
315
316   /**
317    * @copydoc TextureCacheManager::AddExternalTexture
318    */
319   inline std::string AddExternalTexture(const TextureSet& texture, bool preMultiplied = false)
320   {
321     return mTextureCacheManager.AddExternalTexture(texture, preMultiplied);
322   }
323
324   /**
325    * @copydoc TextureCacheManager::AddEncodedImageBuffer
326    */
327   inline std::string AddEncodedImageBuffer(const EncodedImageBuffer& encodedImageBuffer)
328   {
329     return mTextureCacheManager.AddEncodedImageBuffer(encodedImageBuffer);
330   }
331
332 public: // Load Request API
333   /**
334    * @brief Requests an image load of the given URL.
335    *
336    * The parameters are used to specify how the image is loaded.
337    * The observer has the LoadComplete method called when the load is ready.
338    *
339    * When the client has finished with the Texture, Remove() should be called.
340    *
341    * @param[in] url                   The URL of the image to load
342    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
343    * @param[in] fittingMode           The FittingMode to use
344    * @param[in] samplingMode          The SamplingMode to use
345    * @param[in] useAtlasing           Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
346    *                                  but "useAtlasing" will be set to false in the "LoadCompleted" callback from the TextureManagerUploadObserver.
347    * @param[in] observer              The client object should inherit from this and provide the "LoadCompleted" virtual.
348    *                                  This is called when an image load completes (or fails).
349    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
350    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
351    * @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
352    * @param[in] synchronousLoading    True if the frame should be loaded synchronously. If you skip this parameter,
353    *                                  default is false.
354    * @return                          A TextureId to use as a handle to reference this Texture
355    */
356   TextureId RequestLoad(
357     const VisualUrl&                    url,
358     const ImageDimensions&              desiredSize,
359     const Dali::FittingMode::Type&      fittingMode,
360     const Dali::SamplingMode::Type&     samplingMode,
361     const TextureManager::UseAtlas&     useAtlasing,
362     TextureUploadObserver*              observer,
363     const bool&                         orientationCorrection,
364     const TextureManager::ReloadPolicy& reloadPolicy,
365     TextureManager::MultiplyOnLoad&     preMultiplyOnLoad,
366     const bool&                         synchronousLoading = false);
367
368   /**
369    * @brief Requests an image load of the given URL, when the texture has
370    * have loaded, it will perform a blend with the image mask, and upload
371    * the blended texture.
372    *
373    * The parameters are used to specify how the image is loaded.
374    * The observer has the LoadComplete method called when the load is ready.
375    *
376    * When the client has finished with the Texture, Remove() should be called.
377    *
378    * @param[in] url                   The URL of the image to load
379    * @param[in] maskTextureId         The texture id of an image to mask this with
380    *                                  (can be INVALID if no masking required)
381    * @param[in] contentScale          The scale factor to apply to the image before masking
382    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
383    * @param[in] fittingMode           The FittingMode to use
384    * @param[in] samplingMode          The SamplingMode to use
385    * @param[in] useAtlasing           Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
386    *                                  be loaded, and marked successful,
387    *                                  but "useAtlasing" will be set to false in the "LoadCompleted" callback from
388    *                                  the TextureManagerUploadObserver.
389    * @param[in] cropToMask            Only used with masking, this will crop the scaled image to the mask size.
390    *                                  If false, then the mask will be scaled to fit the image before being applied.
391    * @param[in] observer              The client object should inherit from this and provide the "LoadCompleted"
392    *                                  virtual.
393    *                                  This is called when an image load completes (or fails).
394    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
395    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
396    * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
397    *                                  image has no alpha channel
398    * @param[in] synchronousLoading    True if the frame should be loaded synchronously. If you skip this parameter,
399    *                                  default is false.
400    * @return                          A TextureId to use as a handle to reference this Texture
401    */
402   TextureId RequestLoad(
403     const VisualUrl&                    url,
404     const TextureManager::TextureId&    maskTextureId,
405     const float&                        contentScale,
406     const ImageDimensions&              desiredSize,
407     const Dali::FittingMode::Type&      fittingMode,
408     const Dali::SamplingMode::Type&     samplingMode,
409     const TextureManager::UseAtlas&     useAtlasing,
410     const bool&                         cropToMask,
411     TextureUploadObserver*              observer,
412     const bool&                         orientationCorrection,
413     const TextureManager::ReloadPolicy& reloadPolicy,
414     TextureManager::MultiplyOnLoad&     preMultiplyOnLoad,
415     const bool&                         synchronousLoading = false);
416
417   /**
418    * @brief Requests a masking image to be loaded. This mask is not uploaded to GL,
419    * instead, it is stored in CPU memory, and can be used for CPU blending.
420    * @param[in] maskUrl            The URL of the mask image to load
421    * @param[in] storageType,       Whether the pixel data is stored in the cache or uploaded to the GPU
422    * @param[in] synchronousLoading True if the frame should be loaded synchronously. If you skip this parameter,
423    *                               default is false.
424    * @return                       A TextureId to use as a handle to reference this mask Texture
425    */
426   TextureId RequestMaskLoad(
427     const VisualUrl& maskUrl,
428     StorageType      storageType,
429     const bool&      synchronousLoading = false);
430
431 private:
432   /**
433    * @brief Requests an image load of the given URL, when the texture has
434    * have loaded, if there is a valid maskTextureId, it will perform a
435    * CPU blend with the mask, and upload the blend texture.
436    *
437    * The parameters are used to specify how the image is loaded.
438    * The observer has the LoadComplete method called when the load is ready.
439    *
440    * When the client has finished with the Texture, Remove() should be called.
441    *
442    * @param[in] url                   The URL of the image to load
443    * @param[in] maskTextureId         The texture id of an image to use as a mask. If no mask is required, then set
444    *                                  to INVALID_TEXTURE_ID
445    * @param[in] contentScale          The scaling factor to apply to the content when masking
446    * @param[in] desiredSize           The size the image is likely to appear at. This can be set to 0,0 for automatic
447    * @param[in] fittingMode           The FittingMode to use
448    * @param[in] samplingMode          The SamplingMode to use
449    * @param[in] useAtlasing           Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be
450    *                                  loaded, and marked successful, but "useAtlasing" will be set to false in the
451    *                                  "LoadCompleted" callback from the TextureManagerUploadObserver.
452    * @param[in] cropToMask            Whether to crop the target after masking, or scale the mask to the image before
453    *                                  masking.
454    * @param[in] storageType,          Whether the pixel data is stored in the cache or uploaded to the GPU
455    * @param[in] observer              The client object should inherit from this and provide the "LoadCompleted"
456    *                                  virtual.
457    *                                  This is called when an image load completes (or fails).
458    * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
459    * @param[in] reloadPolicy          Forces a reload of the texture even if already cached
460    * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if
461    *                                  there is no alpha
462    * @param[in] animatedImageLoading  The AnimatedImageLoading to load animated image
463    * @param[in] frameIndex            The frame index of a frame to be loaded frame
464    * @param[in] synchronousLoading    True if the frame should be loaded synchronously. If you skip this parameter,
465    *                                  default is false.
466    * @return                          A TextureId to use as a handle to reference this Texture
467    */
468   TextureId RequestLoadInternal(
469     const VisualUrl&                    url,
470     const TextureManager::TextureId&    maskTextureId,
471     const float&                        contentScale,
472     const Dali::ImageDimensions&        desiredSize,
473     const Dali::FittingMode::Type&      fittingMode,
474     const Dali::SamplingMode::Type&     samplingMode,
475     const TextureManager::UseAtlas&     useAtlas,
476     const bool&                         cropToMask,
477     const TextureManager::StorageType&  storageType,
478     TextureUploadObserver*              observer,
479     const bool&                         orientationCorrection,
480     const TextureManager::ReloadPolicy& reloadPolicy,
481     TextureManager::MultiplyOnLoad&     preMultiplyOnLoad,
482     Dali::AnimatedImageLoading          animatedImageLoading,
483     const std::uint32_t&                frameIndex,
484     const bool&                         synchronousLoading);
485
486   /**
487    * @brief Load a new image synchronously.
488    * @param[in] url                   The URL of the image to load
489    * @param[in] desiredSize           The size the image is likely to appear at.
490    *                                  This can be set to 0,0 for automatic
491    * @param[in] fittingMode           The FittingMode to use
492    * @param[in] samplingMode          The SamplingMode to use
493    * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
494    *                                  e.g., from portrait to landscape
495    * @param[in] loadYuvPlanes         True if the image should be loaded as yuv planes
496    * @param[out] pixelBuffers         The image pixelBuffer
497    * @return PixelBuffer of loaded image.
498    */
499   void LoadImageSynchronously(
500     const VisualUrl&                 url,
501     const Dali::ImageDimensions&     desiredSize,
502     const Dali::FittingMode::Type&   fittingMode,
503     const Dali::SamplingMode::Type&  samplingMode,
504     const bool&                      orientationCorrection,
505     const bool&                      loadYuvPlanes,
506     std::vector<Devel::PixelBuffer>& pixelBuffers);
507
508 public: // Remove Request API
509   /**
510    * @brief Request Remove a Texture from the TextureManager.
511    *
512    * Textures are cached and therefore only the removal of the last
513    * occurrence of a Texture will cause its removal internally.
514    *
515    * @param[in] textureId The ID of the Texture to remove.
516    * @param[in] textureObserver The texture observer.
517    */
518   void RequestRemove(const TextureManager::TextureId& textureId, TextureUploadObserver* textureObserver);
519
520 private:
521   /**
522    * @brief Remove a Texture from the TextureManager.
523    *
524    * Textures are cached and therefore only the removal of the last
525    * occurrence of a Texture will cause its removal internally.
526    *
527    * @param[in] textureId The ID of the Texture to remove.
528    */
529   void Remove(const TextureManager::TextureId& textureId);
530
531   /**
532    * @brief Initiate remove of texture queued.
533    */
534   void ProcessRemoveQueue();
535
536 private:
537   // Load and queue
538
539   /**
540    * Structure to hold info about a texture load queued during NotifyObservers
541    */
542   struct QueueElement
543   {
544     QueueElement(TextureManager::TextureId textureId, TextureUploadObserver* observer)
545     : mTextureId(textureId),
546       mObserver(observer)
547     {
548     }
549
550     TextureManager::TextureId mTextureId; ///< The texture id of the requested load.
551     TextureUploadObserver*    mObserver;  ///< Observer of texture load.
552   };
553
554   /**
555    * @brief Initiate a load or queue load if NotifyObservers is invoking callbacks
556    * @param[in] textureInfo The TextureInfo struct associated with the Texture
557    * @param[in] observer The observer wishing to observe the texture upload
558    */
559   void LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
560
561   /**
562    * @brief Queue a texture load to be subsequently handled by ProcessLoadQueue.
563    * @param[in] textureInfo The TextureInfo struct associated with the Texture
564    * @param[in] observer The observer wishing to observe the texture upload
565    */
566   void QueueLoadTexture(const TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
567
568   /**
569    * @brief Used internally to initiate a load.
570    * @param[in] textureInfo The TextureInfo struct associated with the Texture
571    * @param[in] observer The observer wishing to observe the texture upload
572    */
573   void LoadTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
574
575   /**
576    * @brief Initiate load of textures queued whilst NotifyObservers invoking callbacks.
577    */
578   void ProcessLoadQueue();
579
580   /**
581    * Add the observer to the observer list
582    * @param[in] textureInfo The TextureInfo struct associated with the texture
583    * @param[in] observer The observer wishing to observe the texture upload
584    */
585   void ObserveTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
586
587   /**
588    * @brief Performs Post-Load steps including atlasing.
589    * @param[in] textureInfo  The struct associated with this Texture
590    * @param[in] pixelBuffers The image pixelBuffer
591    * @return    True if successful
592    */
593   void PostLoad(TextureManager::TextureInfo& textureInfo, std::vector<Devel::PixelBuffer>& pixelBuffers);
594
595   /**
596    * Check if there is a texture waiting to be masked. If there
597    * is then apply this mask and upload it.
598    * @param[in] maskTextureInfo The texture info of the mask that has just loaded.
599    */
600   void CheckForWaitingTexture(TextureManager::TextureInfo& maskTextureInfo);
601
602   /**
603    * Apply the mask to the pixelBuffer.
604    * @param[in] textureInfo The information of texture to apply the mask to
605    * @param[in] maskTextureId The texture id of the mask.
606    */
607   void ApplyMask(TextureManager::TextureInfo& textureInfo, const TextureManager::TextureId& maskTextureId);
608
609   /**
610    * Upload the texture specified in pixelBuffer to the appropriate location
611    * @param[in] pixelBuffers The image data to upload
612    * @param[in] textureInfo  The texture info containing the location to store the data to.
613    */
614   void UploadTextures(std::vector<Devel::PixelBuffer>& pixelBuffers, TextureManager::TextureInfo& textureInfo);
615
616   /**
617    * Notify the current observers that the texture upload is complete,
618    * then remove the observers from the list.
619    * @param[in] textureInfo The struct associated with this Texture
620    * @param[in] success If the pixel data was retrieved successfully and uploaded to GPU
621    */
622   void NotifyObservers(TextureManager::TextureInfo& textureInfo, const bool& success);
623
624   /**
625    * Call LoadComplete to the observer.
626    * @param[in] observer    The client object should inherit from this and provide the "LoadCompleted"
627    * @param[in] textureInfo The struct associated with this Texture
628    * @param[in] success     If the pixel data was retrieved successfully and uploaded to GPU
629    */
630   void EmitLoadComplete(TextureUploadObserver* observer, TextureManager::TextureInfo& textureInfo, const bool& success);
631
632   /**
633    * @brief Remove observer in textureInfo
634    *
635    * @param textureInfo The struct associated with this Texture.
636    * @param observer The observer wishing to remove.
637    */
638   void RemoveTextureObserver(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
639
640 public:
641   /**
642    * @brief Common method to handle loading completion.
643    * TextureAsyncLoadingHelper will call this API After async loading finished.
644    * @param[in] textureId    The ID of the texture load complete.
645    * @param[in] pixelBuffers The loaded image data
646    */
647   void AsyncLoadComplete(const TextureManager::TextureId& textureId, std::vector<Devel::PixelBuffer>& pixelBuffers);
648
649 protected: // Implementation of Processor
650   /**
651    * @copydoc Dali::Integration::Processor::Process()
652    */
653   void Process(bool postProcessor) override;
654
655 private:
656   /**
657    * Deleted copy constructor.
658    */
659   TextureManager(const TextureManager&) = delete;
660
661   /**
662    * Deleted assignment operator.
663    */
664   TextureManager& operator=(const TextureManager& rhs) = delete;
665
666   /**
667    * This is called by the TextureManagerUploadObserver when an observer is destroyed.
668    * We use the callback to know when to remove an observer from our notify list.
669    * @param[in] observer The observer that generated the callback
670    */
671   void ObserverDestroyed(TextureUploadObserver* observer);
672
673 private:                                    // Member Variables:
674   TextureCacheManager mTextureCacheManager; ///< Manager the life-cycle and caching of Textures
675
676   std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader;        ///< The Asynchronous image loader used to provide all local async loads
677   Dali::Vector<LifecycleObserver*>           mLifecycleObservers; ///< Lifecycle observers of texture manager
678
679   Dali::Vector<QueueElement> mLoadQueue;             ///< Queue of textures to load after NotifyObservers
680   TextureManager::TextureId  mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued.
681
682   Dali::Vector<TextureManager::TextureId> mRemoveQueue; ///< Queue of textures to remove at PostProcess. It will be cleared after PostProcess.
683
684   bool mLoadYuvPlanes;             ///< A global flag to specify if the image should be loaded as yuv planes
685   bool mRemoveProcessorRegistered; ///< Flag if remove processor registered or not.
686 };
687
688 } // namespace Internal
689
690 } // namespace Toolkit
691
692 } // namespace Dali
693
694 #endif // DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H