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