Merge "Change PixelData to use the handle/body pattern" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / update / resources / resource-manager.h
1 #ifndef __DALI_INTERNAL_RESOURCE_MANAGER_H__
2 #define __DALI_INTERNAL_RESOURCE_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
21 // EXTERNAL INCLUDES
22 #include <string>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/images/image.h>
26 #include <dali/public-api/images/frame-buffer-image.h>
27 #include <dali/public-api/images/native-image-interface.h>
28 #include <dali/public-api/images/buffer-image.h>
29 #include <dali/devel-api/common/ref-counted-dali-vector.h>
30
31 #include <dali/integration-api/bitmap.h>
32 #include <dali/integration-api/platform-abstraction.h>
33 #include <dali/integration-api/resource-cache.h>
34
35 #include <dali/internal/common/message.h>
36 #include <dali/internal/event/common/event-thread-services.h>
37 #include <dali/internal/event/common/thread-local-storage.h>
38 #include <dali/internal/event/images/pixel-data-impl.h>
39 #include <dali/internal/event/resources/resource-type-path.h>
40 #include <dali/internal/event/resources/resource-client-declarations.h>
41 #include <dali/internal/update/resources/resource-manager-declarations.h>
42
43 namespace Dali
44 {
45
46 class NativeImageInterface;
47
48 namespace Integration
49 {
50 struct ResourceType;
51 }
52
53 namespace Internal
54 {
55 class TextureMetadata;
56 class ImageAttributes;
57
58 // value types used by messages
59 template <> struct ParameterType< Integration::LoadResourcePriority >
60 : public BasicType< Integration::LoadResourcePriority > {};
61 template <> struct ParameterType< Pixel::Format >
62 : public BasicType< Pixel::Format > {};
63 template <> struct ParameterType< RenderBuffer::Format >
64 : public BasicType< RenderBuffer::Format > {};
65 template <> struct ParameterType< Integration::ResourceTypeId >
66 : public BasicType< Integration::ResourceTypeId > {};
67
68 namespace SceneGraph
69 {
70 class DiscardQueue;
71 class RenderQueue;
72 class TextureCacheDispatcher;
73 }
74
75 class NotificationManager;
76
77 /** Raw bytes of a resource laid out exactly as it wouldbe in a file, but in memory. */
78 typedef Dali::RefCountedVector<uint8_t> RequestBuffer;
79 /** Counting smart pointer for managing a buffer of raw bytes. */
80 typedef IntrusivePtr<RequestBuffer> RequestBufferPtr;
81
82 /**
83  * ResourceManager keeps track of resource loading requests, and caches resources that are loaded.
84  * It uses ResourceTicket objects, to keep track of the lifetime of each request.
85  * If the same resource is required by two client objects, they will share the same ResourceTicket
86  * i.e. only one load will occur using the native filesystem.
87  *
88  * Multi-threading notes:
89  * Resources are received from the PlatformAbstraction API during the Core::Render() method, which
90  * may be called from a dedicated rendering thread.
91  * Loading requests must be made from the application's main thread e.g. when Dali::Image is created.
92  */
93 class ResourceManager : public Integration::ResourceCache
94 {
95 public:
96
97   /**
98    * Create a resource manager.
99    * There should exactly one of these objects per Dali Core.
100    * @param[in] platformAbstraction Used to request resources from the native filesystem.
101    * @param[in] notificationManager Used to send NotifyTickets message.
102    * @param[in] textureUploadedProcessResourcesQueue Used for performing post processing on resources
103    * @param[in] discardQueue Used to cleanup nodes & resources when no longer in use.
104    * @param[in] renderQueue Used to queue resource updates until the next Render.
105    */
106   ResourceManager( Integration::PlatformAbstraction& platformAbstraction,
107                    NotificationManager& notificationManager,
108                    SceneGraph::TextureCacheDispatcher& textureCacheDispatcher,
109                    LockedResourceQueue& textureUploadedProcessResourcesQueue,
110                    SceneGraph::DiscardQueue& discardQueue,
111                    SceneGraph::RenderQueue& renderQueue );
112
113   /**
114    * Virtual destructor.
115    */
116   virtual ~ResourceManager();
117
118 public: // Used by ResourceClient
119
120   /********************************************************************************
121    ************************ ResourceClient direct interface  **********************
122    ********************************************************************************/
123
124   /**
125    * Resource client passes itself for secondary intialisation.
126    * (The resource client requires the ResourceManager to be instantiated first).
127    * @param[in] resourceClient The ResourceClient.
128    */
129   void SetClient( ResourceClient& resourceClient );
130
131   /********************************************************************************
132    ************************ UpdateManager direct interface  ***********************
133    ********************************************************************************/
134
135   /**
136    * Called to update the resource cache before rendering.
137    * New resources will be added to the cache using PlatformAbstraction::FillResourceCache().
138    * Unwanted resources will be added to the DiscardQueue.
139    * @param[in] updateBufferIndex The current update buffer index.
140    * @return true, if a resource load was completed or failed
141    */
142   bool UpdateCache( BufferIndex updateBufferIndex );
143
144   /**
145    * Iterate through the post process queue, performing requested updates.
146    * @param[in] updateBufferIndex The current update buffer index.
147    */
148   void PostProcessResources( BufferIndex updateBufferIndex );
149
150   /********************************************************************************
151    *************************** CoreImpl direct interface  *************************
152    ********************************************************************************/
153
154   /**
155    * Returns whether the Resource Manager is still processing any resource requests.
156    * @return true if still processing, false otherwise.
157    */
158   bool ResourcesToProcess();
159
160   /********************************************************************************
161    ********************************* Message handlers *****************************
162    ********************************************************************************/
163
164   /**
165    * Request a resource from the native filesystem.
166    * @param[in] id The Id of the requested resource
167    * @param[in] typePath The type & path of requested resource.
168    * @param[in] priority The priority of the request. This is ignored if the resource is already being loaded.
169    */
170   void HandleLoadResourceRequest( ResourceId id,
171                                   const ResourceTypePath& typePath,
172                                   Integration::LoadResourcePriority priority );
173
174   /**
175    * Decode a resource from a memory buffer with the semantics of loading.
176    * Notifications of partial completion, success, and failure will happen via
177    * the same loading notification path used for loading from files: Update()
178    * will retrieve loading events in its main loop and notify listeners to its
179    * own loading events, and forward them, still as loading events, to the event
180    * thread via its update queue.
181    * Resource manager and lower levels make no attempt to detect resource
182    * aliases as is done for multiple requests to load the same resource
183    * file, so the caller is responsible for ensuring that it only requests
184    * the decoding of an in-memory resource once and for doing the sharing of the
185    * resulting object itself. Ultimately this responsibility resides with the
186    * application.
187    * @note ! Only Bitmap resources are supported for decoding from memory !
188    * @param[in] id The Id of the requested resource.
189    * @param[in] typePath The type of the requested resource and a path that is ignored.
190    * @param[in] buffer The raw encoded bytes of the resource as they would appear in a file.
191    * @param[in] priority The priority of the request. This is ignored if the resource is already being loaded.
192    */
193   void HandleDecodeResourceRequest( ResourceId id,
194                                     const ResourceTypePath& typePath,
195                                     RequestBufferPtr buffer,
196                                     Integration::LoadResourcePriority priority );
197
198   /**
199    * Injects a bitmap resource (does not require loading).
200    * @pre bitmap has to be initialized
201    * @param[in] id The resource id
202    * @param[in] bitmap an initialized bitmap
203    */
204   void HandleAddBitmapImageRequest(ResourceId id, Integration::BitmapPtr bitmap);
205
206   /**
207    * Add an existing resource to the resource manager.
208    * @param[in] id The resource id
209    * @param [in] resourceData the NativeImageInterface object
210    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
211    */
212   void HandleAddNativeImageRequest( ResourceId id, NativeImageInterfacePtr resourceData );
213
214   /**
215    * Add an existing resource to the resource manager.
216    * @param[in] id The resource id
217    * @param[in] width       width in pixels
218    * @param[in] height      height in pixels
219    * @param[in] pixelFormat Pixel format
220    */
221   void HandleAddFrameBufferImageRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat );
222
223   /**
224    * Add an existing resource to the resource manager.
225    * @param[in] id            The resource id
226    * @param[in] nativeImage   The NativeImage
227    */
228   void HandleAddFrameBufferImageRequest( ResourceId id, NativeImageInterfacePtr nativeImage );
229
230   /**
231    * Allocate a new empty texture.
232    * @param[in] id The resource id
233    * @param[in] width       width in pixels
234    * @param[in] height      height in pixels
235    * @param[in] pixelFormat Pixel format
236    */
237   void HandleAllocateTextureRequest( ResourceId id, unsigned int width, unsigned int height, Pixel::Format pixelFormat );
238
239   /**
240    * Update bitmap area request
241    * @param[in] textureId The resource ID of a bitmap-texture to remove.
242    * @param[in] area The updated area. Zero width/height indicates the whole bitmap has been updated
243    */
244   void HandleUpdateBitmapAreaRequest( ResourceId textureId, const RectArea& area );
245
246   /**
247    * Upload a bitmap to a position within a specified texture
248    * @param[in] destId The destination texture ID
249    * @param[in] bitmap The pointer pointing to the bitmap data to upload
250    * @param [in] xOffset Specifies an offset in the x direction within the texture
251    * @param [in] yOffset Specifies an offset in the y direction within the texture
252    */
253   void HandleUploadBitmapRequest( ResourceId destId, Integration::BitmapPtr bitmap, std::size_t xOffset, std::size_t yOffset );
254
255   /**
256    * Upload a bitmap to a position within a specified texture
257    * @param[in] destId The destination texture ID
258    * @param[in] srcId The resource ID of the bitmap to upload
259    * @param [in] xOffset Specifies an offset in the x direction within the texture
260    * @param [in] yOffset Specifies an offset in the y direction within the texture
261    */
262   void HandleUploadBitmapRequest( ResourceId destId, ResourceId srcId, std::size_t xOffset, std::size_t yOffset );
263
264   /**
265    * Upload a pixel buffer to a position within a specified texture
266    * @param[in] destId The destination texture ID
267    * @param[in] pixelData pointer pointing to the pixel data to upload
268    * @param [in] xOffset Specifies an offset in the x direction within the texture
269    * @param [in] yOffset Specifies an offset in the y direction within the texture
270    */
271   void HandleUploadBitmapRequest( ResourceId destId, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset );
272
273   /**
274    * Request reloading a resource from the native filesystem.
275    * @param[in] id The resource id
276    * @param[in] typePath The type & path of the resource
277    * @param[in] priority The priority of the request. This is ignored if the resource is already being refreshed.
278    * @param[in] resetFinishedStatus True if the finished status of the resource id should be reset
279    */
280   void HandleReloadResourceRequest( ResourceId id, const ResourceTypePath& typePath, Integration::LoadResourcePriority priority, bool resetFinishedStatus );
281
282   /**
283    * Resource ticket has been discarded, throw away the actual resource
284    */
285   void HandleDiscardResourceRequest( ResourceId id, Integration::ResourceTypeId typeId );
286
287    /**
288     * @brief Create GL texture for resource.
289     * @param[in] id The resource id.
290     */
291    void HandleCreateGlTextureRequest( ResourceId id );
292
293   /********************************************************************************
294    ******************** Update thread object direct interface  ********************
295    ********************************************************************************/
296
297   /**
298    * Check if a resource has completed loading.
299    * @param[in] id The ID of a bitmap/texture resource.
300    * @return true if the bitmap or texture has finished loading
301    */
302   bool IsResourceLoaded( ResourceId id ) const;
303
304   /**
305    * Check if a resource has failed to load, e.g. file not found, etc.
306    * @param[in] id The ID of a bitmap/texture resource.
307    * @return true if the bitmap or texture has failed to load
308    */
309   bool HasResourceLoadFailed( ResourceId id ) const;
310
311   /**
312    * @param[in] id The ID of a texture resource.
313    * @param[in] value if the FBO has been rendered to
314    */
315   void SetFrameBufferBeenRenderedTo( ResourceId id, bool value );
316
317   /**
318    * @param[in] id The ID of a texture resource.
319    * @return true if the FBO has been rendered to
320    */
321   bool HasFrameBufferBeenRenderedTo( ResourceId id ) const;
322
323   /**
324    * Get texture metadata. This stores meta data about the resource, but
325    * doesn't keep track of the resource
326    * @param id of the texture
327    * @param metadata reference
328    * @return false if metadata does not exist
329    */
330   bool GetTextureMetadata( ResourceId id, TextureMetadata*& metadata ) const;
331
332    /********************************************************************************
333     ************************* ResourceCache Implementation  ************************
334     ********************************************************************************/
335 public:
336
337   /**
338    * @copydoc Integration::ResourceCache::LoadResponse
339    */
340   virtual void LoadResponse(ResourceId id, Integration::ResourceTypeId type, Integration::ResourcePointer resource, Integration::LoadStatus loadStatus);
341
342   /**
343    * @copydoc Integration::ResourceCache::LoadFailed
344    */
345   virtual void LoadFailed(ResourceId id, Integration::ResourceFailure failure);
346
347   /********************************************************************************
348    ********************************* Private Methods  *****************************
349    ********************************************************************************/
350
351   /**
352    * Sends notification messages for load sucess & failure,
353    * pushes from newComplete / newFailed into oldComplete / oldFailed respectively
354    */
355   void NotifyTickets();
356
357   /**
358    * Triggers message to Event thread to update the ticket's image attributes
359    * @pre An Image resource with the given id should exist in the cache.
360    * @param id ID of the image resource
361    * @param attributes Resource image attributes
362    */
363   void UpdateImageTicket( ResourceId id, ImageAttributes& attributes );
364
365   /**
366    * Send message to ResourceClient in event thread
367    * @param[in] message The message to send
368    */
369   void SendToClient( MessageBase* message );
370
371   /**
372    * Discard all dead resources.
373    * @param[in] updateBufferIndex The current update buffer index.
374    */
375   void DiscardDeadResources( BufferIndex updateBufferIndex );
376
377 private:
378
379   // Undefined
380   ResourceManager( const ResourceManager& resourceManager );
381
382   // Undefined
383   ResourceManager& operator=( const ResourceManager& rhs );
384
385 private:
386   struct ResourceManagerImpl;
387   ResourceManagerImpl* mImpl;
388 };
389
390 // Messages sent to resource manager from other threads:
391 // These functions are run on other threads and insert messages to be
392 // picked-up by the update thread in its main loop and executed on that in
393 // submission order.
394
395 inline void RequestLoadResourceMessage( EventThreadServices& eventThreadServices,
396                                         ResourceManager& manager,
397                                         ResourceId id,
398                                         const ResourceTypePath& typePath,
399                                         Integration::LoadResourcePriority priority )
400 {
401   typedef MessageValue3< ResourceManager, ResourceId, ResourceTypePath, Integration::LoadResourcePriority > LocalType;
402
403   // Reserve some memory inside the message queue
404   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ), false );
405
406   // Construct message in the message queue memory; note that delete should not be called on the return value
407   new (slot) LocalType( &manager, &ResourceManager::HandleLoadResourceRequest, id, typePath, priority );
408 }
409
410 inline void RequestDecodeResourceMessage( EventThreadServices& eventThreadServices,
411                                           ResourceManager& manager,
412                                           const ResourceId id,
413                                           /// We use typePath instead of the raw type for ownership and to enable copying of a concrete type.
414                                           const ResourceTypePath& typePath,
415                                           RequestBufferPtr buffer,
416                                           Integration::LoadResourcePriority priority )
417 {
418   typedef MessageValue4< ResourceManager, ResourceId, ResourceTypePath, RequestBufferPtr, Integration::LoadResourcePriority > LocalType;
419
420   // Reserve some memory inside the message queue
421   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ), false );
422
423   // Construct message in the message queue memory; note that delete should not be called on the return value
424   new (slot) LocalType( &manager, &ResourceManager::HandleDecodeResourceRequest, id, typePath, buffer, priority );
425 }
426
427 inline void RequestAddBitmapImageMessage( EventThreadServices& eventThreadServices,
428                                           ResourceManager& manager,
429                                           ResourceId id,
430                                           Integration::Bitmap* resourceData )
431 {
432   typedef MessageValue2< ResourceManager, ResourceId, Integration::BitmapPtr > LocalType;
433
434   // Reserve some memory inside the message queue
435   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
436
437   // Construct message in the message queue memory; note that delete should not be called on the return value
438   new (slot) LocalType( &manager, &ResourceManager::HandleAddBitmapImageRequest, id, resourceData );
439 }
440
441 inline void RequestAddNativeImageMessage( EventThreadServices& eventThreadServices,
442                                           ResourceManager& manager,
443                                           ResourceId id,
444                                           NativeImageInterfacePtr resourceData )
445 {
446   typedef MessageValue2< ResourceManager, ResourceId, NativeImageInterfacePtr > LocalType;
447
448   // Reserve some memory inside the message queue
449   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
450
451   // Construct message in the message queue memory; note that delete should not be called on the return value
452   new (slot) LocalType( &manager, &ResourceManager::HandleAddNativeImageRequest, id, resourceData );
453 }
454
455 inline void RequestAddFrameBufferImageMessage( EventThreadServices& eventThreadServices,
456                                                ResourceManager& manager,
457                                                ResourceId id,
458                                                unsigned int width,
459                                                unsigned int height,
460                                                Pixel::Format pixelFormat,
461                                                RenderBuffer::Format bufferFormat
462                                                )
463 {
464   typedef MessageValue5< ResourceManager, ResourceId, unsigned int, unsigned int, Pixel::Format, RenderBuffer::Format > LocalType;
465
466   // Reserve some memory inside the message queue
467   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
468
469   // Construct message in the message queue memory; note that delete should not be called on the return value
470   new (slot) LocalType( &manager, &ResourceManager::HandleAddFrameBufferImageRequest, id, width, height, pixelFormat, bufferFormat );
471 }
472
473 inline void RequestAddFrameBufferImageMessage( EventThreadServices& eventThreadServices,
474                                                ResourceManager& manager,
475                                                ResourceId id,
476                                                NativeImageInterfacePtr resourceData )
477 {
478   typedef MessageValue2< ResourceManager, ResourceId, NativeImageInterfacePtr > LocalType;
479
480   // Reserve some memory inside the message queue
481   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
482
483   // Construct message in the message queue memory; note that delete should not be called on the return value
484   new (slot) LocalType( &manager, &ResourceManager::HandleAddFrameBufferImageRequest, id, resourceData );
485 }
486
487 inline void RequestAllocateTextureMessage( EventThreadServices& eventThreadServices,
488                                            ResourceManager& manager,
489                                            ResourceId id,
490                                            unsigned int width,
491                                            unsigned int height,
492                                            Pixel::Format pixelFormat)
493 {
494   typedef MessageValue4< ResourceManager, ResourceId, unsigned int, unsigned int, Pixel::Format > LocalType;
495
496   // Reserve some memory inside the message queue
497   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
498
499   // Construct message in the message queue memory; note that delete should not be called on the return value
500   new (slot) LocalType( &manager, &ResourceManager::HandleAllocateTextureRequest, id, width, height, pixelFormat );
501 }
502
503 inline void RequestUpdateBitmapAreaMessage( EventThreadServices& eventThreadServices,
504                                             ResourceManager& manager,
505                                             ResourceId id,
506                                             const Dali::RectArea& area )
507 {
508   typedef MessageValue2< ResourceManager, ResourceId, Dali::RectArea > LocalType;
509
510   // Reserve some memory inside the message queue
511   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ), false );
512
513   // Construct message in the message queue memory; note that delete should not be called on the return value
514   new (slot) LocalType( &manager, &ResourceManager::HandleUpdateBitmapAreaRequest, id, area );
515 }
516
517 inline void RequestUploadBitmapMessage( EventThreadServices& eventThreadServices,
518                                         ResourceManager& manager,
519                                         ResourceId destId,
520                                         Integration::BitmapPtr bitmap,
521                                         std::size_t xOffset,
522                                         std::size_t yOffset )
523 {
524   typedef MessageValue4< ResourceManager, ResourceId, Integration::BitmapPtr , std::size_t, std::size_t > LocalType;
525
526   // Reserve some memory inside the message queue
527   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ), false );
528
529   // Construct message in the message queue memory; note that delete should not be called on the return value
530   new (slot) LocalType( &manager, &ResourceManager::HandleUploadBitmapRequest, destId, bitmap, xOffset, yOffset );
531 }
532
533 inline void RequestUploadBitmapMessage( EventThreadServices& eventThreadServices,
534                                         ResourceManager& manager,
535                                         ResourceId destId,
536                                         ResourceId srcId,
537                                         std::size_t xOffset,
538                                         std::size_t yOffset )
539 {
540   typedef MessageValue4< ResourceManager, ResourceId, ResourceId, std::size_t, std::size_t > LocalType;
541
542   // Reserve some memory inside the message queue
543   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ), false );
544
545   // Construct message in the message queue memory; note that delete should not be called on the return value
546   new (slot) LocalType( &manager, &ResourceManager::HandleUploadBitmapRequest, destId, srcId, xOffset, yOffset );
547 }
548
549 inline void RequestUploadBitmapMessage(EventThreadServices& eventThreadServices,
550                                        ResourceManager& manager,
551                                        ResourceId destId,
552                                        PixelDataPtr pixelData,
553                                        std::size_t xOffset,
554                                        std::size_t yOffset)
555 {
556   typedef MessageValue4< ResourceManager, ResourceId, PixelDataPtr , std::size_t, std::size_t > LocalType;
557
558   // Reserve some memory inside the message queue
559   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ), false );
560
561   // Construct message in the message queue memory; note that delete should not be called on the return value
562   new (slot) LocalType( &manager, &ResourceManager::HandleUploadBitmapRequest, destId, pixelData, xOffset, yOffset );
563 }
564
565 inline void RequestReloadResourceMessage( EventThreadServices& eventThreadServices,
566                                           ResourceManager& manager,
567                                           ResourceId id,
568                                           const ResourceTypePath& typePath,
569                                           Integration::LoadResourcePriority priority,
570                                           bool resetFinishedStatus )
571 {
572   typedef MessageValue4< ResourceManager, ResourceId, ResourceTypePath, Integration::LoadResourcePriority, bool > LocalType;
573
574   // Reserve some memory inside the message queue
575   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ), false );
576
577   // Construct message in the message queue memory; note that delete should not be called on the return value
578   new (slot) LocalType( &manager, &ResourceManager::HandleReloadResourceRequest, id, typePath, priority, resetFinishedStatus );
579 }
580
581 inline void RequestDiscardResourceMessage( EventThreadServices& eventThreadServices,
582                                            ResourceManager& manager,
583                                            ResourceId id,
584                                            Integration::ResourceTypeId typeId )
585 {
586   typedef MessageValue2< ResourceManager, ResourceId, Integration::ResourceTypeId > LocalType;
587
588   // Reserve some memory inside the message queue
589   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
590
591   // Construct message in the message queue memory; note that delete should not be called on the return value
592   new (slot) LocalType( &manager, &ResourceManager::HandleDiscardResourceRequest, id, typeId );
593 }
594
595 inline void RequestCreateGlTextureMessage( EventThreadServices& eventThreadServices,
596                                            ResourceManager& manager,
597                                            ResourceId id )
598 {
599   typedef MessageValue1< ResourceManager, ResourceId > LocalType;
600
601   // Reserve some memory inside the message queue
602   unsigned int* slot = eventThreadServices.ReserveMessageSlot( sizeof( LocalType ) );
603
604   // Construct message in the message queue memory; note that delete should not be called on the return value
605   new (slot) LocalType( &manager, &ResourceManager::HandleCreateGlTextureRequest, id );
606 }
607
608 } // namespace Internal
609
610 } // namespace Dali
611
612 #endif // __DALI_INTERNAL_RESOURCE_MANAGER_H__