HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VEX_VexOp.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: VEX_VexOp.h ( VEX Library, C++)
7  *
8  * COMMENTS: External VEX function definition
9  *
10  * The signature of a VEX OP function determines the parameters the function
11  * expects. The signature is composed as follows:
12  * name@parms
13  * where name is the user function name and the parms are the single character
14  * representations of the parameters expected. The single character mnemonics
15  * are:
16  * F = float
17  * I = integer
18  * S = string
19  * D = dict
20  * U = vector2 (Think uv)
21  * V = vector
22  * P = vector4 (originally "point")
23  * 2 = matrix2
24  * 3 = matrix3
25  * 4 = matrix
26  *
27  * Arrays of primitive types use the single character mnemonic for that
28  * type preceeded by the open square bracket ([) character. The array
29  * types are then represented as:
30  * [F = float array
31  * [I = integer array
32  * [S = string array
33  * [D = dict array
34  * [U = vector2 array
35  * [V = vector array
36  * [P = vector4 array
37  * [2 = matrix2 array
38  * [3 = matrix3 array
39  * [4 = matrix array
40  *
41  * If a parameter is written to by the VexOp function, the parameter mnemonic
42  * should be preceded by an ampersand (&) or an asterix (*). The ampersand is
43  * used it the value of the variable is not read by the function, while the
44  * asterix is used if the variable is read and then modified. The signature
45  * specification is very important if the compiler is to work correctly.
46  *
47  * The compiler is "smart" in that if only one argument is written to (and not
48  * read from), that argument will be flagged as the return code for the
49  * function.
50  *
51  * Examples:
52  * Signature: test@&IF
53  * Decoded: int test(float)
54  *
55  * Signature: test@*IF
56  * Decoded: void test(int &, float)
57  * Details: The integer parameter must be set since this function
58  * reads the argument before modifying it.
59  *
60  * Signature: test@S&VFF
61  * Decoded: vector test(string; float, float)
62  *
63  * Signature: test@&IF+
64  * Decoded: int test(float, ...)
65  *
66  */
67 
68 #ifndef __VEX_VexOp__
69 #define __VEX_VexOp__
70 
71 #include "VEX_API.h"
72 #include "VEX_PodTypes.h"
73 #include "VEX_VexTypes.h"
74 #include "VEX_Error.h"
75 
76 /// A structure used to provide arguments with type information to the
77 /// callback function.
78 struct VEX_VexOpArg {
79  void *myArg;
81  bool myArray;
82 };
83 
84 /// VEX operator initialization callback. When called, it should allocated
85 /// and initialize custom state data.
86 typedef void *(*VEX_VexOpInit)();
87 /// VEX operator evaluation callback. When called, the data returned by the
88 /// VEX_VexOpInit function will be passed as the "data" argument.
89 typedef void (*VEX_VexOpCallback)(int argc, void *argv[], void *data);
90 /// VEX operator evaluation callback with argument type information. This
91 /// version of the operator callback must be used for variadic functions.
92 /// When called, the data returned by the VEX_VexOpInit function will be
93 /// passed as the "data" argument.
95  int argc, VEX_VexOpArg argv[], void *data);
96 /// VEX operator cleanup callback. When called, it should deallocate the data.
97 typedef void (*VEX_VexOpCleanup)(void *data);
98 /// VEX operator completed callback. Called when a shader that evaluated a
99 /// custom operator completes.
100 typedef void (*VEX_VexOpCompleted)(void *data);
101 
102 //
103 // It's possible to give hints to the compiler as to what optimizations may be
104 // performed on the function. The different levels of optimizations are:
105 // 0 = No optimizations may be performed on the custom function.
106 // 1 = If the result of the function is unused, the function can
107 // be eliminated.
108 // 2 = If all parameters to the function are constant, then the result may
109 // be pre-computed and cached.
110 // The only time you would want to turn off optimization is to guarantee that
111 // your custom function is evaluated in all cases (i.e. something like printf).
112 // Typically, functions used in computation can be optimized by VEX.
113 //
114 // Turning off optimization may result in an overall performance hit.
115 //
116 
117 /// @def VEX_OPTIMIZE_0
118 /// Perform no optimization on the VEX function
119 /// @warning this may impact performance severely.
120 /// @def VEX_OPTIMIZE_1
121 /// If the result of the function is unused, the function can be
122 /// eliminated.
123 /// @def VEX_OPTIMIZE_2
124 // If all parameters to the function are constant, then the result may
125 // be pre-computed and cached. (preferred mode)
126 #define VEX_OPTIMIZE_0 0
127 #define VEX_OPTIMIZE_1 1
128 #define VEX_OPTIMIZE_2 2
129 
130 //
131 // When a function modifies only one parameter (without reading from it), the
132 // compiler will automatically interpret the first argument as a return code
133 // for the function. However, if the function modifies multiple arguments, the
134 // compiler assumes that all arguments should be passed by reference.
135 // Sometimes, it's useful to have the first modified argument treated as a
136 // return code rather than an actual parameter to the function. This behaviour
137 // can be forced (if all conditions are met) by passing in a true on the
138 // "force_return_code" parameter.
139 // For example, something like the function:
140 // import@&IS&F
141 // would decode to
142 // import(int &success, string, float &result)
143 // But, with the force_return_code argument set to true, the function would be
144 // interpreted as:
145 // int import(string, float &result)
146 // which is most likely more friendly to the user.
147 //
148 
149 /// Use this class to extend VEX by adding custom VEX functions.
151 {
152 public:
153  /// Function declaration
154  /// @param signature @n The function name and parameters expected
155  /// @param evaluator32 @n The evaluation callback (32 bit)
156  /// @param evaluator64 @n The evaluation callback (64 bit)
157  /// @param ctx_mask @n Which contexts this function is available in
158  /// @param init32 @n Initialization callback (called for every 32 bit instance)
159  /// @param init64 @n Initialization callback (called for every 64 bit instance)
160  /// @param cleanup32 @n Cleanup callback (32 bit)
161  /// @param cleanup64 @n Cleanup callback (64 bit)
162  /// @param optimize_level @n Optimization level
163  /// @param force_return_code @n
164  /// For signatures which have multiple write-only variables, this
165  /// @c bool forces the first write-only variable to be interpreted
166  /// as a return code.
167  /// @{
168  VEX_VexOp(const UT_StringHolder &signature,
169  VEX_VexOpCallback evaluator32,
170  int ctx_mask=(VEX_ALL_CONTEXT),
171  VEX_VexOpInit init32 = 0,
172  VEX_VexOpCleanup cleanup32 = 0,
173  int optimize_level = VEX_OPTIMIZE_2,
174  bool force_return_code=false);
175  VEX_VexOp(const UT_StringHolder &signature,
176  VEX_VexOpCallback evaluator32,
177  VEX_VexOpCallback evaluator64,
178  int ctx_mask=(VEX_ALL_CONTEXT),
179  VEX_VexOpInit init32 = 0,
180  VEX_VexOpInit init64 = 0,
181  VEX_VexOpCleanup cleanup32 = 0,
182  VEX_VexOpCleanup cleanup64 = 0,
183  int optimize_level = VEX_OPTIMIZE_2,
184  bool force_return_code=false);
185  VEX_VexOp(const UT_StringHolder &signature,
186  VEX_VexOpTypedCallback evaluator32,
187  int ctx_mask=(VEX_ALL_CONTEXT),
188  VEX_VexOpInit init32 = 0,
189  VEX_VexOpCleanup cleanup32 = 0,
190  int optimize_level = VEX_OPTIMIZE_2,
191  bool force_return_code=false);
192  VEX_VexOp(const UT_StringHolder &signature,
193  VEX_VexOpTypedCallback evaluator32,
194  VEX_VexOpTypedCallback evaluator64,
195  int ctx_mask=(VEX_ALL_CONTEXT),
196  VEX_VexOpInit init32 = 0,
197  VEX_VexOpInit init64 = 0,
198  VEX_VexOpCleanup cleanup32 = 0,
199  VEX_VexOpCleanup cleanup64 = 0,
200  int optimize_level = VEX_OPTIMIZE_2,
201  bool force_return_code=false);
202  /// @}
203 
204  /// Set the completed callback, called when all evaluate calls for a
205  /// given shader invokation are finished.
206 
207  template <VEX_Precision PREC>
208  void setCompleted(VEX_VexOpCompleted cback);
209 
210  /// Query the signature
211  const UT_StringHolder &getSignature() const { return mySignature; }
212  /// Query the context mask
213  int getContextMask() const { return myContextMask; }
214  /// Query the initialization function
215  template <VEX_Precision PREC>
216  VEX_VexOpInit getInit() const;
217  /// Query the evaluation function
218  template <VEX_Precision PREC>
219  VEX_VexOpCallback getEvaluator() const;
220  /// Query the typed evaluation function
221  template <VEX_Precision PREC>
222  VEX_VexOpTypedCallback getTypedEvaluator() const;
223  /// Query the cleanup function
224  template <VEX_Precision PREC>
225  VEX_VexOpCleanup getCleanup() const;
226  /// Query the completed function
227  template <VEX_Precision PREC>
228  VEX_VexOpCompleted getCompleted() const;
229  /// Query the optimization level
230  int getOptimizer() const { return myOptimizeLevel; }
231 
232  /// @private: Internal used to query state
233  unsigned int getFlag(unsigned int f) const { return myFlags&f; }
234  /// @private: Internal used to store state
235  void setFlag(unsigned int f) { myFlags |= f; }
236  /// @private: Internal used to store state
237  void clearFlag(unsigned int f) { myFlags &= ~f; }
238 
239  /// When dealing assigning to string arguments, you must "free" the previous
240  /// string value by calling "stringFree". You must set the resulting string
241  /// to the return code from "stringAlloc". If you do your own memory
242  /// management (i.e. calling strdup() or setting strings to constant
243  /// values), you will most likely crash VEX.
244  /// For example:
245  /// @code
246  /// void
247  /// vexStrCat(int argc, void *argv[], void *)
248  /// {
249  /// // arg[0] = result, arg[1..2] == strings to concat
250  /// char work_buf[256];
251  /// VEX_VexOp::stringFree((char *)argv[0]);
252  /// strcpy(work_buf, (char *)argv[1]);
253  /// strcat(work_buf, (char *)argv[2]);
254  /// argv[0] = VEX_VexOp::stringAlloc(work_buf);
255  /// }
256  /// @endcode
257  static const char *stringAlloc(const char *str);
258  /// Function to free an allocated string
259  static void stringFree(const char *str);
260 
261  /// During execution of a callback, this method can be used to retrieve
262  /// the current VEX error log for error reporting. This method will
263  /// only operate correctly in the thread that executed the callback.
264  static VEX_ErrorLog &getErrorLog();
265 
266  /// These functions can be used to query the number of DSO's loaded by VEX
267  /// and the locations of the shared objects loaded.
268  static int getNumVexOps();
269  /// Query the Nth function
270  static const VEX_VexOp *getVexOp(int idx);
271  /// Get the path to the DSO associated with the VEX plug-in
272  static const char *getVexOpLocation(int idx);
273 
274 protected:
275  // The signature of the function call. This is documented in the header
276  // above. The constructor will duplicate the string passed in.
278 
279  // Initialization, Evaluation and Cleanup callbacks
285 
291 
292  // The contexts which this VEXOp is valid for. The mask is a bit-field
293  // represented by or'ing the context defines above together.
296  unsigned int myFlags;
297 
298 private:
299  void construct(const UT_StringHolder &signature,
300  VEX_VexOpCallback evaluator32,
301  VEX_VexOpCallback evaluator64,
302  VEX_VexOpTypedCallback typed_evaluator32,
303  VEX_VexOpTypedCallback typed_evaluator64,
304  int ctx_mask,
305  VEX_VexOpInit init32,
306  VEX_VexOpInit init64,
307  VEX_VexOpCleanup cleanup32,
308  VEX_VexOpCleanup cleanup64,
309  int optimize,
310  bool rcode);
311 };
312 
313 extern "C" {
314  /// Function called in DSO to install new functions
315  /// All files found in $HOUDINI_DSO_PATH/vex are automatically scanned for
316  /// this function.
317  SYS_VISIBILITY_EXPORT extern void newVEXOp(void *);
318 }
319 
320 template <> inline void
321 VEX_VexOp::setCompleted<VEX_32>(VEX_VexOpCompleted callback)
322 { myCompleted32 = callback; }
323 template <> inline VEX_VexOpInit
324 VEX_VexOp::getInit<VEX_32>() const
325 { return myInit32; }
326 template <> inline VEX_VexOpCallback
327 VEX_VexOp::getEvaluator<VEX_32>() const
328 { return myEvaluator32; }
329 template <> inline VEX_VexOpTypedCallback
330 VEX_VexOp::getTypedEvaluator<VEX_32>() const
331 { return myTypedEvaluator32; }
332 template <> inline VEX_VexOpCleanup
333 VEX_VexOp::getCleanup<VEX_32>() const
334 { return myCleanup32; }
335 template <> inline VEX_VexOpCleanup
336 VEX_VexOp::getCompleted<VEX_32>() const
337 { return myCompleted32; }
338 
339 template <> inline void
340 VEX_VexOp::setCompleted<VEX_64>(VEX_VexOpCompleted callback)
341 { myCompleted64 = callback; }
342 template <> inline VEX_VexOpInit
343 VEX_VexOp::getInit<VEX_64>() const
344 { return myInit64; }
345 template <> inline VEX_VexOpCallback
346 VEX_VexOp::getEvaluator<VEX_64>() const
347 { return myEvaluator64; }
348 template <> inline VEX_VexOpTypedCallback
349 VEX_VexOp::getTypedEvaluator<VEX_64>() const
350 { return myTypedEvaluator64; }
351 template <> inline VEX_VexOpCleanup
352 VEX_VexOp::getCleanup<VEX_64>() const
353 { return myCleanup64; }
354 template <> inline VEX_VexOpCleanup
355 VEX_VexOp::getCompleted<VEX_64>() const
356 { return myCompleted64; }
357 
358 #endif
VEX_Type
VEX variable types.
Definition: VEX_VexTypes.h:18
VEX_VexOpCompleted myCompleted32
Definition: VEX_VexOp.h:284
#define SYS_VISIBILITY_EXPORT
void
Definition: png.h:1083
GLboolean * data
Definition: glcorearb.h:131
int myOptimizeLevel
Definition: VEX_VexOp.h:295
VEX_Type myType
Definition: VEX_VexOp.h:80
Use this class to extend VEX by adding custom VEX functions.
Definition: VEX_VexOp.h:150
VEX_VexOpCompleted myCompleted64
Definition: VEX_VexOp.h:290
void * myArg
Definition: VEX_VexOp.h:79
VEX_VexOpTypedCallback myTypedEvaluator32
Definition: VEX_VexOp.h:282
VEX_VexOpCleanup myCleanup32
Definition: VEX_VexOp.h:283
VEX_VexOpTypedCallback myTypedEvaluator64
Definition: VEX_VexOp.h:288
#define VEX_API
Definition: VEX_API.h:14
int myContextMask
Definition: VEX_VexOp.h:294
void *(* VEX_VexOpInit)()
Definition: VEX_VexOp.h:86
#define VEX_OPTIMIZE_2
Definition: VEX_VexOp.h:128
void(* VEX_VexOpTypedCallback)(int argc, VEX_VexOpArg argv[], void *data)
Definition: VEX_VexOp.h:94
GLfloat f
Definition: glcorearb.h:1926
void(* VEX_VexOpCallback)(int argc, void *argv[], void *data)
Definition: VEX_VexOp.h:89
const UT_StringHolder & getSignature() const
Query the signature.
Definition: VEX_VexOp.h:211
void(* VEX_VexOpCompleted)(void *data)
Definition: VEX_VexOp.h:100
VEX_VexOpCallback myEvaluator64
Definition: VEX_VexOp.h:287
VEX_VexOpCleanup myCleanup64
Definition: VEX_VexOp.h:289
bool myArray
Definition: VEX_VexOp.h:81
void(* VEX_VexOpCleanup)(void *data)
VEX operator cleanup callback. When called, it should deallocate the data.
Definition: VEX_VexOp.h:97
UT_StringHolder mySignature
Definition: VEX_VexOp.h:277
unsigned int myFlags
Definition: VEX_VexOp.h:296
VEX_VexOpInit myInit32
Definition: VEX_VexOp.h:280
SYS_VISIBILITY_EXPORT void newVEXOp(void *)
Definition: VEX_Example.C:143
#define VEX_ALL_CONTEXT
Definition: VEX_VexTypes.h:91
VEX_VexOpInit myInit64
Definition: VEX_VexOp.h:286
VEX_VexOpCallback myEvaluator32
Definition: VEX_VexOp.h:281
int getContextMask() const
Query the context mask.
Definition: VEX_VexOp.h:213
int getOptimizer() const
Query the optimization level.
Definition: VEX_VexOp.h:230