Merge "Dont register accessibility and keyboard focus properties as scene graph prope...
[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/devel-api/geometry/mesh-data.h>
24 #include <dali/devel-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   struct AtlasSize
164   {
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
169   };
170
171   /**
172    * Metrics structures to describe Atlas Manager state
173    *
174    */
175   struct AtlasMetricsEntry
176   {
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
181   };
182
183   struct Metrics
184   {
185     SizeType mAtlasCount;                               // number of atlases
186     SizeType mTextureMemoryUsed;                        // texture memory used by atlases
187     Dali::Vector< AtlasMetricsEntry > mAtlasMetrics;    // container of atlas information
188   };
189
190   /**
191    * Create an AtlasManager handle; this can be initialised with AtlasManager::New()
192    * Calling member functions with an uninitialised handle is not allowed.
193    */
194   AtlasManager();
195
196   /**
197    * @brief Get new instance of AtlasManager object.
198    *
199    * @return A handle to the AtlasManager control.
200    */
201   static AtlasManager New();
202
203   /**
204    * @brief Destructor
205    *
206    * This is non-virtual since derived Handle types must not contain data or virtual methods.
207    */
208   ~AtlasManager();
209
210   /**
211    * Policy on failing to add an image
212    */
213   enum AddFailPolicy
214   {
215     FAIL_ON_ADD_FAILS,
216     FAIL_ON_ADD_CREATES
217   };
218
219   /**
220    * @brief Container to hold result of placing texture into atlas
221    */
222   struct AtlasSlot
223   {
224     ImageId mImageId;                           // Id of stored Image
225     AtlasId mAtlasId;                           // Id of Atlas containing this slot
226   };
227
228   typedef Dali::Vector< AtlasManager::AtlasSlot > slotContainer;
229
230   /**
231    * @brief Create a blank atlas of specific dimensions and pixel format with a certain block size
232    *
233    * @param[in] size desired atlas dimensions
234    * @param[in] pixelformat format of a pixel in atlas
235    *
236    * @return atlas Id
237    */
238   AtlasId CreateAtlas( const AtlasSize& size, Pixel::Format pixelformat = Pixel::RGBA8888 );
239
240   /**
241    * @brief Set the policy on failure to add an image to an atlas
242    *
243    * @param policy policy to carry out if add fails
244    */
245   void SetAddPolicy( AddFailPolicy policy );
246
247   /**
248    * @brief Attempts to add an image to the most suitable atlas
249    *
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
253    *
254    * @param[in] image reference to a bitmapimage
255    * @param[out] slot result of add operation
256    * @param[in] atlas optional preferred atlas
257    */
258   void Add( const BufferImage& image,
259             AtlasSlot& slot,
260             AtlasId atlas = 0 );
261
262   /**
263    * @brief Remove previously added bitmapimage from atlas
264    *
265    * @param[in] id ImageId returned in the AtlasSlot from the add operation
266    *
267    * @return if true then image has been removed from the atlas
268    */
269   bool Remove( ImageId id );
270
271   /**
272    * @brief Generate mesh data for a previously added image
273    *
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
277    * @param[in] addReference Whether to increase the internal reference count for image or not
278    */
279   void GenerateMeshData( ImageId id,
280                          const Vector2& position,
281                          MeshData& mesh,
282                          bool addReference = true );
283
284   /**
285    * @brief Append second mesh to the first mesh
286    *
287    * @param[in] first First mesh
288    * @param[in] second Second mesh
289    * @param[in] optimize should we optimize vertex data
290    */
291   void StitchMesh( MeshData& first,
292                    const MeshData& second,
293                    bool optimize = false );
294
295   /**
296    * @brief Combine two meshes, outputting the result into a new mesh
297    *
298    * @param[in] first First mesh
299    * @param[in] second Second mesh
300    * @param[in] optimize should we optimize vertex data
301    * @param[out] out resulting mesh
302    */
303   void StitchMesh( const MeshData& first,
304                    const MeshData& second,
305                    MeshData& out,
306                    bool optimize = false );
307
308   /**
309    * @brief Get the BufferImage containing an atlas
310    *
311    * @param[in] atlas AtlasId returned when atlas was created
312    *
313    * @return Atlas Handle
314    */
315   Dali::Atlas GetAtlasContainer( AtlasId atlas ) const;
316
317   /**
318    * @brief Get the Id of the atlas containing an image
319    *
320    * @param[in] id ImageId
321    *
322    * @return Atlas Id
323    */
324   AtlasId GetAtlas( ImageId id );
325   /**
326    * @brief Get the current size of an atlas
327    *
328    * @param[in] atlas AtlasId
329    *
330    * @return AtlasSize structure for the atlas
331    */
332   const AtlasSize& GetAtlasSize( AtlasId atlas );
333
334   /**
335    * @brief Get the number of blocks available in an atlas
336    *
337    * @param[in] atlas AtlasId
338    *
339    * @return Number of blocks free in this atlas
340    */
341   SizeType GetFreeBlocks( AtlasId atlas );
342
343   /**
344    * @brief Sets the pixel area of any new atlas and also the individual block size
345    *
346    * @param[in] size Atlas size structure
347    *
348    * @param blockSize pixel area in atlas for a block
349    */
350   void SetNewAtlasSize( const AtlasSize& size );
351
352   /**
353    * @brief Get the number of atlases created
354    *
355    * @return number of atlases
356    */
357   SizeType GetAtlasCount() const;
358
359   /**
360    * @brief Get the pixel format used by an atlas
361    *
362    * @param[in] atlas AtlasId
363    *
364    * @return Pixel format used by this atlas
365    */
366   Pixel::Format GetPixelFormat( AtlasId atlas );
367
368   /**
369    * @brief Fill in a metrics structure showing current status of this Atlas Manager
370    *
371    * @param[in] metrics metrics structure to be filled
372    */
373   void GetMetrics( Metrics& metrics );
374
375 private:
376
377   explicit DALI_INTERNAL AtlasManager(Internal::AtlasManager *impl);
378
379 };
380
381 } // namespace Toolkit
382
383 } // namespace Dali
384
385 #endif // __DALI_TOOLKIT_ATLAS_MANAGER_H__