text: // Copyright 2018 The Fuchsia Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef GARNET_LIB_UI_GFX_RESOURCES_SNAPSHOT_SNAPSHOTTER_H_
  #define GARNET_LIB_UI_GFX_RESOURCES_SNAPSHOT_SNAPSHOTTER_H_
  
  #include "garnet/lib/ui/gfx/resources/resource_visitor.h"
  #include "garnet/lib/ui/gfx/resources/snapshot/serializer.h"
  #include "garnet/lib/ui/scenic/scenic.h"
  #include "lib/escher/renderer/batch_gpu_uploader.h"
  
  namespace scenic_impl {
  namespace gfx {
  
  class Node;
  class Resource;
  
  using TakeSnapshotCallback = fit::function<void(::fuchsia::mem::Buffer)>;
  
  // Defines a |ResourceVisitor| that takes snapshot of a branch of the scene
  // graph. It provides the snapshot in flatbuffer formatted |fuchsia.mem.Buffer|.
  // It uses |Serializer| set of classes to recreate the node hierarchy while
  // visiting every entity of the scenic node. After the visit, the serializer
  // generates the flatbuffer in |TakeSnapshot|.
  class Snapshotter : public ResourceVisitor {
   public:
    Snapshotter(escher::BatchGpuUploaderPtr gpu_uploader);
    virtual ~Snapshotter() = default;
  
    // Takes the snapshot of the |node| and calls the |callback| with a
    // |fuchsia.mem.Buffer| buffer.
    void TakeSnapshot(Resource* resource, TakeSnapshotCallback callback);
  
   protected:
    void Visit(Memory* r) override;
    void Visit(Image* r) override;
    void Visit(ImagePipe* r) override;
    void Visit(Buffer* r) override;
    void Visit(View* r) override;
    void Visit(ViewHolder* r) override;
    void Visit(EntityNode* r) override;
    void Visit(OpacityNode* r) override;
    void Visit(ShapeNode* r) override;
    void Visit(Scene* r) override;
    void Visit(CircleShape* r) override;
    void Visit(RectangleShape* r) override;
    void Visit(RoundedRectangleShape* r) override;
    void Visit(MeshShape* r) override;
    void Visit(Material* r) override;
    void Visit(Compositor* r) override;
    void Visit(DisplayCompositor* r) override;
    void Visit(LayerStack* r) override;
    void Visit(Layer* r) override;
    void Visit(Camera* r) override;
    void Visit(Renderer* r) override;
    void Visit(Light* r) override;
    void Visit(AmbientLight* r) override;
    void Visit(DirectionalLight* r) override;
    void Visit(Import* r) override;
  
   private:
    void VisitNode(Node* r);
    void VisitResource(Resource* r);
    void VisitMesh(escher::MeshPtr mesh);
    void VisitImage(escher::ImagePtr i);
  
    void ReadImage(escher::ImagePtr image,
                   std::function<void(escher::BufferPtr buffer)> callback);
    void ReadBuffer(escher::BufferPtr buffer,
                    std::function<void(escher::BufferPtr buffer)> callback);
  
    escher::BatchGpuUploaderPtr gpu_uploader_;
  
    // Holds the current serializer for the scenic node being serialized. This is
    // needed when visiting node's content like mesh, material and images.
    std::shared_ptr<NodeSerializer> current_node_serializer_;
  
    FXL_DISALLOW_COPY_AND_ASSIGN(Snapshotter);
  };
  
  }  // namespace gfx
  }  // namespace scenic_impl
  
  #endif  // GARNET_LIB_UI_GFX_RESOURCES_SNAPSHOT_SNAPSHOTTER_H_
  