1 #ifndef __DALI_TOOLKIT_ATLAS_MANAGER_H__
2 #define __DALI_TOOLKIT_ATLAS_MANAGER_H__
5 * Copyright (c) 2015 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.
22 #include <dali/public-api/common/dali-vector.h>
23 #include <dali/devel-api/geometry/mesh-data.h>
24 #include <dali/devel-api/images/atlas.h>
25 #include <dali/public-api/images/buffer-image.h>
33 namespace Internal DALI_INTERNAL
38 } // namespace Internal
44 * Creates and manages additions and removals of images from Texture Atlases
46 * The AtlasManager will match pixeltype and optimal block use to determine
47 * the appropriate atlas to upload an image to.
49 * A policy can be specified to determine the action the AtlasManager will carry
50 * out, should it not be able to add an image. This can return an error, or create
51 * a new atlas of pre-determined dimensions to accomodate the new image.
53 * Images are referenced by an ImageId once they have been successfully uploaded.
55 * Once an image has been successfully uploaded, Geometry can be generated by passing
56 * the ImageId to the GenerateMeshData method and geometry can be consolidated via
57 * the StitchMesh method.
59 * Images are reference counted once mesh data has been generated. An image is removed
60 * from the Atlas via the Remove( ImageId ) method. This unreferences the image and only
61 * physically removes it from the atlas once all references have been freed.
63 * If the AddPolicy is set to generate and error if an image can't be uploaded, then it
64 * is the applications responsibility to deal with the situation. An error will be indicated
65 * with an ImageId of 0.
67 * Examples using the AtlasManager
69 * Create or obtain the AtlasManager
72 * AtlasManager manager = AtlasManager::Get();
76 * Set the AtlasManager AddPolicy
80 * // Tell the atlas manager to create a new atlas, if it needs to
81 * manager.SetAddPolicy( FAIL_ON_ADD_CREATES );
83 * // Tell the atlas manager to return an error, if it can't add an image
84 * manager.SetAddPolicy( FAIL_ON_ADD_FAILS );
88 * Simple add and removal of BufferImage to and from an atlas
92 * // Structure returned by AtlasManager operations
95 * // Add image to an atlas ( will be created if none suitable exists )
96 * manager.Add( bitmapImage, slot );
98 * // slot.mImage returns the imageId for the bitmap, slot.mAtlas indicates the atlasId
99 * // that the image was added to. The imageId is used to communicate with the AtlasManager
100 * uint32_t imageId = slot.mImage;
103 * // Addition has failed.....
107 * // Done with image, so remove from atlas, if not being used elsewhere
108 * manager.Remove( imageId );
112 * Create a Specific Atlas for adding BufferImages to
116 * // Create an RGB888 atlas of 2048x2848, with a blocksize of 128x128
117 * uint32_t atlas = manager.CreateAtlas( 2048u, 2048u, 128u, 128u, Pixel::RGB888 );
119 * // Add an image to a preferred atlas ( note not specifying atlas may still result
120 * // in the bitmap being added to the atlas above )
121 * manager.Add( bitmapImage, slot, atlas );
125 * Create Geometry for a previously added image
129 * // Top left corner of geometry to be generated
130 * Vector2 position( 1.0f, 1.0f );
132 * // Geometry will end up here!
134 * manager.GenerateMeshData( imageId, position, meshData );
138 * Generating Geometry from multiple images in the same atlas
142 * MeshData firstMesh;
143 * MeshData secondMesh;
144 * manager.GenerateMeshData( imageid_1, position_1, firstMesh );
145 * manager.GenerateMeshData( imageid_2, position_2, secondMesh );
147 * // Combine the two meshes. Passing MESH_OPTIMIZE as an optional third parameter will remove duplicate vertices
148 * manager.StitchMesh( first, second );
154 class AtlasManager : public BaseHandle
158 typedef uint32_t SizeType;
159 typedef SizeType AtlasId;
160 typedef SizeType ImageId;
161 static const bool MESH_OPTIMIZE = true;
165 SizeType mWidth; // width of the atlas in pixels
166 SizeType mHeight; // height of the atlas in pixels
167 SizeType mBlockWidth; // width of a block in pixels
168 SizeType mBlockHeight; // height of a block in pixels
172 * Metrics structures to describe Atlas Manager state
175 struct AtlasMetricsEntry
177 AtlasSize mSize; // size of atlas and blocks
178 SizeType mBlocksUsed; // number of blocks used in the atlas
179 SizeType mTotalBlocks; // total blocks used by atlas
180 Pixel::Format mPixelFormat; // pixel format of the atlas
185 SizeType mAtlasCount; // number of atlases
186 SizeType mTextureMemoryUsed; // texture memory used by atlases
187 Dali::Vector< AtlasMetricsEntry > mAtlasMetrics; // container of atlas information
191 * Create an AtlasManager handle; this can be initialised with AtlasManager::New()
192 * Calling member functions with an uninitialised handle is not allowed.
197 * @brief Get new instance of AtlasManager object.
199 * @return A handle to the AtlasManager control.
201 static AtlasManager New();
206 * This is non-virtual since derived Handle types must not contain data or virtual methods.
211 * Policy on failing to add an image
220 * @brief Container to hold result of placing texture into atlas
224 ImageId mImageId; // Id of stored Image
225 AtlasId mAtlasId; // Id of Atlas containing this slot
228 typedef Dali::Vector< AtlasManager::AtlasSlot > slotContainer;
231 * @brief Create a blank atlas of specific dimensions and pixel format with a certain block size
233 * @param[in] size desired atlas dimensions
234 * @param[in] pixelformat format of a pixel in atlas
238 AtlasId CreateAtlas( const AtlasSize& size, Pixel::Format pixelformat = Pixel::RGBA8888 );
241 * @brief Set the policy on failure to add an image to an atlas
243 * @param policy policy to carry out if add fails
245 void SetAddPolicy( AddFailPolicy policy );
248 * @brief Attempts to add an image to the most suitable atlas
250 * @details Add Policy may dictate that a new atlas is created if it can't presently be placed.
251 * If an add is made before an atlas is created under this policy,
252 * then a default size atlas will be created
254 * @param[in] image reference to a bitmapimage
255 * @param[out] slot result of add operation
256 * @param[in] atlas optional preferred atlas
258 void Add( const BufferImage& image,
263 * @brief Remove previously added bitmapimage from atlas
265 * @param[in] id ImageId returned in the AtlasSlot from the add operation
267 * @return if true then image has been removed from the atlas
269 bool Remove( ImageId id );
272 * @brief Generate mesh data for a previously added image
274 * @param[in] id Image Id returned in the AtlasSlot from the add operation
275 * @param[in] position position of the resulting mesh in model space
276 * @param[out] mesh Mesh Data Object to populate with mesh data
278 void GenerateMeshData( ImageId id,
279 const Vector2& position,
283 * @brief Append second mesh to the first mesh
285 * @param[in] first First mesh
286 * @param[in] second Second mesh
287 * @param[in] optimize should we optimize vertex data
289 void StitchMesh( MeshData& first,
290 const MeshData& second,
291 bool optimize = false );
294 * @brief Combine two meshes, outputting the result into a new mesh
296 * @param[in] first First mesh
297 * @param[in] second Second mesh
298 * @param[in] optimize should we optimize vertex data
299 * @param[out] out resulting mesh
301 void StitchMesh( const MeshData& first,
302 const MeshData& second,
304 bool optimize = false );
307 * @brief Get the BufferImage containing an atlas
309 * @param[in] atlas AtlasId returned when atlas was created
311 * @return Atlas Handle
313 Dali::Atlas GetAtlasContainer( AtlasId atlas ) const;
316 * @brief Get the Id of the atlas containing an image
318 * @param[in] id ImageId
322 AtlasId GetAtlas( ImageId id );
324 * @brief Get the current size of an atlas
326 * @param[in] atlas AtlasId
328 * @return AtlasSize structure for the atlas
330 const AtlasSize& GetAtlasSize( AtlasId atlas );
333 * @brief Get the number of blocks available in an atlas
335 * @param[in] atlas AtlasId
337 * @return Number of blocks free in this atlas
339 SizeType GetFreeBlocks( AtlasId atlas );
342 * @brief Sets the pixel area of any new atlas and also the individual block size
344 * @param[in] size Atlas size structure
346 * @param blockSize pixel area in atlas for a block
348 void SetNewAtlasSize( const AtlasSize& size );
351 * @brief Get the number of atlases created
353 * @return number of atlases
355 SizeType GetAtlasCount() const;
358 * @brief Get the pixel format used by an atlas
360 * @param[in] atlas AtlasId
362 * @return Pixel format used by this atlas
364 Pixel::Format GetPixelFormat( AtlasId atlas );
367 * @brief Fill in a metrics structure showing current status of this Atlas Manager
369 * @param[in] metrics metrics structure to be filled
371 void GetMetrics( Metrics& metrics );
375 explicit DALI_INTERNAL AtlasManager(Internal::AtlasManager *impl);
379 } // namespace Toolkit
383 #endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__