1 #ifndef DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
2 #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
5 * Copyright (c) 2021 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/adaptor-framework/pixel-buffer.h>
22 #include <dali/devel-api/common/owner-container.h>
23 #include <dali/public-api/common/dali-vector.h>
24 #include <dali/public-api/object/ref-object.h>
25 #include <dali/public-api/rendering/geometry.h>
26 #include <dali/public-api/rendering/texture-set.h>
33 #include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
34 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
35 #include <dali-toolkit/internal/helpers/round-robin-container-view.h>
36 #include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
37 #include <dali-toolkit/internal/visuals/texture-upload-observer.h>
38 #include <dali-toolkit/internal/visuals/visual-url.h>
39 #include <dali-toolkit/public-api/image-loader/async-image-loader.h>
47 class ImageAtlasManager;
48 typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
51 * The TextureManager provides a common Image loading API for Visuals.
53 * The TextureManager is responsible for providing sync, async, atlased and non-atlased loads.
54 * Texture caching is provided and performed when possible.
55 * Broken Images are automatically provided on load failure.
57 class TextureManager : public ConnectionTracker
60 typedef int32_t TextureId; ///< The TextureId type. This is used as a handle to refer to a particular Texture.
61 static const int INVALID_TEXTURE_ID = -1; ///< Used to represent a null TextureId or error
64 * Whether the texture should be atlased or uploaded into it's own GPU texture
73 * Whether the pixel data should be kept in TextureManager, returned with pixelBuffer or uploaded for rendering
75 enum class StorageType : uint8_t
83 * Whether the texture should be loaded synchronously or asynchronously.
85 enum class LoadType : uint8_t
92 * @brief The LoadState Enumeration represents the current state of a particular Texture's life-cycle.
94 enum class LoadState : uint8_t
96 NOT_STARTED, ///< Default
97 LOADING, ///< Loading has been started, but not finished.
98 LOAD_FINISHED, ///< Loading has finished. (for CPU storage only)
99 WAITING_FOR_MASK, ///< Loading has finished, but waiting for mask image
100 MASK_APPLYING, ///< Loading has finished, Mask is applying
101 MASK_APPLIED, ///< Loading has finished, Mask is applyied by GPU
102 UPLOADED, ///< Uploaded and ready. (For GPU upload only)
103 CANCELLED, ///< Removed before loading completed
104 LOAD_FAILED ///< Async loading failed, e.g. connection problem
108 * @brief Types of reloading policies
110 enum class ReloadPolicy
112 CACHED = 0, ///< Loads cached texture if it exists.
113 FORCED ///< Forces reloading of texture.
117 * @brief Whether to multiply alpha into color channels on load
119 enum class MultiplyOnLoad
121 LOAD_WITHOUT_MULTIPLY = 0, ///< Don't modify the image
122 MULTIPLY_ON_LOAD ///< Multiply alpha into color channels on load
129 ~MaskingData() = default;
131 VisualUrl mAlphaMaskUrl;
132 TextureManager::TextureId mAlphaMaskId;
133 float mContentScaleFactor;
136 using MaskingDataPointer = std::unique_ptr<MaskingData>;
139 * Class to provide lifecycle event on destruction of texture manager.
141 struct LifecycleObserver
144 * Called shortly before the texture manager is destroyed.
146 virtual void TextureManagerDestroyed() = 0;
157 ~TextureManager() override;
159 // TextureManager Main API:
162 * @brief Requests an frame of animated image load.
164 * The parameters are used to specify how the animated image is loaded.
165 * The observer has the LoadComplete method called when the load is ready.
167 * @param[in] animatedImageLoading The AnimatedImageLoading that contain the animated image information
168 * @param[in] frameIndex The frame index to load.
169 * @param[in] samplingMode The SamplingMode to use
170 * @param[in] synchronousLoading true if the frame should be loaded synchronously
171 * @param[out] textureId The textureId of the frame
172 * @param[in] wrapModeU Horizontal Wrap mode
173 * @param[in] wrapModeV Vertical Wrap mode
174 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
175 * This is called when an image load completes (or fails).
177 * @return The texture set containing the frame of animated image, or empty if still loading.
180 TextureSet LoadAnimatedImageTexture(Dali::AnimatedImageLoading animatedImageLoading,
182 Dali::SamplingMode::Type samplingMode,
183 bool synchronousLoading,
184 TextureManager::TextureId& textureId,
185 Dali::WrapMode::Type wrapModeU,
186 Dali::WrapMode::Type wrapModeV,
187 TextureUploadObserver* textureObserver);
190 * @brief Requests an image load of the given URL to get PixelBuffer.
192 * The parameters are used to specify how the image is loaded.
193 * The observer has the LoadComplete method called when the load is ready.
195 * @param[in] url The URL of the image to load
196 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
197 * @param[in] fittingMode The FittingMode to use
198 * @param[in] samplingMode The SamplingMode to use
199 * @param[in] synchronousLoading true if the URL should be loaded synchronously
200 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
201 * This is called when an image load completes (or fails).
202 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
203 * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
204 * image has no alpha channel
206 * @return The pixel buffer containing the image, or empty if still loading.
209 Devel::PixelBuffer LoadPixelBuffer(const VisualUrl& url,
210 Dali::ImageDimensions desiredSize,
211 Dali::FittingMode::Type fittingMode,
212 Dali::SamplingMode::Type samplingMode,
213 bool synchronousLoading,
214 TextureUploadObserver* textureObserver,
215 bool orientationCorrection,
216 TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
219 * @brief Requests an image load of the given URL.
221 * The parameters are used to specify how the image is loaded.
222 * The observer has the UploadComplete method called when the load is ready.
224 * When the client has finished with the Texture, Remove() should be called.
226 * @param[in] url The URL of the image to load
227 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
228 * @param[in] fittingMode The FittingMode to use
229 * @param[in] samplingMode The SamplingMode to use
230 * @param[in, out] maskInfo Mask info structure
231 * @param[in] synchronousLoading true if the URL should be loaded synchronously
232 * @param[out] textureId, The textureId of the URL
233 * @param[out] textureRect The rectangle within the texture atlas that this URL occupies,
234 * this is the rectangle in normalized coordinates.
235 * @param[out] textureRectSize The rectangle within the texture atlas that this URL occupies,
236 * this is the same rectangle in pixels.
237 * @param[in,out] atlasingStatus Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
238 * be loaded, and marked successful, but this will be set to false.
239 * If atlasing succeeds, this will be set to true.
240 * @param[out] loadingStatus The loading status of the texture
241 * @param[in] wrapModeU Horizontal Wrap mode
242 * @param[in] wrapModeV Vertical Wrap mode
243 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
244 * This is called when an image load completes (or fails).
245 * @param[in] atlasObserver This is used if the texture is atlased, and will be called instead of
246 * textureObserver.UploadCompleted
247 * @param[in] imageAtlasManager The atlas manager to use for atlasing textures
248 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
249 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
250 * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
251 * image has no alpha channel
253 * @return The texture set containing the image, or empty if still loading.
256 TextureSet LoadTexture(const VisualUrl& url,
257 Dali::ImageDimensions desiredSize,
258 Dali::FittingMode::Type fittingMode,
259 Dali::SamplingMode::Type samplingMode,
260 MaskingDataPointer& maskInfo,
261 bool synchronousLoading,
262 TextureManager::TextureId& textureId,
263 Vector4& textureRect,
264 Dali::ImageDimensions& textureRectSize,
265 bool& atlasingStatus,
267 Dali::WrapMode::Type wrapModeU,
268 Dali::WrapMode::Type wrapModeV,
269 TextureUploadObserver* textureObserver,
270 AtlasUploadObserver* atlasObserver,
271 ImageAtlasManagerPtr imageAtlasManager,
272 bool orientationCorrection,
273 TextureManager::ReloadPolicy reloadPolicy,
274 MultiplyOnLoad& preMultiplyOnLoad);
277 * @brief Requests an image load of the given URL.
279 * The parameters are used to specify how the image is loaded.
280 * The observer has the UploadComplete method called when the load is ready.
282 * When the client has finished with the Texture, Remove() should be called.
284 * @param[in] url The URL of the image to load
285 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
286 * @param[in] fittingMode The FittingMode to use
287 * @param[in] samplingMode The SamplingMode to use
288 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
289 * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
290 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
291 * This is called when an image load completes (or fails).
292 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
293 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
294 * @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
295 * @return A TextureId to use as a handle to reference this Texture
297 TextureId RequestLoad(const VisualUrl& url,
298 const ImageDimensions desiredSize,
299 FittingMode::Type fittingMode,
300 Dali::SamplingMode::Type samplingMode,
301 const UseAtlas useAtlasing,
302 TextureUploadObserver* observer,
303 bool orientationCorrection,
304 TextureManager::ReloadPolicy reloadPolicy,
305 MultiplyOnLoad& preMultiplyOnLoad);
308 * @brief Requests an image load of the given URL, when the texture has
309 * have loaded, it will perform a blend with the image mask, and upload
310 * the blended texture.
312 * The parameters are used to specify how the image is loaded.
313 * The observer has the UploadComplete method called when the load is ready.
315 * When the client has finished with the Texture, Remove() should be called.
317 * @param[in] url The URL of the image to load
318 * @param[in] maskTextureId The texture id of an image to mask this with
319 * (can be INVALID if no masking required)
320 * @param[in] contentScale The scale factor to apply to the image before masking
321 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
322 * @param[in] fittingMode The FittingMode to use
323 * @param[in] samplingMode The SamplingMode to use
324 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
325 * be loaded, and marked successful,
326 * but "useAtlasing" will be set to false in the "UploadCompleted" callback from
327 * the TextureManagerUploadObserver.
328 * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size.
329 * If false, then the mask will be scaled to fit the image before being applied.
330 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
332 * This is called when an image load completes (or fails).
333 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
334 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
335 * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
336 * image has no alpha channel
337 * @return A TextureId to use as a handle to reference this Texture
339 TextureId RequestLoad(const VisualUrl& url,
340 TextureId maskTextureId,
342 const ImageDimensions desiredSize,
343 FittingMode::Type fittingMode,
344 Dali::SamplingMode::Type samplingMode,
345 const UseAtlas useAtlasing,
347 TextureUploadObserver* observer,
348 bool orientationCorrection,
349 TextureManager::ReloadPolicy reloadPolicy,
350 MultiplyOnLoad& preMultiplyOnLoad);
353 * Requests a masking image to be loaded. This mask is not uploaded to GL,
354 * instead, it is stored in CPU memory, and can be used for CPU blending.
356 TextureId RequestMaskLoad(const VisualUrl& maskUrl);
359 * @brief Remove a Texture from the TextureManager.
361 * Textures are cached and therefore only the removal of the last
362 * occurrence of a Texture will cause its removal internally.
364 * @param[in] textureId The ID of the Texture to remove.
365 * @param[in] textureObserver The texture observer.
367 void Remove(const TextureManager::TextureId textureId, TextureUploadObserver* textureObserver);
370 * @brief Get the visualUrl associated with the texture id.
371 * @param[in] textureId The texture Id to get
372 * @return The visual Url associated with the texture id.
374 VisualUrl GetVisualUrl(TextureId textureId);
377 * @brief Get the current state of a texture
378 * @param[in] textureId The texture id to query
379 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
382 LoadState GetTextureState(TextureId textureId);
385 * @brief Get the associated texture set if the texture id is valid
386 * @param[in] textureId The texture Id to look up
387 * @return the associated texture set, or an empty handle if textureId is not valid
389 TextureSet GetTextureSet(TextureId textureId);
392 * Adds an external texture to the texture manager
393 * @param[in] texture The texture to add
394 * @return string containing the URL for the texture
396 std::string AddExternalTexture(TextureSet& texture);
399 * Removes an external texture from texture manager
400 * @param[in] url The string containing the texture to remove
401 * @return handle to the texture
403 TextureSet RemoveExternalTexture(const std::string& url);
406 * @brief Notify that external textures are used.
407 * @param[in] url The URL of the texture to use.
409 void UseExternalTexture(const VisualUrl& url);
412 * Add an observer to the object.
413 * @param[in] observer The observer to add.
415 void AddObserver(TextureManager::LifecycleObserver& observer);
418 * Remove an observer from the object
419 * @pre The observer has already been added.
420 * @param[in] observer The observer to remove.
422 void RemoveObserver(TextureManager::LifecycleObserver& observer);
425 * @brief Returns the geometry associated with texture.
426 * @param[in] textureId Id of the texture
427 * @param[out] frontElements number of front elements
428 * @param[out] backElements number of back elements
429 * @return Returns valid geometry object
431 Geometry GetRenderGeometry(TextureId textureId, uint32_t& frontElements, uint32_t& backElements);
435 * @brief Requests an image load of the given URL, when the texture has
436 * have loaded, if there is a valid maskTextureId, it will perform a
437 * CPU blend with the mask, and upload the blend texture.
439 * The parameters are used to specify how the image is loaded.
440 * The observer has the UploadComplete method called when the load is ready.
442 * When the client has finished with the Texture, Remove() should be called.
444 * @param[in] url The URL of the image to load
445 * @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set
446 * to INVALID_TEXTURE_ID
447 * @param[in] contentScale The scaling factor to apply to the content when masking
448 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
449 * @param[in] fittingMode The FittingMode to use
450 * @param[in] samplingMode The SamplingMode to use
451 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be
452 * loaded, and marked successful, but "useAtlasing" will be set to false in the
453 * "UploadCompleted" callback from the TextureManagerUploadObserver.
454 * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before
456 * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
457 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
459 * This is called when an image load completes (or fails).
460 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
461 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
462 * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if
464 * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image
465 * @param[in] frameIndex The frame index of a frame to be loaded frame
466 * @return A TextureId to use as a handle to reference this Texture
468 TextureId RequestLoadInternal(
469 const VisualUrl& url,
470 TextureId maskTextureId,
472 const ImageDimensions desiredSize,
473 FittingMode::Type fittingMode,
474 Dali::SamplingMode::Type samplingMode,
477 StorageType storageType,
478 TextureUploadObserver* observer,
479 bool orientationCorrection,
480 TextureManager::ReloadPolicy reloadPolicy,
481 MultiplyOnLoad& preMultiplyOnLoad,
482 Dali::AnimatedImageLoading animatedImageLoading,
483 uint32_t frameIndex);
486 * @brief Get the current state of a texture
487 * @param[in] textureId The texture id to query
488 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
491 LoadState GetTextureStateInternal(TextureId textureId);
493 typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
498 * @brief This struct is used to manage the life-cycle of Texture loading and caching.
502 TextureInfo(TextureId textureId,
503 TextureId maskTextureId,
504 const VisualUrl& url,
505 ImageDimensions desiredSize,
507 FittingMode::Type fittingMode,
508 Dali::SamplingMode::Type samplingMode,
509 bool loadSynchronously,
512 TextureManager::TextureHash hash,
513 bool orientationCorrection,
514 bool preMultiplyOnLoad,
515 Dali::AnimatedImageLoading animatedImageLoading,
518 desiredSize(desiredSize),
519 useSize(desiredSize),
520 atlasRect(0.0f, 0.0f, 1.0f, 1.0f), // Full atlas rectangle
521 textureId(textureId),
522 maskTextureId(maskTextureId),
524 scaleFactor(scaleFactor),
526 loadState(LoadState::NOT_STARTED),
527 fittingMode(fittingMode),
528 samplingMode(samplingMode),
529 storageType(StorageType::UPLOAD_TO_TEXTURE),
530 animatedImageLoading(animatedImageLoading),
531 frameIndex(frameIndex),
532 loadSynchronously(loadSynchronously),
534 cropToMask(cropToMask),
535 orientationCorrection(true),
536 preMultiplyOnLoad(preMultiplyOnLoad),
542 * Container type used to store all observer clients of this Texture
544 typedef Dali::Vector<TextureUploadObserver*> ObserverListType;
546 ObserverListType observerList; ///< Container used to store all observer clients of this Texture
547 Toolkit::ImageAtlas atlas; ///< The atlas this Texture lays within (if any)
548 Devel::PixelBuffer pixelBuffer; ///< The PixelBuffer holding the image data (May be empty after upload)
549 TextureSet textureSet; ///< The TextureSet holding the Texture
550 VisualUrl url; ///< The URL of the image
551 ImageDimensions desiredSize; ///< The size requested
552 ImageDimensions useSize; ///< The size used
553 Vector4 atlasRect; ///< The atlas rect used if atlased
554 TextureId textureId; ///< The TextureId associated with this Texture
555 TextureId maskTextureId; ///< The mask TextureId to be applied on load
556 TextureManager::TextureHash hash; ///< The hash used to cache this Texture
557 float scaleFactor; ///< The scale factor to apply to the Texture when masking
558 int16_t referenceCount; ///< The reference count of clients using this Texture
559 LoadState loadState; ///< The load state showing the load progress of the Texture
560 FittingMode::Type fittingMode : 3; ///< The requested FittingMode
561 Dali::SamplingMode::Type samplingMode : 3; ///< The requested SamplingMode
562 StorageType storageType; ///< CPU storage / GPU upload;
563 Dali::AnimatedImageLoading animatedImageLoading; ///< AnimatedImageLoading that contains animated image information.
564 uint32_t frameIndex; ///< frame index that be loaded, in case of animated image
565 bool loadSynchronously : 1; ///< True if synchronous loading was requested
566 UseAtlas useAtlas : 2; ///< USE_ATLAS if an atlas was requested.
567 ///< This is updated to false if atlas is not used
568 bool cropToMask : 1; ///< true if the image should be cropped to the mask size.
569 bool orientationCorrection : 1; ///< true if the image should be rotated to match exif orientation data
570 bool preMultiplyOnLoad : 1; ///< true if the image's color should be multiplied by it's alpha
571 bool preMultiplied : 1; ///< true if the image's color was multiplied by it's alpha
575 * Structure to hold info about a texture load queued during NotifyObservers
577 struct LoadQueueElement
579 LoadQueueElement(TextureId textureId, TextureUploadObserver* observer)
580 : mTextureId(textureId),
585 TextureId mTextureId; ///< The texture id of the requested load.
586 TextureUploadObserver* mObserver; ///< Observer of texture load.
590 * Struct to hold information about a requested Async load.
591 * This is used to look up a TextureManager::TextureId from the returned AsyncLoad Id.
593 struct AsyncLoadingInfo
595 AsyncLoadingInfo(TextureId textureId)
596 : textureId(textureId),
601 TextureId textureId; ///< The external Texture Id assigned to this load
602 uint32_t loadId; ///< The load Id used by the async loader to reference this load
607 typedef std::deque<AsyncLoadingInfo> AsyncLoadingInfoContainerType; ///< The container type used to manage Asynchronous loads in progress
608 typedef std::vector<TextureInfo> TextureInfoContainerType; ///< The container type used to manage the life-cycle and caching of Textures
611 * @brief Initiate a load or queue load if NotifyObservers is invoking callbacks
612 * @param[in] textureInfo The TextureInfo struct associated with the Texture
613 * @param[in] observer The observer wishing to observe the texture upload
615 void LoadOrQueueTexture(TextureInfo& textureInfo, TextureUploadObserver* observer);
618 * @brief Queue a texture load to be subsequently handled by ProcessQueuedTextures.
619 * @param[in] textureInfo The TextureInfo struct associated with the Texture
620 * @param[in] observer The observer wishing to observe the texture upload
622 void QueueLoadTexture(TextureInfo& textureInfo, TextureUploadObserver* observer);
625 * @brief Used internally to initiate a load.
626 * @param[in] textureInfo The TextureInfo struct associated with the Texture
627 * @param[in] observer The observer wishing to observe the texture upload
629 void LoadTexture(TextureInfo& textureInfo, TextureUploadObserver* observer);
632 * @brief Initiate load of textures queued whilst NotifyObservers invoking callbacks.
634 void ProcessQueuedTextures();
637 * Add the observer to the observer list
638 * @param[in] textureInfo The TextureInfo struct associated with the texture
639 * @param[in] observer The observer wishing to observe the texture upload
641 void ObserveTexture(TextureInfo& textureInfo, TextureUploadObserver* observer);
644 * @brief This signal handler is called when the async local loader finishes loading.
645 * @param[in] id This is the async image loaders Id
646 * @param[in] pixelBuffer The loaded image data
648 void AsyncLocalLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
651 * @brief This signal handler is called when the async local loader finishes loading.
652 * @param[in] id This is the async image loaders Id
653 * @param[in] pixelBuffer The loaded image data
655 void AsyncRemoteLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
658 * Common method to handle loading completion
659 * @param[in] container The Async loading container
660 * @param[in] id This is the async image loaders Id
661 * @param[in] pixelBuffer The loaded image data
663 void AsyncLoadComplete(AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer);
666 * @brief Performs Post-Load steps including atlasing.
667 * @param[in] textureInfo The struct associated with this Texture
668 * @param[in] pixelBuffer The image pixelBuffer
669 * @return True if successful
671 void PostLoad(TextureManager::TextureInfo& textureInfo, Devel::PixelBuffer& pixelBuffer);
674 * Check if there is a texture waiting to be masked. If there
675 * is then apply this mask and upload it.
676 * @param[in] maskTextureInfo The texture info of the mask that has just loaded.
678 void CheckForWaitingTexture(TextureInfo& maskTextureInfo);
681 * Apply the mask to the pixelBuffer.
682 * @param[in] textureInfo The information of texture to apply the mask to
683 * @param[in] maskTextureId The texture id of the mask.
685 void ApplyMask(TextureInfo& textureInfo, TextureId maskTextureId);
688 * Upload the texture specified in pixelBuffer to the appropriate location
689 * @param[in] pixelBuffer The image data to upload
690 * @param[in] textureInfo The texture info containing the location to
693 void UploadTexture(Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo);
696 * Creates tiled geometry of for the texture which separates fully-opaque
697 * tiles from ones which use transparency.
701 bool CreateTiledGeometry(const Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo);
704 * Mark the texture as complete, and inform observers
705 * @param[in] textureInfo The struct associated with this Texture
707 void UploadComplete(TextureInfo& textureInfo);
710 * Notify the current observers that the texture upload is complete,
711 * then remove the observers from the list.
712 * @param[in] textureInfo The struct associated with this Texture
713 * @param[in] success If the pixel data was retrieved successfully and uploaded to GPU
715 void NotifyObservers(TextureInfo& textureInfo, bool success);
718 * @brief Generates a new, unique TextureId
719 * @return A unique TextureId
721 TextureManager::TextureId GenerateUniqueTextureId();
724 * @brief Used to lookup an index into the TextureInfoContainer from a TextureId
725 * @param[in] textureId The TextureId to look up
726 * @return The cache index
728 int GetCacheIndexFromId(TextureId textureId);
731 * @brief Generates a hash for caching based on the input parameters.
732 * Only applies size, fitting mode andsampling mode if the size is specified.
733 * Only applies maskTextureId if it isn't INVALID_TEXTURE_ID
734 * Always applies useAtlas.
735 * @param[in] url The URL of the image to load
736 * @param[in] size The image size
737 * @param[in] fittingMode The FittingMode to use
738 * @param[in] samplingMode The SamplingMode to use
739 * @param[in] useAtlas True if atlased
740 * @param[in] maskTextureId The masking texture id (or INVALID_TEXTURE_ID)
741 * @return A hash of the provided data for caching.
743 TextureHash GenerateHash(const std::string& url, const ImageDimensions size, const FittingMode::Type fittingMode, const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas, TextureId maskTextureId);
746 * @brief Looks up a cached texture by its hash.
747 * If found, the given parameters are used to check there is no hash-collision.
748 * @param[in] hash The hash to look up
749 * @param[in] url The URL of the image to load
750 * @param[in] size The image size
751 * @param[in] fittingMode The FittingMode to use
752 * @param[in] samplingMode The SamplingMode to use
753 * @param[in] useAtlas True if atlased
754 * @param[in] maskTextureId Optional texture ID to use to mask this image
755 * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
756 * @return A TextureId of a cached Texture if found. Or INVALID_TEXTURE_ID if not found.
758 TextureManager::TextureId FindCachedTexture(
759 const TextureManager::TextureHash hash,
760 const std::string& url,
761 const ImageDimensions size,
762 const FittingMode::Type fittingMode,
763 const Dali::SamplingMode::Type samplingMode,
765 TextureId maskTextureId,
766 MultiplyOnLoad preMultiplyOnLoad);
770 * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container
772 class AsyncLoadingHelper : public ConnectionTracker
776 * @brief Create an AsyncLoadingHelper.
777 * @param[in] textureManager Reference to the texture manager
779 AsyncLoadingHelper(TextureManager& textureManager);
782 * @brief Load a new frame of animated image
783 * @param[in] textureId TextureId to reference the texture that will be loaded
784 * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image
785 * @param[in] frameIndex The frame index of a frame to be loaded frame
787 void LoadAnimatedImage(TextureId textureId,
788 Dali::AnimatedImageLoading animatedImageLoading,
789 uint32_t frameIndex);
792 * @brief Load a new texture.
793 * @param[in] textureId TextureId to reference the texture that will be loaded
794 * @param[in] url The URL of the image to load
795 * @param[in] desiredSize The size the image is likely to appear at.
796 * This can be set to 0,0 for automatic
797 * @param[in] fittingMode The FittingMode to use
798 * @param[in] samplingMode The SamplingMode to use
799 * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
800 * e.g., from portrait to landscape
801 * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha or if the image need to be applied alpha mask.
803 void Load(TextureId textureId,
804 const VisualUrl& url,
805 ImageDimensions desiredSize,
806 FittingMode::Type fittingMode,
807 SamplingMode::Type samplingMode,
808 bool orientationCorrection,
809 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
813 * @param [in] id of the texture
814 * @param [in] pixelBuffer of the to be masked image
815 * @param [in] maskPixelBuffer of the mask image
816 * @param [in] contentScale The factor to scale the content
817 * @param [in] cropToMask Whether to crop the content to the mask size
818 * @param [in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
820 void ApplyMask(TextureId textureId,
821 Devel::PixelBuffer pixelBuffer,
822 Devel::PixelBuffer maskPixelBuffer,
825 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
828 AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
829 AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete;
831 AsyncLoadingHelper(AsyncLoadingHelper&& rhs);
832 AsyncLoadingHelper& operator=(AsyncLoadingHelper&& rhs) = delete;
836 * @brief Main constructor that used by all other constructors
838 AsyncLoadingHelper(Toolkit::AsyncImageLoader loader,
839 TextureManager& textureManager,
840 AsyncLoadingInfoContainerType&& loadingInfoContainer);
843 * @brief Callback to be called when texture loading is complete, it passes the pixel buffer on to texture manager.
844 * @param[in] id Loader id
845 * @param[in] pixelBuffer Image data
847 void AsyncLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
850 Toolkit::AsyncImageLoader mLoader;
851 TextureManager& mTextureManager;
852 AsyncLoadingInfoContainerType mLoadingInfoContainer;
855 struct ExternalTextureInfo
858 TextureSet textureSet;
859 int16_t referenceCount{1};
864 * Deleted copy constructor.
866 TextureManager(const TextureManager&) = delete;
869 * Deleted assignment operator.
871 TextureManager& operator=(const TextureManager& rhs) = delete;
874 * This is called by the TextureManagerUploadObserver when an observer is destroyed.
875 * We use the callback to know when to remove an observer from our notify list.
876 * @param[in] observer The observer that generated the callback
878 void ObserverDestroyed(TextureUploadObserver* observer);
880 private: // Member Variables:
881 TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
882 RoundRobinContainerView<AsyncLoadingHelper> mAsyncLocalLoaders; ///< The Asynchronous image loaders used to provide all local async loads
883 RoundRobinContainerView<AsyncLoadingHelper> mAsyncRemoteLoaders; ///< The Asynchronous image loaders used to provide all remote async loads
884 std::vector<ExternalTextureInfo> mExternalTextures; ///< Externally provided textures
885 Dali::Vector<LifecycleObserver*> mLifecycleObservers; ///< Lifecycle observers of texture manager
886 Dali::Vector<LoadQueueElement> mLoadQueue; ///< Queue of textures to load after NotifyObservers
887 TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
888 bool mQueueLoadFlag; ///< Flag that causes Load Textures to be queued.
891 } // namespace Internal
893 } // namespace Toolkit
897 #endif // DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H