License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-core.git] / dali / internal / event / resources / resource-client.h
1 #ifndef __DALI_INTERNAL_RESOURCE_CLIENT_H__
2 #define __DALI_INTERNAL_RESOURCE_CLIENT_H__
3
4 /*
5  * Copyright (c) 2014 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
21 // EXTERNAL INCLUDES
22 #include <string>
23 #include <boost/functional/hash.hpp>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/ref-counted-dali-vector.h>
27 #include <dali/public-api/images/native-image.h>
28 #include <dali/integration-api/glyph-set.h>
29 #include <dali/internal/event/resources/resource-client-declarations.h>
30 #include <dali/internal/event/resources/image-ticket.h>
31 #include <dali/internal/event/resources/resource-ticket-lifetime-observer.h>
32 #include <dali/internal/common/bitmap-upload.h>
33 #include <dali/internal/common/message.h>
34 #include <dali/internal/update/modeling/internal-mesh-data.h>
35
36 namespace Dali
37 {
38
39 typedef boost::hash<const std::string> StringHash;
40 class NativeImage;
41
42 namespace Integration
43 {
44 class Bitmap;
45 class GlyphSet;
46 }
47
48 namespace Internal
49 {
50 class ResourceManager;
51 class NotificationManager;
52 class GlyphLoadObserver;
53
54 namespace SceneGraph
55 {
56 class UpdateManager;
57 }
58
59 typedef Integration::ResourceId ResourceId;
60
61 /** Raw bytes of a resource laid out exactly as it wouldbe in a file, but in memory. */
62 typedef Dali::RefCountedVector<uint8_t> RequestBuffer;
63 /** Counting smart pointer for managing a buffer of raw bytes. */
64 typedef IntrusivePtr<RequestBuffer> RequestBufferPtr;
65
66 /**
67  * ResourceClient is an event side object that manages resource requests.
68  * It uses ResourceTicket objects to keep track of the lifetime of each request.
69  * If the same resource is required by two client objects, they will share the same ResourceTicket
70  * i.e. only one load will occur using the native filesystem.
71  *
72  * Resources themselves are handled by the Resource Manager in the update thread
73  */
74 class ResourceClient : public ResourceTicketLifetimeObserver
75 {
76 public:
77   typedef Rect<unsigned int>    RectArea;     ///< rectangular area (x,y,w,h)
78
79   /**
80    * Create a resource client.
81    * There should exactly one of these objects per Dali Core.
82    * @param[in] resourceManager The resource manager
83    * @param[in] updateManager The update manager
84    */
85   ResourceClient( ResourceManager& resourceManager, SceneGraph::UpdateManager& updateManager );
86
87   /**
88    * Virtual destructor.
89    */
90   virtual ~ResourceClient();
91
92 public: // Used by application-side objects e.g. Dali::Image
93
94   /**
95    * Request a resource from the native filesystem.
96    * Adding an observer to the ticket will enable the application to determine when the
97    * resource has finished loading.
98    * @param[in] type The type of requested resource.
99    * @param[in] path The path to the requested resource.
100    * @param[in] priority The priority of the request. This is ignored if the resource is already being loaded.
101    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
102    */
103   ResourceTicketPtr RequestResource( const Integration::ResourceType& type,
104                                      const std::string& path,
105                                      Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
106   /**
107    * Request that a resource be decoded in the background from the memory buffer
108    * that is passed-in. The data in the memory buffer should be formatted exactly
109    * as it would be in a file of a supported resource type.
110    *
111    * Adding an observer to the ticket will enable the application to determine when the
112    * resource has finished decoding.
113    * @note Only images are currently supported by this function.
114    * @param[in] type The type of resource. Must be BitmapResourceType.
115    * @param[in] buffer The raw data of the resource.
116    * @param[in] priority The priority of the request. This is ignored if the resource is already being loaded.
117    * @return A ref-counted request object on success or a null pointer on failure.
118    *         Keep a copy until the resource is no longer required.
119    */
120   ResourceTicketPtr DecodeResource( const Integration::ResourceType& type,
121                                     RequestBufferPtr buffer,
122                                     Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
123
124   /**
125    * Load a shader program from a file
126    * @param[in] type     A ResourceType specialization describing a shader program resource
127    * @param[in] filename The file's full path/file name
128    * @return             A ref-counted request object. Keep a copy until the resource is no longer required.
129    */
130   ResourceTicketPtr LoadShader(Integration::ShaderResourceType& type, const std::string& filename);
131
132   /**
133    * Request reloading a resource from the native filesystem.
134    * If the resource is still loading, this request is ignored.
135    * The ticket observer will be notified of completion with ResourceLoadingSucceeded() or
136    * ResourceLoadingFailed()
137    *
138    * @param[in] id resource id
139    * @param[in] priority The priority of the request. This is ignored if the resource is already being refreshed.
140    * @return true if successful, false if resource doesn't exist
141    */
142   bool ReloadResource( ResourceId id, Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
143
144   /**
145    * Save a resource to the given url.
146    * If the resource type is saveable (model or shader), then the ticket observer will get
147    * notified with ResourceSavingSucceeded() or ResourceSavingFailed(), otherwise there
148    * will be no response.
149    * @param[in] ticket The ticket of the resource to save
150    * @param[in] url The url to save the resource to.
151    */
152   void SaveResource( ResourceTicketPtr ticket, const std::string& url );
153
154   /**
155    * Get the ticket for the associated resource ID.
156    * If no ticket can be found for this resource, then this returns
157    * NULL to indicate the resource doesn't exist.
158    * @param[in] id The resource ID.
159    * @return A resource ticket, or NULL if no resource existed with the given ID.
160    */
161   ResourceTicketPtr RequestResourceTicket( ResourceId id );
162
163   /**
164    * Reqeust allocation of a bitmap resource
165    * @note Older hardware may require bufferWidth and bufferHeight to be a power of two
166    * @param[in] width         Image width in pixels
167    * @param[in] height        Image height in pixels
168    * @param[in] bufferWidth   Buffer width (stride) in pixels
169    * @param[in] bufferHeight  Buffer height in pixels
170    * @param[in] pixelformat   Pixel format
171    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
172    */
173   ImageTicketPtr AllocateBitmapImage ( unsigned int width,
174                                        unsigned int height,
175                                        unsigned int bufferWidth,
176                                        unsigned int bufferHeight,
177                                        Pixel::Format pixelformat );
178
179   /**
180    * Injects a bitmap resource (does not require loading).
181    * @pre bitmap has to be initialized
182    * @param[in] bitmap an initialized bitmap
183    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
184    */
185   ImageTicketPtr AddBitmapImage(Integration::Bitmap* bitmap);
186
187   /**
188    * Add an existing resource to the resource manager.
189    * @param [in] resourceData the NativeImage object
190    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
191    */
192   ResourceTicketPtr AddNativeImage ( NativeImage& resourceData );
193
194   /**
195    * Add a framebuffer resource to the resource manager.
196    * @param[in] width       width in pixels
197    * @param[in] height      height in pixels
198    * @param[in] pixelFormat Pixel format
199    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
200    */
201   ImageTicketPtr AddFrameBufferImage ( unsigned int width, unsigned int height, Pixel::Format pixelFormat );
202
203   /**
204    * Add a framebuffer resource to the resource manager.
205    * @param[in] nativeImage the NativeImage object
206    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
207    */
208   ImageTicketPtr AddFrameBufferImage ( NativeImage& nativeImage );
209
210   /**
211    * Request allocation of a texture.
212    * The texture is initially empty.
213    * @note Older hardware may require image width and image height to be a power of two
214    * @param[in] width         Image width in pixels
215    * @param[in] height        Image height in pixels
216    * @param[in] pixelformat   Pixel format
217    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
218    */
219   ResourceTicketPtr AllocateTexture( unsigned int width,
220                                      unsigned int height,
221                                      Pixel::Format pixelformat );
222
223   /**
224    * Update a texture with an array of bitmaps.
225    * Typically used to upload multiple glyph bitmaps to a texture.
226    * @param[in] id texture resource id
227    * @param[in] uploadArray the upload array
228    */
229   void UpdateTexture( ResourceId id,
230                       BitmapUploadArray uploadArray );
231
232   /**
233    * Requests allocation of a mesh resource
234    * @param[in] meshData representing the mesh; ownership is taken.
235    */
236   ResourceTicketPtr AllocateMesh( OwnerPointer<MeshData>& meshData );
237
238   /**
239    * Update bitmap area
240    * @param[in] ticket The ticket representing the bitmap
241    * @param[in] updateArea the area updated.
242    */
243   void UpdateBitmapArea( ResourceTicketPtr ticket, RectArea& updateArea );
244
245   /**
246    * Update the mesh used by ticket
247    * @note Should use same mechanism as update manager
248    * @param[in] ticket The ticket holding the mesh data
249    * @param[in] meshData The new mesh data
250    */
251   void UpdateMesh( ResourceTicketPtr ticket, const Dali::MeshData& meshData );
252
253   /**
254    * Find Bitmap by ticket.
255    * @pre ticket has to identify a Bitmap
256    * @param[in] ticket The ticket returned from AllocateBitmapImage() or AddBitmapImage()
257    * @return The bitmap, or NULL if the ticket did not reference a bitmap
258    */
259   Integration::Bitmap* GetBitmap(ResourceTicketPtr ticket);
260
261   /**
262    * Set the glyph load observer
263    * @param glyphLoadedInterface pointer to an object which supports the glyphLoadedInterface
264    */
265   void SetGlyphLoadObserver( GlyphLoadObserver* glyphLoadedInterface );
266
267   /**
268    * Update atlas status
269    * @param id The ticket resource Id
270    * @param atlasId The atlas texture Id
271    * @param loadStatus The status update
272    */
273   void UpdateAtlasStatus( ResourceId id, ResourceId atlasId, Integration::LoadStatus loadStatus );
274
275 public: // From ResourceTicketLifetimeObserver.
276
277   /**
278    * This indicates that the previously requested resource is no longer needed.
279    * @param[in] ticket The ticket to remove from resource manager.
280    */
281   virtual void ResourceTicketDiscarded(const ResourceTicket& ticket);
282
283 public: // Message methods
284
285   /**
286    * Notify associated ticket observers that the resource has been uploaded to GL.
287    * @param[in] id The resource id of the uploaded resource
288    */
289   void NotifyUploaded( ResourceId id );
290
291   /**
292    * Notify client that the resource has been updated and requires saving.
293    * @param[in] id The resource id of the updated resource
294    */
295   void NotifySaveRequested( ResourceId id );
296
297   /**
298    * Notify associated ticket observers that the resource is loading.
299    * @param[in] id The resource id of the loading resource
300    */
301   void NotifyLoading( ResourceId id );
302
303   /**
304    * Notify associated ticket observers that the resource has loaded.
305    * @param[in] id The resource id of the loaded resource
306    */
307   void NotifyLoadingSucceeded( ResourceId id );
308
309   /**
310    * Notify associated ticket observers that the resource has failed to load
311    * @param[in] id The resource id of the resource
312    */
313   void NotifyLoadingFailed( ResourceId id );
314
315   /**
316    * Notify associated ticket observers that the resource has saved successfully
317    * @param[in] id The resource id of the saved resource
318    */
319   void NotifySavingSucceeded( ResourceId id );
320
321   /**
322    * Notify associated ticket observers that the resource save failed
323    * @param[in] id The resource id of the failed resource
324    */
325   void NotifySavingFailed( ResourceId id );
326
327   /**
328    * Notify associated glyph loader observer that a glyph set is loading
329    * @param[in] id The resource id of the loaded id
330    * @param[in] glyphSet The loading glyph set
331    * @param[in] loadStatus The current load status
332    */
333   void NotifyGlyphSetLoaded( ResourceId id, const Integration::GlyphSet& glyphSet, Integration::LoadStatus loadStatus );
334
335   /**
336    * Finds ImageTicket which belongs to resource identified by id and updates the cached size and pixelformat
337    * with the data from texture.
338    * !!! NOTE, this will replace the whole ImageAttributes member of the ticket, not just the three properties mentioned !!!
339    * @param id The resource id to find the ticket of
340    * @param imageAttributes The image attributes to assign to the ticket
341    */
342   void UpdateImageTicket( ResourceId id, const Dali::ImageAttributes& imageAttributes ); ///!< Issue #AHC01
343
344 private:
345   ResourceManager& mResourceManager;          ///< The resource manager
346   SceneGraph::UpdateManager& mUpdateManager;  ///< update manager
347
348 private:
349   struct Impl;
350   Impl* mImpl;
351 };
352
353 inline MessageBase* UpdateImageTicketMessage( ResourceClient& client, ResourceId id, const Dali::ImageAttributes& attrs )
354 {
355   return new MessageValue2< ResourceClient, ResourceId, Dali::ImageAttributes >(
356     &client, &ResourceClient::UpdateImageTicket, id, attrs );
357 }
358
359 inline MessageBase* UploadedMessage( ResourceClient& client, ResourceId id )
360 {
361   return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifyUploaded, id );
362 }
363
364 inline MessageBase* SaveResourceMessage( ResourceClient& client, ResourceId id )
365 {
366   return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifySaveRequested, id );
367 }
368
369 inline MessageBase* LoadingMessage( ResourceClient& client, ResourceId id )
370 {
371   return new MessageValue1< ResourceClient, ResourceId  >( &client, &ResourceClient::NotifyLoading, id );
372 }
373
374 inline MessageBase* LoadingSucceededMessage( ResourceClient& client, ResourceId id )
375 {
376   return new MessageValue1< ResourceClient, ResourceId  >( &client, &ResourceClient::NotifyLoadingSucceeded, id );
377 }
378
379 inline MessageBase* LoadingFailedMessage( ResourceClient& client, ResourceId id )
380 {
381   return new MessageValue1< ResourceClient, ResourceId  >( &client, &ResourceClient::NotifyLoadingFailed, id );
382 }
383
384 inline MessageBase* SavingSucceededMessage( ResourceClient& client, ResourceId id )
385 {
386   return new MessageValue1< ResourceClient, ResourceId  >( &client, &ResourceClient::NotifySavingSucceeded, id );
387 }
388
389 inline MessageBase* SavingFailedMessage( ResourceClient& client, ResourceId id )
390 {
391   return new MessageValue1< ResourceClient, ResourceId  >( &client, &ResourceClient::NotifySavingFailed, id );
392 }
393
394 inline MessageBase* LoadingGlyphSetSucceededMessage( ResourceClient& client, ResourceId id, const Integration::GlyphSetPointer& glyphSet, Integration::LoadStatus loadStatus )
395 {
396   return new MessageValue3< ResourceClient, ResourceId, Integration::GlyphSet, Integration::LoadStatus >( &client, &ResourceClient::NotifyGlyphSetLoaded, id, *glyphSet, loadStatus );
397 }
398
399 } // namespace Internal
400 } // namespace Dali
401
402 #endif // __DALI_INTERNAL_RESOURCE_CLIENT_H__