Merge "Change PixelData to use the handle/body pattern" into devel/master
[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/images/frame-buffer-image.h>
26 #include <dali/public-api/images/native-image-interface.h>
27 #include <dali/devel-api/common/ref-counted-dali-vector.h>
28 #include <dali/internal/event/images/pixel-data-impl.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/message.h>
33 #include <dali/integration-api/bitmap.h>
34
35 namespace Dali
36 {
37 class NativeImage;
38
39 namespace Integration
40 {
41 class Bitmap;
42 }
43
44 namespace Internal
45 {
46 class EventThreadServices;
47 class ResourceManager;
48 class NotificationManager;
49
50
51 typedef Integration::ResourceId ResourceId;
52
53 /** Raw bytes of a resource laid out exactly as it wouldbe in a file, but in memory. */
54 typedef Dali::RefCountedVector<uint8_t> RequestBuffer;
55 /** Counting smart pointer for managing a buffer of raw bytes. */
56 typedef IntrusivePtr<RequestBuffer>     RequestBufferPtr;
57 /** rectangular area (x,y,w,h) */
58 typedef Rect<unsigned int>              RectArea;
59
60 /**
61  * ResourceClient is an event side object that manages resource requests.
62  * It uses ResourceTicket objects to keep track of the lifetime of each request.
63  * If the same resource is required by two client objects, they will share the same ResourceTicket
64  * i.e. only one load will occur using the native filesystem.
65  *
66  * Resources themselves are handled by the Resource Manager in the update thread
67  */
68 class ResourceClient : public ResourceTicketLifetimeObserver
69 {
70 public:
71
72   /**
73    * Create a resource client.
74    * There should exactly one of these objects per Dali Core.
75    * @param[in] resourceManager The resource manager
76    * @param[in] eventThreadServices Used for messaging to and reading from scene-graph.
77    */
78   ResourceClient( ResourceManager& resourceManager,
79                   EventThreadServices& eventThreadServices );
80
81   /**
82    * Virtual destructor.
83    */
84   virtual ~ResourceClient();
85
86 public:
87
88   /**
89    * Request a resource from the native filesystem.
90    * Adding an observer to the ticket will enable the application to determine when the
91    * resource has finished loading.
92    * @param[in] type The type of requested resource.
93    * @param[in] path The path to the requested resource.
94    * @param[in] priority The priority of the request. This is ignored if the resource is already being loaded.
95    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
96    */
97   ResourceTicketPtr RequestResource( const Integration::ResourceType& type,
98                                      const std::string& path,
99                                      Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
100   /**
101    * Request that a resource be decoded in the background from the memory buffer
102    * that is passed-in. The data in the memory buffer should be formatted exactly
103    * as it would be in a file of a supported resource type.
104    *
105    * Adding an observer to the ticket will enable the application to determine when the
106    * resource has finished decoding.
107    * @note Only images are currently supported by this function.
108    * @param[in] type The type of resource. Must be BitmapResourceType.
109    * @param[in] buffer The raw data of the resource.
110    * @param[in] priority The priority of the request. This is ignored if the resource is already being loaded.
111    * @return A ref-counted request object on success or a null pointer on failure.
112    *         Keep a copy until the resource is no longer required.
113    */
114   ResourceTicketPtr DecodeResource( const Integration::ResourceType& type,
115                                     RequestBufferPtr buffer,
116                                     Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
117
118   /**
119    * Request reloading a resource from the native filesystem.
120    * If the resource is still loading, this request is ignored.
121    * The ticket observer will be notified of completion with ResourceLoadingSucceeded() or
122    * ResourceLoadingFailed()
123    *
124    * @param[in] id resource id
125    * @param[in] resetFinishedStatus True if the finished status of the current image should be reset.
126    * @param[in] priority The priority of the request. This is ignored if the resource is already being refreshed.
127    * @return true if successful, false if resource doesn't exist
128    */
129   bool ReloadResource( ResourceId id, bool resetFinishedStatus = false, Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
130
131   /**
132    * Get the ticket for the associated resource ID.
133    * If no ticket can be found for this resource, then this returns
134    * NULL to indicate the resource doesn't exist.
135    * @param[in] id The resource ID.
136    * @return A resource ticket, or NULL if no resource existed with the given ID.
137    */
138   ResourceTicketPtr RequestResourceTicket( ResourceId id );
139
140   /**
141    * Injects a bitmap resource (does not require loading).
142    * @pre bitmap has to be initialized
143    * @param[in] bitmap an initialized bitmap
144    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
145    */
146   ImageTicketPtr AddBitmapImage(Integration::Bitmap* bitmap);
147
148   /**
149    * Add an existing resource to the resource manager.
150    * @param [in] resourceData the NativeImage object
151    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
152    */
153   ResourceTicketPtr AddNativeImage ( NativeImageInterface& resourceData );
154
155   /**
156    * Add a framebuffer resource to the resource manager.
157    * @param[in] width       width in pixels
158    * @param[in] height      height in pixels
159    * @param[in] pixelFormat Pixel format
160    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
161    */
162   ImageTicketPtr AddFrameBufferImage ( unsigned int width, unsigned int height, Pixel::Format pixelFormat, RenderBuffer::Format bufferFormat );
163
164   /**
165    * Add a framebuffer resource to the resource manager.
166    * @param[in] nativeImage the NativeImage object
167    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
168    */
169   ImageTicketPtr AddFrameBufferImage ( NativeImageInterface& nativeImage );
170
171   /**
172    * Request allocation of a texture.
173    * The texture is initially empty.
174    * @note Older hardware may require image width and image height to be a power of two
175    * @param[in] width         Image width in pixels
176    * @param[in] height        Image height in pixels
177    * @param[in] pixelformat   Pixel format
178    * @return A ref-counted request object. Keep a copy until the resource is no longer required.
179    */
180   ResourceTicketPtr AllocateTexture( unsigned int width,
181                                      unsigned int height,
182                                      Pixel::Format pixelformat );
183
184   /**
185    * Update bitmap area
186    * @param[in] ticket The ticket representing the bitmap
187    * @param[in] updateArea the area updated.
188    */
189   void UpdateBitmapArea( ResourceTicketPtr ticket, RectArea& updateArea );
190
191   /**
192    * Upload a bitmap to a texture
193    * @param[in] destId The destination texture ID
194    * @param[in] srcId The resource ID of the bitmap to upload
195    * @param [in] xOffset Specifies an offset in the x direction within the texture
196    * @param [in] yOffset Specifies an offset in the y direction within the texture
197    */
198   void UploadBitmap( ResourceId destId, ResourceId srcId, std::size_t xOffset, std::size_t yOffset );
199
200   /**
201    * Upload a bitmap to a texture
202    * @param[in] destId The destination texture ID
203    * @param[in] bitmap The pointer pointing to the bitmap to upload
204    * @param [in] xOffset Specifies an offset in the x direction within the texture
205    * @param [in] yOffset Specifies an offset in the y direction within the texture
206    */
207   void UploadBitmap( ResourceId destId, Integration::BitmapPtr bitmap, std::size_t xOffset, std::size_t yOffset);
208
209   /**
210    * Upload a pixel buffer to a texture
211    * @param[in] destId The destination texture ID
212    * @param[in] bitmap The pointer pointing to the pixel data
213    * @param [in] xOffset Specifies an offset in the x direction within the texture
214    * @param [in] yOffset Specifies an offset in the y direction within the texture
215    */
216   void UploadBitmap( ResourceId destId, PixelDataPtr pixelData, std::size_t xOffset, std::size_t yOffset);
217
218   /**
219    * @brief Trigger asynchronous creation of GL texture to back resource immediately.
220    * @param[in] id The resource ID to allocate a GL texture for.
221    */
222   void CreateGlTexture( ResourceId id );
223
224 public: // From ResourceTicketLifetimeObserver.
225
226   /**
227    * This indicates that the previously requested resource is no longer needed.
228    * @param[in] ticket The ticket to remove from resource manager.
229    */
230   virtual void ResourceTicketDiscarded(const ResourceTicket& ticket);
231
232 public: // Message methods
233
234   /**
235    * Notify associated ticket observers that the resource has been uploaded to GL.
236    * @param[in] id The resource id of the uploaded resource
237    */
238   void NotifyUploaded( ResourceId id );
239
240   /**
241    * Notify associated ticket observers that the resource is loading.
242    * @param[in] id The resource id of the loading resource
243    */
244   void NotifyLoading( ResourceId id );
245
246   /**
247    * Notify associated ticket observers that the resource has loaded.
248    * @param[in] id The resource id of the loaded resource
249    */
250   void NotifyLoadingSucceeded( ResourceId id );
251
252   /**
253    * Notify associated ticket observers that the resource has failed to load
254    * @param[in] id The resource id of the resource
255    */
256   void NotifyLoadingFailed( ResourceId id );
257
258  /**
259    * Finds ImageTicket which belongs to resource identified by id and updates the cached
260    * attributes with a new set which contains the actual width and height of the loaded
261    * image but has undefined values for all other fields.
262    * @param id The resource id to find the ticket of
263    * @param imageAttributes The image attributes to assign to the ticket
264    */
265   void UpdateImageTicket( ResourceId id, const ImageAttributes& imageAttributes ); ///!< Issue #AHC01
266
267 private:
268   ResourceManager& mResourceManager;          ///< The resource manager
269   EventThreadServices& mEventThreadServices;        ///< Interface to send messages through
270
271 private:
272   struct Impl;
273   Impl* mImpl;
274 };
275
276 inline MessageBase* UpdateImageTicketMessage( ResourceClient& client, ResourceId id, const ImageAttributes& attrs )
277 {
278   return new MessageValue2< ResourceClient, ResourceId, ImageAttributes >(
279     &client, &ResourceClient::UpdateImageTicket, id, attrs );
280 }
281
282 inline MessageBase* UploadedMessage( ResourceClient& client, ResourceId id )
283 {
284   return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifyUploaded, id );
285 }
286
287 inline MessageBase* LoadingMessage( ResourceClient& client, ResourceId id )
288 {
289   return new MessageValue1< ResourceClient, ResourceId  >( &client, &ResourceClient::NotifyLoading, id );
290 }
291
292 inline MessageBase* LoadingSucceededMessage( ResourceClient& client, ResourceId id )
293 {
294   return new MessageValue1< ResourceClient, ResourceId  >( &client, &ResourceClient::NotifyLoadingSucceeded, id );
295 }
296
297 inline MessageBase* LoadingFailedMessage( ResourceClient& client, ResourceId id )
298 {
299   return new MessageValue1< ResourceClient, ResourceId  >( &client, &ResourceClient::NotifyLoadingFailed, id );
300 }
301
302 } // namespace Internal
303 } // namespace Dali
304
305 #endif // __DALI_INTERNAL_RESOURCE_CLIENT_H__