Updates to handle context loss and regain
[platform/core/uifw/dali-core.git] / dali / internal / event / images / image-factory.h
1 #ifndef __DALI_INTERNAL_IMAGE_FACTORY_H__
2 #define __DALI_INTERNAL_IMAGE_FACTORY_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 // INTERNAL INCLUDES
22 #include <dali/internal/event/resources/resource-type-path-id-map.h>
23 #include <dali/internal/event/resources/resource-ticket.h>
24 #include <dali/internal/event/images/image-factory-cache.h>
25
26 namespace Dali
27 {
28
29 namespace Internal
30 {
31 class ResourceType;
32
33 namespace ImageFactoryCache
34 {
35 struct Request;
36 }
37
38 /**
39  * ImageFactory is an object that manages Image resource load requests.
40  * It utilises an internal caching system where previous requests and associated
41  * resources are stored to avoid accessing the file system when not neccessary.
42  */
43 class ImageFactory : public ImageFactoryCache::RequestLifetimeObserver
44 {
45 public:
46
47   /**
48    * default constructor
49    */
50   ImageFactory( ResourceClient& resourceClient );
51
52   /**
53    * Default destructor
54    */
55   virtual ~ImageFactory();
56
57   /**
58    * Registers a request for an image resource if not yet available, but does not start loading yet.
59    * Use Load( req ) to issue load request.
60    * If image was already requested, an existing request is returned.
61    * @param [in] filename   path of requested image resource
62    * @param [in] attributes pointer to the ImageAttributes of the request. If NULL, default attributes are used.
63    * @return     request pointer
64    */
65   ImageFactoryCache::Request* RegisterRequest( const std::string& filename, const ImageAttributes *attributes );
66
67   /**
68    * Issue a request which has already been registered with ImageFactory.
69    * If the associated Ticket is no longer alive ImageFactory issues a resource load request.
70    * @param [in] req pointer to request
71    * @return     intrusive pointer to image ticket. If Load fails, returned pointer is invalid. (!ret)
72    */
73   ResourceTicketPtr Load( ImageFactoryCache::Request* req );
74
75   /**
76    * Tells ResourceManager to reload image from filesystem.
77    * Also sends message to render thread.
78    * This operation uses the originally requested attributes when reloading the image.
79    * @pre req must be registered with ImageFactory
80    * @note if image is still loading, no new load request will be issued
81    * @param[in]  requestPtr Request pointer
82    * @return the ResourceTicket mapped to the request
83    */
84   ResourceTicketPtr Reload( ImageFactoryCache::Request* requestPtr );
85
86   /**
87    * Ensures all filesystem images are reloaded into textures.
88    * This operation uses the originally requested attributes when reloading the image.
89    *
90    * Recovering from context loss does not change the number of tickets if the
91    * image size has changed on the file system since the last load/reload.
92    *
93    * If two different requests mapped to the same resource before, they will still
94    * map to the same resource after context regain even if there would be a better
95    * fitting texture.
96    * @pre requests must be registered with ImageFactory
97    * @note If an image is still loading, no new load request will be issued.
98    */
99   void RecoverFromContextLoss();
100
101   /**
102    * Get resource path used in request.
103    * @param [in] request of the image
104    * @return     resource path
105    */
106   const std::string& GetRequestPath( const ImageFactoryCache::RequestPtr& request ) const;
107
108   /**
109    * Get ImageAttributes for an already requested image resource.
110    * @pre id should mark an existing Resource (Ticket is alive)
111    * @param [in] ticket of the image
112    * @return     ImageAttributes used for request.
113    * @throws     Throws exception if id is not valid.
114    */
115   const ImageAttributes& GetActualAttributes( const ResourceTicketPtr& ticket ) const;
116
117   /**
118    * Get ImageAttributes used for request.
119    * @pre req must point to a Request registered with ImageFactory
120    * @param [in] request of the image
121    * @return     ImageAttributes used for request.
122    */
123   const ImageAttributes& GetRequestAttributes( const ImageFactoryCache::RequestPtr& request ) const;
124
125   /**
126    * Retrieve the size of an image. This is either the application requested size or
127    * the actual (full size) that is or will be loaded.
128    * @param[in] request of the image
129    * @param[in] ticket of the image
130    * @param[out] size of the image
131    */
132   void GetImageSize( const ImageFactoryCache::RequestPtr& request, const ResourceTicketPtr& ticket, Size& size );
133
134   /**
135    * Prevents releasing and reloading image resources in the same frame
136    * @param [in] ticket the resource ticket to queue for releasing
137    */
138   void ReleaseTicket( ResourceTicket* ticket );
139
140   /**
141    * Flush the queue of resource tickets that were about to be relased.
142    * This discards the kept ticket handles at the end of each frame, and this way prevents
143    * releasing and reloading image resources in the same frame.
144    */
145   void FlushReleaseQueue();
146
147 public: // From RequestLifetimeObserver
148
149   /**
150    * Finds request by id in mRequestCache and mUrlCache and removes relevant entries.
151    * @param [in] id request id
152    */
153   virtual void RequestDiscarded( const ImageFactoryCache::Request& request );
154
155 private:
156
157   // Undefined
158   ImageFactory( const ImageFactory& );
159
160   // Undefined
161   ImageFactory& operator=( const ImageFactory& rhs );
162
163   /**
164    * Checks if the previously loaded image's attributes are compatible with a new request
165    * @param [in] requested The requested attributes
166    * @param [in] actual    The actual attributes
167    * @return True if the attributes are compatible
168    */
169   bool CompareAttributes( const Dali::ImageAttributes& requested,
170                           const Dali::ImageAttributes& actual ) const;
171
172   /**
173    * Inserts a new request to the request cache and url cache.
174    * @note this method increases the current request Id counter (mReqIdCurrent)
175    * @param [in] resourceId Ticket id to insert.
176    * @param [in] url        The requested url to insert.
177    * @param [in] urlHash    Calculated hash value for the url.
178    * @param [in] attr       Pointer to the requested attributes, NULL if default values are used.
179    * @return pointer to Request
180    */
181   ImageFactoryCache::Request* InsertNewRequest( ResourceId resourceId, const std::string& url, std::size_t urlHash, const ImageAttributes* attr );
182
183   /**
184    * Searches request cache for exact match.
185    * @param [in] filename    The url of the image resource.
186    * @param [in] hash        Hash value for the filename.
187    * @param [in] attributes  Pointer to ImageAttributes used for the request or NULL if default attributes were used.
188    * @return pointer to the found request or NULL if no exact match is found.
189    */
190   ImageFactoryCache::Request* FindRequest( const std::string& filename, size_t hash, const ImageAttributes *attributes );
191
192   /**
193    * Searches through tickets to find a compatible resource.
194    * @param [in] filename   The url of the image resource.
195    * @param [in] hash       Hash value for the filename.
196    * @param [in] attributes Pointer to ImageAttributes used for the request or NULL if default attributes were used.
197    * @return A ticket pointer to the found resource or an unitialized pointer if no compatible one is found.
198    */
199   ResourceTicketPtr FindCompatibleResource( const std::string& filename, size_t hash, const ImageAttributes* attributes );
200
201   /**
202    * Helper function that requests the image resource from platform abstraction.
203    * @param [in] filename   The url of the image resource.
204    * @param [in] attributes Pointer to ImageAttributes to be used for the request or NULL if default attributes are used.
205    * @return intrusive pointer to Ticket
206    */
207   ResourceTicketPtr IssueLoadRequest( const std::string& filename, const ImageAttributes* attributes );
208
209 private:
210   ResourceClient&                        mResourceClient;
211   ImageFactoryCache::RequestPathHashMap  mUrlCache;         ///< A multimap of url hashes and request IDs
212   ImageFactoryCache::RequestIdMap        mRequestCache;     ///< A map of request IDs and request information.
213   ResourceTicketContainer                mTicketsToRelease; ///< List of ticket handles
214   float                                  mMaxScale;         ///< Defines maximum size difference between compatible resources
215   ImageFactoryCache::RequestId           mReqIdCurrent;     ///< Internal counter for Request IDs
216 };
217
218 } // namespace Internal
219
220 } // namespace Dali
221
222 #endif // __DALI_INTERNAL_IMAGE_FACTORY_H__