1 #ifndef __DALI_INTERNAL_RESOURCE_CLIENT_H__
2 #define __DALI_INTERNAL_RESOURCE_CLIENT_H__
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <boost/functional/hash.hpp>
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>
39 typedef boost::hash<const std::string> StringHash;
50 class ResourceManager;
51 class NotificationManager;
52 class GlyphLoadObserver;
59 typedef Integration::ResourceId ResourceId;
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;
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.
72 * Resources themselves are handled by the Resource Manager in the update thread
74 class ResourceClient : public ResourceTicketLifetimeObserver
77 typedef Rect<unsigned int> RectArea; ///< rectangular area (x,y,w,h)
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
85 ResourceClient( ResourceManager& resourceManager, SceneGraph::UpdateManager& updateManager );
90 virtual ~ResourceClient();
92 public: // Used by application-side objects e.g. Dali::Image
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.
103 ResourceTicketPtr RequestResource( const Integration::ResourceType& type,
104 const std::string& path,
105 Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
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.
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.
120 ResourceTicketPtr DecodeResource( const Integration::ResourceType& type,
121 RequestBufferPtr buffer,
122 Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
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.
130 ResourceTicketPtr LoadShader(Integration::ShaderResourceType& type, const std::string& filename);
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()
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
142 bool ReloadResource( ResourceId id, Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
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.
152 void SaveResource( ResourceTicketPtr ticket, const std::string& url );
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.
161 ResourceTicketPtr RequestResourceTicket( ResourceId id );
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.
173 ImageTicketPtr AllocateBitmapImage ( unsigned int width,
175 unsigned int bufferWidth,
176 unsigned int bufferHeight,
177 Pixel::Format pixelformat );
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.
185 ImageTicketPtr AddBitmapImage(Integration::Bitmap* bitmap);
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.
192 ResourceTicketPtr AddNativeImage ( NativeImage& resourceData );
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.
201 ImageTicketPtr AddFrameBufferImage ( unsigned int width, unsigned int height, Pixel::Format pixelFormat );
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.
208 ImageTicketPtr AddFrameBufferImage ( NativeImage& nativeImage );
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.
219 ResourceTicketPtr AllocateTexture( unsigned int width,
221 Pixel::Format pixelformat );
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
229 void UpdateTexture( ResourceId id,
230 BitmapUploadArray uploadArray );
233 * Requests allocation of a mesh resource
234 * @param[in] meshData representing the mesh; ownership is taken.
236 ResourceTicketPtr AllocateMesh( OwnerPointer<MeshData>& meshData );
240 * @param[in] ticket The ticket representing the bitmap
241 * @param[in] updateArea the area updated.
243 void UpdateBitmapArea( ResourceTicketPtr ticket, RectArea& updateArea );
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
251 void UpdateMesh( ResourceTicketPtr ticket, const Dali::MeshData& meshData );
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
259 Integration::Bitmap* GetBitmap(ResourceTicketPtr ticket);
262 * Set the glyph load observer
263 * @param glyphLoadedInterface pointer to an object which supports the glyphLoadedInterface
265 void SetGlyphLoadObserver( GlyphLoadObserver* glyphLoadedInterface );
268 * Update atlas status
269 * @param id The ticket resource Id
270 * @param atlasId The atlas texture Id
271 * @param loadStatus The status update
273 void UpdateAtlasStatus( ResourceId id, ResourceId atlasId, Integration::LoadStatus loadStatus );
275 public: // From ResourceTicketLifetimeObserver.
278 * This indicates that the previously requested resource is no longer needed.
279 * @param[in] ticket The ticket to remove from resource manager.
281 virtual void ResourceTicketDiscarded(const ResourceTicket& ticket);
283 public: // Message methods
286 * Notify associated ticket observers that the resource has been uploaded to GL.
287 * @param[in] id The resource id of the uploaded resource
289 void NotifyUploaded( ResourceId id );
292 * Notify client that the resource has been updated and requires saving.
293 * @param[in] id The resource id of the updated resource
295 void NotifySaveRequested( ResourceId id );
298 * Notify associated ticket observers that the resource is loading.
299 * @param[in] id The resource id of the loading resource
301 void NotifyLoading( ResourceId id );
304 * Notify associated ticket observers that the resource has loaded.
305 * @param[in] id The resource id of the loaded resource
307 void NotifyLoadingSucceeded( ResourceId id );
310 * Notify associated ticket observers that the resource has failed to load
311 * @param[in] id The resource id of the resource
313 void NotifyLoadingFailed( ResourceId id );
316 * Notify associated ticket observers that the resource has saved successfully
317 * @param[in] id The resource id of the saved resource
319 void NotifySavingSucceeded( ResourceId id );
322 * Notify associated ticket observers that the resource save failed
323 * @param[in] id The resource id of the failed resource
325 void NotifySavingFailed( ResourceId id );
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
333 void NotifyGlyphSetLoaded( ResourceId id, const Integration::GlyphSet& glyphSet, Integration::LoadStatus loadStatus );
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
342 void UpdateImageTicket( ResourceId id, const Dali::ImageAttributes& imageAttributes ); ///!< Issue #AHC01
345 ResourceManager& mResourceManager; ///< The resource manager
346 SceneGraph::UpdateManager& mUpdateManager; ///< update manager
353 inline MessageBase* UpdateImageTicketMessage( ResourceClient& client, ResourceId id, const Dali::ImageAttributes& attrs )
355 return new MessageValue2< ResourceClient, ResourceId, Dali::ImageAttributes >(
356 &client, &ResourceClient::UpdateImageTicket, id, attrs );
359 inline MessageBase* UploadedMessage( ResourceClient& client, ResourceId id )
361 return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifyUploaded, id );
364 inline MessageBase* SaveResourceMessage( ResourceClient& client, ResourceId id )
366 return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifySaveRequested, id );
369 inline MessageBase* LoadingMessage( ResourceClient& client, ResourceId id )
371 return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifyLoading, id );
374 inline MessageBase* LoadingSucceededMessage( ResourceClient& client, ResourceId id )
376 return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifyLoadingSucceeded, id );
379 inline MessageBase* LoadingFailedMessage( ResourceClient& client, ResourceId id )
381 return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifyLoadingFailed, id );
384 inline MessageBase* SavingSucceededMessage( ResourceClient& client, ResourceId id )
386 return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifySavingSucceeded, id );
389 inline MessageBase* SavingFailedMessage( ResourceClient& client, ResourceId id )
391 return new MessageValue1< ResourceClient, ResourceId >( &client, &ResourceClient::NotifySavingFailed, id );
394 inline MessageBase* LoadingGlyphSetSucceededMessage( ResourceClient& client, ResourceId id, const Integration::GlyphSetPointer& glyphSet, Integration::LoadStatus loadStatus )
396 return new MessageValue3< ResourceClient, ResourceId, Integration::GlyphSet, Integration::LoadStatus >( &client, &ResourceClient::NotifyGlyphSetLoaded, id, *glyphSet, loadStatus );
399 } // namespace Internal
402 #endif // __DALI_INTERNAL_RESOURCE_CLIENT_H__