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