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 image load of the given URL to get PixelBuffer.
169 * The parameters are used to specify how the image is loaded.
170 * The observer has the LoadComplete method called when the load is ready.
172 * @param[in] url The URL of the image to load
173 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
174 * @param[in] fittingMode The FittingMode to use
175 * @param[in] samplingMode The SamplingMode to use
176 * @param[in] synchronousLoading true if the URL should be loaded synchronously
177 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
178 * This is called when an image load completes (or fails).
179 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
180 * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
181 * image has no alpha channel
183 * @return The pixel buffer containing the image, or empty if still loading.
186 Devel::PixelBuffer LoadPixelBuffer( const VisualUrl& url,
187 Dali::ImageDimensions desiredSize,
188 Dali::FittingMode::Type fittingMode,
189 Dali::SamplingMode::Type samplingMode,
190 bool synchronousLoading,
191 TextureUploadObserver* textureObserver,
192 bool orientationCorrection,
193 TextureManager::MultiplyOnLoad& preMultiplyOnLoad );
197 * @brief Requests an image load of the given URL.
199 * The parameters are used to specify how the image is loaded.
200 * The observer has the UploadComplete method called when the load is ready.
202 * When the client has finished with the Texture, Remove() should be called.
204 * @param[in] url The URL of the image to load
205 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
206 * @param[in] fittingMode The FittingMode to use
207 * @param[in] samplingMode The SamplingMode to use
208 * @param[in, out] maskInfo Mask info structure
209 * @param[in] synchronousLoading true if the URL should be loaded synchronously
210 * @param[out] textureId, The textureId of the URL
211 * @param[out] textureRect The rectangle within the texture atlas that this URL occupies,
212 * this is the rectangle in normalized coordinates.
213 * @param[out] textureRectSize The rectangle within the texture atlas that this URL occupies,
214 * this is the same rectangle in pixels.
215 * @param[in,out] atlasingStatus Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
216 * be loaded, and marked successful, but this will be set to false.
217 * If atlasing succeeds, this will be set to true.
218 * @param[out] loadingStatus The loading status of the texture
219 * @param[in] wrapModeU Horizontal Wrap mode
220 * @param[in] wrapModeV Vertical Wrap mode
221 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
222 * This is called when an image load completes (or fails).
223 * @param[in] atlasObserver This is used if the texture is atlased, and will be called instead of
224 * textureObserver.UploadCompleted
225 * @param[in] imageAtlasManager The atlas manager to use for atlasing textures
226 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
227 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
228 * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
229 * image has no alpha channel
231 * @return The texture set containing the image, or empty if still loading.
234 TextureSet LoadTexture( const VisualUrl& url,
235 Dali::ImageDimensions desiredSize,
236 Dali::FittingMode::Type fittingMode,
237 Dali::SamplingMode::Type samplingMode,
238 MaskingDataPointer& maskInfo,
239 bool synchronousLoading,
240 TextureManager::TextureId& textureId,
241 Vector4& textureRect,
242 Dali::ImageDimensions& textureRectSize,
243 bool& atlasingStatus,
245 Dali::WrapMode::Type wrapModeU,
246 Dali::WrapMode::Type wrapModeV,
247 TextureUploadObserver* textureObserver,
248 AtlasUploadObserver* atlasObserver,
249 ImageAtlasManagerPtr imageAtlasManager,
250 bool orientationCorrection,
251 TextureManager::ReloadPolicy reloadPolicy,
252 MultiplyOnLoad& preMultiplyOnLoad );
255 * @brief Requests an image load of the given URL.
257 * The parameters are used to specify how the image is loaded.
258 * The observer has the UploadComplete method called when the load is ready.
260 * When the client has finished with the Texture, Remove() should be called.
262 * @param[in] url The URL of the image to load
263 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
264 * @param[in] fittingMode The FittingMode to use
265 * @param[in] samplingMode The SamplingMode to use
266 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
267 * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
268 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
269 * This is called when an image load completes (or fails).
270 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
271 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
272 * @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
273 * @return A TextureId to use as a handle to reference this Texture
275 TextureId RequestLoad( const VisualUrl& url,
276 const ImageDimensions desiredSize,
277 FittingMode::Type fittingMode,
278 Dali::SamplingMode::Type samplingMode,
279 const UseAtlas useAtlasing,
280 TextureUploadObserver* observer,
281 bool orientationCorrection,
282 TextureManager::ReloadPolicy reloadPolicy,
283 MultiplyOnLoad& preMultiplyOnLoad );
286 * @brief Requests an image load of the given URL, when the texture has
287 * have loaded, it will perform a blend with the image mask, and upload
288 * the blended texture.
290 * The parameters are used to specify how the image is loaded.
291 * The observer has the UploadComplete method called when the load is ready.
293 * When the client has finished with the Texture, Remove() should be called.
295 * @param[in] url The URL of the image to load
296 * @param[in] maskTextureId The texture id of an image to mask this with
297 * (can be INVALID if no masking required)
298 * @param[in] contentScale The scale factor to apply to the image before masking
299 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
300 * @param[in] fittingMode The FittingMode to use
301 * @param[in] samplingMode The SamplingMode to use
302 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
303 * be loaded, and marked successful,
304 * but "useAtlasing" will be set to false in the "UploadCompleted" callback from
305 * the TextureManagerUploadObserver.
306 * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size.
307 * If false, then the mask will be scaled to fit the image before being applied.
308 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
310 * This is called when an image load completes (or fails).
311 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
312 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
313 * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
314 * image has no alpha channel
315 * @return A TextureId to use as a handle to reference this Texture
317 TextureId RequestLoad( const VisualUrl& url,
318 TextureId maskTextureId,
320 const ImageDimensions desiredSize,
321 FittingMode::Type fittingMode,
322 Dali::SamplingMode::Type samplingMode,
323 const UseAtlas useAtlasing,
325 TextureUploadObserver* observer,
326 bool orientationCorrection,
327 TextureManager::ReloadPolicy reloadPolicy,
328 MultiplyOnLoad& preMultiplyOnLoad );
331 * Requests a masking image to be loaded. This mask is not uploaded to GL,
332 * instead, it is stored in CPU memory, and can be used for CPU blending.
334 TextureId RequestMaskLoad( const VisualUrl& maskUrl );
337 * @brief Remove a Texture from the TextureManager.
339 * Textures are cached and therefore only the removal of the last
340 * occurrence of a Texture will cause its removal internally.
342 * @param[in] textureId The ID of the Texture to remove.
343 * @param[in] textureObserver The texture observer.
345 void Remove( const TextureManager::TextureId textureId, TextureUploadObserver* textureObserver );
348 * @brief Get the visualUrl associated with the texture id.
349 * @param[in] textureId The texture Id to get
350 * @return The visual Url associated with the texture id.
352 VisualUrl GetVisualUrl( TextureId textureId );
355 * @brief Get the current state of a texture
356 * @param[in] textureId The texture id to query
357 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
360 LoadState GetTextureState( TextureId textureId );
363 * @brief Get the associated texture set if the texture id is valid
364 * @param[in] textureId The texture Id to look up
365 * @return the associated texture set, or an empty handle if textureId is not valid
367 TextureSet GetTextureSet( TextureId textureId );
370 * Adds an external texture to the texture manager
371 * @param[in] texture The texture to add
372 * @return string containing the URL for the texture
374 std::string AddExternalTexture( TextureSet& texture );
377 * Removes an external texture from texture manager
378 * @param[in] url The string containing the texture to remove
379 * @return handle to the texture
381 TextureSet RemoveExternalTexture( const std::string& url );
384 * Add an observer to the object.
385 * @param[in] observer The observer to add.
387 void AddObserver( TextureManager::LifecycleObserver& observer );
390 * Remove an observer from the object
391 * @pre The observer has already been added.
392 * @param[in] observer The observer to remove.
394 void RemoveObserver( TextureManager::LifecycleObserver& observer );
397 * @brief Set an image to be used when a visual has failed to correctly render
398 * @param[in] brokenImageUrl The broken image url.
400 void SetBrokenImageUrl(const std::string& brokenImageUrl);
405 * @brief Requests an image load of the given URL, when the texture has
406 * have loaded, if there is a valid maskTextureId, it will perform a
407 * CPU blend with the mask, and upload the blend texture.
409 * The parameters are used to specify how the image is loaded.
410 * The observer has the UploadComplete method called when the load is ready.
412 * When the client has finished with the Texture, Remove() should be called.
414 * @param[in] url The URL of the image to load
415 * @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set
416 * to INVALID_TEXTURE_ID
417 * @param[in] contentScale The scaling factor to apply to the content when masking
418 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
419 * @param[in] fittingMode The FittingMode to use
420 * @param[in] samplingMode The SamplingMode to use
421 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be
422 * loaded, and marked successful, but "useAtlasing" will be set to false in the
423 * "UploadCompleted" callback from the TextureManagerUploadObserver.
424 * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before
426 * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
427 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
429 * This is called when an image load completes (or fails).
430 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
431 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
432 * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if
434 * @return A TextureId to use as a handle to reference this Texture
436 TextureId RequestLoadInternal(
437 const VisualUrl& url,
438 TextureId maskTextureId,
440 const ImageDimensions desiredSize,
441 FittingMode::Type fittingMode,
442 Dali::SamplingMode::Type samplingMode,
445 StorageType storageType,
446 TextureUploadObserver* observer,
447 bool orientationCorrection,
448 TextureManager::ReloadPolicy reloadPolicy,
449 MultiplyOnLoad& preMultiplyOnLoad );
452 * @brief Get the current state of a texture
453 * @param[in] textureId The texture id to query
454 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
457 LoadState GetTextureStateInternal( TextureId textureId );
459 typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
464 * @brief This struct is used to manage the life-cycle of Texture loading and caching.
468 TextureInfo( TextureId textureId,
469 TextureId maskTextureId,
470 const VisualUrl& url,
471 ImageDimensions desiredSize,
473 FittingMode::Type fittingMode,
474 Dali::SamplingMode::Type samplingMode,
475 bool loadSynchronously,
478 TextureManager::TextureHash hash,
479 bool orientationCorrection,
480 bool preMultiplyOnLoad )
482 desiredSize( desiredSize ),
483 useSize( desiredSize ),
484 atlasRect( 0.0f, 0.0f, 1.0f, 1.0f ), // Full atlas rectangle
485 textureId( textureId ),
486 maskTextureId( maskTextureId ),
488 scaleFactor( scaleFactor ),
489 referenceCount( 1u ),
490 loadState( NOT_STARTED ),
491 fittingMode( fittingMode ),
492 samplingMode( samplingMode ),
493 storageType( UPLOAD_TO_TEXTURE ),
494 loadSynchronously( loadSynchronously ),
495 useAtlas( useAtlas ),
496 cropToMask( cropToMask ),
497 orientationCorrection( true ),
498 preMultiplyOnLoad( preMultiplyOnLoad ),
499 preMultiplied( false )
504 * Container type used to store all observer clients of this Texture
506 typedef Dali::Vector< TextureUploadObserver* > ObserverListType;
508 ObserverListType observerList; ///< Container used to store all observer clients of this Texture
509 Toolkit::ImageAtlas atlas; ///< The atlas this Texture lays within (if any)
510 Devel::PixelBuffer pixelBuffer;///< The PixelBuffer holding the image data (May be empty after upload)
511 TextureSet textureSet; ///< The TextureSet holding the Texture
512 VisualUrl url; ///< The URL of the image
513 ImageDimensions desiredSize; ///< The size requested
514 ImageDimensions useSize; ///< The size used
515 Vector4 atlasRect; ///< The atlas rect used if atlased
516 TextureId textureId; ///< The TextureId associated with this Texture
517 TextureId maskTextureId; ///< The mask TextureId to be applied on load
518 TextureManager::TextureHash hash; ///< The hash used to cache this Texture
519 float scaleFactor; ///< The scale factor to apply to the Texture when masking
520 int16_t referenceCount; ///< The reference count of clients using this Texture
521 LoadState loadState:4; ///< The load state showing the load progress of the Texture
522 FittingMode::Type fittingMode:3; ///< The requested FittingMode
523 Dali::SamplingMode::Type samplingMode:3; ///< The requested SamplingMode
524 StorageType storageType:2; ///< CPU storage / GPU upload;
525 bool loadSynchronously:1; ///< True if synchronous loading was requested
526 UseAtlas useAtlas:2; ///< USE_ATLAS if an atlas was requested.
527 ///< This is updated to false if atlas is not used
528 bool cropToMask:1; ///< true if the image should be cropped to the mask size.
529 bool orientationCorrection:1; ///< true if the image should be rotated to match exif orientation data
530 bool preMultiplyOnLoad:1; ///< true if the image's color should be multiplied by it's alpha
531 bool preMultiplied:1; ///< true if the image's color was multiplied by it's alpha
535 * Structure to hold info about a texture load queued during NotifyObservers
537 struct LoadQueueElement
539 LoadQueueElement( TextureId textureId, TextureUploadObserver* observer )
540 : mTextureId( textureId ),
541 mObserver( observer )
545 TextureId mTextureId; ///< The texture id of the requested load.
546 TextureUploadObserver* mObserver; ///< Observer of texture load.
550 * Struct to hold information about a requested Async load.
551 * This is used to look up a TextureManager::TextureId from the returned AsyncLoad Id.
553 struct AsyncLoadingInfo
555 AsyncLoadingInfo( TextureId textureId )
556 : textureId( textureId ),
561 TextureId textureId; ///< The external Texture Id assigned to this load
562 uint32_t loadId; ///< The load Id used by the async loader to reference this load
567 typedef std::deque<AsyncLoadingInfo> AsyncLoadingInfoContainerType; ///< The container type used to manage Asynchronous loads in progress
568 typedef std::vector<TextureInfo> TextureInfoContainerType; ///< The container type used to manage the life-cycle and caching of Textures
571 * @brief Initiate a load or queue load if NotifyObservers is invoking callbacks
572 * @param[in] textureInfo The TextureInfo struct associated with the Texture
573 * @param[in] observer The observer wishing to observe the texture upload
575 void LoadOrQueueTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
578 * @brief Queue a texture load to be subsequently handled by ProcessQueuedTextures.
579 * @param[in] textureInfo The TextureInfo struct associated with the Texture
580 * @param[in] observer The observer wishing to observe the texture upload
582 void QueueLoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
585 * @brief Used internally to initiate a load.
586 * @param[in] textureInfo The TextureInfo struct associated with the Texture
587 * @param[in] observer The observer wishing to observe the texture upload
589 void LoadTexture( TextureInfo& textureInfo, TextureUploadObserver* observer );
592 * @brief Initiate load of textures queued whilst NotifyObservers invoking callbacks.
594 void ProcessQueuedTextures();
597 * Add the observer to the observer list
598 * @param[in] textureInfo The TextureInfo struct associated with the texture
599 * @param[in] observer The observer wishing to observe the texture upload
601 void ObserveTexture( TextureInfo & textureInfo, TextureUploadObserver* observer );
604 * @brief This signal handler is called when the async local loader finishes loading.
605 * @param[in] id This is the async image loaders Id
606 * @param[in] pixelBuffer The loaded image data
608 void AsyncLocalLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer );
611 * @brief This signal handler is called when the async local loader finishes loading.
612 * @param[in] id This is the async image loaders Id
613 * @param[in] pixelBuffer The loaded image data
615 void AsyncRemoteLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer );
618 * Common method to handle loading completion
619 * @param[in] container The Async loading container
620 * @param[in] id This is the async image loaders Id
621 * @param[in] pixelBuffer The loaded image data
623 void AsyncLoadComplete( AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer );
626 * @brief Performs Post-Load steps including atlasing.
627 * @param[in] textureInfo The struct associated with this Texture
628 * @param[in] pixelBuffer The image pixelBuffer
629 * @return True if successful
631 void PostLoad( TextureManager::TextureInfo& textureInfo, Devel::PixelBuffer& pixelBuffer );
634 * Check if there is a texture waiting to be masked. If there
635 * is then apply this mask and upload it.
636 * @param[in] maskTextureInfo The texture info of the mask that has just loaded.
638 void CheckForWaitingTexture( TextureInfo& maskTextureInfo );
641 * Apply the mask to the pixelBuffer.
642 * @param[in] textureInfo The information of texture to apply the mask to
643 * @param[in] maskTextureId The texture id of the mask.
645 void ApplyMask( TextureInfo& textureInfo, TextureId maskTextureId );
648 * Upload the texture specified in pixelBuffer to the appropriate location
649 * @param[in] pixelBuffer The image data to upload
650 * @param[in] textureInfo The texture info containing the location to
653 void UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo );
656 * Mark the texture as complete, and inform observers
657 * @param[in] textureInfo The struct associated with this Texture
659 void UploadComplete( TextureInfo& textureInfo );
662 * Notify the current observers that the texture upload is complete,
663 * then remove the observers from the list.
664 * @param[in] textureInfo The struct associated with this Texture
665 * @param[in] success If the pixel data was retrieved successfully and uploaded to GPU
667 void NotifyObservers( TextureInfo& textureInfo, bool success );
670 * @brief Generates a new, unique TextureId
671 * @return A unique TextureId
673 TextureManager::TextureId GenerateUniqueTextureId();
676 * @brief Used to lookup an index into the TextureInfoContainer from a TextureId
677 * @param[in] textureId The TextureId to look up
678 * @return The cache index
680 int GetCacheIndexFromId( TextureId textureId );
684 * @brief Generates a hash for caching based on the input parameters.
685 * Only applies size, fitting mode andsampling mode if the size is specified.
686 * Only applies maskTextureId if it isn't INVALID_TEXTURE_ID
687 * Always applies useAtlas.
688 * @param[in] url The URL of the image to load
689 * @param[in] size The image size
690 * @param[in] fittingMode The FittingMode to use
691 * @param[in] samplingMode The SamplingMode to use
692 * @param[in] useAtlas True if atlased
693 * @param[in] maskTextureId The masking texture id (or INVALID_TEXTURE_ID)
694 * @return A hash of the provided data for caching.
696 TextureHash GenerateHash( const std::string& url, const ImageDimensions size,
697 const FittingMode::Type fittingMode,
698 const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas,
699 TextureId maskTextureId );
702 * @brief Looks up a cached texture by its hash.
703 * If found, the given parameters are used to check there is no hash-collision.
704 * @param[in] hash The hash to look up
705 * @param[in] url The URL of the image to load
706 * @param[in] size The image size
707 * @param[in] fittingMode The FittingMode to use
708 * @param[in] samplingMode The SamplingMode to use
709 * @param[in] useAtlas True if atlased
710 * @param[in] maskTextureId Optional texture ID to use to mask this image
711 * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
712 * @param[in] storageType Whether the pixel data is stored in the cache, returned with PixelBuffer or uploaded to the GPU
713 * @return A TextureId of a cached Texture if found. Or INVALID_TEXTURE_ID if not found.
715 TextureManager::TextureId FindCachedTexture(
716 const TextureManager::TextureHash hash,
717 const std::string& url,
718 const ImageDimensions size,
719 const FittingMode::Type fittingMode,
720 const Dali::SamplingMode::Type samplingMode,
722 TextureId maskTextureId,
723 MultiplyOnLoad preMultiplyOnLoad,
724 StorageType storageType );
729 * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container
731 class AsyncLoadingHelper : public ConnectionTracker
735 * @brief Create an AsyncLoadingHelper.
736 * @param[in] textureManager Reference to the texture manager
738 AsyncLoadingHelper(TextureManager& textureManager);
741 * @brief Load a new texture.
742 * @param[in] textureId TextureId to reference the texture that will be loaded
743 * @param[in] url The URL of the image to load
744 * @param[in] desiredSize The size the image is likely to appear at.
745 * This can be set to 0,0 for automatic
746 * @param[in] fittingMode The FittingMode to use
747 * @param[in] samplingMode The SamplingMode to use
748 * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
749 * e.g., from portrait to landscape
750 * @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.
752 void Load(TextureId textureId,
753 const VisualUrl& url,
754 ImageDimensions desiredSize,
755 FittingMode::Type fittingMode,
756 SamplingMode::Type samplingMode,
757 bool orientationCorrection,
758 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
762 * @param [in] id of the texture
763 * @param [in] pixelBuffer of the to be masked image
764 * @param [in] maskPixelBuffer of the mask image
765 * @param [in] contentScale The factor to scale the content
766 * @param [in] cropToMask Whether to crop the content to the mask size
767 * @param [in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
769 void ApplyMask( TextureId textureId,
770 Devel::PixelBuffer pixelBuffer,
771 Devel::PixelBuffer maskPixelBuffer,
774 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad );
777 AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
778 AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete;
780 AsyncLoadingHelper(AsyncLoadingHelper&& rhs);
781 AsyncLoadingHelper& operator=(AsyncLoadingHelper&&rhs) = delete;
785 * @brief Main constructor that used by all other constructors
787 AsyncLoadingHelper( Toolkit::AsyncImageLoader loader,
788 TextureManager& textureManager,
789 AsyncLoadingInfoContainerType&& loadingInfoContainer );
792 * @brief Callback to be called when texture loading is complete, it passes the pixel buffer on to texture manager.
793 * @param[in] id Loader id
794 * @param[in] pixelBuffer Image data
796 void AsyncLoadComplete( uint32_t id, Devel::PixelBuffer pixelBuffer );
799 Toolkit::AsyncImageLoader mLoader;
800 TextureManager& mTextureManager;
801 AsyncLoadingInfoContainerType mLoadingInfoContainer;
804 struct ExternalTextureInfo
807 TextureSet textureSet;
813 * Deleted copy constructor.
815 TextureManager( const TextureManager& ) = delete;
818 * Deleted assignment operator.
820 TextureManager& operator=( const TextureManager& rhs ) = delete;
823 * This is called by the TextureManagerUploadObserver when an observer is destroyed.
824 * We use the callback to know when to remove an observer from our notify list.
825 * @param[in] observer The observer that generated the callback
827 void ObserverDestroyed( TextureUploadObserver* observer );
829 private: // Member Variables:
831 TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
832 RoundRobinContainerView< AsyncLoadingHelper > mAsyncLocalLoaders; ///< The Asynchronous image loaders used to provide all local async loads
833 RoundRobinContainerView< AsyncLoadingHelper > mAsyncRemoteLoaders; ///< The Asynchronous image loaders used to provide all remote async loads
834 std::vector< ExternalTextureInfo > mExternalTextures; ///< Externally provided textures
835 Dali::Vector<LifecycleObserver*> mLifecycleObservers; ///< Lifecycle observers of texture manager
836 Dali::Vector<LoadQueueElement> mLoadQueue; ///< Queue of textures to load after NotifyObservers
837 std::string mBrokenImageUrl; ///< Broken image url
838 TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
839 bool mQueueLoadFlag; ///< Flag that causes Load Textures to be queued.
845 } // namespace Toolkit
849 #endif // DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H