code: def on_draw(self, event):
      if self.use_shaders:
          last_rend = 0
          self.fbo_to[last_rend].activate()
          set_viewport(0, 0, *self.texture_size)
          self.programs[0]["texture"] = self.orig_tex
          self.programs[0].draw("triangle_strip")
          self.fbo_to[last_rend].deactivate()
          stepsize = (np.array(self.texture_size) // 2).max()
          while stepsize > 0:
              self.programs[1]["step"] = stepsize
              self.programs[1]["texture"] = self.comp_texs[last_rend]
              last_rend = 1 if last_rend == 0 else 0
              self.fbo_to[last_rend].activate()
              set_viewport(0, 0, *self.texture_size)
              self.programs[1].draw("triangle_strip")
              self.fbo_to[last_rend].deactivate()
              stepsize //= 2
          self.programs[2]["texture"] = self.comp_texs[last_rend]
      else:
          self.programs[2]["texture"] = self.orig_tex
      set_viewport(0, 0, *self.physical_size)
      self.programs[2].draw("triangle_strip")
  
file_path: vispy/examples/demo/gloo/jfa/jfa_vispy.py
imports: import numpy
  from os import path
  import sys
  from vispy import app
  from vispy.gloo import Program, FrameBuffer, VertexBuffer, Texture2D, set_viewport
  from vispy.io import load_data_file, imread
label_desc: Use image node_id 3 for calling the Canvas obj's underlying member method code with example usage: obj.on_draw(event) without return types