code: def __call__(
      self, *bufs, global_size, local_size=None, vals=(), wait=False
  ):
      vert = ctx.buffer(
          np.asarray([-1, 1, -1, -1, 1, 1, 1, -1], dtype="f4").tobytes()
      )
      uv = ctx.buffer(
          np.asarray([0, 1, 0, 0, 1, 1, 1, 0], dtype="f4").tobytes()
      )
      self.vao = ctx.vertex_array(self.prg, [])
      self.vao.bind(
          self.prg["in_position"].location
          if "in_position" in self.prg
          else 0,
          buffer=vert,
          cls="f",
          fmt="2f4",
      )
      self.vao.bind(
          self.prg["in_uv"].location if "in_uv" in self.prg else 1,
          buffer=uv,
          cls="f",
          fmt="2f4",
      )
      self.vao.vertices = vert.size // 4 // 2
      self.fbo = ctx.framebuffer(color_attachments=[bufs[0]])
  
      for i, x in enumerate(bufs[1:], start=1):
          if f"data{i}" in self.prg:
              self.prg[f"data{i}"] = i
              x.use(i)
  
      if "width" in self.prg:
          self.prg["width"].value = self.fbo.size[0]
      ctx.viewport = (0, 0, self.fbo.size[0], self.fbo.size[1])
      self.fbo.use()
      self.vao.render(mode=moderngl.TRIANGLE_STRIP)
  
file_path: tinygrad/extra/backends/ops_webgl.py
imports: import numpy
  import functools
  from tinygrad.dtype import dtypes, ImageDType
  from tinygrad.device import Compiled, Allocator
  from tinygrad.codegen.kernel import LinearizerOptions, OptOps
  from tinygrad.renderer.cstyle import uops_to_cstyle
  from tinygrad.renderer.cstyle import GLSLLanguage
  import moderngl
label_desc: Use image node_id 2 for calling the WebGLProgram obj's underlying member method code with example usage: obj.__call__() without return types