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