// 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.mem; // Commands that are used to modify the state of a |Session|. // TODO(SCN-237): reorder Command definitions to match the order in this union. union Command { CreateResourceCmd create_resource; ReleaseResourceCmd release_resource; ExportResourceCmd export_resource; ImportResourceCmd import_resource; // Tagging commands. SetTagCmd set_tag; // Grouping commands. DetachCmd detach; // Spatial commands. SetTranslationCmd set_translation; SetScaleCmd set_scale; SetRotationCmd set_rotation; SetAnchorCmd set_anchor; SetSizeCmd set_size; SetOpacityCmd set_opacity; SendSizeChangeHintCmdHACK send_size_change_hint_hack; // Node-specific commands. AddChildCmd add_child; // TODO: Should we require a DetachCmd before // re-parenting? AddPartCmd add_part; DetachChildrenCmd detach_children; SetShapeCmd set_shape; SetMaterialCmd set_material; SetClipCmd set_clip; SetHitTestBehaviorCmd set_hit_test_behavior; SetViewPropertiesCmd set_view_properties; TakeSnapshotCmdHACK take_snapshot_cmd; // Camera and lighting commands. SetCameraCmd set_camera; SetCameraTransformCmd set_camera_transform; SetCameraProjectionCmd set_camera_projection; SetStereoCameraProjectionCmd set_stereo_camera_projection; SetCameraPoseBufferCmd set_camera_pose_buffer; SetLightColorCmd set_light_color; SetLightDirectionCmd set_light_direction; AddLightCmd add_light; DetachLightCmd detach_light; DetachLightsCmd detach_lights; SetTextureCmd set_texture; SetColorCmd set_color; // Mesh commands. BindMeshBuffersCmd bind_mesh_buffers; // Layer and renderer commands. AddLayerCmd add_layer; RemoveLayerCmd remove_layer; RemoveAllLayersCmd remove_all_layers; SetLayerStackCmd set_layer_stack; SetRendererCmd set_renderer; SetRendererParamCmd set_renderer_param; // Events. SetEventMaskCmd set_event_mask; // Diagnostic commands. SetLabelCmd set_label; // Debugging commands. SetDisableClippingCmd set_disable_clipping; // TODO(SCN-1026): Remove this. SetImportFocusCmd set_import_focus; }; // Instructs the compositor to create the specified |Resource|, and to register // it in a table so that it can be referenced by subsequent commands. struct CreateResourceCmd { // An ID that is currently not used within the session. uint32 id; ResourceArgs resource; }; // Releases the client's reference to the resource; it is then illegal to use // the ID in subsequent Commands. Other references to the resource may exist, // so releasing the resource does not result in its immediate destruction; it is // only destroyed once the last reference is released. For example, the // resource may be required to render an in-progress frame, or it may be // referred to by another resource). However, the ID will be immediately // unregistered, and may be reused to create a new resource. struct ReleaseResourceCmd { // ID of the resource to be dereferenced. uint32 id; }; // Create an external reference to the specified resource, which can then be // imported into another Session by passing a handle to |token|'s peer to // ImportResourceCmd; see that comment for more details. // // The importing client is typically in a different process than the exporter. // No specific mechanism is provided for transferring a token from an exporter // to an importer; collaborators may choose any out-of-band API they wish to do // so. struct ExportResourceCmd { uint32 id; handle<eventpair> token; }; // Import a resource that was exported via ExportResourceCmd(). |token| is // a handle to the eventpair peer that was used to export the resource, and // |spec| describes the type of the imported resource, and the commands which // can legally be applied to it. Afterward, |id| can be used to refer to the // resource in an Command, similarly (but not identically: see below) to a // resource that was created in the session. For example, you can add children // to an imported EntityNode via AddChildCmd. // // However, note that the importer does not gain full access to the imported // resource, but rather to an attenuated subset of its capabilities. For // example, you cannot use a DetachCmd to detach an imported EntityNode from // its parent. // // Unlike ExportResourceCmd, there is no configurable timeout. There is an // expectation that the exported resource will become available in a short // amount of time. TODO: this needs elaboration... e.g. we might notify via the // SessionListener when we know that the link will never be made (e.g. if the // peer of the import token is destroyed). // // TODO: describe how the imported resource behaves if the exported resource // isn't yet available, or becomes unavailable (e.g. an imported Material might // act as a plain white texture). struct ImportResourceCmd { uint32 id; handle<eventpair> token; ImportSpec spec; }; // Maximum length for a resource label. const uint32 kLabelMaxLength = 32; // Sets/clears a label to help developers identify the purpose of the resource // when using diagnostic tools. // // The label serves no functional purpose in the scene graph. It exists only // to help developers understand its structure. The scene manager may truncate // or discard labels at will. // // Constraints: // - The label's maximum length is |kLabelMaxLength| characters. // - Setting the label to an empty string clears it. struct SetLabelCmd { uint32 id; string label; }; // Add a node as a child to another node. // // Constraints: // - |id| refs a Node with the has_children characteristic. // - |child_id| refs any Node. // // Discussion: // The child node is first removed from its existing parent, as if DetachCmd // was applied first. struct AddChildCmd { uint32 node_id; uint32 child_id; }; // Add a node as a part of another node. The implications of being a part // rather than a child differ based on the type of the part. However, one // implication is constant: removing all of a node's children (e.g. via // DetachChildrenCmd) does not affect its parts. This is similar to the // "shadow DOM" in a web browser: the controls of a <video> element are // implemented as using the shadow DOM, and do no show up amongst the children // of that element. // // Constraints: // - |id| refs a Node with the has_parts characteristic. // - |part_id| refs any Node. // // Discussion: // The part node is first removed from its existing parent, as if DetachCmd // was applied first. struct AddPartCmd { uint32 node_id; uint32 part_id; }; interface SnapshotCallbackHACK { 1: OnData(fuchsia.mem.Buffer data); }; struct TakeSnapshotCmdHACK { uint32 node_id; SnapshotCallbackHACK callback; }; // Detaches a parentable object from its parent (e.g. a node from a parent node, // or a layer from a layer stack). It is illegal to apply this command to a // non-parentable object. No-op if the target object currently has no parent. // // Constraints: // - |id| refs a parentable object // // Discussion: // For nodes, this command will detach a node from its parent, regardless of // whether it is a part or a child of its parent. struct DetachCmd { uint32 id; }; // Detaches all of a node's children (but not its parts). struct DetachChildrenCmd { uint32 node_id; }; // Sets/clears a node's tag value. // // A session can apply a tag value to any node to which it has access, including // imported nodes. These tags are private to the session and cannot be read // or modified by other sessions. When multiple sessions import the same node, // each session will only observe its own tag values. // // Hit test results for a session only include nodes which the session has // tagged with a non-zero value. Therefore a session can use tag values to // associate nodes with their functional purpose when picked. // // Constraints: // - |node_id| refs a |Node|. // - |tag_value| is the tag value to assign, or 0 to remove the tag. struct SetTagCmd { uint32 node_id; uint32 tag_value; }; // Sets a Resource's (typically a Node's) translation. // // Constraints: // - |id| refs a Resource with the has_transform characteristic. struct SetTranslationCmd { uint32 id; Vector3Value value; }; // Sets a Resource's (typically a Node's) scale. // // Constraints: // - |id| refs a Resource with the has_transform characteristic. struct SetScaleCmd { uint32 id; Vector3Value value; }; // Sets a Resource's (typically a Node's) rotation. // // Constraints: // - |id| refs a Resource with the has_transform characteristic. struct SetRotationCmd { uint32 id; QuaternionValue value; }; // Sets a Resource's (typically a Node's) anchor point. // // Constraints: // - |id| refs a Resource with the has_transform characteristic. struct SetAnchorCmd { uint32 id; Vector3Value value; }; // Sets an object's size. // // Constraints: // - |id| refs a resizeable object. // - some objects that support this command may have additional constraints // (e.g. in some cases |depth| must be zero). struct SetSizeCmd { uint32 id; Vector2Value value; }; // Sends a hint about a pending size change to the given node and all nodes // below. This is generally sent before an animation. // // |width_change_factor| and |height_change_factor| is how much bigger or smaller // the item is expected to be in the near future. This one number encapsulate // both changes in scale, as well as changes to layout width and height. struct SendSizeChangeHintCmdHACK { uint32 node_id; float32 width_change_factor; float32 height_change_factor; }; // Sets a node's opacity. // // Constraints: // - |node_id| refs a |Node| with the has_opacity characteristic. // - |opacity| is in the range [0, 1]. struct SetOpacityCmd { uint32 node_id; float32 opacity; }; // Sets/clears a node's shape. // // Constraints: // - |node_id| refs a |Node| with the has_shape characteristic. // - |shape_id| refs a |Shape|, or nothing. // - if this command causes the target to have both a |Shape| and a |Material|, // then these must be compatible with each other (see README.md regarding // "Shape/Material Compatibility"). // TODO: add "Shape/Material Compatibility section" // // Discussion: // In order to be painted, a node requires both a |Shape| and a |Material|. // Without a material, a node can still participate in hit-testing and clipping. // Without a shape, a node cannot do any of the above. struct SetShapeCmd { uint32 node_id; uint32 shape_id; }; // Sets/clears a node's material. // // Constraints: // - |node_id| refs a |Node| with the has_material characteristic. // - |material_id| refs a |Material|, or nothing. // - if this command causes the target to have both a |Shape| and a |Material|, // then these must be compatible with each other (see README.md regarding // "Shape/Material Compatibility"). // TODO: add "Shape/Material Compatibility section" // // Discussion: // In order to be painted, a node requires both a |Shape| and a |Material|. // Without a material, a node can still participate in hit-testing and clipping. // Without a shape, a node cannot do any of the above. struct SetMaterialCmd { uint32 node_id; uint32 material_id; }; // Sets/clears a node's clip. // // Constraints: // - |node_id| refs a |Node| with the has_clip characteristic. // - |clip_id| a |Node| with the is_clip characteristic, or nothing. If the // referenced node is not rooted, then it will have no effect (since its // full world-transform cannot be determined). // - |clip_to_self| If false, children are only clipped to the region specified // by |clip_id|. If true, children are additionally clipped to the node's // shape (as determined by its ShapeNode parts). // // Discussion: // If a node has a clip, it will be applied to both the parts and the children // of the node. Under some circumstances (TBD), a clip will not be applicable // to a node; in such cases it will be as though no clip has been specified for // the node. // TODO: elaborate on the circumstances under which a clip is inapplicable. // For example, consider a 3D space that looks through a portal into a 2D space // that uses a clip for a circular reveal. It would not be meaningful to clip // objects on the outside (i.e. in the 3D space). struct SetClipCmd { uint32 node_id; uint32 clip_id; bool clip_to_self; }; // Sets a node's hit test behavior. // // Discussion: // By default, hit testing is performed on the node's content, its parts, // and its children. struct SetHitTestBehaviorCmd { uint32 node_id; HitTestBehavior hit_test_behavior; }; // Sets the properties for a ViewHolder's attached View. // // Constraints: // - |view_holder_id| refs a |ViewHolder|. struct SetViewPropertiesCmd { uint32 view_holder_id; ViewProperties properties; }; // Sets a renderer's camera. // // Constraints: // - |renderer_id| refs a |Renderer|. // - |camera_id| refs a |Camera|, or stops rendering by passing zero. // - |matrix| is a value or variable of type kMatrix4x4. struct SetCameraCmd { uint32 renderer_id; uint32 camera_id; }; // Sets a camera's view matrix. // This operation can be applied to both Cameras and StereoCameras. // // Constraints: // - |camera_id| refs a |Camera|. // - |eye_position| is the position of the eye. // - |eye_look_at| is the point is the scene the that eye is pointed at. // - |eye_up| defines the camera's "up" vector. struct SetCameraTransformCmd { uint32 camera_id; Vector3Value eye_position; Vector3Value eye_look_at; Vector3Value eye_up; }; // Sets a camera's projection matrix. // This operation cannot be applied to a StereoCamera. // // Constraints: // - |camera_id| refs a |Camera| that is not a |StereoCamera|. // - |fovy| is the Y-axis field of view, in radians. // // NOTE: A default orthographic projection is specified by setting |fovy| to // zero. In this case, the camera transform is ignored. struct SetCameraProjectionCmd { uint32 camera_id; FloatValue fovy; // Y-axis field of view, in radians. }; // Sets a StereoCamera's projection matrices. // This operation can only be applied to a StereoCamera. // // Constraints: // - |camera_id| refs a |StereoCamera|. // - |left_projection| is the projection matrix for the left eye. // - |right_projection| is the projection matrix for the right eye. // // These projection matrices may also contain a transform in camera space for // their eye if needed. struct SetStereoCameraProjectionCmd { uint32 camera_id; Matrix4Value left_projection; Matrix4Value right_projection; }; // Sets the "pose buffer" for the camera identified by |camera_id|. // This operation can be applied to both Cameras and StereoCameras. // // This will override any position and rotation set for the camera and will // make it take its position and rotation from the pose buffer each frame // based on the presentation time for that frame. // // A pose buffer represents a ring buffer of poses for a fixed number of time // points in the future. Each entry in the buffer identified by |buffer_id| is // a quaternion and a position layed out as follows: // // struct Pose { // // Quaternion // float32 a; // float32 b; // float32 c; // float32 d; // // // Position // float32 x; // float32 y; // float32 z; // // // Reserved/Padding // byte[4] reserved; // } // // The buffer can be thought of as a packed array of |num_entries| Pose structs // and is required to be at least num_entries * sizeof(Pose) bytes. // // The quaternions and positions are specified in the space of the camera's // parent node. // // |base_time| is a base time point expressed in nanoseconds in the // |CLOCK_MONOTONIC| timebase and |time_interval| is the time in nanoseconds // between entries in the buffer. |base_time| must be in the past. // // For a given point in time |t| expressed in nanoseconds in the // |CLOCK_MONOTONIC| timebase the index of the corresponding pose in // the pose buffer can be computed as follows: // // index(t) = ((t - base_time) / time_interval) % num_entries // // poses[index(t)] is valid for t over the time interval (t - time_interval, t] // and should be expected to updated continuously without synchronization // for the duration of that interval. If a single pose value is needed for // multiple non-atomic operations a value should be latched and stored outside // the pose buffer. // // Because the poses are not protected by any synchronization primitives it is // possible that when a pose is latched it will be only partially updated, and // the pose being read will contain some components from the pose before it is // updated and some components from the updated pose. The safety of using these // "torn" poses relies on two things: // // 1) Sequential poses written to poses[index(t)] are very similar to each // other numerically, so that if some components are taken from the first and // some are taken from another the result is numerically similar to both // // 2) The space of positions and quaternions is locally flat at the scale of // changes between sequential updates, which guarantees that two poses which // are numerically similar also represent semantically similar poses (i.e. // there are no discontinuities which will cause a small numerical change in // the position or quaterninon to cause a large change in the encoded pose) // For positions this is guaranteed because Scenic uses a Euclidean 3-space // which is globally flat and for quaternions this is guaranteed because // quaternions encode rotation as points on a unit 4-sphere, and spheres are // locally flat. For more details on the encoding of rotations in quaterions // see https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation // // This commanderation is intended for late latching camera pose to support // low-latency motion-tracked rendering. struct SetCameraPoseBufferCmd { uint32 camera_id; uint32 buffer_id; uint32 num_entries; int64 base_time; uint64 time_interval; }; // Sets the color of the Light identified by |light_id|. struct SetLightColorCmd { uint32 light_id; ColorRgbValue color; }; // Sets the direction of the DirectionalLight identified by |light_id|. struct SetLightDirectionCmd { uint32 light_id; Vector3Value direction; }; // Adds the light specified by |light_id| specified by |light_id| to the scene // identified by |scene_id|. struct AddLightCmd { uint32 scene_id; uint32 light_id; }; // Detach the light specified by |light_id| from the scene that it is attached // to, if any. struct DetachLightCmd { uint32 light_id; }; // Detach all lights from the scene specified by |scene_id|. struct DetachLightsCmd { uint32 scene_id; }; // Sets/clears a material's texture. // // Constraints: // - |material_id| refs a |Material|. // - |texture_id| refs a |Image|, |ImagePipe|, or nothing. // // If no texture is provided (i.e. |texture_id| is zero), a solid color is used. // If a texture is provided, then the value sampled from the texture is // multiplied by the color. struct SetTextureCmd { uint32 material_id; uint32 texture_id; // Refers to an Image resource. May be zero (no texture). }; // Sets a material's color. // // Constraints: // - |material_id| refs a |Material|. // // If a texture is set on the material, then the value sampled from the texture // is multiplied by the color. struct SetColorCmd { uint32 material_id; ColorRgbaValue color; }; // Set a mesh's indices and vertices. // // |mesh_id| refs the Mesh to be updated. // |index_buffer_id| refs a Buffer that contains the mesh indices. // |index_format| defines how the index buffer data is to be interpreted. // |index_offset| number of bytes from the start of the index Buffer. // |index_count| number of indices. // |vertex_buffer_id| refs a Buffer that contains the mesh vertices. // |vertex_format| defines how the vertex buffer data is to be interpreted. // |vertex_offset| number of bytes from the start of the vertex Buffer. // |vertex_count| number of vertices. // |bounding_box| must contain all vertices within the specified range. // // The MeshVertexFormat defines which per-vertex attributes are provided by the // mesh, and the size of each attribute (and therefore the size of each vertex). // The attributes are ordered within the vertex in the same order that they // appear within the MeshVertexFormat struct. For example, if the values are // kVector3, kNone and kVector2, then: // - each vertex has a position and UV-coordinates, but no surface normal. // - the 3D position occupies bytes 0-11 (3 dimensions * 4 bytes per float32). // - the UV coords occupy bytes 12-19, since no surface normal is provided. enum MeshIndexFormat { // TODO(SCN-275): only kUint32 is currently supported. kUint16 = 1; kUint32 = 2; }; struct MeshVertexFormat { // kVector2 or kVector3. ValueType position_type; // kVector2 or kVector3 (must match position_type), or kNone. ValueType normal_type; // kVector2 or kNone. ValueType tex_coord_type; }; struct BindMeshBuffersCmd { uint32 mesh_id; uint32 index_buffer_id; MeshIndexFormat index_format; uint64 index_offset; uint32 index_count; uint32 vertex_buffer_id; MeshVertexFormat vertex_format; uint64 vertex_offset; uint32 vertex_count; BoundingBox bounding_box; }; // Add a layer to a layer stack. // Constraints: // - |layer_stack_id| refs a |LayerStack|. // - |layer_id| refs a |Layer|. // - The layer must not already belong to a different stack; it must first be // detached. struct AddLayerCmd { uint32 layer_stack_id; uint32 layer_id; }; // Remove a layer from a layer stack. // Constraints: // - |layer_stack_id| refs a |LayerStack|. // - |layer_id| refs a |Layer|. // - The layer must belong to this stack. struct RemoveLayerCmd { uint32 layer_stack_id; uint32 layer_id; }; // Remove all layers from a layer stack. // Constraints // - |layer_stack_id| refs a |LayerStack|. struct RemoveAllLayersCmd { uint32 layer_stack_id; }; // Set a compositor's layer stack, replacing the current stack (if any). // Constraints: // - |compositor_id| refs a |DisplayCompositor| or |ImagePipeCompositor|. // - |layer_stack_id| refs a |LayerStack|. struct SetLayerStackCmd { uint32 compositor_id; uint32 layer_stack_id; }; // Set a layer's renderer, replacing the current renderer (if any). // Constraints: // - |layer_id| refs a |Layer|. // - |renderer_id| refs a |Renderer|. struct SetRendererCmd { uint32 layer_id; uint32 renderer_id; }; // Sets a parameter that affects how a renderer renders a scene. // // |renderer_id| refs the Renderer that is being modified. // |param| describes the parameter that should be set, and to what. struct SetRendererParamCmd { uint32 renderer_id; RendererParam param; }; // Sets which events a resource should deliver to the session listener. // This command replaces any prior event mask for the resource. // // The initial event mask for a resource is zero, meaning no events are // reported. // // Constraints: // - |resource_id| is a valid resource id // - |event_mask| is zero or a combination of |k*EventMask| bits OR'ed together. struct SetEventMaskCmd { uint32 id; uint32 event_mask; }; // Set whether clipping should be disabled for the specified renderer. For a // newly-created renderer, clipping will NOT be disabled (i.e. it will be // enabled). // // NOTE: this disables visual clipping only; objects are still clipped for the // purposes of hit-testing. // // |renderer_id| refs the target renderer. // |disable_clipping| specifies whether the clipping should be disabled. struct SetDisableClippingCmd { uint32 renderer_id; bool disable_clipping; }; // TODO(SCN-1026): Remove this. struct SetImportFocusCmd { uint32 id; bool focusable; };