1 #ifndef DALI_TOOLKIT_TEXTURE_CACHE_MANAGER_H
2 #define DALI_TOOLKIT_TEXTURE_CACHE_MANAGER_H
5 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <dali/devel-api/common/free-list.h>
22 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
23 #include <unordered_map>
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>
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.
42 * Also, You can store external TextureSet or EncodedImageBuffer here.
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
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
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.
59 class TextureCacheManager
62 // Copy enum and types and const values that TextureCacheManager will use.
63 using TextureCacheIndexType = TextureManagerType::TextureCacheIndexType;
64 using TextureCacheIndexData = TextureManagerType::TextureCacheIndexData;
66 using TextureId = TextureManagerType::TextureId;
67 using TextureCacheIndex = TextureManagerType::TextureCacheIndex;
68 using TextureHash = TextureManagerType::TextureHash;
70 static constexpr TextureId INVALID_TEXTURE_ID = TextureManagerType::INVALID_TEXTURE_ID;
71 static constexpr TextureCacheIndex INVALID_CACHE_INDEX = TextureManagerType::INVALID_CACHE_INDEX;
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;
85 TextureCacheManager();
90 ~TextureCacheManager();
93 // TextureCacheManager Main API:
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.
100 VisualUrl GetVisualUrl(const TextureCacheManager::TextureId& textureId);
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
106 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
109 TextureCacheManager::LoadState GetTextureState(const TextureCacheManager::TextureId& textureId);
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
118 TextureCacheManager::LoadState GetTextureStateInternal(const TextureCacheManager::TextureId& textureId);
121 * @brief Get the associated texture set if the texture id is valid
122 * @param[in] textureId The texture Id to look up
123 * @return the associated texture set, or an empty handle if textureId is not valid
125 TextureSet GetTextureSet(const TextureCacheManager::TextureId& textureId);
128 * @brief Get the external texture set if the texture id is valid
129 * @param[in] textureId The texture Id to look up
130 * @return the external texture set, or an empty handle if textureId is not valid
132 TextureSet GetExternalTextureSet(const TextureCacheManager::TextureId& textureId);
135 * @brief Get the encoded image buffer
136 * @param[in] bufferId The bufferId to look up
137 * @return the encoded image buffer, or an empty handle if bufferId is not valid
139 EncodedImageBuffer GetEncodedImageBuffer(const TextureCacheManager::TextureId& bufferId);
142 * @brief Get the encoded image buffer by VisualUrl
143 * @param[in] url The url to look up
144 * @return the encoded image buffer, or an empty handle if url is not buffer resource or buffer is not valid
146 EncodedImageBuffer GetEncodedImageBuffer(const VisualUrl& url);
149 * Adds an external texture to the texture manager
150 * @param[in] texture The texture to add
151 * @return string containing the URL for the texture
153 std::string AddExternalTexture(const TextureSet& texture);
156 * Adds an encoded image buffer to the texture manager
157 * @param[in] encodedImageBuffer The image buffer to add
158 * @return string containing the URL for the texture
160 std::string AddEncodedImageBuffer(const EncodedImageBuffer& encodedImageBuffer);
163 * Removes an external texture from texture manager
164 * @param[in] url The string containing the texture to remove
165 * @return handle to the texture
167 TextureSet RemoveExternalTexture(const VisualUrl& url);
170 * Removes an external encoded image buffer from texture manager
171 * @param[in] url The string containing the encoded image buffer to remove
172 * @return handle to the encoded image buffer
174 EncodedImageBuffer RemoveEncodedImageBuffer(const VisualUrl& url);
177 * @brief Notify that external textures or encoded image buffers are used.
178 * @param[in] url The URL of the texture to use.
180 void UseExternalResource(const VisualUrl& url);
183 // To Generate / Get / Remove TextureId.
186 * @brief Generates a new valid TextureId.
187 * @param[in] textureCacheIndex the index of the cache container. If we don't setup this value, default is INVALID_CACHE_INDEX
188 * @return A TextureId
190 TextureCacheManager::TextureId GenerateTextureId(const TextureCacheIndex& textureCacheIndex = INVALID_CACHE_INDEX);
193 * @brief Used to lookup an index into the TextureInfoContainer from a TextureId
194 * @param[in] textureId The TextureId to look up
195 * @return The cache index
197 TextureCacheManager::TextureCacheIndex GetCacheIndexFromId(const TextureCacheManager::TextureId& textureId);
200 * @brief Generates a hash for caching based on the input parameters.
201 * Only applies size, fitting mode andsampling mode if the size is specified.
202 * Only applies maskTextureId if it isn't INVALID_TEXTURE_ID
203 * Always applies useAtlas.
204 * @param[in] url The URL of the image to load
205 * @param[in] size The image size
206 * @param[in] fittingMode The FittingMode to use
207 * @param[in] samplingMode The SamplingMode to use
208 * @param[in] useAtlas True if atlased
209 * @param[in] maskTextureId The masking texture id (or INVALID_TEXTURE_ID)
210 * @param[in] cropToMask True if crop to mask
211 * @param[in] frameIndex The frame index to use
212 * @return A hash of the provided data for caching.
214 TextureCacheManager::TextureHash GenerateHash(
215 const VisualUrl& url,
216 const Dali::ImageDimensions& size,
217 const Dali::FittingMode::Type& fittingMode,
218 const Dali::SamplingMode::Type& samplingMode,
219 const TextureCacheManager::UseAtlas& useAtlas,
220 const TextureCacheManager::TextureId& maskTextureId,
221 const bool& cropToMask,
222 const std::uint32_t& frameIndex);
225 * @brief Looks up a cached texture by its hash.
226 * If found, the given parameters are used to check there is no hash-collision.
227 * @param[in] hash The hash to look up
228 * @param[in] url The URL of the image to load
229 * @param[in] size The image size
230 * @param[in] fittingMode The FittingMode to use
231 * @param[in] samplingMode The SamplingMode to use
232 * @param[in] useAtlas True if atlased
233 * @param[in] storageType Whether the pixel data is stored in the cache or uploaded to the GPU
234 * @param[in] maskTextureId Optional texture ID to use to mask this image
235 * @param[in] cropToMask True if crop to mask
236 * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
237 * @param[in] isAnimatedImage True if the texture is from animated image.
238 * @param[in] frameIndex The frame index to use
239 * @return A TextureCacheIndex of a cached Texture if found. Or INVALID_CACHE_INDEX if not found.
241 TextureCacheManager::TextureCacheIndex FindCachedTexture(
242 const TextureCacheManager::TextureHash& hash,
243 const VisualUrl& url,
244 const Dali::ImageDimensions& size,
245 const Dali::FittingMode::Type& fittingMode,
246 const Dali::SamplingMode::Type& samplingMode,
247 const TextureCacheManager::UseAtlas& useAtlas,
248 const StorageType& storageType,
249 const TextureCacheManager::TextureId& maskTextureId,
250 const bool& cropToMask,
251 const TextureCacheManager::MultiplyOnLoad& preMultiplyOnLoad,
252 const bool& isAnimatedImage,
253 const std::uint32_t& frameIndex);
256 * @brief Append a Texture to the TextureCacheManager.
257 * @note This API doesn't check duplication of TextureId.
258 * @note This API doesn't consider external & encodedimagebuffer.
260 * @param[in] textureInfo TextureInfo that want to cache in container.
261 * @return Index of newly appended texture info.
263 TextureCacheManager::TextureCacheIndex AppendCache(const TextureCacheManager::TextureInfo& textureInfo);
266 * @brief Remove a Texture from the TextureCacheManager.
267 * @note This API doesn't consider external & encodedimagebuffer.
269 * Textures are cached and therefore only the removal of the last
270 * occurrence of a Texture will cause its removal internally.
272 * @param[in] textureId The Id of the Texture to remove at Cache.
274 void RemoveCache(const TextureCacheManager::TextureId& textureId);
278 * @brief Get TextureInfo as TextureCacheIndex.
279 * @note This API doesn't consider external & encodedimagebuffer.
280 * @param[in] textureCacheIndex Index of cahced texture.
281 * @return TextureInfo as textureCacheIndex
283 inline TextureCacheManager::TextureInfo& operator[](const TextureCacheManager::TextureCacheIndex& textureCacheIndex) noexcept
285 return mTextureInfoContainer[textureCacheIndex.GetIndex()];
289 * @brief The number of associated cached image
290 * @note This API doesn't consider external & encodedimagebuffer.
291 * @return The number of associated cached image
293 inline std::size_t size() noexcept
295 return mTextureInfoContainer.size();
299 // Private defined structs.
302 * @brief This struct is used to manage the life-cycle of ExternalTexture url.
304 struct ExternalTextureInfo
306 ExternalTextureInfo(const TextureCacheManager::TextureId& textureId,
307 const TextureSet& textureSet)
308 : textureId(textureId),
309 textureSet(textureSet),
313 TextureCacheManager::TextureId textureId;
314 TextureSet textureSet;
315 std::int16_t referenceCount;
319 * @brief This struct is used to manage the life-cycle of EncodedImageBuffer url.
321 struct EncodedImageBufferInfo
323 EncodedImageBufferInfo(const TextureCacheManager::TextureId& bufferId,
324 const TextureCacheManager::TextureHash& bufferHash,
325 const EncodedImageBuffer& encodedImageBuffer)
326 : bufferId(bufferId),
327 bufferHash(bufferHash),
328 encodedImageBuffer(encodedImageBuffer),
332 TextureCacheManager::TextureId bufferId;
333 TextureCacheManager::TextureHash bufferHash;
334 EncodedImageBuffer encodedImageBuffer;
335 std::int16_t referenceCount;
338 typedef Dali::FreeList TextureIdConverterType; ///< The converter type from TextureId to index of TextureInfoContainer.
340 typedef std::unordered_map<TextureCacheManager::TextureHash, std::vector<TextureCacheManager::TextureId>> TextureHashContainerType; ///< The container type used to fast-find the TextureId by TextureHash.
341 typedef std::vector<TextureCacheManager::TextureInfo> TextureInfoContainerType; ///< The container type used to manage the life-cycle and caching of Textures
342 typedef std::vector<TextureCacheManager::ExternalTextureInfo> ExternalTextureInfoContainerType; ///< The container type used to manage the life-cycle and caching of ExternalTexture url
343 typedef std::vector<TextureCacheManager::EncodedImageBufferInfo> EncodedImageBufferInfoContainerType; ///< The container type used to manage the life-cycle and caching of EncodedImageBuffer url
346 // Private API: only used internally
349 * @brief Used to lookup an index into the ExternalTextureInfoContainer from a textureId
350 * @param[in] textureId The TextureId to look up
351 * @return The cache index
353 TextureCacheManager::TextureCacheIndex GetCacheIndexFromExternalTextureId(const TextureCacheManager::TextureId& textureId);
356 * @brief Used to lookup an index into the EncodedImageBufferInfoContainer from a bufferId
357 * @param[in] bufferId The bufferId to look up
358 * @return The cache index
360 TextureCacheManager::TextureCacheIndex GetCacheIndexFromEncodedImageBufferId(const TextureCacheManager::TextureId& bufferId);
363 * @brief Looks up a cached encoded image buffer cached by its hash.
364 * If found, the given parameters are used to check there is no hash-collision.
365 * @param[in] hash The hash to look up
366 * @param[in] encodedImageBuffer The image buffer to load
367 * @return A TextureCacheIndex of a cached Texture if found. Or INVALID_CACHE_INDEX if not found.
369 TextureCacheManager::TextureCacheIndex FindCachedEncodedImageBuffer(const TextureCacheManager::TextureHash& hash, const EncodedImageBuffer& encodedImageBuffer);
372 * @brief Remove id in HashContainer.
373 * @param[in] hash The hash of the texture/buffer to be delete
374 * @param[in] id The texture/buffer id to be deleted.
376 void RemoveHashId(const TextureCacheManager::TextureHash& hash, const TextureCacheManager::TextureId& id);
379 * @brief Remove data from container by the TextureCacheIndex.
380 * It also valiate the TextureIdConverter internally.
381 * We will assume that only valid TextureCacheIndex will come.
383 * @tparam ContainerType The type of container. It will automatically defined
384 * @param[in] cacheContainer The container that will remove texture info.
385 * @param[in] removeContainerIndex The index of texture info that will remove.
387 template<class ContainerType>
388 void RemoveTextureInfoByIndex(ContainerType& cacheContainer, const TextureCacheManager::TextureCacheIndex& removeContainerIndex);
392 * Deleted copy constructor.
394 TextureCacheManager(const TextureCacheManager&) = delete;
397 * Deleted assignment operator.
399 TextureCacheManager& operator=(const TextureCacheManager& rhs) = delete;
401 private: // Member Variables:
402 TextureIdConverterType mTextureIdConverter{}; ///< Convert TextureId into various container's index.
403 TextureHashContainerType mTextureHashContainer{}; ///< Used to manage the life-cycle and caching of Textures + EncodedImageBuffer by TextureHash
405 TextureInfoContainerType mTextureInfoContainer{}; ///< Used to manage the life-cycle and caching of Textures
406 ExternalTextureInfoContainerType mExternalTextures{}; ///< Externally provided textures
407 EncodedImageBufferInfoContainerType mEncodedImageBuffers{}; ///< Externally encoded image buffer
410 } // namespace Internal
412 } // namespace Toolkit
416 #endif // DALI_TOOLKIT_TEXTURE_CACHE_MANAGER_H