internal/restorable/images.go
func (i *images) restore() error {
	if !IsRestoringEnabled() {
		panic("restorable: restore cannot be called when restoring is disabled")
	}

	// Dispose image explicitly
	for img := range i.images {
		img.image.Dispose()
		// img.image can't be set nil here, or Size() panics when restoring.
	}

	// Let's do topological sort based on dependencies of drawing history.
	// It is assured that there are not loops since cyclic drawing makes images stale.
	type edge struct {
		source *Image
		target *Image
	}
	images := map[*Image]struct{}{}
	for i := range i.images {
		if !i.priority {
			images[i] = struct{}{}
		}
	}
	edges := map[edge]struct{}{}
	for t := range images {
		for s := range t.dependingImages() {
			edges[edge{source: s, target: t}] = struct{}{}
		}
	}

	sorted := []*Image{}
	for i := range i.images {
		if i.priority {
			sorted = append(sorted, i)
		}
	}
	for len(images) > 0 {
		// current repesents images that have no incoming edges.
		current := map[*Image]struct{}{}
		for i := range images {
			current[i] = struct{}{}
		}
		for e := range edges {
			if _, ok := current[e.target]; ok {
				delete(current, e.target)
			}
		}
		for i := range current {
			delete(images, i)
			sorted = append(sorted, i)
		}
		removed := []edge{}
		for e := range edges {
			if _, ok := current[e.source]; ok {
				removed = append(removed, e)
			}
		}
		for _, e := range removed {
			delete(edges, e)
		}
	}

	for _, img := range sorted {
		if err := img.restore(); err != nil {
			return err
		}
	}
	return nil
}
func (i *images) restore() error {
	if !IsRestoringEnabled() {
		panic("restorable: restore cannot be called when restoring is disabled")
	}

	// Dispose image explicitly
	for img := range i.images {
		img.image.Dispose()
		// img.image can't be set nil here, or Size() panics when restoring.
	}

	// Let's do topological sort based on dependencies of drawing history.
	// It is assured that there are not loops since cyclic drawing makes images stale.
	type edge struct {
		source *Image
		target *Image
	}
	images := map[*Image]struct{}{}
	for i := range i.images {
		if !i.priority {
			images[i] = struct{}{}
		}
	}
	edges := map[edge]struct{}{}
	for t := range images {
		for s := range t.dependingImages() {
			edges[edge{source: s, target: t}] = struct{}{}
		}
	}

	sorted := []*Image{}
	for i := range i.images {
		if i.priority {
			sorted = append(sorted, i)
		}
	}
	for len(images) > 0 {
		// current repesents images that have no incoming edges.
		current := map[*Image]struct{}{}
		for i := range images {
			current[i] = struct{}{}
		}
		for e := range edges {
			if _, ok := current[e.target]; ok {
				delete(current, e.target)
			}
		}
		for i := range current {
			delete(images, i)
			sorted = append(sorted, i)
		}
		removed := []edge{}
		for e := range edges {
			if _, ok := current[e.source]; ok {
				removed = append(removed, e)
			}
		}
		for _, e := range removed {
			delete(edges, e)
		}
	}

	for _, img := range sorted {
		if err := img.restore(); err != nil {
			return err
		}
	}
	return nil
}
// restore restores the images.
//
// Restoring means to make all *graphicscommand.Image objects have their textures and framebuffers.