1 #ifndef DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
2 #define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
5 * Copyright (c) 2020 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.
25 #include <dali/public-api/common/dali-vector.h>
26 #include <dali/public-api/object/ref-object.h>
27 #include <dali/public-api/rendering/texture-set.h>
28 #include <dali/devel-api/common/owner-container.h>
29 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
32 #include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
33 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
34 #include <dali-toolkit/public-api/image-loader/async-image-loader.h>
35 #include <dali-toolkit/internal/visuals/texture-upload-observer.h>
36 #include <dali-toolkit/internal/visuals/visual-url.h>
37 #include <dali-toolkit/internal/helpers/round-robin-container-view.h>
38 #include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
49 class ImageAtlasManager;
50 typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
53 * The TextureManager provides a common Image loading API for Visuals.
55 * The TextureManager is responsible for providing sync, async, atlased and non-atlased loads.
56 * Texture caching is provided and performed when possible.
57 * Broken Images are automatically provided on load failure.
59 class TextureManager : public ConnectionTracker
63 typedef int32_t TextureId; ///< The TextureId type. This is used as a handle to refer to a particular Texture.
64 static const int INVALID_TEXTURE_ID = -1; ///< Used to represent a null TextureId or error
67 * Whether the texture should be atlased or uploaded into it's own GPU texture
76 * Whether the pixel data should be kept in TextureManager, returned with pixelBuffer or uploaded for rendering
86 * Whether the texture should be loaded synchronously or asynchronously.
95 * @brief The LoadState Enumeration represents the current state of a particular Texture's life-cycle.
99 NOT_STARTED, ///< Default
100 LOADING, ///< Loading has been started, but not finished.
101 LOAD_FINISHED, ///< Loading has finished. (for CPU storage only)
102 WAITING_FOR_MASK,///< Loading has finished, but waiting for mask image
103 MASK_APPLYING, ///< Loading has finished, Mask is applying
104 MASK_APPLIED, ///< Loading has finished, Mask is applyied by GPU
105 UPLOADED, ///< Uploaded and ready. (For GPU upload only)
106 CANCELLED, ///< Removed before loading completed
107 LOAD_FAILED ///< Async loading failed, e.g. connection problem
111 * @brief Types of reloading policies
113 enum class ReloadPolicy
115 CACHED = 0, ///< Loads cached texture if it exists.
116 FORCED ///< Forces reloading of texture.
120 * @brief Whether to multiply alpha into color channels on load
122 enum class MultiplyOnLoad
124 LOAD_WITHOUT_MULTIPLY = 0, ///< Don't modify the image
125 MULTIPLY_ON_LOAD ///< Multiply alpha into color channels on load
133 ~MaskingData() = default;
135 VisualUrl mAlphaMaskUrl;
136 TextureManager::TextureId mAlphaMaskId;
137 float mContentScaleFactor;
140 using MaskingDataPointer = std::unique_ptr<MaskingData>;
144 * Class to provide lifecycle event on destruction of texture manager.
146 struct LifecycleObserver
149 * Called shortly before the texture manager is destroyed.
151 virtual void TextureManagerDestroyed() = 0;
164 // TextureManager Main API:
167 * @brief Requests an frame of animated image load.
169 * The parameters are used to specify how the animated image is loaded.
170 * The observer has the LoadComplete method called when the load is ready.
172 * @param[in] animatedImageLoading The AnimatedImageLoading that contain the animated image information
173 * @param[in] frameIndex The frame index to load.
174 * @param[in] samplingMode The SamplingMode to use
175 * @param[in] synchronousLoading true if the frame should be loaded synchronously
176 * @param[out] textureId The textureId of the frame
177 * @param[in] wrapModeU Horizontal Wrap mode
178 * @param[in] wrapModeV Vertical Wrap mode
179 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
180 * This is called when an image load completes (or fails).
182 * @return The texture set containing the frame of animated image, or empty if still loading.
185 TextureSet LoadAnimatedImageTexture( Dali::AnimatedImageLoading animatedImageLoading,
187 Dali::SamplingMode::Type samplingMode,
188 bool synchronousLoading,
189 TextureManager::TextureId& textureId,
190 Dali::WrapMode::Type wrapModeU, Dali::WrapMode::Type wrapModeV,
191 TextureUploadObserver* textureObserver );
194 * @brief Requests an image load of the given URL to get PixelBuffer.
196 * The parameters are used to specify how the image is loaded.
197 * The observer has the LoadComplete method called when the load is ready.
199 * @param[in] url The URL of the image to load
200 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
201 * @param[in] fittingMode The FittingMode to use
202 * @param[in] samplingMode The SamplingMode to use
203 * @param[in] synchronousLoading true if the URL should be loaded synchronously
204 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
205 * This is called when an image load completes (or fails).
206 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
207 * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
208 * image has no alpha channel
210 * @return The pixel buffer containing the image, or empty if still loading.
213 Devel::PixelBuffer LoadPixelBuffer( const VisualUrl& url,
214 Dali::ImageDimensions desiredSize,
215 Dali::FittingMode::Type fittingMode,
216 Dali::SamplingMode::Type samplingMode,
217 bool synchronousLoading,
218 TextureUploadObserver* textureObserver,
219 bool orientationCorrection,
220 TextureManager::MultiplyOnLoad& preMultiplyOnLoad );
224 * @brief Requests an image load of the given URL.
226 * The parameters are used to specify how the image is loaded.
227 * The observer has the UploadComplete method called when the load is ready.
229 * When the client has finished with the Texture, Remove() should be called.
231 * @param[in] url The URL of the image to load
232 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
233 * @param[in] fittingMode The FittingMode to use
234 * @param[in] samplingMode The SamplingMode to use
235 * @param[in, out] maskInfo Mask info structure
236 * @param[in] synchronousLoading true if the URL should be loaded synchronously
237 * @param[out] textureId, The textureId of the URL
238 * @param[out] textureRect The rectangle within the texture atlas that this URL occupies,
239 * this is the rectangle in normalized coordinates.
240 * @param[out] textureRectSize The rectangle within the texture atlas that this URL occupies,
241 * this is the same rectangle in pixels.
242 * @param[in,out] atlasingStatus Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
243 * be loaded, and marked successful, but this will be set to false.
244 * If atlasing succeeds, this will be set to true.
245 * @param[out] loadingStatus The loading status of the texture
246 * @param[in] wrapModeU Horizontal Wrap mode
247 * @param[in] wrapModeV Vertical Wrap mode
248 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
249 * This is called when an image load completes (or fails).
250 * @param[in] atlasObserver This is used if the texture is atlased, and will be called instead of
251 * textureObserver.UploadCompleted
252 * @param[in] imageAtlasManager The atlas manager to use for atlasing textures
253 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
254 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
255 * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
256 * image has no alpha channel
258 * @return The texture set containing the image, or empty if still loading.
261 TextureSet LoadTexture( const VisualUrl& url,
262 Dali::ImageDimensions desiredSize,
263 Dali::FittingMode::Type fittingMode,
264 Dali::SamplingMode::Type samplingMode,
265 MaskingDataPointer& maskInfo,
266 bool synchronousLoading,
267 TextureManager::TextureId& textureId,
268 Vector4& textureRect,
269 Dali::ImageDimensions& textureRectSize,
270 bool& atlasingStatus,
272 Dali::WrapMode::Type wrapModeU,
273 Dali::WrapMode::Type wrapModeV,
274 TextureUploadObserver* textureObserver,
275 AtlasUploadObserver* atlasObserver,
276 ImageAtlasManagerPtr imageAtlasManager,
277 bool orientationCorrection,
278 TextureManager::ReloadPolicy reloadPolicy,
279 MultiplyOnLoad& preMultiplyOnLoad );
282 * @brief Requests an image load of the given URL.
284 * The parameters are used to specify how the image is loaded.
285 * The observer has the UploadComplete method called when the load is ready.
287 * When the client has finished with the Texture, Remove() should be called.
289 * @param[in] url The URL of the image to load
290 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
291 * @param[in] fittingMode The FittingMode to use
292 * @param[in] samplingMode The SamplingMode to use
293 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
294 * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
295 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
296 * This is called when an image load completes (or fails).
297 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
298 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
299 * @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
300 * @return A TextureId to use as a handle to reference this Texture
302 TextureId RequestLoad( const VisualUrl& url,
303 const ImageDimensions desiredSize,
304 FittingMode::Type fittingMode,
305 Dali::SamplingMode::Type samplingMode,
306 const UseAtlas useAtlasing,
307 TextureUploadObserver* observer,
308 bool orientationCorrection,
309 TextureManager::ReloadPolicy reloadPolicy,
310 MultiplyOnLoad& preMultiplyOnLoad );
313 * @brief Requests an image load of the given URL, when the texture has
314 * have loaded, it will perform a blend with the image mask, and upload
315 * the blended texture.
317 * The parameters are used to specify how the image is loaded.
318 * The observer has the UploadComplete method called when the load is ready.
320 * When the client has finished with the Texture, Remove() should be called.
322 * @param[in] url The URL of the image to load
323 * @param[in] maskTextureId The texture id of an image to mask this with
324 * (can be INVALID if no masking required)
325 * @param[in] contentScale The scale factor to apply to the image before masking
326 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
327 * @param[in] fittingMode The FittingMode to use
328 * @param[in] samplingMode The SamplingMode to use
329 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
330 * be loaded, and marked successful,
331 * but "useAtlasing" will be set to false in the "UploadCompleted" callback from
332 * the TextureManagerUploadObserver.
333 * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size.
334 * If false, then the mask will be scaled to fit the image before being applied.
335 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
337 * This is called when an image load completes (or fails).
338 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
339 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
340 * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
341 * image has no alpha channel
342 * @return A TextureId to use as a handle to reference this Texture
344 TextureId RequestLoad( const VisualUrl& url,
345 TextureId maskTextureId,
347 const ImageDimensions desiredSize,
348 FittingMode::Type fittingMode,
349 Dali::SamplingMode::Type samplingMode,
350 const UseAtlas useAtlasing,
352 TextureUploadObserver* observer,
353 bool orientationCorrection,
354 TextureManager::ReloadPolicy reloadPolicy,
355 MultiplyOnLoad& preMultiplyOnLoad );
358 * Requests a masking image to be loaded. This mask is not uploaded to GL,
359 * instead, it is stored in CPU memory, and can be used for CPU blending.
361 TextureId RequestMaskLoad( const VisualUrl& maskUrl );
364 * @brief Remove a Texture from the TextureManager.
366 * Textures are cached and therefore only the removal of the last
367 * occurrence of a Texture will cause its removal internally.
369 * @param[in] textureId The ID of the Texture to remove.
370 * @param[in] textureObserver The texture observer.
372 void Remove( const TextureManager::TextureId textureId, TextureUploadObserver* textureObserver );
375 * @brief Get the visualUrl associated with the texture id.
376 * @param[in] textureId The texture Id to get
377 * @return The visual Url associated with the texture id.
379 VisualUrl GetVisualUrl( TextureId textureId );
382 * @brief Get the current state of a texture
383 * @param[in] textureId The texture id to query
384 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
387 LoadState GetTextureState( TextureId textureId );
390 * @brief Get the associated texture set if the texture id is valid
391 * @param[in] textureId The texture Id to look up
392 * @return the associated texture set, or an empty handle if textureId is not valid
394 TextureSet GetTextureSet( TextureId textureId );
397 * Adds an external texture to the texture manager
398 * @param[in] texture The texture to add
399 * @return string containing the URL for the texture
401 std::string AddExternalTexture( TextureSet& texture );
404 * Removes an external texture from texture manager
405 * @param[in] url The string containing the texture to remove
406 * @return handle to the texture
408 TextureSet RemoveExternalTexture( const std::string& url );
411 * Add an observer to the object.
412 * @param[in] observer The observer to add.
414 void AddObserver( TextureManager::LifecycleObserver& observer );
417 * Remove an observer from the object
418 * @pre The observer has already been added.
419 * @param[in] observer The observer to remove.
421 void RemoveObserver( TextureManager::LifecycleObserver& observer );
424 * @brief Set an image to be used when a visual has failed to correctly render
425 * @param[in] brokenImageUrl The broken image url.
427 void SetBrokenImageUrl(const std::string& brokenImageUrl);
432 * @brief Requests an image load of the given URL, when the texture has
433 * have loaded, if there is a valid maskTextureId, it will perform a
434 * CPU blend with the mask, and upload the blend texture.
436 * The parameters are used to specify how the image is loaded.
437 * The observer has the UploadComplete method called when the load is ready.
439 * When the client has finished with the Texture, Remove() should be called.
441 * @param[in] url The URL of the image to load
442 * @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set
443 * to INVALID_TEXTURE_ID
444 * @param[in] contentScale The scaling factor to apply to the content when masking
445 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
446 * @param[in] fittingMode The FittingMode to use
447 * @param[in] samplingMode The SamplingMode to use
448 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be
449 * loaded, and marked successful, but "useAtlasing" will be set to false in the
450 * "UploadCompleted" callback from the TextureManagerUploadObserver.
451 * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before
453 * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
454 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
456 * This is called when an image load completes (or fails).
457 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
458 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
459 * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if
461 * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image
462 * @param[in] frameIndex The frame index of a frame to be loaded frame
463 * @return A TextureId to use as a handle to reference this Texture
465 TextureId RequestLoadInternal(
466 const VisualUrl& url,
467 TextureId maskTextureId,
469 const ImageDimensions desiredSize,
470 FittingMode::Type fittingMode,
471 Dali::SamplingMode::Type samplingMode,
474 StorageType storageType,
475 TextureUploadObserver* observer,
476 bool orientationCorrection,
477 TextureManager::ReloadPolicy reloadPolicy,
478 MultiplyOnLoad& preMultiplyOnLoad,
479 Dali::AnimatedImageLoading animatedImageLoading,
480 uint32_t frameIndex );
483 * @brief Get the current state of a texture
484 * @param[in] textureId The texture id to query
485 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
488 LoadState GetTextureStateInternal( TextureId textureId );
490 typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
495 * @brief This struct is used to manage the life-cycle of Texture loading and caching.
499 TextureInfo( TextureId textureId,
500 TextureId maskTextureId,
501 const VisualUrl& url,
502 ImageDimensions desiredSize,
504 FittingMode::Type fittingMode,
505 Dali::SamplingMode::Type samplingMode,
506 bool loadSynchronously,
509 TextureManager::TextureHash hash,
510 bool orientationCorrection,
511 bool preMultiplyOnLoad,
512 Dali::AnimatedImageLoading animatedImageLoading,
513 uint32_t frameIndex )
515 desiredSize( desiredSize ),
516 useSize( desiredSize ),
517 atlasRect( 0.0f, 0.0f, 1.0f, 1.0f ), // Full atlas rectangle
518 textureId( textureId ),
519 maskTextureId( maskTextureId ),
521 scaleFactor( scaleFactor ),
522 referenceCount( 1u ),
523 loadState( NOT_STARTED ),
524 fittingMode( fittingMode ),
525 samplingMode( samplingMode ),
526 storageType( UPLOAD_TO_TEXTURE ),
527 animatedImageLoading( animatedImageLoading ),
528 frameIndex( frameIndex ),
529 loadSynchronously( loadSynchronously ),
530 useAtlas( useAtlas ),
531 cropToMask( cropToMask ),
532 orientationCorrection( true ),
533 preMultiplyOnLoad( preMultiplyOnLoad ),
534 preMultiplied( false )
539 * Container type used to store all observer clients of this Texture
541 typedef Dali::Vector< TextureUploadObserver* > ObserverListType;
543 ObserverListType observerList; ///< Container used to store all observer clients of this Texture
544 Toolkit::ImageAtlas atlas; ///< The atlas this Texture lays within (if any)
545 Devel::PixelBuffer pixelBuffer;///< The PixelBuffer holding the image data (May be empty after upload)
546 TextureSet textureSet; ///< The TextureSet holding the Texture
547 VisualUrl url; ///< The URL of the image
548 ImageDimensions desiredSize; ///< The size requested
549 ImageDimensions useSize; ///< The size used
550 Vector4 atlasRect; ///< The atlas rect used if atlased
551 TextureId textureId; ///< The TextureId associated with this Texture
552 TextureId maskTextureId; ///< The mask TextureId to be applied on load
553 TextureManager::TextureHash hash; ///< The hash used to cache this Texture
554 float scaleFactor; ///< The scale factor to apply to the Texture when masking
555 int16_t referenceCount; ///< The reference count of clients using this Texture
556 LoadState loadState:4; ///< The load state showing the load progress of the Texture
557 FittingMode::Type fittingMode:3; ///< The requested FittingMode
558 Dali::SamplingMode::Type samplingMode:3; ///< The requested SamplingMode
559 StorageType storageType:2; ///< CPU storage / GPU upload;
560 Dali::AnimatedImageLoading animatedImageLoading; ///< AnimatedImageLoading that contains animated image information.
561 uint32_t frameIndex; ///< frame index that be loaded, in case of animated image
562 bool loadSynchronously:1; ///< True if synchronous loading was requested
563 UseAtlas useAtlas:2; ///< USE_ATLAS if an atlas was requested.
564 ///< This is updated to false if atlas is not used
565 bool cropToMask:1; ///< true if the image should be cropped to the mask size.
566 bool orientationCorrection:1; ///< true if the image should be rotated to match exif orientation data
567 bool preMultiplyOnLoad:1; ///< true if the image's color should be multiplied by it's alpha
568 bool preMultiplied:1; ///< true if the image's color was multiplied by it's alpha
572 * Structure to hold info about a texture load queued during NotifyObservers
574 struct LoadQueueElement
576 LoadQueueElement( TextureId textureId, TextureUploadObserver* observer )
577 : mTextureId( textureId ),
578 mObserver( observer )
582 TextureId mTextureId; ///< The texture id of the requested load.
583 TextureUploadObserver* mObserver; ///< Observer of texture load.
587 * Struct to hold information about a requested Async load.
588 * This is used to look up a TextureManager::TextureId from the returned AsyncLoad Id.
590 struct AsyncLoadingInfo
592 AsyncLoadingInfo( TextureId textureId )
593 : textureId( textureId ),
598 TextureId textureId; ///< The external Texture Id assigned to this load
599 uint32_t loadId; ///< The load Id used by the async loader to reference this load
604 typedef std::deque<AsyncLoadingInfo> AsyncLoadingInfoContainerType; ///< The container type used to manage Asynchronous loads in progress
605 typedef std::vector<TextureInfo> TextureInfoContainerType; ///< The container type used to manage the life-cycle and caching of Textures
608 * @brief Initiate a load or queue load if NotifyObservers is invoking callbacks
609 * @param[in] textureInfo The TextureInfo struct associated with the Texture
610 * @param[in] observer The observer wishing to observe the texture upload
612 void LoadOrQueueTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
615 * @brief Queue a texture load to be subsequently handled by ProcessQueuedTextures.
616 * @param[in] textureInfo The TextureInfo struct associated with the Texture
617 * @param[in] observer The observer wishing to observe the texture upload
619 void QueueLoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
622 * @brief Used internally to initiate a load.
623 * @param[in] textureInfo The TextureInfo struct associated with the Texture
624 * @param[in] observer The observer wishing to observe the texture upload
626 void LoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
629 * @brief Initiate load of textures queued whilst NotifyObservers invoking callbacks.
631 void ProcessQueuedTextures();
634 * Add the observer to the observer list
635 * @param[in] textureInfo The TextureInfo struct associated with the texture
636 * @param[in] observer The observer wishing to observe the texture upload
638 void ObserveTexture( TextureInfo & textureInfo, TextureUploadObserver* observer );
641 * @brief This signal handler is called when the async local loader finishes loading.
642 * @param[in] id This is the async image loaders Id
643 * @param[in] pixelBuffer The loaded image data
645 void AsyncLocalLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer );
648 * @brief This signal handler is called when the async local loader finishes loading.
649 * @param[in] id This is the async image loaders Id
650 * @param[in] pixelBuffer The loaded image data
652 void AsyncRemoteLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer );
655 * Common method to handle loading completion
656 * @param[in] container The Async loading container
657 * @param[in] id This is the async image loaders Id
658 * @param[in] pixelBuffer The loaded image data
660 void AsyncLoadComplete( AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer );
663 * @brief Performs Post-Load steps including atlasing.
664 * @param[in] textureInfo The struct associated with this Texture
665 * @param[in] pixelBuffer The image pixelBuffer
666 * @return True if successful
668 void PostLoad( TextureManager::TextureInfo& textureInfo, Devel::PixelBuffer& pixelBuffer );
671 * Check if there is a texture waiting to be masked. If there
672 * is then apply this mask and upload it.
673 * @param[in] maskTextureInfo The texture info of the mask that has just loaded.
675 void CheckForWaitingTexture( TextureInfo& maskTextureInfo );
678 * Apply the mask to the pixelBuffer.
679 * @param[in] textureInfo The information of texture to apply the mask to
680 * @param[in] maskTextureId The texture id of the mask.
682 void ApplyMask( TextureInfo& textureInfo, TextureId maskTextureId );
685 * Upload the texture specified in pixelBuffer to the appropriate location
686 * @param[in] pixelBuffer The image data to upload
687 * @param[in] textureInfo The texture info containing the location to
690 void UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo );
693 * Mark the texture as complete, and inform observers
694 * @param[in] textureInfo The struct associated with this Texture
696 void UploadComplete( TextureInfo& textureInfo );
699 * Notify the current observers that the texture upload is complete,
700 * then remove the observers from the list.
701 * @param[in] textureInfo The struct associated with this Texture
702 * @param[in] success If the pixel data was retrieved successfully and uploaded to GPU
704 void NotifyObservers( TextureInfo& textureInfo, bool success );
707 * @brief Generates a new, unique TextureId
708 * @return A unique TextureId
710 TextureManager::TextureId GenerateUniqueTextureId();
713 * @brief Used to lookup an index into the TextureInfoContainer from a TextureId
714 * @param[in] textureId The TextureId to look up
715 * @return The cache index
717 int GetCacheIndexFromId( TextureId textureId );
721 * @brief Generates a hash for caching based on the input parameters.
722 * Only applies size, fitting mode andsampling mode if the size is specified.
723 * Only applies maskTextureId if it isn't INVALID_TEXTURE_ID
724 * Always applies useAtlas.
725 * @param[in] url The URL of the image to load
726 * @param[in] size The image size
727 * @param[in] fittingMode The FittingMode to use
728 * @param[in] samplingMode The SamplingMode to use
729 * @param[in] useAtlas True if atlased
730 * @param[in] maskTextureId The masking texture id (or INVALID_TEXTURE_ID)
731 * @param[in] isAnimatedImage The boolean value to know whether the request is for animated image or not
732 * @param[in] frameIndex The frame index of a frame to be loaded frame
733 * @return A hash of the provided data for caching.
735 TextureHash GenerateHash( const std::string& url, const ImageDimensions size,
736 const FittingMode::Type fittingMode,
737 const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas,
738 TextureId maskTextureId, StorageType storageType, bool isAnimatedImage, uint32_t frameIndex );
741 * @brief Looks up a cached texture by its hash.
742 * If found, the given parameters are used to check there is no hash-collision.
743 * @param[in] hash The hash to look up
744 * @param[in] url The URL of the image to load
745 * @param[in] size The image size
746 * @param[in] fittingMode The FittingMode to use
747 * @param[in] samplingMode The SamplingMode to use
748 * @param[in] useAtlas True if atlased
749 * @param[in] maskTextureId Optional texture ID to use to mask this image
750 * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
751 * @param[in] storageType Whether the pixel data is stored in the cache, returned with PixelBuffer or uploaded to the GPU
752 * @param[in] isAnimatedImage The boolean value to know whether the request is for animated image or not
753 * @param[in] frameIndex The frame index of a frame to be loaded frame
754 * @return A TextureId of a cached Texture if found. Or INVALID_TEXTURE_ID if not found.
756 TextureManager::TextureId FindCachedTexture(
757 const TextureManager::TextureHash hash,
758 const std::string& url,
759 const ImageDimensions size,
760 const FittingMode::Type fittingMode,
761 const Dali::SamplingMode::Type samplingMode,
763 TextureId maskTextureId,
764 MultiplyOnLoad preMultiplyOnLoad,
765 StorageType storageType,
766 bool isAnimatedImage,
767 uint32_t frameIndex );
772 * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container
774 class AsyncLoadingHelper : public ConnectionTracker
778 * @brief Create an AsyncLoadingHelper.
779 * @param[in] textureManager Reference to the texture manager
781 AsyncLoadingHelper(TextureManager& textureManager);
784 * @brief Load a new frame of animated image
785 * @param[in] textureId TextureId to reference the texture that will be loaded
786 * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image
787 * @param[in] frameIndex The frame index of a frame to be loaded frame
789 void LoadAnimatedImage( TextureId textureId,
790 Dali::AnimatedImageLoading animatedImageLoading,
791 uint32_t frameIndex);
794 * @brief Load a new texture.
795 * @param[in] textureId TextureId to reference the texture that will be loaded
796 * @param[in] url The URL of the image to load
797 * @param[in] desiredSize The size the image is likely to appear at.
798 * This can be set to 0,0 for automatic
799 * @param[in] fittingMode The FittingMode to use
800 * @param[in] samplingMode The SamplingMode to use
801 * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
802 * e.g., from portrait to landscape
803 * @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.
805 void Load(TextureId textureId,
806 const VisualUrl& url,
807 ImageDimensions desiredSize,
808 FittingMode::Type fittingMode,
809 SamplingMode::Type samplingMode,
810 bool orientationCorrection,
811 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
815 * @param [in] id of the texture
816 * @param [in] pixelBuffer of the to be masked image
817 * @param [in] maskPixelBuffer of the mask image
818 * @param [in] contentScale The factor to scale the content
819 * @param [in] cropToMask Whether to crop the content to the mask size
820 * @param [in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
822 void ApplyMask( TextureId textureId,
823 Devel::PixelBuffer pixelBuffer,
824 Devel::PixelBuffer maskPixelBuffer,
827 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad );
830 AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
831 AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete;
833 AsyncLoadingHelper(AsyncLoadingHelper&& rhs);
834 AsyncLoadingHelper& operator=(AsyncLoadingHelper&&rhs) = delete;
838 * @brief Main constructor that used by all other constructors
840 AsyncLoadingHelper( Toolkit::AsyncImageLoader loader,
841 TextureManager& textureManager,
842 AsyncLoadingInfoContainerType&& loadingInfoContainer );
845 * @brief Callback to be called when texture loading is complete, it passes the pixel buffer on to texture manager.
846 * @param[in] id Loader id
847 * @param[in] pixelBuffer Image data
849 void AsyncLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer );
852 Toolkit::AsyncImageLoader mLoader;
853 TextureManager& mTextureManager;
854 AsyncLoadingInfoContainerType mLoadingInfoContainer;
857 struct ExternalTextureInfo
860 TextureSet textureSet;
866 * Deleted copy constructor.
868 TextureManager( const TextureManager& ) = delete;
871 * Deleted assignment operator.
873 TextureManager& operator=( const TextureManager& rhs ) = delete;
876 * This is called by the TextureManagerUploadObserver when an observer is destroyed.
877 * We use the callback to know when to remove an observer from our notify list.
878 * @param[in] observer The observer that generated the callback
880 void ObserverDestroyed( TextureUploadObserver* observer );
882 private: // Member Variables:
884 TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
885 RoundRobinContainerView< AsyncLoadingHelper > mAsyncLocalLoaders; ///< The Asynchronous image loaders used to provide all local async loads
886 RoundRobinContainerView< AsyncLoadingHelper > mAsyncRemoteLoaders; ///< The Asynchronous image loaders used to provide all remote async loads
887 std::vector< ExternalTextureInfo > mExternalTextures; ///< Externally provided textures
888 Dali::Vector<LifecycleObserver*> mLifecycleObservers; ///< Lifecycle observers of texture manager
889 Dali::Vector<LoadQueueElement> mLoadQueue; ///< Queue of textures to load after NotifyObservers
890 std::string mBrokenImageUrl; ///< Broken image url
891 TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
892 bool mQueueLoadFlag; ///< Flag that causes Load Textures to be queued.
898 } // namespace Toolkit
902 #endif // DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H