[dali_2.1.40] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / texture-manager / texture-cache-manager.h
1 #ifndef DALI_TOOLKIT_TEXTURE_CACHE_MANAGER_H
2 #define DALI_TOOLKIT_TEXTURE_CACHE_MANAGER_H
3
4 /*
5  * Copyright (c) 2022 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/common/free-list.h>
22 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
23 #include <unordered_map>
24
25 // INTERNAL INCLUDES
26 #include <dali-toolkit/internal/texture-manager/texture-manager-type.h>
27 #include <dali-toolkit/internal/texture-manager/texture-upload-observer.h>
28 #include <dali-toolkit/internal/visuals/visual-url.h>
29
30 namespace Dali
31 {
32 namespace Toolkit
33 {
34 namespace Internal
35 {
36 /**
37  * @brief The contain and managing cached textures.
38  * Each Texture hold there TextureId. These TextureId can be used outside of TextureManager.
39  * Internally, each cached texture can be accessed by TextureCacheIndex.
40  * You can Convert TextureId into TextureCacheIndex by this class.
41  *
42  * Also, You can store external TextureSet or EncodedImageBuffer here.
43  *
44  * There are 3 type of CachedContainer in this manager
45  *  - mTextureInfoContainer : Cache all kind of textures that need some load/upload jobs.
46  *                            All kind of images that visual using (not vector image) will be stored here.
47  *                            This container will use TEXTURE_CACHE_INDEX_TYPE_LOCAL
48  *
49  *  - mExternalTextures : External appended TextureSet cache container.
50  *                        External TextureSet can be Something like NativeImageSource, FrameBuffer and PixelData.
51  *                        This container will use TEXTURE_CACHE_INDEX_TYPE_TEXTURE
52  *                        The textureId will be used for VisualUrl. ex) dali://1
53  *
54  *  - mEncodedImageBuffers : External appended EncodedImageBuffer cache container.
55  *                           This container will use TEXTURE_CACHE_INDEX_TYPE_BUFFER
56  *                           The bufferId will be used for VisualUrl. ex) enbuf://1
57  *                           Note that this bufferId is not equal with textureId in mTextureInfoContainer.
58  */
59 class TextureCacheManager
60 {
61 public:
62   // Copy enum and types and const values that TextureCacheManager will use.
63   using TextureCacheIndexType = TextureManagerType::TextureCacheIndexType;
64   using TextureCacheIndexData = TextureManagerType::TextureCacheIndexData;
65
66   using TextureId         = TextureManagerType::TextureId;
67   using TextureCacheIndex = TextureManagerType::TextureCacheIndex;
68   using TextureHash       = TextureManagerType::TextureHash;
69
70   static constexpr TextureId         INVALID_TEXTURE_ID  = TextureManagerType::INVALID_TEXTURE_ID;
71   static constexpr TextureCacheIndex INVALID_CACHE_INDEX = TextureManagerType::INVALID_CACHE_INDEX;
72
73   using UseAtlas       = TextureManagerType::UseAtlas;
74   using StorageType    = TextureManagerType::StorageType;
75   using LoadType       = TextureManagerType::LoadType;
76   using LoadState      = TextureManagerType::LoadState;
77   using ReloadPolicy   = TextureManagerType::ReloadPolicy;
78   using MultiplyOnLoad = TextureManagerType::MultiplyOnLoad;
79   using TextureInfo    = TextureManagerType::TextureInfo;
80
81 public:
82   /**
83    * Constructor.
84    */
85   TextureCacheManager();
86
87   /**
88    * Destructor.
89    */
90   ~TextureCacheManager();
91
92 public:
93   // TextureCacheManager Main API:
94
95   /**
96    * @brief Get the visualUrl associated with the texture id.
97    * @param[in] textureId The texture Id to get
98    * @return The visual Url associated with the texture id.
99    */
100   VisualUrl GetVisualUrl(const TextureCacheManager::TextureId& textureId);
101
102   /**
103    * @brief Get the current state of a texture
104    * @note This API doesn't consider encodedimagebuffer.
105    * @param[in] textureId The texture id to query.defaul value is 0.
106    * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
107    * is not valid.
108    */
109   TextureCacheManager::LoadState GetTextureState(const TextureCacheManager::TextureId& textureId);
110
111   /**
112    * @brief Get the current state of a texture
113    * @note This API doesn't consider external & encodedimagebuffer.
114    * @param[in] textureId The texture id to query
115    * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
116    * is not valid.
117    */
118   TextureCacheManager::LoadState GetTextureStateInternal(const TextureCacheManager::TextureId& textureId);
119
120   /**
121    * @brief Get the associated texture set if the texture id is valid
122    * @param[in] textureId The texture Id to look up
123    * @param[in] textureIndex The texture index to query
124    * @return the associated texture, or an empty handle if textureId is not valid
125    */
126   Texture GetTexture(const TextureCacheManager::TextureId& textureId, uint32_t textureIndex = 0);
127
128   /**
129    * @brief Get the external texture set if the texture id is valid
130    * @param[in] textureId The texture Id to look up
131    * @return the external texture set, or an empty handle if textureId is not valid
132    */
133   TextureSet GetExternalTextureSet(const TextureCacheManager::TextureId& textureId);
134
135   /**
136    * @brief Get the encoded image buffer
137    * @param[in] bufferId The bufferId to look up
138    * @return the encoded image buffer, or an empty handle if bufferId is not valid
139    */
140   EncodedImageBuffer GetEncodedImageBuffer(const TextureCacheManager::TextureId& bufferId);
141
142   /**
143    * @brief Get the encoded image buffer by VisualUrl
144    * @param[in] url The url to look up
145    * @return the encoded image buffer, or an empty handle if url is not buffer resource or buffer is not valid
146    */
147   EncodedImageBuffer GetEncodedImageBuffer(const VisualUrl& url);
148
149   /**
150    * Adds an external texture to the texture manager
151    * @param[in] texture The texture to add
152    * @return string containing the URL for the texture
153    */
154   std::string AddExternalTexture(const TextureSet& texture);
155
156   /**
157    * Adds an encoded image buffer to the texture manager
158    * @param[in] encodedImageBuffer The image buffer to add
159    * @return string containing the URL for the texture
160    */
161   std::string AddEncodedImageBuffer(const EncodedImageBuffer& encodedImageBuffer);
162
163   /**
164    * Removes an external texture from texture manager
165    * @param[in] url The string containing the texture to remove
166    * @return handle to the texture
167    */
168   TextureSet RemoveExternalTexture(const VisualUrl& url);
169
170   /**
171    * Removes an external encoded image buffer from texture manager
172    * @param[in] url The string containing the encoded image buffer to remove
173    * @return handle to the encoded image buffer
174    */
175   EncodedImageBuffer RemoveEncodedImageBuffer(const VisualUrl& url);
176
177   /**
178    * @brief Notify that external textures or encoded image buffers are used.
179    * @param[in] url The URL of the texture to use.
180    */
181   void UseExternalResource(const VisualUrl& url);
182
183 public:
184   // To Generate / Get / Remove TextureId.
185
186   /**
187    * @brief Generates a new valid TextureId.
188    * @param[in] textureCacheIndex the index of the cache container. If we don't setup this value, default is INVALID_CACHE_INDEX
189    * @return A TextureId
190    */
191   TextureCacheManager::TextureId GenerateTextureId(const TextureCacheIndex& textureCacheIndex = INVALID_CACHE_INDEX);
192
193   /**
194    * @brief Used to lookup an index into the TextureInfoContainer from a TextureId
195    * @param[in] textureId The TextureId to look up
196    * @return              The cache index
197    */
198   TextureCacheManager::TextureCacheIndex GetCacheIndexFromId(const TextureCacheManager::TextureId& textureId);
199
200   /**
201    * @brief Generates a hash for caching based on the input parameters.
202    * Only applies size, fitting mode andsampling mode if the size is specified.
203    * Only applies maskTextureId if it isn't INVALID_TEXTURE_ID
204    * Always applies useAtlas.
205    * @param[in] url              The URL of the image to load
206    * @param[in] size             The image size
207    * @param[in] fittingMode      The FittingMode to use
208    * @param[in] samplingMode     The SamplingMode to use
209    * @param[in] useAtlas         True if atlased
210    * @param[in] maskTextureId    The masking texture id (or INVALID_TEXTURE_ID)
211    * @param[in] cropToMask       True if crop to mask
212    * @param[in] frameIndex       The frame index to use
213    * @return                     A hash of the provided data for caching.
214    */
215   TextureCacheManager::TextureHash GenerateHash(
216     const VisualUrl&                      url,
217     const Dali::ImageDimensions&          size,
218     const Dali::FittingMode::Type&        fittingMode,
219     const Dali::SamplingMode::Type&       samplingMode,
220     const TextureCacheManager::UseAtlas&  useAtlas,
221     const TextureCacheManager::TextureId& maskTextureId,
222     const bool&                           cropToMask,
223     const std::uint32_t&                  frameIndex);
224
225   /**
226    * @brief Looks up a cached texture by its hash.
227    * If found, the given parameters are used to check there is no hash-collision.
228    * @param[in] hash              The hash to look up
229    * @param[in] url               The URL of the image to load
230    * @param[in] size              The image size
231    * @param[in] fittingMode       The FittingMode to use
232    * @param[in] samplingMode      The SamplingMode to use
233    * @param[in] useAtlas          True if atlased
234    * @param[in] storageType       Whether the pixel data is stored in the cache or uploaded to the GPU
235    * @param[in] maskTextureId     Optional texture ID to use to mask this image
236    * @param[in] cropToMask        True if crop to mask
237    * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
238    * @param[in] isAnimatedImage   True if the texture is from animated image.
239    * @param[in] frameIndex        The frame index to use
240    * @return                      A TextureCacheIndex of a cached Texture if found. Or INVALID_CACHE_INDEX if not found.
241    */
242   TextureCacheManager::TextureCacheIndex FindCachedTexture(
243     const TextureCacheManager::TextureHash&    hash,
244     const VisualUrl&                           url,
245     const Dali::ImageDimensions&               size,
246     const Dali::FittingMode::Type&             fittingMode,
247     const Dali::SamplingMode::Type&            samplingMode,
248     const TextureCacheManager::UseAtlas&       useAtlas,
249     const StorageType&                         storageType,
250     const TextureCacheManager::TextureId&      maskTextureId,
251     const bool&                                cropToMask,
252     const TextureCacheManager::MultiplyOnLoad& preMultiplyOnLoad,
253     const bool&                                isAnimatedImage,
254     const std::uint32_t&                       frameIndex);
255
256   /**
257    * @brief Append a Texture to the TextureCacheManager.
258    * @note This API doesn't check duplication of TextureId.
259    * @note This API doesn't consider external & encodedimagebuffer.
260    *
261    * @param[in] textureInfo TextureInfo that want to cache in container.
262    * @return Index of newly appended texture info.
263    */
264   TextureCacheManager::TextureCacheIndex AppendCache(const TextureCacheManager::TextureInfo& textureInfo);
265
266   /**
267    * @brief Remove a Texture from the TextureCacheManager.
268    * @note This API doesn't consider external & encodedimagebuffer.
269    *
270    * Textures are cached and therefore only the removal of the last
271    * occurrence of a Texture will cause its removal internally.
272    *
273    * @param[in] textureInfo TextureInfo that want to cache in container.
274    */
275   void RemoveCache(TextureCacheManager::TextureInfo& textureInfo);
276
277 public:
278   /**
279    * @brief Get TextureInfo as TextureCacheIndex.
280    * @note This API doesn't consider external & encodedimagebuffer.
281    * @param[in] textureCacheIndex Index of cahced texture.
282    * @return TextureInfo as textureCacheIndex
283    */
284   inline TextureCacheManager::TextureInfo& operator[](const TextureCacheManager::TextureCacheIndex& textureCacheIndex) noexcept
285   {
286     return mTextureInfoContainer[textureCacheIndex.GetIndex()];
287   }
288
289   /**
290    * @brief The number of associated cached image
291    * @note This API doesn't consider external & encodedimagebuffer.
292    * @return The number of associated cached image
293    */
294   inline std::size_t size() noexcept
295   {
296     return mTextureInfoContainer.size();
297   }
298
299 private:
300   // Private defined structs.
301
302   /**
303    * @brief This struct is used to manage the life-cycle of ExternalTexture url.
304    */
305   struct ExternalTextureInfo
306   {
307     ExternalTextureInfo(const TextureCacheManager::TextureId& textureId,
308                         const TextureSet&                     textureSet)
309     : textureId(textureId),
310       textureSet(textureSet),
311       referenceCount(1u)
312     {
313     }
314     TextureCacheManager::TextureId textureId;
315     TextureSet                     textureSet;
316     std::int16_t                   referenceCount;
317   };
318
319   /**
320    * @brief This struct is used to manage the life-cycle of EncodedImageBuffer url.
321    */
322   struct EncodedImageBufferInfo
323   {
324     EncodedImageBufferInfo(const TextureCacheManager::TextureId&   bufferId,
325                            const TextureCacheManager::TextureHash& bufferHash,
326                            const EncodedImageBuffer&               encodedImageBuffer)
327     : bufferId(bufferId),
328       bufferHash(bufferHash),
329       encodedImageBuffer(encodedImageBuffer),
330       referenceCount(1u)
331     {
332     }
333     TextureCacheManager::TextureId   bufferId;
334     TextureCacheManager::TextureHash bufferHash;
335     EncodedImageBuffer               encodedImageBuffer;
336     std::int16_t                     referenceCount;
337   };
338
339   typedef Dali::FreeList TextureIdConverterType; ///< The converter type from TextureId to index of TextureInfoContainer.
340
341   typedef std::unordered_map<TextureCacheManager::TextureHash, std::vector<TextureCacheManager::TextureId>> TextureHashContainerType;            ///< The container type used to fast-find the TextureId by TextureHash.
342   typedef std::vector<TextureCacheManager::TextureInfo>                                                     TextureInfoContainerType;            ///< The container type used to manage the life-cycle and caching of Textures
343   typedef std::vector<TextureCacheManager::ExternalTextureInfo>                                             ExternalTextureInfoContainerType;    ///< The container type used to manage the life-cycle and caching of ExternalTexture url
344   typedef std::vector<TextureCacheManager::EncodedImageBufferInfo>                                          EncodedImageBufferInfoContainerType; ///< The container type used to manage the life-cycle and caching of EncodedImageBuffer url
345
346 private:
347   // Private API: only used internally
348
349   /**
350    * @brief Used to lookup an index into the ExternalTextureInfoContainer from a textureId
351    * @param[in] textureId The TextureId to look up
352    * @return              The cache index
353    */
354   TextureCacheManager::TextureCacheIndex GetCacheIndexFromExternalTextureId(const TextureCacheManager::TextureId& textureId);
355
356   /**
357    * @brief Used to lookup an index into the EncodedImageBufferInfoContainer from a bufferId
358    * @param[in] bufferId The bufferId to look up
359    * @return             The cache index
360    */
361   TextureCacheManager::TextureCacheIndex GetCacheIndexFromEncodedImageBufferId(const TextureCacheManager::TextureId& bufferId);
362
363   /**
364    * @brief Looks up a cached encoded image buffer cached by its hash.
365    * If found, the given parameters are used to check there is no hash-collision.
366    * @param[in] hash               The hash to look up
367    * @param[in] encodedImageBuffer The image buffer to load
368    * @return                       A TextureCacheIndex of a cached Texture if found. Or INVALID_CACHE_INDEX if not found.
369    */
370   TextureCacheManager::TextureCacheIndex FindCachedEncodedImageBuffer(const TextureCacheManager::TextureHash& hash, const EncodedImageBuffer& encodedImageBuffer);
371
372   /**
373    * @brief Remove id in HashContainer.
374    * @param[in] hash The hash of the texture/buffer to be delete
375    * @param[in] id   The texture/buffer id to be deleted.
376    */
377   void RemoveHashId(const TextureCacheManager::TextureHash& hash, const TextureCacheManager::TextureId& id);
378
379   /**
380    * @brief Remove data from container by the TextureCacheIndex.
381    * It also valiate the TextureIdConverter internally.
382    * We will assume that only valid TextureCacheIndex will come.
383    *
384    * @tparam ContainerType The type of container. It will automatically defined
385    * @param[in] cacheContainer The container that will remove texture info.
386    * @param[in] removeContainerIndex The index of texture info that will remove.
387    */
388   template<class ContainerType>
389   void RemoveTextureInfoByIndex(ContainerType& cacheContainer, const TextureCacheManager::TextureCacheIndex& removeContainerIndex);
390
391 private:
392   /**
393    * Deleted copy constructor.
394    */
395   TextureCacheManager(const TextureCacheManager&) = delete;
396
397   /**
398    * Deleted assignment operator.
399    */
400   TextureCacheManager& operator=(const TextureCacheManager& rhs) = delete;
401
402 private:                                            // Member Variables:
403   TextureIdConverterType   mTextureIdConverter{};   ///< Convert TextureId into various container's index.
404   TextureHashContainerType mTextureHashContainer{}; ///< Used to manage the life-cycle and caching of Textures + EncodedImageBuffer by TextureHash
405
406   TextureInfoContainerType            mTextureInfoContainer{}; ///< Used to manage the life-cycle and caching of Textures
407   ExternalTextureInfoContainerType    mExternalTextures{};     ///< Externally provided textures
408   EncodedImageBufferInfoContainerType mEncodedImageBuffers{};  ///< Externally encoded image buffer
409 };
410
411 } // namespace Internal
412
413 } // namespace Toolkit
414
415 } // namespace Dali
416
417 #endif // DALI_TOOLKIT_TEXTURE_CACHE_MANAGER_H