// Copyright 2017 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.

library fuchsia.ui.gfx;

using fuchsia.images;

// These are all of the types of resources that can be created within a
// |Session|.
union ResourceArgs {
  // Memory resources.
  MemoryArgs memory;
  ImageArgs image;
  ImagePipeArgs image_pipe;
  BufferArgs buffer;

  // Views.
  ViewArgs view;
  ViewHolderArgs view_holder;

  // Shapes (see shapes.fidl).
  RectangleArgs rectangle;
  RoundedRectangleArgs rounded_rectangle;
  CircleArgs circle;
  MeshArgs mesh;

  // Nodes (see nodes.fidl).
  ShapeNodeArgs shape_node;
  ClipNodeArgs clip_node;
  EntityNodeArgs entity_node;
  OpacityNodeArgs opacity_node;

  // Materials.
  MaterialArgs material;

  // Layers.
  CompositorArgs compositor;
  DisplayCompositorArgs display_compositor;
  ImagePipeCompositorArgs image_pipe_compositor;
  LayerStackArgs layer_stack;
  LayerArgs layer;

  // Scene representation and display.
  SceneArgs scene;
  CameraArgs camera;
  StereoCameraArgs stereo_camera;
  RendererArgs renderer;

  // Lighting.
  AmbientLightArgs ambient_light;
  DirectionalLightArgs directional_light;

  // A value that can be used in place of a constant value.
  VariableArgs variable;
};

struct ImagePipeArgs {
  request<fuchsia.images.ImagePipe> image_pipe_request;
};

// |Memory| is a |Resource| that wraps a client-provided Zircon vmo to register
// it with Scenic.
// TODO: specify resizing behavior.  Who can resize?  Client/Scenic/both/none?
struct MemoryArgs {
  // The VMO which backs this memory.
  handle<vmo> vmo;

  // The amount of memory from |vmo| that should be utilized.
  uint64 allocation_size;

  // The type of memory stored in the VMO, namely whether it's GPU memory or
  // host memory.
  fuchsia.images.MemoryType memory_type;
};

// An image mapped to a range of a |Memory| resource.
// TODO: more precise and extensive docs.
struct ImageArgs {
  fuchsia.images.ImageInfo info;

  uint32 memory_id;      // id of a |Memory| resource
  uint32 memory_offset;  // byte offset of image within |Memory| resource
};

// A buffer mapped to a range of |Memory|.
struct BufferArgs {
  uint32 memory_id;      // id of a |Memory| resource
  uint32 memory_offset;  // byte offset of buffer within |Memory| resource
  uint32 num_bytes;
};

// Represents a transform space which serves as a container for Nodes.  The
// Nodes will have the Views' coordinate transform applied to their own, in
// addition to being clipped to the Views' bounding box.
// See |ViewProperties|.
//
// Each View is linked to a paired ViewHolder via a shared token.
//
// Usually the View and its associated ViewHolder exist in separate processes,
// allowing a distributed scene graph to be constructed.
struct ViewArgs {
  handle<eventpair> token;
  string? debug_name;
};

// Represents a proxy for a View which can be added to a scene graph in order
// to embed the View within it.
//
// Each ViewHolder is linked to a paired View via a shared token.
//
// Usually the ViewHolder and its associated View exist in separate processes,
// allowing a distributed scene graph to be constructed.
struct ViewHolderArgs {
  handle<eventpair> token;
  string? debug_name;
};

// A Compositor draws its |LayerStack| into a framebuffer provided by its
// attached |Display|, if any.  If no display is attached, nothing is rendered.
// TODO(SCN-452): there is currently no way to create/attach a display.
struct CompositorArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

// A DisplayCompositor draws its attached |LayerStack| into an image that is
// presented on a display.
struct DisplayCompositorArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

// An ImagePipeCompositor draws its attached |LayerStack| into an image that is
// presented on an image-pipe.
struct ImagePipeCompositorArgs {
  fuchsia.images.ImagePipe target;
};

// A LayerStack is a stack of layers that are attached to a Compositor, which
// draws them in order of increasing Z-order (or rather, presents the illusion
// of drawing them in that order: it may apply any optimizations that don't
// affect the output).
//
// Supported commands:
// - AddLayer
struct LayerStackArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

// Supported commands:
// - Detach
// - SetCamera
// - SetColor
// - SetTexture
// - SetSize (depth must be zero)
// - SetSize
// - SetTranslation (z component determines the relative Z-ordering of layers)
// - SetRotation (must rotate around Z-axis)
// - SetScale
//
// A layer is not drawn unless it has a camera, texture, or color.
struct LayerArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

// A Scene is the root of a scene-graph, and defines the rendering environment
// (lighting, etc.) for the tree of nodes beneath it.  The following commands
// may be  applied to a Scene (public/fidl/fuchsia.ui.gfx/commands.fidl):
//   - Add/RemoveLight
//   - AddChild
struct SceneArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

// A Camera is used to render a Scene from a particular viewpoint.  This is
// achieved by setting a Renderer to use the camera.  The following operations
// may be applied to a Camera (see ops.fidl):
//   - SetCameraTransform
//   - SetCameraProjection
//   - SetCameraPoseBuffer
struct CameraArgs {
  // The scene that the camera is viewing.
  uint32 scene_id;
};

// A StereoCamera is a Camera that renders the scene in side-by-side stereo.
// The following operations may be applied to a StereoCamera but not a Camera:
//   - SetStereoCameraProjection
// Additionally, any operation which can be applied to a Camera can also be
// applied to a StereoCamera.
struct StereoCameraArgs {
  // The scene that the camera is viewing.
  uint32 scene_id;
};

// A Renderer renders a Scene via a Camera.  The following operations may be
// applied to a Renderer (see ops.fidl):
//   - SetCamera
//   - SetRendererParam
struct RendererArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

// An AmbientLight is a Light that is is assumed to be everywhere in the scene,
// in all directions.
//
// The following commands may be applied to an AmbientLight
// (public/fidl/fuchsia.ui.gfx/commands.fidl):
//   - SetLightColor
struct AmbientLightArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

// A DirectionalLight is a Light that is emitted from a point at infinity.
//
// Although the light is directional, the light has some amount of angular
// dispersion (i.e., the light is not fully columnated). For simplicity, we
// assume the dispersion of the light source is symmetric about the light's
// primary direction.
//
// The following commands may be applied to a DirectionalLight
// (public/fidl/fuchsia.ui.gfx/commands.fidl):
//   - SetLightColor
//   - SetDirection
struct DirectionalLightArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

// Simple texture-mapped material.
//
// Commands that can be performed later:
// SetTextureCmd will set the texture, or it can be left as zero (no
// texture).
//   The texture can be an Image or ImagePipe.
// SetColorCmd will set the color.
struct MaterialArgs {
  // TODO(SCN-694): Clean up dummy args.
  uint32 dummy = 0;
};

struct VariableArgs {
  ValueType type;
  Value initial_value;  // Must match type.  Must not be a variable_id.
};

// Describes an exported resource that is to be imported by an
// ImportResourceCmd.
//
// NOTE: Currently just an enum of importable resource types, but may later be
// expanded to express concepts like "meshes with a particular vertex format".
enum ImportSpec {
  NODE = 0;
};