anchor.diff:    final _onAddProgramCtxs = new List<RunOnProgramContextRegistration>();
     final _onRemoveProgramCtxs = new List<RunOnProgramContextRegistration>();
     final _autoData = new Map<String, RunOnProgramContext>();
  +  FBO fbo;
   
     ProgramsRunner(this.gl);
   
  
positive.code:     });
  
      _afterAlls.forEach((f) => f(gl));
      if (_frameBuf != null) {
        gl.bindFramebuffer(FRAMEBUFFER, null);
      }
  
  
negative.code:   }
  }
  
  class FBO {
    final RenderingContext gl;
  
    get buffer => _buf;
    get texture => _tex;
  
    Framebuffer _buf;
    Renderbuffer _renderBuf;
    Texture _tex;
  
    FBO(this.gl, [int width = -1, int height = -1, int type = UNSIGNED_BYTE]) {
      if (width < 0) width = gl.canvas.width;
      if (height < 0) height = gl.canvas.height;
  
      _buf = gl.createFramebuffer();
      gl.bindFramebuffer(FRAMEBUFFER, _buf);
  
      _tex = gl.createTexture();
      gl.bindTexture(TEXTURE_2D, _tex);
      gl.texImage2DTyped(TEXTURE_2D, 0, RGBA, width, height, 0, RGBA, type, null);
      gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);
      gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
      gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, NEAREST);
      gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, NEAREST);
      //gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, LINEAR);
      //gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, LINEAR_MIPMAP_NEAREST);
      //gl.generateMipmap(TEXTURE_2D);
  
      _renderBuf = gl.createRenderbuffer();
      gl.bindRenderbuffer(RENDERBUFFER, _renderBuf);
      gl.renderbufferStorage(RENDERBUFFER, DEPTH_COMPONENT16, width, height);
  
      gl.framebufferTexture2D(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D, _tex, 0);
      gl.framebufferRenderbuffer(FRAMEBUFFER, DEPTH_ATTACHMENT, RENDERBUFFER, _renderBuf);
  
      gl.bindTexture(TEXTURE_2D, null);
      gl.bindRenderbuffer(RENDERBUFFER, null);
      gl.bindFramebuffer(FRAMEBUFFER, null);
    }
  
    dispose() {
      if (_renderBuf != null) {
        gl.deleteRenderbuffer(_renderBuf);
        _renderBuf = null;
      }
      if (_tex != null) {
        gl.deleteTexture(_tex);
        _tex = null;
      }
      if (_buf == null) {
        gl.deleteFramebuffer(_buf);
        _buf = null;
      }
    }
  }
  _compileShader(RenderingContext gl, String src, int type) {
    var shader = gl.createShader(type);
    gl.shaderSource(shader, src);
  