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