anchor.diff:       for (nil area) in (array-bindings attribute-set)
        unless (gl-finalized-p area)
        do (gl-finalize area errorp))
  -  (when (and (element-binding attribute-set)
  -             (not (gl-finalized-p (element-binding attribute-set))))
  -    (gl-finalize (element-binding attribute-set) errorp))
  -  (let* ((vao-id (gl:gen-vertex-array))
  -         (vao (make-instance 'vertex-array-object :id vao-id))
  -         (nullptr (cffi:null-pointer))
  -         (element-binding (element-binding attribute-set)))
  -    (setf (vao attribute-set) vao)
  -    (gl:bind-vertex-array vao-id)
  -    (loop
  -       for (nil area index) in (array-bindings attribute-set)
  -       when index
  -       do (progn
  -            (gl:bind-buffer :array-buffer (id (buffer area)))
  -            (gl:enable-vertex-attrib-array index)
  -            (gl:vertex-attrib-pointer index
  -                                      (components area)
  -                                      (buffer-type area)
  -                                      (normalizedp area)
  -                                      (stride area)
  -                                      (cffi:inc-pointer nullptr (offset area)))))
  -    (when element-binding
  -      (gl:bind-buffer :element-array-buffer (id (buffer element-binding))))
  -    (gl:bind-vertex-array 0)
  -    attribute-set))
  +  (let ((element-binding (element-binding attribute-set)))
  +    (when (and element-binding (not (gl-finalized-p (element-binding attribute-set))))
  +      (gl-finalize (element-binding attribute-set) errorp))
  +    (let* ((attr-set-key (make-attribute-set-key attribute-set)))
  +      (multiple-value-bind (vao presentp)
  +          (gethash attr-set-key (vao-cache *renderer*))
  +        (unless presentp
  +          (let* ((vao-id (gl:gen-vertex-array))
  +                 (nullptr (cffi:null-pointer)))
  +            (setq vao (make-instance 'vertex-array-object :id vao-id))
  +            (gl:bind-vertex-array vao-id)
  +            (loop
  +               for (nil area index) in (array-bindings attribute-set)
  +               when index
  +               do (progn
  +                    (gl:bind-buffer :array-buffer (id (buffer area)))
  +                    (gl:enable-vertex-attrib-array index)
  +                    (gl:vertex-attrib-pointer index
  +                                              (components area)
  +                                              (buffer-type area)
  +                                              (normalizedp area)
  +                                              (stride area)
  +                                              (cffi:inc-pointer nullptr (offset area)))))
  +            (when element-binding
  +              (gl:bind-buffer :element-array-buffer (id (buffer element-binding))))
  +            (gl:bind-vertex-array 0)
  +            (setf (gethash attr-set-key (vao-cache *renderer*)) vao)))
  +        (setf (vao attribute-set) vao))))
  +  attribute-set)
  +
   
   (defclass graphics-state ()
     ((bindings)
  
positive.code:         ;; XXX bindings
        (setf (current-state renderer) state))))
  
  (defvar *renderer*)
  
  (defmethod draw ((renderer renderer))
    (let ((*renderer* renderer))
      (loop
  
negative.code: (defclass vertex-array-object (gl-object)
    ())
  
  (defun make-attribute-set-key (attr-set)
    (let ((vertex-keys (mapcar (lambda (binding)
                                 (destructuring-bind (name area index)
                                     binding
                                   (declare (ignore name))
                                   (list (id (buffer area))
                                         index
                                         (components area)
                                         (normalizedp area)
                                         (stride area)
                                         (offset area))))
                               (array-bindings attr-set))))
      (if (element-binding attr-set)
          (cons (id (buffer (element-binding attr-set))) vertex-keys)
          vertex-keys)))
  
  (defmethod gl-finalized-p ((obj attribute-set))
    (slot-boundp obj 'vao))
  
  