@@ -33,6 +33,7 @@ def __init__(self, requirejs=True, insert_runtime=True, webworker=False, functio
3333
3434 self .special_decorators = set (['__typedef__' , '__glsl__' ])
3535 self ._glsl = False
36+ self ._has_glsl = False
3637
3738 def indent (self ): return ' ' * self ._indent
3839 def push (self ): self ._indent += 1
@@ -67,13 +68,15 @@ def visit_AugAssign(self, node):
6768 return a
6869
6970 def visit_Module (self , node ):
71+ header = []
72+ lines = []
73+
7074 if self ._requirejs and not self ._webworker :
71- lines = [
75+ header . extend ( [
7276 'define( function(){' ,
7377 '__module__ = {}'
74- ]
75- else :
76- lines = []
78+ ])
79+
7780
7881 if self ._insert_runtime :
7982 dirname = os .path .dirname (os .path .abspath (__file__ ))
@@ -95,7 +98,10 @@ def visit_Module(self, node):
9598 lines .append ( 'return __module__' )
9699 lines .append ('}) //end requirejs define' )
97100
98- #return '\n'.join(lines)
101+ if self ._has_glsl :
102+ header .append ( 'var __shader__ = []' )
103+
104+ lines = header + lines
99105 ## fixed by Foxboron
100106 return '\n ' .join (l if isinstance (l ,str ) else l .encode ("utf-8" ) for l in lines )
101107
@@ -184,23 +190,32 @@ def _visit_call_helper_var_glsl(self, node):
184190
185191 def _visit_function (self , node ):
186192 glsl = False
193+ glsl_wrapper_name = False
187194 args_typedefs = {}
188195 for decor in node .decorator_list :
189196 if isinstance (decor , ast .Name ) and decor .id == '__glsl__' :
190197 glsl = True
198+ elif isinstance (decor , ast .Attribute ) and isinstance (decor .value , ast .Name ) and decor .value .id == '__glsl__' :
199+ glsl_wrapper_name = decor .attr
191200 elif isinstance (decor , ast .Call ) and isinstance (decor .func , ast .Name ) and decor .func .id == '__typedef__' :
192201 for key in decor .keywords :
193202 args_typedefs [ key .arg ] = key .value .id
194203
195204 args = self .visit (node .args )
196205
197206 if glsl :
198- lines = ['var __program__ = [];' ]
207+ is_main = node .name == 'main'
208+ self ._has_glsl = True ## writes `__shader__ = []` in header
209+ lines = []
199210 x = []
200211 for i ,arg in enumerate (args ):
201212 assert arg in args_typedefs
202213 x .append ( '%s %s' % (args_typedefs [arg ].replace ('POINTER' , '*' ), arg ) )
203- lines .append ( '__program__.push("void main( %s ) {");' % ', ' .join (x ) )
214+
215+ if is_main :
216+ lines .append ( '__shader__.push("void main( %s ) {");' % ', ' .join (x ) )
217+ else : ## TODO return type
218+ lines .append ( '__shader__.push("void %s( %s ) {");' % (node .name , ', ' .join (x )) )
204219
205220 self .push ()
206221 self ._glsl = True
@@ -209,27 +224,30 @@ def _visit_function(self, node):
209224 continue
210225 else :
211226 for sub in self .visit (child ).splitlines ():
212- lines .append ( '__program__ .push("%s");' % (self .indent ()+ sub ) )
227+ lines .append ( '__shader__ .push("%s");' % (self .indent ()+ sub ) )
213228 self ._glsl = False
214229 #buffer += '\n'.join(body)
215230 self .pull ()
216- lines .append ('\n __program__.push("%s}");' % self .indent ())
217- lines .append ('function call_webclgl_program( %s ) {' % ',' .join (args ))
218- lines .append (' var offset = 0' ) ## TODO data range, 0 allows 0-1.0
219- lines .append (' var __webclgl = new WebCLGL()' )
220- lines .append (' var return_buffer = __webclgl.createBuffer(1, "FLOAT", offset)' ) ## TODO length of return buffer
221- for arg in args :
222- lines .append (' var %s_buffer = __webclgl.createBuffer(%s.length, "FLOAT", offset)' % (arg ,arg ))
223- lines .append (' __webclgl.enqueueWriteBuffer(%s_buffer, %s)' % (arg , arg ))
224-
225- lines .append (' var __kernel = __webclgl.createKernel( __program__ );' )
226- for i ,arg in enumerate (args ):
227- lines .append (' __kernel.setKernelArg(%s, %s_buffer)' % (i , arg ))
228-
229- lines .append (' __kernel.compile()' )
230- lines .append (' __webclgl.enqueueNDRangeKernel(__kernel, return_buffer)' )
231- lines .append (' return __webclgl.enqueueReadBuffer_Float( return_buffer )' )
232- lines .append ('} // end of wrapper' )
231+ lines .append ('__shader__.push("%s}");' % self .indent ())
232+
233+ if is_main :
234+ lines .append ('function %s( %s, __offset ) {' % (glsl_wrapper_name , ',' .join (args )) )
235+ lines .append (' __offset = __offset || 0' ) ## note by default: 0 allows 0-1.0
236+ lines .append (' var __webclgl = new WebCLGL()' )
237+ lines .append (' var __kernel = __webclgl.createKernel( __shader__ );' )
238+
239+ lines .append (' var return_buffer = __webclgl.createBuffer(1, "FLOAT", __offset)' ) ## TODO length of return buffer
240+ for i ,arg in enumerate (args ):
241+ lines .append (' if (%s instanceof Array) {' % arg )
242+ lines .append (' var %s_buffer = __webclgl.createBuffer(%s.length, "FLOAT", __offset)' % (arg ,arg ))
243+ lines .append (' __webclgl.enqueueWriteBuffer(%s_buffer, %s)' % (arg , arg ))
244+ lines .append (' __kernel.setKernelArg(%s, %s_buffer)' % (i , arg ))
245+ lines .append (' } else { __kernel.setKernelArg(%s, %s) }' % (i , arg ))
246+
247+ lines .append (' __kernel.compile()' )
248+ lines .append (' __webclgl.enqueueNDRangeKernel(__kernel, return_buffer)' )
249+ lines .append (' return __webclgl.enqueueReadBuffer_Float( return_buffer )' )
250+ lines .append ('} // end of wrapper' )
233251
234252 return '\n ' .join (lines )
235253
0 commit comments