anchor.diff:                  | Error err ->
                       Error err
                       
  +        member x.TryGetProgramBinary(prog : Program) =
  +            use __ = x.ResourceLock
  +
  +            let mutable length = 0
  +            GL.GetProgram(prog.Handle, unbox 0x8741, &length)
  +            let err = GL.GetError()
  +            if err <> ErrorCode.NoError then 
  +                None
  +            else
  +                let data : byte[] = Array.zeroCreate length
  +                let mutable format = Unchecked.defaultof<BinaryFormat>
  +                GL.GetProgramBinary(prog.Handle, length, &length, &format, data)
  +                let err = GL.GetError()
  +                if err <> ErrorCode.NoError then 
  +                    None
  +                else
  +                    Some (format, data)
  +
  +
  +
           member x.TryCompileProgram(fboSignature : Map<string, int>, expectsRowMajorMatrices : bool, code : string) =
               using x.ResourceLock (fun _ ->
                   match x |> ShaderCompiler.tryCompileShaders true code with
  
positive.code: 
          member x.TryCompileProgram(id : string, signature : IFramebufferSignature, code : Lazy<GLSL.GLSLShader>) : Error<_> =
              codeCache.GetOrAdd((x, id, signature), fun (x, id, signature) ->
                  let code = code.Value
                  let outputs = code.iface.outputs |> List.map (fun p -> p.paramName, p.paramLocation) |> Map.ofList
                  match x.TryCompileProgram(outputs, true, code.code) with
                      | Success prog ->
                          Success (code.iface, prog)
                      | Error e ->
                          Error e
              )
  
  
  
negative.code:  
      let private codeCache = ConcurrentDictionary<Context * string * IFramebufferSignature, Error<FShade.GLSL.GLSLProgramInterface * Program>>()
      let private shaderCache = ConcurrentDictionary<Context * Surface * IFramebufferSignature, Error<FShade.GLSL.GLSLProgramInterface * IMod<Program>>>()
      let private shaderPickler = MBrace.FsPickler.FsPickler.CreateBinarySerializer()
      let private cachePath =
          let temp = Path.combine [System.IO.Path.GetTempPath(); "aardvark-gl-shadercache"]
          if not (System.IO.Directory.Exists temp) then System.IO.Directory.CreateDirectory temp |> ignore
          temp
  
      type private OutputSignature =
          {
              device      : string
              id          : string
              outputs     : Map<string, int * RenderbufferFormat>
              layered     : Set<string>
              layerCount  : int
          }
  
      type private ShaderCacheEntry =
          {
              iface       : FShade.GLSL.GLSLProgramInterface
              format      : BinaryFormat
              binary      : byte[]
  
          }
  
  
      type Aardvark.Rendering.GL.Context with
  