Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / atlas-manager / atlas-manager.h
1 #ifndef __DALI_TOOLKIT_ATLAS_MANAGER_H__
2 #define __DALI_TOOLKIT_ATLAS_MANAGER_H__
3
4 /*
5  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <stdint.h>
22 #include <dali/public-api/common/dali-vector.h>
23 #include <dali/public-api/geometry/mesh-data.h>
24 #include <dali/public-api/images/atlas.h>
25 #include <dali/public-api/images/buffer-image.h>
26
27 namespace Dali
28 {
29
30 namespace Toolkit
31 {
32
33 namespace Internal DALI_INTERNAL
34 {
35
36 class AtlasManager;
37
38 } // namespace Internal
39
40 /**
41  * AtlasManager
42  * ------------
43  *
44  * Creates and manages additions and removals of images from Texture Atlases
45  *
46  * The AtlasManager will match pixeltype and optimal block use to determine
47  * the appropriate atlas to upload an image to.
48  *
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.
52  *
53  * Images are referenced by an ImageId once they have been successfully uploaded.
54  *
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.
58  *
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.
62  *
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.
66  *
67  * Examples using the AtlasManager
68  *
69  * Create or obtain the AtlasManager
70  * @code
71  *
72  * AtlasManager manager = AtlasManager::Get();
73  *
74  * @endcode
75  *
76  * Set the AtlasManager AddPolicy
77  *
78  * @code
79  *
80  * // Tell the atlas manager to create a new atlas, if it needs to
81  * manager.SetAddPolicy( FAIL_ON_ADD_CREATES );
82  *
83  * // Tell the atlas manager to return an error, if it can't add an image
84  * manager.SetAddPolicy( FAIL_ON_ADD_FAILS );
85  *
86  * @endcode
87  *
88  * Simple add and removal of BufferImage to and from an atlas
89  *
90  * @code
91  *
92  * // Structure returned by AtlasManager operations
93  * AtlasSlot slot;
94  *
95  * // Add image to an atlas ( will be created if none suitable exists )
96  * manager.Add( bitmapImage, slot );
97  *
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;
101  * if ( !imageId )
102  * {
103  *  // Addition has failed.....
104  * }
105  * ...
106  * ...
107  * // Done with image, so remove from atlas, if not being used elsewhere
108  * manager.Remove( imageId );
109  *
110  * @endcode
111  *
112  * Create a Specific Atlas for adding BufferImages to
113  *
114  * @code
115  *
116  * // Create an RGB888 atlas of 2048x2848, with a blocksize of 128x128
117  * uint32_t atlas = manager.CreateAtlas( 2048u, 2048u, 128u, 128u, Pixel::RGB888 );
118  *
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 );
122  *
123  * @endcode
124  *
125  * Create Geometry for a previously added image
126  *
127  * @code
128  *
129  * // Top left corner of geometry to be generated
130  * Vector2 position( 1.0f, 1.0f );
131  *
132  * // Geometry will end up here!
133  * MeshData meshData;
134  * manager.GenerateMeshData( imageId, position, meshData );
135  *
136  * @endcode
137  *
138  * Generating Geometry from multiple images in the same atlas
139  *
140  * @code
141  *
142  * MeshData firstMesh;
143  * MeshData secondMesh;
144  * manager.GenerateMeshData( imageid_1, position_1, firstMesh );
145  * manager.GenerateMeshData( imageid_2, position_2, secondMesh );
146  *
147  * // Combine the two meshes. Passing MESH_OPTIMIZE as an optional third parameter will remove duplicate vertices
148  * manager.StitchMesh( first, second );
149  *
150  * @endcode
151  *
152  */
153
154 class AtlasManager : public BaseHandle
155 {
156 public:
157
158   typedef uint32_t SizeType;
159   typedef SizeType AtlasId;
160   typedef SizeType ImageId;
161   static const bool MESH_OPTIMIZE = true;
162
163   /**
164    * Create an AtlasManager handle; this can be initialised with AtlasManager::New()
165    * Calling member functions with an uninitialised handle is not allowed.
166    */
167   AtlasManager();
168
169   /**
170    * @brief Get new instance of AtlasManager object.
171    *
172    * @return A handle to the AtlasManager control.
173    */
174   static AtlasManager New();
175
176   /**
177    * @brief Destructor
178    *
179    * This is non-virtual since derived Handle types must not contain data or virtual methods.
180    */
181   ~AtlasManager();
182
183   /**
184    * Policy on failing to add an image
185    */
186   enum AddFailPolicy
187   {
188     FAIL_ON_ADD_FAILS,
189     FAIL_ON_ADD_CREATES
190   };
191
192   /**
193    * @brief Container to hold result of placing texture into atlas
194    */
195   struct AtlasSlot
196   {
197     ImageId mImageId;                           // Id of stored Image
198     AtlasId mAtlasId;                           // Id of Atlas containing this slot
199   };
200
201   typedef Dali::Vector< AtlasManager::AtlasSlot > slotContainer;
202
203   /**
204    * @brief Create a blank atlas of specific dimensions and pixel format with a certain block size
205    *
206    * @param width desired atlas width in pixels
207    * @param height desired atlas height in pixels
208    * @param blockWidth block width to use in atlas in pixels
209    * @param blockHeight block height to use in atlas in pixels
210    * @param pixelformat format of a pixel in atlas
211    *
212    * @return atlas Id
213    */
214   AtlasId CreateAtlas(  SizeType width,
215                         SizeType height,
216                         SizeType blockWidth,
217                         SizeType blockHeight,
218                         Pixel::Format pixelformat = Pixel::RGBA8888 );
219
220   /**
221    * @brief Set the policy on failure to add an image to an atlas
222    *
223    * @param policy policy to carry out if add fails
224    */
225   void SetAddPolicy( AddFailPolicy policy );
226
227   /**
228    * @brief Attempts to add an image to the most suitable atlas
229    *
230    * @details Add Policy may dictate that a new atlas is created if it can't presently be placed.
231    *          If an add is made before an atlas is created under this policy,
232    *          then a default size atlas will be created
233    *
234    * @param[in] image reference to a bitmapimage
235    * @param[out] slot result of add operation
236    * @param[in] atlas optional preferred atlas
237    */
238   void Add( const BufferImage& image,
239             AtlasSlot& slot,
240             AtlasId atlas = 0 );
241
242   /**
243    * @brief Remove previously added bitmapimage from atlas
244    *
245    * @param[in] id ImageId returned in the AtlasSlot from the add operation
246    *
247    * @return if true then image has been removed from the atlas
248    */
249   bool Remove( ImageId id );
250
251   /**
252    * @brief Generate mesh data for a previously added image
253    *
254    * @param[in] id Image Id returned in the AtlasSlot from the add operation
255    * @param[in] position position of the resulting mesh in model space
256    * @param[out] mesh Mesh Data Object to populate with mesh data
257    */
258   void GenerateMeshData( ImageId id,
259                          const Vector2& position,
260                          MeshData& mesh );
261
262   /**
263    * @brief Append second mesh to the first mesh
264    *
265    * @param[in] first First mesh
266    * @param[in] second Second mesh
267    * @param[in] optimize should we optimize vertex data
268    */
269   void StitchMesh( MeshData& first,
270                    const MeshData& second,
271                    bool optimize = false );
272
273   /**
274    * @brief Combine two meshes, outputting the result into a new mesh
275    *
276    * @param[in] first First mesh
277    * @param[in] second Second mesh
278    * @param[in] optimize should we optimize vertex data
279    * @param[out] out resulting mesh
280    */
281   void StitchMesh( const MeshData& first,
282                    const MeshData& second,
283                    MeshData& out,
284                    bool optimize = false );
285
286   /**
287    * @brief Get the BufferImage containing an atlas
288    *
289    * @param atlas AtlasId returned when atlas was created
290    * @return Atlas Handle
291    */
292   Dali::Atlas GetAtlasContainer( AtlasId atlas ) const;
293
294   /**
295    * @brief Get the Id of the atlas containing an image
296    *
297    * @param id ImageId
298    * @return Atlas Id
299    */
300   AtlasId GetAtlas( ImageId id );
301
302   /**
303    * @brief Get the size of the blocks used in an atlas
304    *
305    * @param atlas AtlasId
306    * @return width and height of the blocks used
307    */
308   Vector2 GetBlockSize( AtlasId atlas );
309
310   /**
311    * @brief Get the number of blocks available in an atlas
312    *
313    * @param atlas AtlasId
314    * @return Number of blocks free in this atlas
315    */
316   SizeType GetFreeBlocks( AtlasId atlas );
317
318   /**
319    * @brief Sets the pixel area of any new atlas and also the individual block size
320    *
321    * @param size pixel area of atlas
322    * @param blockSize pixel area in atlas for a block
323    */
324   void SetAtlasSize( const Vector2& size,
325                      const Vector2& blockSize );
326
327   /**
328    * @brief Get the number of atlases created
329    *
330    * @return number of atlases
331    */
332   SizeType GetAtlasCount() const;
333
334   /**
335    * @brief Get the pixel format used by an atlas
336    *
337    * @param atlas AtlasId
338    * @return Pixel format used by this atlas
339    */
340   Pixel::Format GetPixelFormat( AtlasId atlas );
341
342 private:
343
344   explicit DALI_INTERNAL AtlasManager(Internal::AtlasManager *impl);
345
346 };
347
348 } // namespace Toolkit
349
350 } // namespace Dali
351
352 #endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__