1 #pragma once
2 
3 #ifndef TFXCACHEMANAGER_H
4 #define TFXCACHEMANAGER_H
5 
6 #include <memory>
7 
8 #include "trenderresourcemanager.h"
9 #include "tcacheresource.h"
10 
11 //=======================================================================
12 
13 //  Forward declarations
14 struct ResourceDeclaration;
15 typedef std::pair<ResourceDeclaration *, TCacheResourceP> ResourceData;
16 
17 class TFxCacheManager;
18 class TFxCacheManagerDelegate;
19 // class TFxCacheManagerListener;
20 
21 //=======================================================================
22 
23 //=====================================
24 //    ResourceBuilder class
25 //-------------------------------------
26 
27 /*!
28 The ResourceBuilder class is the preferential base interface that must be used
29 to
30 by eventual users to interact with the Toonz cache during render processes.
31 
32 Caching can be used to specify that some intermediate rendering result is
33 useful,
34 and efforts should be taken to ensure that it is stored in memory rather than
35 repeatedly rebuilt, when it is sufficiently convenient.
36 \n
37 These kind of operations are automatically performed by Toonz on the overall
38 results of
39 fx nodes - users should definitely implement hidden fx nodes rather than a
40 specialized
41 ResourceBuilder class. However, ResourceBuilder provides a more simple and
42 generic API
43 than TRasterFx's, and does not force code splitting into several fxs.
44 
45 This class already works out most of the implementation details necessary
46 to deal with cache management and predictability issues.
47 \n \n
48 It just requires the implementation of two essential functions:
49 
50 <li> The compute() method, which performs the effective calculation of the
51 passed tile.
52 <li> The simCompute() method, which is a dummy simulation of the above
53 compute(),
54 used by the builder for predictive purposes.
55 
56 Please refer to their descriptions for implementation details.
57 \n \n
58 Once the necessary compute() and simCompute() functions have been supplied, the
59 ResourceBuilder can be used to obtain the resource data associated with passed
60 TTile
61 simply by invoking the build() method. The build() invocation performs all the
62 cache resource availability checkings, retrieval, and the eventual resource
63 calculation
64 on its own.
65 \n \n
66 The simBuild() method is the dummy counterpart for build(), which must be used
67 in the
68 simCompute() simulations whenever some father resource requires that a child
69 resource
70 is built first.
71 */
72 
73 class DVAPI ResourceBuilder {
74   TFxCacheManager *m_cacheManager;
75   ResourceData m_data;
76 
77 protected:
78   virtual void simCompute(const TRectD &rect) = 0;
79   virtual void compute(const TRectD &rect)    = 0;
80 
81   virtual void upload(TCacheResourceP &resource)   = 0;
82   virtual bool download(TCacheResourceP &resource) = 0;
83 
84 public:
85   ResourceBuilder(const std::string &resourceName, const TFxP &fx, double frame,
86                   const TRenderSettings &rs);
~ResourceBuilder()87   virtual ~ResourceBuilder() {}
88 
89   static void declareResource(const std::string &alias, const TFxP &fx,
90                               const TRectD &rect, double frame,
91                               const TRenderSettings &rs,
92                               bool subtileable = true);
93 
94   void simBuild(const TRectD &tile);
95   void build(const TRectD &tile);
96 };
97 
98 //************************************************************************************************
99 //    Cache Management internals
100 //************************************************************************************************
101 
102 //! The ResourceDeclaration structure contains the informations retrieved in the
103 //! predictive processes performed before a render process. It can be retrieved
104 //! via the TFxCacheManager::getResource() method or passed directly by it to
105 //! TFxCacheManagerDelegate instances.
106 
107 struct ResourceDeclaration {
108   //! ResourceDeclaration's Raw data is gathered in the first predictive run for
109   //! a render process. It is destroyed before the actual process begins due to
110   //! its considerable size.
111   struct RawData {
112     // Requested infos for calculation
113 
114     //! Fx who generated the data
115     TFxP m_fx;
116     //! Frame at which the data was generated
117     double m_frame;
118     //! Render settings associated with the data
119     TRenderSettings m_rs;
120     //! Tiles declared in the prediction process.
121     //! May differ from those actually calculated by the renderer.
122     std::vector<TRectD> m_tiles;
123 
124     // Useful infos
125 
126     //! Bounding box associated with the considered fx calculation
127     // TRectD m_bbox;
128 
129     //! Whether the resource may be subdivided for calculation
130     bool m_subtileable;
131   };
132 
133   //! The ResourceDeclaration's Raw data is processed into a vector of
134   //! TileDatas, representing the actual tiles to be computed in the render
135   //! process.
136   struct TileData {
137     TRectD m_rect;
138     int m_refCount;
139     bool m_calculated;
140 
TileDataResourceDeclaration::TileData141     TileData(const TRectD &rect)
142         : m_rect(rect), m_refCount(0), m_calculated(false) {}
143   };
144 
145 public:
146   RawData *m_rawData;
147   std::vector<TileData> m_tiles;
148   int m_tilesCount;
149 
ResourceDeclarationResourceDeclaration150   ResourceDeclaration() : m_rawData(0), m_tilesCount(0) {}
~ResourceDeclarationResourceDeclaration151   ~ResourceDeclaration() {}
152 };
153 
154 //=======================================================================
155 
156 typedef std::pair<ResourceDeclaration *, TCacheResourceP> ResourceData;
157 
158 //=======================================================================
159 
160 //======================
161 //    Cache Manager
162 //----------------------
163 
164 /*!
165 The TFxCacheManager is the main resource manager that deals with fx nodes
166 caching
167 inside Toonz rendering processes. During a render process, a considerable amount
168 of time
169 can be saved if any intermediate rendered result used more than once is saved in
170 cache
171 and reused multiple times rather than rebuilding it every time. In some cases,
172 the user may even
173 know that some specific intermediate result is useful for rendering purposes,
174 and could
175 explicitly require that it needs to be cached.
176 \n \n
177 In Toonz's rendering workflow, these operations are managed by the
178 TFxCacheManager class,
179 which delegates specific caching procedures to a group of
180 TFxCacheManagerDelegate instances.
181 \n \n
182 Access to a cache resource is performed through the getResource() method, which
183 requires
184 a description of the resource (as specified in the TCacheResource class)
185 and some informations - namely, the fx, render settings and frame - about the
186 circumstances
187 of the request. If the resource is managed by some manager delegate, it will be
188 returned.
189 \n \n
190 Resource uploads and downloads must be notified through the apposite methods to
191 inform the
192 manager delegates appropriately. These notifications can be invoked without need
193 that
194 the associated method is actually invoked for the resource - this is especially
195 required
196 when the TRenderer instance is simulating the actual render process for
197 predictive purposes.
198 
199 \sa TCacheResource, TPassiveCacheManager, TPredictiveCacheManager and TRenderer
200 classes
201 */
202 
203 class DVAPI TFxCacheManager final : public TRenderResourceManager {
204   T_RENDER_RESOURCE_MANAGER
205 
206 private:
207   // std::set<TFxCacheManagerListener*> m_listeners;
208   std::set<TFxCacheManagerDelegate *> m_delegates;
209 
210   std::set<std::string> m_staticCacheIds;
211 
212   class Imp;
213   std::unique_ptr<Imp> m_imp;
214 
215 public:
216   TFxCacheManager();
217   ~TFxCacheManager();
218 
219   static TFxCacheManager *instance();
220 
221   void add(const std::string &cacheId, TImageP img);
222   void remove(const std::string &cacheId);
223 
224   void onRenderStatusStart(int renderStatus) override;
225   void onRenderStatusEnd(int renderStatus) override;
226 
227   // void install(TFxCacheManagerListener* listener);
228   // void uninstall(TFxCacheManagerListener* listener);
229 
230 private:
231   friend class ResourceBuilder;
232 
233   void declareResource(const std::string &alias, const TFxP &fx,
234                        const TRectD &rect, double frame,
235                        const TRenderSettings &rs, bool subtileable);
236 
237   ResourceData getResource(const std::string &resourceName, const TFxP &fx,
238                            double frame, const TRenderSettings &rs);
239 
240   /*void notifyResourceUpload(const TCacheResourceP& resource, const TRect&
241 rect);
242 void notifyResourceDownload(const TCacheResourceP& resource, const TRect& rect);
243 void notifyPredictedRelease(const TCacheResourceP& resource);*/
244 
245 private:
246   friend class TFxCacheManagerDelegate;
247 
248   void install(TFxCacheManagerDelegate *managerDelegate);
249 };
250 
251 //=======================================================================
252 
253 //===============================
254 //    Cache Manager Delegate
255 //-------------------------------
256 
257 /*!
258 TFxCacheManagerDelegate is the base class to implement cache managers used
259 in Toonz render processes.
260 
261 A TFxCacheManagerDelegate instance automatically receives access notifications
262 through the TFxCacheManager associated with a render process.
263 These may either concern a request of a certain cache resource, or the storage
264 proposal of a calculated node result.
265 
266 \warning Delegates are expected to be dependent on TFxCacheManager - use the
267 MANAGER_FILESCOPE_DECLARATION_DEP macro to achieve that.
268 
269 \sa TCacheResource and TFxCacheManager classes
270 */
271 
272 class TFxCacheManagerDelegate : public TRenderResourceManager {
273 public:
TFxCacheManagerDelegate()274   TFxCacheManagerDelegate() {}
275 
276   virtual void getResource(TCacheResourceP &resource, const std::string &alias,
277                            const TFxP &fx, double frame,
278                            const TRenderSettings &rs,
279                            ResourceDeclaration *resData) = 0;
280 
onRenderInstanceStart(unsigned long renderId)281   void onRenderInstanceStart(unsigned long renderId) override {
282     assert(TFxCacheManager::instance());
283     TFxCacheManager::instance()->install(this);
284   }
285 };
286 
287 //=======================================================================
288 
289 //===============================
290 //    Cache Manager Listener
291 //-------------------------------
292 
293 /*class TFxCacheManagerListener
294 {
295 public:
296 
297   TFxCacheManagerListener() {}
298 
299   virtual void onResourceUpload(const TCacheResourceP& resource, const TRect&
300 rect) {}
301   virtual void onResourceDownload(const TCacheResourceP& resource, const TRect&
302 rect) {}
303   virtual void onPredictedRelease(const TCacheResourceP& resource) {}
304 };*/
305 
306 #endif  // TFXCACHEMANAGER_H
307