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/adaptor-framework/encoded-image-buffer.h>
24 #include <dali/public-api/common/dali-vector.h>
25 #include <dali/public-api/object/ref-object.h>
26 #include <dali/public-api/rendering/geometry.h>
27 #include <dali/public-api/rendering/texture-set.h>
34 #include <dali-toolkit/devel-api/image-loader/async-image-loader-devel.h>
35 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
36 #include <dali-toolkit/internal/helpers/round-robin-container-view.h>
37 #include <dali-toolkit/internal/image-loader/async-image-loader-impl.h>
38 #include <dali-toolkit/internal/visuals/texture-upload-observer.h>
39 #include <dali-toolkit/internal/visuals/visual-url.h>
40 #include <dali-toolkit/public-api/image-loader/async-image-loader.h>
48 class ImageAtlasManager;
49 typedef IntrusivePtr<ImageAtlasManager> ImageAtlasManagerPtr;
52 * The TextureManager provides a common Image loading API for Visuals.
54 * The TextureManager is responsible for providing sync, async, atlased and non-atlased loads.
55 * Texture caching is provided and performed when possible.
56 * Broken Images are automatically provided on load failure.
58 class TextureManager : public ConnectionTracker
61 typedef int32_t TextureId; ///< The TextureId type. This is used as a handle to refer to a particular Texture.
62 static const int INVALID_TEXTURE_ID = -1; ///< Used to represent a null TextureId or error
65 * Whether the texture should be atlased or uploaded into it's own GPU texture
74 * Whether the pixel data should be kept in TextureManager, returned with pixelBuffer or uploaded for rendering
76 enum class StorageType : uint8_t
84 * Whether the texture should be loaded synchronously or asynchronously.
86 enum class LoadType : uint8_t
93 * @brief The LoadState Enumeration represents the current state of a particular Texture's life-cycle.
95 enum class LoadState : uint8_t
97 NOT_STARTED, ///< Default
98 LOADING, ///< Loading has been started, but not finished.
99 LOAD_FINISHED, ///< Loading has finished. (for CPU storage only)
100 WAITING_FOR_MASK, ///< Loading has finished, but waiting for mask image
101 MASK_APPLYING, ///< Loading has finished, Mask is applying
102 MASK_APPLIED, ///< Loading has finished, Mask is applyied by GPU
103 UPLOADED, ///< Uploaded and ready. (For GPU upload only)
104 CANCELLED, ///< Removed before loading completed
105 LOAD_FAILED ///< Async loading failed, e.g. connection problem
109 * @brief Types of reloading policies
111 enum class ReloadPolicy
113 CACHED = 0, ///< Loads cached texture if it exists.
114 FORCED ///< Forces reloading of texture.
118 * @brief Whether to multiply alpha into color channels on load
120 enum class MultiplyOnLoad
122 LOAD_WITHOUT_MULTIPLY = 0, ///< Don't modify the image
123 MULTIPLY_ON_LOAD ///< Multiply alpha into color channels on load
130 ~MaskingData() = default;
132 VisualUrl mAlphaMaskUrl;
133 TextureManager::TextureId mAlphaMaskId;
134 float mContentScaleFactor;
137 using MaskingDataPointer = std::unique_ptr<MaskingData>;
140 * Class to provide lifecycle event on destruction of texture manager.
142 struct LifecycleObserver
145 * Called shortly before the texture manager is destroyed.
147 virtual void TextureManagerDestroyed() = 0;
158 ~TextureManager() override;
160 // TextureManager Main API:
163 * @brief Requests an frame of animated image load.
165 * The parameters are used to specify how the animated image is loaded.
166 * The observer has the LoadComplete method called when the load is ready.
168 * @param[in] animatedImageLoading The AnimatedImageLoading that contain the animated image information
169 * @param[in] frameIndex The frame index to load.
170 * @param[in] samplingMode The SamplingMode to use
171 * @param[in] synchronousLoading true if the frame should be loaded synchronously
172 * @param[out] textureId The textureId of the frame
173 * @param[in] wrapModeU Horizontal Wrap mode
174 * @param[in] wrapModeV Vertical Wrap mode
175 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
176 * This is called when an image load completes (or fails).
178 * @return The texture set containing the frame of animated image, or empty if still loading.
181 TextureSet LoadAnimatedImageTexture(Dali::AnimatedImageLoading animatedImageLoading,
183 Dali::SamplingMode::Type samplingMode,
184 bool synchronousLoading,
185 TextureManager::TextureId& textureId,
186 Dali::WrapMode::Type wrapModeU,
187 Dali::WrapMode::Type wrapModeV,
188 TextureUploadObserver* textureObserver);
191 * @brief Requests an image load of the given URL to get PixelBuffer.
193 * The parameters are used to specify how the image is loaded.
194 * The observer has the LoadComplete method called when the load is ready.
196 * @param[in] url The URL of the image to load
197 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
198 * @param[in] fittingMode The FittingMode to use
199 * @param[in] samplingMode The SamplingMode to use
200 * @param[in] synchronousLoading true if the URL should be loaded synchronously
201 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
202 * This is called when an image load completes (or fails).
203 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
204 * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
205 * image has no alpha channel
207 * @return The pixel buffer containing the image, or empty if still loading.
210 Devel::PixelBuffer LoadPixelBuffer(const VisualUrl& url,
211 Dali::ImageDimensions desiredSize,
212 Dali::FittingMode::Type fittingMode,
213 Dali::SamplingMode::Type samplingMode,
214 bool synchronousLoading,
215 TextureUploadObserver* textureObserver,
216 bool orientationCorrection,
217 TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
220 * @brief Requests an image load of the given URL.
222 * The parameters are used to specify how the image is loaded.
223 * The observer has the UploadComplete method called when the load is ready.
225 * When the client has finished with the Texture, Remove() should be called.
227 * @param[in] url The URL of the image to load
228 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
229 * @param[in] fittingMode The FittingMode to use
230 * @param[in] samplingMode The SamplingMode to use
231 * @param[in, out] maskInfo Mask info structure
232 * @param[in] synchronousLoading true if the URL should be loaded synchronously
233 * @param[out] textureId, The textureId of the URL
234 * @param[out] textureRect The rectangle within the texture atlas that this URL occupies,
235 * this is the rectangle in normalized coordinates.
236 * @param[out] textureRectSize The rectangle within the texture atlas that this URL occupies,
237 * this is the same rectangle in pixels.
238 * @param[in,out] atlasingStatus Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
239 * be loaded, and marked successful, but this will be set to false.
240 * If atlasing succeeds, this will be set to true.
241 * @param[out] loadingStatus The loading status of the texture
242 * @param[in] wrapModeU Horizontal Wrap mode
243 * @param[in] wrapModeV Vertical Wrap mode
244 * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
245 * This is called when an image load completes (or fails).
246 * @param[in] atlasObserver This is used if the texture is atlased, and will be called instead of
247 * textureObserver.UploadCompleted
248 * @param[in] imageAtlasManager The atlas manager to use for atlasing textures
249 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
250 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
251 * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
252 * image has no alpha channel
254 * @return The texture set containing the image, or empty if still loading.
257 TextureSet LoadTexture(const VisualUrl& url,
258 Dali::ImageDimensions desiredSize,
259 Dali::FittingMode::Type fittingMode,
260 Dali::SamplingMode::Type samplingMode,
261 MaskingDataPointer& maskInfo,
262 bool synchronousLoading,
263 TextureManager::TextureId& textureId,
264 Vector4& textureRect,
265 Dali::ImageDimensions& textureRectSize,
266 bool& atlasingStatus,
268 Dali::WrapMode::Type wrapModeU,
269 Dali::WrapMode::Type wrapModeV,
270 TextureUploadObserver* textureObserver,
271 AtlasUploadObserver* atlasObserver,
272 ImageAtlasManagerPtr imageAtlasManager,
273 bool orientationCorrection,
274 TextureManager::ReloadPolicy reloadPolicy,
275 MultiplyOnLoad& preMultiplyOnLoad);
278 * @brief Requests an image load of the given URL.
280 * The parameters are used to specify how the image is loaded.
281 * The observer has the UploadComplete method called when the load is ready.
283 * When the client has finished with the Texture, Remove() should be called.
285 * @param[in] url The URL of the image to load
286 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
287 * @param[in] fittingMode The FittingMode to use
288 * @param[in] samplingMode The SamplingMode to use
289 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
290 * but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
291 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted" virtual.
292 * This is called when an image load completes (or fails).
293 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
294 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
295 * @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
296 * @return A TextureId to use as a handle to reference this Texture
298 TextureId RequestLoad(const VisualUrl& url,
299 const ImageDimensions desiredSize,
300 FittingMode::Type fittingMode,
301 Dali::SamplingMode::Type samplingMode,
302 const UseAtlas useAtlasing,
303 TextureUploadObserver* observer,
304 bool orientationCorrection,
305 TextureManager::ReloadPolicy reloadPolicy,
306 MultiplyOnLoad& preMultiplyOnLoad);
309 * @brief Requests an image load of the given URL, when the texture has
310 * have loaded, it will perform a blend with the image mask, and upload
311 * the blended texture.
313 * The parameters are used to specify how the image is loaded.
314 * The observer has the UploadComplete method called when the load is ready.
316 * When the client has finished with the Texture, Remove() should be called.
318 * @param[in] url The URL of the image to load
319 * @param[in] maskTextureId The texture id of an image to mask this with
320 * (can be INVALID if no masking required)
321 * @param[in] contentScale The scale factor to apply to the image before masking
322 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
323 * @param[in] fittingMode The FittingMode to use
324 * @param[in] samplingMode The SamplingMode to use
325 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still
326 * be loaded, and marked successful,
327 * but "useAtlasing" will be set to false in the "UploadCompleted" callback from
328 * the TextureManagerUploadObserver.
329 * @param[in] cropToMask Only used with masking, this will crop the scaled image to the mask size.
330 * If false, then the mask will be scaled to fit the image before being applied.
331 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
333 * This is called when an image load completes (or fails).
334 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
335 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
336 * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the
337 * image has no alpha channel
338 * @return A TextureId to use as a handle to reference this Texture
340 TextureId RequestLoad(const VisualUrl& url,
341 TextureId maskTextureId,
343 const ImageDimensions desiredSize,
344 FittingMode::Type fittingMode,
345 Dali::SamplingMode::Type samplingMode,
346 const UseAtlas useAtlasing,
348 TextureUploadObserver* observer,
349 bool orientationCorrection,
350 TextureManager::ReloadPolicy reloadPolicy,
351 MultiplyOnLoad& preMultiplyOnLoad);
354 * Requests a masking image to be loaded. This mask is not uploaded to GL,
355 * instead, it is stored in CPU memory, and can be used for CPU blending.
357 TextureId RequestMaskLoad(const VisualUrl& maskUrl);
360 * @brief Remove a Texture from the TextureManager.
362 * Textures are cached and therefore only the removal of the last
363 * occurrence of a Texture will cause its removal internally.
365 * @param[in] textureId The ID of the Texture to remove.
366 * @param[in] textureObserver The texture observer.
368 void Remove(const TextureManager::TextureId textureId, TextureUploadObserver* textureObserver);
371 * @brief Get the visualUrl associated with the texture id.
372 * @param[in] textureId The texture Id to get
373 * @return The visual Url associated with the texture id.
375 VisualUrl GetVisualUrl(TextureId textureId);
378 * @brief Get the current state of a texture
379 * @param[in] textureId The texture id to query
380 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
383 LoadState GetTextureState(TextureId textureId);
386 * @brief Get the associated texture set if the texture id is valid
387 * @param[in] textureId The texture Id to look up
388 * @return the associated texture set, or an empty handle if textureId is not valid
390 TextureSet GetTextureSet(TextureId textureId);
393 * @brief Get the encoded image buffer
394 * @param[in] textureId The textureId to look up
395 * @return the encoded image buffer, or an empty handle if textureId is not valid
397 EncodedImageBuffer GetEncodedImageBuffer(TextureId textureId);
400 * @brief Get the encoded image buffer by VisualUrl
401 * @param[in] url The url to look up
402 * @return the encoded image buffer, or an empty handle if url is not buffer resource or buffer is not valid
404 EncodedImageBuffer GetEncodedImageBuffer(const std::string& url);
407 * Adds an external texture to the texture manager
408 * @param[in] texture The texture to add
409 * @return string containing the URL for the texture
411 std::string AddExternalTexture(TextureSet& texture);
414 * Adds an external encoded image buffer to the texture manager
415 * @param[in] encodedImageBuffer The image buffer to add
416 * @return string containing the URL for the texture
418 std::string AddExternalEncodedImageBuffer(const EncodedImageBuffer& encodedImageBuffer);
421 * Removes an external texture from texture manager
422 * @param[in] url The string containing the texture to remove
423 * @return handle to the texture
425 TextureSet RemoveExternalTexture(const std::string& url);
428 * Removes an external encoded image buffer from texture manager
429 * @param[in] url The string containing the encoded image buffer to remove
430 * @return handle to the encoded image buffer
432 EncodedImageBuffer RemoveExternalEncodedImageBuffer(const std::string& url);
435 * @brief Notify that external textures or external encoded image buffers are used.
436 * @param[in] url The URL of the texture to use.
438 void UseExternalResource(const VisualUrl& url);
441 * Add an observer to the object.
442 * @param[in] observer The observer to add.
444 void AddObserver(TextureManager::LifecycleObserver& observer);
447 * Remove an observer from the object
448 * @pre The observer has already been added.
449 * @param[in] observer The observer to remove.
451 void RemoveObserver(TextureManager::LifecycleObserver& observer);
454 * @brief Returns the geometry associated with texture.
455 * @param[in] textureId Id of the texture
456 * @param[out] frontElements number of front elements
457 * @param[out] backElements number of back elements
458 * @return Returns valid geometry object
460 Geometry GetRenderGeometry(TextureId textureId, uint32_t& frontElements, uint32_t& backElements);
464 * @brief Requests an image load of the given URL, when the texture has
465 * have loaded, if there is a valid maskTextureId, it will perform a
466 * CPU blend with the mask, and upload the blend texture.
468 * The parameters are used to specify how the image is loaded.
469 * The observer has the UploadComplete method called when the load is ready.
471 * When the client has finished with the Texture, Remove() should be called.
473 * @param[in] url The URL of the image to load
474 * @param[in] maskTextureId The texture id of an image to use as a mask. If no mask is required, then set
475 * to INVALID_TEXTURE_ID
476 * @param[in] contentScale The scaling factor to apply to the content when masking
477 * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
478 * @param[in] fittingMode The FittingMode to use
479 * @param[in] samplingMode The SamplingMode to use
480 * @param[in] useAtlasing Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be
481 * loaded, and marked successful, but "useAtlasing" will be set to false in the
482 * "UploadCompleted" callback from the TextureManagerUploadObserver.
483 * @param[in] cropToMask Whether to crop the target after masking, or scale the mask to the image before
485 * @param[in] storageType, Whether the pixel data is stored in the cache or uploaded to the GPU
486 * @param[in] observer The client object should inherit from this and provide the "UploadCompleted"
488 * This is called when an image load completes (or fails).
489 * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
490 * @param[in] reloadPolicy Forces a reload of the texture even if already cached
491 * @param[in] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if
493 * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image
494 * @param[in] frameIndex The frame index of a frame to be loaded frame
495 * @return A TextureId to use as a handle to reference this Texture
497 TextureId RequestLoadInternal(
498 const VisualUrl& url,
499 TextureId maskTextureId,
501 const ImageDimensions desiredSize,
502 FittingMode::Type fittingMode,
503 Dali::SamplingMode::Type samplingMode,
506 StorageType storageType,
507 TextureUploadObserver* observer,
508 bool orientationCorrection,
509 TextureManager::ReloadPolicy reloadPolicy,
510 MultiplyOnLoad& preMultiplyOnLoad,
511 Dali::AnimatedImageLoading animatedImageLoading,
512 uint32_t frameIndex);
515 * @brief Get the current state of a texture
516 * @param[in] textureId The texture id to query
517 * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
520 LoadState GetTextureStateInternal(TextureId textureId);
522 typedef size_t TextureHash; ///< The type used to store the hash used for Texture caching.
527 * @brief This struct is used to manage the life-cycle of Texture loading and caching.
531 TextureInfo(TextureId textureId,
532 TextureId maskTextureId,
533 const VisualUrl& url,
534 ImageDimensions desiredSize,
536 FittingMode::Type fittingMode,
537 Dali::SamplingMode::Type samplingMode,
538 bool loadSynchronously,
541 TextureManager::TextureHash hash,
542 bool orientationCorrection,
543 bool preMultiplyOnLoad,
544 Dali::AnimatedImageLoading animatedImageLoading,
547 desiredSize(desiredSize),
548 useSize(desiredSize),
549 atlasRect(0.0f, 0.0f, 1.0f, 1.0f), // Full atlas rectangle
550 textureId(textureId),
551 maskTextureId(maskTextureId),
553 scaleFactor(scaleFactor),
555 loadState(LoadState::NOT_STARTED),
556 fittingMode(fittingMode),
557 samplingMode(samplingMode),
558 storageType(StorageType::UPLOAD_TO_TEXTURE),
559 animatedImageLoading(animatedImageLoading),
560 frameIndex(frameIndex),
561 loadSynchronously(loadSynchronously),
563 cropToMask(cropToMask),
564 orientationCorrection(true),
565 preMultiplyOnLoad(preMultiplyOnLoad),
571 * Container type used to store all observer clients of this Texture
573 typedef Dali::Vector<TextureUploadObserver*> ObserverListType;
575 ObserverListType observerList; ///< Container used to store all observer clients of this Texture
576 Toolkit::ImageAtlas atlas; ///< The atlas this Texture lays within (if any)
577 Devel::PixelBuffer pixelBuffer; ///< The PixelBuffer holding the image data (May be empty after upload)
578 TextureSet textureSet; ///< The TextureSet holding the Texture
579 VisualUrl url; ///< The URL of the image
580 ImageDimensions desiredSize; ///< The size requested
581 ImageDimensions useSize; ///< The size used
582 Vector4 atlasRect; ///< The atlas rect used if atlased
583 TextureId textureId; ///< The TextureId associated with this Texture
584 TextureId maskTextureId; ///< The mask TextureId to be applied on load
585 TextureManager::TextureHash hash; ///< The hash used to cache this Texture
586 float scaleFactor; ///< The scale factor to apply to the Texture when masking
587 int16_t referenceCount; ///< The reference count of clients using this Texture
588 LoadState loadState; ///< The load state showing the load progress of the Texture
589 FittingMode::Type fittingMode : 3; ///< The requested FittingMode
590 Dali::SamplingMode::Type samplingMode : 3; ///< The requested SamplingMode
591 StorageType storageType; ///< CPU storage / GPU upload;
592 Dali::AnimatedImageLoading animatedImageLoading; ///< AnimatedImageLoading that contains animated image information.
593 uint32_t frameIndex; ///< frame index that be loaded, in case of animated image
594 bool loadSynchronously : 1; ///< True if synchronous loading was requested
595 UseAtlas useAtlas : 2; ///< USE_ATLAS if an atlas was requested.
596 ///< This is updated to false if atlas is not used
597 bool cropToMask : 1; ///< true if the image should be cropped to the mask size.
598 bool orientationCorrection : 1; ///< true if the image should be rotated to match exif orientation data
599 bool preMultiplyOnLoad : 1; ///< true if the image's color should be multiplied by it's alpha
600 bool preMultiplied : 1; ///< true if the image's color was multiplied by it's alpha
604 * Structure to hold info about a texture load queued during NotifyObservers
606 struct LoadQueueElement
608 LoadQueueElement(TextureId textureId, TextureUploadObserver* observer)
609 : mTextureId(textureId),
614 TextureId mTextureId; ///< The texture id of the requested load.
615 TextureUploadObserver* mObserver; ///< Observer of texture load.
619 * Struct to hold information about a requested Async load.
620 * This is used to look up a TextureManager::TextureId from the returned AsyncLoad Id.
622 struct AsyncLoadingInfo
624 AsyncLoadingInfo(TextureId textureId)
625 : textureId(textureId),
630 TextureId textureId; ///< The external Texture Id assigned to this load
631 uint32_t loadId; ///< The load Id used by the async loader to reference this load
636 typedef std::deque<AsyncLoadingInfo> AsyncLoadingInfoContainerType; ///< The container type used to manage Asynchronous loads in progress
637 typedef std::vector<TextureInfo> TextureInfoContainerType; ///< The container type used to manage the life-cycle and caching of Textures
640 * @brief Initiate a load or queue load if NotifyObservers is invoking callbacks
641 * @param[in] textureInfo The TextureInfo struct associated with the Texture
642 * @param[in] observer The observer wishing to observe the texture upload
644 void LoadOrQueueTexture(TextureInfo& textureInfo, TextureUploadObserver* observer);
647 * @brief Queue a texture load to be subsequently handled by ProcessQueuedTextures.
648 * @param[in] textureInfo The TextureInfo struct associated with the Texture
649 * @param[in] observer The observer wishing to observe the texture upload
651 void QueueLoadTexture(TextureInfo& textureInfo, TextureUploadObserver* observer);
654 * @brief Used internally to initiate a load.
655 * @param[in] textureInfo The TextureInfo struct associated with the Texture
656 * @param[in] observer The observer wishing to observe the texture upload
658 void LoadTexture(TextureInfo& textureInfo, TextureUploadObserver* observer);
661 * @brief Initiate load of textures queued whilst NotifyObservers invoking callbacks.
663 void ProcessQueuedTextures();
666 * Add the observer to the observer list
667 * @param[in] textureInfo The TextureInfo struct associated with the texture
668 * @param[in] observer The observer wishing to observe the texture upload
670 void ObserveTexture(TextureInfo& textureInfo, TextureUploadObserver* observer);
673 * @brief This signal handler is called when the async local loader finishes loading.
674 * @param[in] id This is the async image loaders Id
675 * @param[in] pixelBuffer The loaded image data
677 void AsyncLocalLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
680 * @brief This signal handler is called when the async local loader finishes loading.
681 * @param[in] id This is the async image loaders Id
682 * @param[in] pixelBuffer The loaded image data
684 void AsyncRemoteLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
687 * Common method to handle loading completion
688 * @param[in] container The Async loading container
689 * @param[in] id This is the async image loaders Id
690 * @param[in] pixelBuffer The loaded image data
692 void AsyncLoadComplete(AsyncLoadingInfoContainerType& container, uint32_t id, Devel::PixelBuffer pixelBuffer);
695 * @brief Performs Post-Load steps including atlasing.
696 * @param[in] textureInfo The struct associated with this Texture
697 * @param[in] pixelBuffer The image pixelBuffer
698 * @return True if successful
700 void PostLoad(TextureManager::TextureInfo& textureInfo, Devel::PixelBuffer& pixelBuffer);
703 * Check if there is a texture waiting to be masked. If there
704 * is then apply this mask and upload it.
705 * @param[in] maskTextureInfo The texture info of the mask that has just loaded.
707 void CheckForWaitingTexture(TextureInfo& maskTextureInfo);
710 * Apply the mask to the pixelBuffer.
711 * @param[in] textureInfo The information of texture to apply the mask to
712 * @param[in] maskTextureId The texture id of the mask.
714 void ApplyMask(TextureInfo& textureInfo, TextureId maskTextureId);
717 * Upload the texture specified in pixelBuffer to the appropriate location
718 * @param[in] pixelBuffer The image data to upload
719 * @param[in] textureInfo The texture info containing the location to
722 void UploadTexture(Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo);
725 * Creates tiled geometry of for the texture which separates fully-opaque
726 * tiles from ones which use transparency.
730 bool CreateTiledGeometry(const Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo);
733 * Mark the texture as complete, and inform observers
734 * @param[in] textureInfo The struct associated with this Texture
736 void UploadComplete(TextureInfo& textureInfo);
739 * Notify the current observers that the texture upload is complete,
740 * then remove the observers from the list.
741 * @param[in] textureInfo The struct associated with this Texture
742 * @param[in] success If the pixel data was retrieved successfully and uploaded to GPU
744 void NotifyObservers(TextureInfo& textureInfo, bool success);
747 * @brief Generates a new, unique TextureId
748 * @return A unique TextureId
750 TextureManager::TextureId GenerateUniqueTextureId();
753 * @brief Used to lookup an index into the TextureInfoContainer from a TextureId
754 * @param[in] textureId The TextureId to look up
755 * @return The cache index
757 int GetCacheIndexFromId(TextureId textureId);
760 * @brief Generates a hash for caching based on the input parameters.
761 * Only applies size, fitting mode andsampling mode if the size is specified.
762 * Only applies maskTextureId if it isn't INVALID_TEXTURE_ID
763 * Always applies useAtlas.
764 * @param[in] url The URL of the image to load
765 * @param[in] size The image size
766 * @param[in] fittingMode The FittingMode to use
767 * @param[in] samplingMode The SamplingMode to use
768 * @param[in] useAtlas True if atlased
769 * @param[in] maskTextureId The masking texture id (or INVALID_TEXTURE_ID)
770 * @return A hash of the provided data for caching.
772 TextureHash GenerateHash(const std::string& url, const ImageDimensions size, const FittingMode::Type fittingMode, const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas, TextureId maskTextureId);
775 * @brief Looks up a cached texture by its hash.
776 * If found, the given parameters are used to check there is no hash-collision.
777 * @param[in] hash The hash to look up
778 * @param[in] url The URL of the image to load
779 * @param[in] size The image size
780 * @param[in] fittingMode The FittingMode to use
781 * @param[in] samplingMode The SamplingMode to use
782 * @param[in] useAtlas True if atlased
783 * @param[in] maskTextureId Optional texture ID to use to mask this image
784 * @param[in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
785 * @return A TextureId of a cached Texture if found. Or INVALID_TEXTURE_ID if not found.
787 TextureManager::TextureId FindCachedTexture(
788 const TextureManager::TextureHash hash,
789 const std::string& url,
790 const ImageDimensions size,
791 const FittingMode::Type fittingMode,
792 const Dali::SamplingMode::Type samplingMode,
794 TextureId maskTextureId,
795 MultiplyOnLoad preMultiplyOnLoad);
799 * @brief Helper class to keep the relation between AsyncImageLoader and corresponding LoadingInfo container
801 class AsyncLoadingHelper : public ConnectionTracker
805 * @brief Create an AsyncLoadingHelper.
806 * @param[in] textureManager Reference to the texture manager
808 AsyncLoadingHelper(TextureManager& textureManager);
811 * @brief Load a new frame of animated image
812 * @param[in] textureId TextureId to reference the texture that will be loaded
813 * @param[in] animatedImageLoading The AnimatedImageLoading to load animated image
814 * @param[in] frameIndex The frame index of a frame to be loaded frame
816 void LoadAnimatedImage(TextureId textureId,
817 Dali::AnimatedImageLoading animatedImageLoading,
818 uint32_t frameIndex);
821 * @brief Load a new texture.
822 * @param[in] textureId TextureId to reference the texture that will be loaded
823 * @param[in] url The URL of the image to load
824 * @param[in] desiredSize The size the image is likely to appear at.
825 * This can be set to 0,0 for automatic
826 * @param[in] fittingMode The FittingMode to use
827 * @param[in] samplingMode The SamplingMode to use
828 * @param[in] orientationCorrection Whether to use image metadata to rotate or flip the image,
829 * e.g., from portrait to landscape
830 * @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.
832 void Load(TextureId textureId,
833 const VisualUrl& url,
834 ImageDimensions desiredSize,
835 FittingMode::Type fittingMode,
836 SamplingMode::Type samplingMode,
837 bool orientationCorrection,
838 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
842 * @param [in] id of the texture
843 * @param [in] pixelBuffer of the to be masked image
844 * @param [in] maskPixelBuffer of the mask image
845 * @param [in] contentScale The factor to scale the content
846 * @param [in] cropToMask Whether to crop the content to the mask size
847 * @param [in] preMultiplyOnLoad if the image's color should be multiplied by it's alpha. Set to OFF if there is no alpha.
849 void ApplyMask(TextureId textureId,
850 Devel::PixelBuffer pixelBuffer,
851 Devel::PixelBuffer maskPixelBuffer,
854 DevelAsyncImageLoader::PreMultiplyOnLoad preMultiplyOnLoad);
857 AsyncLoadingHelper(const AsyncLoadingHelper&) = delete;
858 AsyncLoadingHelper& operator=(const AsyncLoadingHelper&) = delete;
860 AsyncLoadingHelper(AsyncLoadingHelper&& rhs);
861 AsyncLoadingHelper& operator=(AsyncLoadingHelper&& rhs) = delete;
865 * @brief Main constructor that used by all other constructors
867 AsyncLoadingHelper(Toolkit::AsyncImageLoader loader,
868 TextureManager& textureManager,
869 AsyncLoadingInfoContainerType&& loadingInfoContainer);
872 * @brief Callback to be called when texture loading is complete, it passes the pixel buffer on to texture manager.
873 * @param[in] id Loader id
874 * @param[in] pixelBuffer Image data
876 void AsyncLoadComplete(uint32_t id, Devel::PixelBuffer pixelBuffer);
879 Toolkit::AsyncImageLoader mLoader;
880 TextureManager& mTextureManager;
881 AsyncLoadingInfoContainerType mLoadingInfoContainer;
884 struct ExternalTextureInfo
887 TextureSet textureSet;
888 int16_t referenceCount{1};
891 struct EncodedBufferTextureInfo
893 EncodedBufferTextureInfo(TextureId textureId,
894 const EncodedImageBuffer& encodedImageBuffer)
895 : textureId(textureId),
896 encodedImageBuffer(encodedImageBuffer),
901 EncodedImageBuffer encodedImageBuffer;
902 int16_t referenceCount;
907 * Deleted copy constructor.
909 TextureManager(const TextureManager&) = delete;
912 * Deleted assignment operator.
914 TextureManager& operator=(const TextureManager& rhs) = delete;
917 * This is called by the TextureManagerUploadObserver when an observer is destroyed.
918 * We use the callback to know when to remove an observer from our notify list.
919 * @param[in] observer The observer that generated the callback
921 void ObserverDestroyed(TextureUploadObserver* observer);
923 private: // Member Variables:
924 TextureInfoContainerType mTextureInfoContainer; ///< Used to manage the life-cycle and caching of Textures
925 RoundRobinContainerView<AsyncLoadingHelper> mAsyncLocalLoaders; ///< The Asynchronous image loaders used to provide all local async loads
926 RoundRobinContainerView<AsyncLoadingHelper> mAsyncRemoteLoaders; ///< The Asynchronous image loaders used to provide all remote async loads
927 std::vector<ExternalTextureInfo> mExternalTextures; ///< Externally provided textures
928 std::vector<EncodedBufferTextureInfo> mEncodedBufferTextures; ///< Externally encoded buffer textures
929 Dali::Vector<LifecycleObserver*> mLifecycleObservers; ///< Lifecycle observers of texture manager
930 Dali::Vector<LoadQueueElement> mLoadQueue; ///< Queue of textures to load after NotifyObservers
931 TextureId mCurrentTextureId; ///< The current value used for the unique Texture Id generation
932 bool mQueueLoadFlag; ///< Flag that causes Load Textures to be queued.
935 } // namespace Internal
937 } // namespace Toolkit
941 #endif // DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H