| // 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. |
| |
| #ifndef LIB_UI_SCENIC_CPP_RESOURCES_H_ |
| #define LIB_UI_SCENIC_CPP_RESOURCES_H_ |
| |
| #include <fuchsia/images/cpp/fidl.h> |
| #include <fuchsia/ui/gfx/cpp/fidl.h> |
| #include <fuchsia/ui/views/cpp/fidl.h> |
| #include <lib/ui/scenic/cpp/session.h> |
| #include <lib/zx/time.h> |
| #include <zircon/assert.h> |
| |
| #include <array> |
| |
| namespace scenic { |
| |
| // Represents a resource in a session with a dynamically allocated id. |
| // The resource is released from the session when this object is destroyed |
| // but it may still be in use within the session if other resources reference |
| // it. |
| // This type cannot be instantiated, please see subclasses. |
| class Resource { |
| public: |
| // Gets the session which owns this resource. |
| Session* session() const { |
| ZX_DEBUG_ASSERT(session_); |
| return session_; |
| } |
| |
| // Gets the resource's id. |
| uint32_t id() const { return id_; } |
| |
| // Exports the resource and associates it with |export_token|. |
| void Export(zx::eventpair export_token); |
| |
| // Exports the resource and returns an import token in |out_import_token| |
| // which allows it to be imported into other sessions. |
| void ExportAsRequest(zx::eventpair* out_import_token); |
| |
| // Sets which events a resource should deliver to the session listener. |
| void SetEventMask(uint32_t event_mask); |
| |
| // Sets a label to help developers identify the purpose of the resource |
| // when using diagnostic tools. |
| void SetLabel(const std::string& label); |
| |
| protected: |
| explicit Resource(Session* session); |
| Resource(Resource&& moved) noexcept; |
| |
| Resource(const Resource&) = delete; |
| Resource& operator=(const Resource&) = delete; |
| |
| virtual ~Resource(); |
| |
| private: |
| Session* const session_; |
| uint32_t const id_; |
| }; |
| |
| // Represents a memory resource in a session. |
| // TODO(SCN-268): Make this class final, and add public move constructor. |
| class Memory : public Resource { |
| public: |
| Memory(Session* session, zx::vmo vmo, uint64_t allocation_size, |
| fuchsia::images::MemoryType memory_type); |
| ~Memory(); |
| |
| // Gets the underlying VMO's memory type, indicating whether it represents |
| // host or GPU memory. |
| fuchsia::images::MemoryType memory_type() const { return memory_type_; } |
| |
| protected: |
| Memory(Memory&& moved) noexcept; |
| |
| private: |
| fuchsia::images::MemoryType const memory_type_; |
| }; |
| |
| // Represents an abstract shape resource in a session. |
| // This type cannot be instantiated, please see subclasses. |
| class Shape : public Resource { |
| protected: |
| explicit Shape(Session* session); |
| Shape(Shape&& moved) noexcept; |
| ~Shape(); |
| }; |
| |
| // Represents a circle shape resource in a session. |
| class Circle final : public Shape { |
| public: |
| Circle(Session* session, float radius); |
| Circle(Circle&& moved) noexcept; |
| ~Circle(); |
| }; |
| |
| // Represents a rectangle shape resource in a session. |
| class Rectangle final : public Shape { |
| public: |
| Rectangle(Session* session, float width, float height); |
| Rectangle(Rectangle&& moved) noexcept; |
| ~Rectangle(); |
| }; |
| |
| // Represents a rounded rectangle shape resource in a session. |
| class RoundedRectangle final : public Shape { |
| public: |
| RoundedRectangle(Session* session, float width, float height, float top_left_radius, |
| float top_right_radius, float bottom_right_radius, float bottom_left_radius); |
| RoundedRectangle(RoundedRectangle&& moved) noexcept; |
| ~RoundedRectangle(); |
| }; |
| |
| // Represents an image resource in a session. |
| // TODO(SCN-268): Make this class final, and add public move constructor. |
| class Image : public Resource { |
| public: |
| // Creates an image resource bound to a session. |
| Image(const Memory& memory, off_t memory_offset, fuchsia::images::ImageInfo info); |
| Image(Session* session, uint32_t memory_id, off_t memory_offset, fuchsia::images::ImageInfo info); |
| ~Image(); |
| |
| // Returns the number of bytes needed to represent an image. |
| static size_t ComputeSize(const fuchsia::images::ImageInfo& image_info); |
| |
| // Gets the byte offset of the image within its memory resource. |
| off_t memory_offset() const { return memory_offset_; } |
| |
| // Gets information about the image's layout. |
| const fuchsia::images::ImageInfo& info() const { return info_; } |
| |
| protected: |
| Image(Image&& moved) noexcept; |
| |
| private: |
| off_t const memory_offset_; |
| fuchsia::images::ImageInfo const info_; |
| }; |
| |
| // Represents a buffer that is immutably bound to a range of a memory resource. |
| class Buffer final : public Resource { |
| public: |
| Buffer(const Memory& memory, off_t memory_offset, size_t num_bytes); |
| Buffer(Session* session, uint32_t memory_id, off_t memory_offset, size_t num_bytes); |
| Buffer(Buffer&& moved) noexcept; |
| ~Buffer(); |
| }; |
| |
| // Represents a mesh resource in a session. Before it can be rendered, it |
| // must be bound to index and vertex arrays by calling the BindBuffers() method. |
| class Mesh final : public Shape { |
| public: |
| Mesh(Session* session); |
| Mesh(Mesh&& moved) noexcept; |
| |
| ~Mesh(); |
| |
| // These arguments are documented in commands.fidl; see |
| // BindMeshBuffersCmd. |
| void BindBuffers(const Buffer& index_buffer, fuchsia::ui::gfx::MeshIndexFormat index_format, |
| uint64_t index_offset, uint32_t index_count, const Buffer& vertex_buffer, |
| fuchsia::ui::gfx::MeshVertexFormat vertex_format, uint64_t vertex_offset, |
| uint32_t vertex_count, const std::array<float, 3>& bounding_box_min, |
| const std::array<float, 3>& bounding_box_max); |
| }; |
| |
| // Represents a material resource in a session. |
| class Material final : public Resource { |
| public: |
| explicit Material(Session* session); |
| Material(Material&& moved) noexcept; |
| ~Material(); |
| |
| // Sets the material's texture. |
| void SetTexture(const Image& image) { |
| ZX_DEBUG_ASSERT(session() == image.session()); |
| SetTexture(image.id()); |
| } |
| void SetTexture(uint32_t image_id); |
| |
| // Sets the material's color. |
| void SetColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); |
| }; |
| |
| // Represents an abstract node resource in a session. |
| // This type cannot be instantiated, please see subclasses. |
| class Node : public Resource { |
| public: |
| // Sets the node's transform properties. |
| void SetTranslation(float tx, float ty, float tz) { SetTranslation({tx, ty, tz}); } |
| |
| void SetTranslation(const std::array<float, 3>& translation); |
| |
| void SetTranslation(uint32_t variable_id); |
| |
| void SetScale(float sx, float sy, float sz) { SetScale({sx, sy, sz}); } |
| void SetScale(const std::array<float, 3>& scale); |
| void SetScale(uint32_t variable_id); |
| void SetRotation(float qi, float qj, float qk, float qw) { SetRotation({qi, qj, qk, qw}); } |
| void SetRotation(const std::array<float, 4>& quaternion); |
| void SetRotation(uint32_t variable_id); |
| void SetAnchor(float ax, float ay, float az) { SetAnchor({ax, ay, az}); } |
| void SetAnchor(const std::array<float, 3>& anchor); |
| void SetAnchor(uint32_t variable_id); |
| |
| void SendSizeChangeHint(float width_change_factor, float height_change_factor); |
| |
| // Sets the node's tag value. |
| void SetTag(uint32_t tag_value); |
| |
| // Sets the node's hit test behavior. |
| void SetHitTestBehavior(fuchsia::ui::gfx::HitTestBehavior hit_test_behavior); |
| |
| // Detaches the node from its parent. |
| void Detach(); |
| |
| protected: |
| explicit Node(Session* session); |
| Node(Node&& moved) noexcept; |
| ~Node(); |
| }; |
| |
| // Represents an shape node resource in a session. |
| class ShapeNode final : public Node { |
| public: |
| explicit ShapeNode(Session* session); |
| ShapeNode(ShapeNode&& moved) noexcept; |
| ~ShapeNode(); |
| |
| // Sets the shape that the shape node should draw. |
| void SetShape(const Shape& shape) { |
| ZX_DEBUG_ASSERT(session() == shape.session()); |
| SetShape(shape.id()); |
| } |
| void SetShape(uint32_t shape_id); |
| |
| // Sets the material with which to draw the shape. |
| void SetMaterial(const Material& material) { |
| ZX_DEBUG_ASSERT(session() == material.session()); |
| SetMaterial(material.id()); |
| } |
| void SetMaterial(uint32_t material_id); |
| }; |
| |
| // Abstract base class for nodes which can have child nodes. |
| // This type cannot be instantiated, please see subclasses. |
| class ContainerNode : public Node { |
| public: |
| // Adds a child to the node. |
| void AddChild(const Node& child) { |
| ZX_DEBUG_ASSERT(session() == child.session()); |
| AddChild(child.id()); |
| } |
| void AddChild(uint32_t child_node_id); |
| |
| // Detaches all children from the node. |
| void DetachChildren(); |
| |
| protected: |
| explicit ContainerNode(Session* session); |
| ContainerNode(ContainerNode&& moved) noexcept; |
| ~ContainerNode(); |
| }; |
| |
| // Required by EntityNode::Attach(). |
| class ViewHolder; |
| |
| // Represents an entity node resource in a session. |
| // TODO(SCN-268): Make this class final, and add public move constructor. |
| class EntityNode : public ContainerNode { |
| public: |
| explicit EntityNode(Session* session); |
| EntityNode(EntityNode&& moved) noexcept; |
| ~EntityNode(); |
| |
| void SetClip(uint32_t clip_id, bool clip_to_self); |
| void SetClipPlanes(std::vector<fuchsia::ui::gfx::Plane3> planes); |
| |
| // Deprecated(38480): use |AddChild| instead. |
| void Attach(const ViewHolder& view_holder); |
| }; |
| |
| // Represents an imported node resource in a session. |
| // The imported node is initially created in an unbound state and must |
| // be bound immediately after creation, prior to use. |
| // |
| // Deprecated(38480): use EntityNode instead or consider omitting. |
| class ImportNode final : public ContainerNode { |
| public: |
| explicit ImportNode(Session* session); |
| ImportNode(ImportNode&& moved) noexcept; |
| ~ImportNode(); |
| |
| // Imports the node associated with |import_token|. |
| void Bind(zx::eventpair import_token); |
| |
| // Imports the node and returns an export token in |out_export_token| |
| // by which another session can export a node to associate with this import. |
| void BindAsRequest(zx::eventpair* out_export_token); |
| |
| // Returns true if the import has been bound. |
| bool is_bound() const { return is_bound_; } |
| |
| void Attach(const ViewHolder& view_holder); |
| |
| private: |
| bool is_bound_ = false; |
| }; |
| |
| /// Represents an attachment point for a subgraph within a larger scene graph. |
| /// The |ViewHolder| can be attached to a Node as a child, and the contents of |
| /// the linked |View| will become a child of the Node as well. |
| /// |
| /// Each |ViewHolder| is linked to a paired |View| via a shared token pair. |
| class ViewHolder final : public Node { |
| public: |
| ViewHolder(Session* session, zx::eventpair token, const std::string& debug_name); |
| ViewHolder(Session* session, fuchsia::ui::views::ViewHolderToken token, |
| const std::string& debug_name); |
| ViewHolder(ViewHolder&& moved) noexcept; |
| ~ViewHolder(); |
| |
| // Set properties of the attached view. |
| |
| void SetViewProperties(float min_x, float min_y, float min_z, float max_x, float max_y, |
| float max_z, float in_min_x, float in_min_y, float in_min_z, |
| float in_max_x, float in_max_y, float in_max_z) { |
| SetViewProperties({min_x, min_y, min_z}, {max_x, max_y, max_z}, {in_min_x, in_min_y, in_min_z}, |
| {in_max_x, in_max_y, in_max_z}); |
| } |
| void SetViewProperties(const std::array<float, 3>& bounding_box_min, |
| const std::array<float, 3>& bounding_box_max, |
| const std::array<float, 3>& inset_from_min, |
| const std::array<float, 3>& inset_from_max); |
| void SetViewProperties(const fuchsia::ui::gfx::ViewProperties& props); |
| |
| void SetDebugBoundsColor(uint8_t red, uint8_t green, uint8_t blue); |
| }; |
| |
| // Represents the root of a subgraph within a larger scene graph. |Node|s can |
| // be attached to the |View| as children, and these |Node|s will have the |
| // |View|s' coordinate transform applied to their own, in addition to being |
| // clipped to the |View|s' bounding box. |
| // |
| // Each |View| is linked to an associated |ViewHolder| via a shared token pair. |
| class View final : public Resource { |
| public: |
| View(Session* session, zx::eventpair token, const std::string& debug_name); |
| View(Session* session, fuchsia::ui::views::ViewToken token, const std::string& debug_name); |
| View(Session* session, fuchsia::ui::views::ViewToken token, |
| fuchsia::ui::views::ViewRefControl control_ref, fuchsia::ui::views::ViewRef view_ref, |
| const std::string& debug_name); |
| View(View&& moved) noexcept; |
| ~View(); |
| |
| void AddChild(const Node& child) const; |
| void DetachChild(const Node& child) const; |
| |
| void enableDebugBounds(bool enable); |
| }; |
| |
| // Creates a node that clips the contents of its hierarchy to the specified clip |
| // shape. |
| class ClipNode final : public ContainerNode { |
| public: |
| explicit ClipNode(Session* session); |
| ClipNode(ClipNode&& moved) noexcept; |
| ~ClipNode(); |
| }; |
| |
| // Creates a node that renders its hierarchy with the specified opacity. |
| class OpacityNodeHACK final : public ContainerNode { |
| public: |
| explicit OpacityNodeHACK(Session* session); |
| OpacityNodeHACK(OpacityNodeHACK&& moved) noexcept; |
| ~OpacityNodeHACK(); |
| |
| // The opacity with which to render the contents of the hierarchy rooted at |
| // this node. The opacity values are clamped 0.0 to 1.0. |
| void SetOpacity(float opacity); |
| }; |
| |
| // A value that can be used in place of a constant value. |
| class Variable final : public Resource { |
| public: |
| explicit Variable(Session* session, fuchsia::ui::gfx::Value initial_value); |
| Variable(Variable&& moved) noexcept; |
| ~Variable(); |
| }; |
| |
| // Represents an abstract light resource in a session. |
| // This type cannot be instantiated, please see subclasses. |
| class Light : public Resource { |
| public: |
| // Sets the light's color. |
| void SetColor(float red, float green, float blue) { SetColor({red, green, blue}); } |
| void SetColor(const std::array<float, 3>& rgb); |
| void SetColor(uint32_t variable_id); |
| |
| // Detach light from the scene it is attached to, if any. |
| void Detach(); |
| |
| protected: |
| explicit Light(Session* session); |
| Light(Light&& moved) noexcept; |
| ~Light(); |
| }; |
| |
| // Represents a directional light resource in a session. |
| class AmbientLight final : public Light { |
| public: |
| explicit AmbientLight(Session* session); |
| AmbientLight(AmbientLight&& moved) noexcept; |
| ~AmbientLight(); |
| }; |
| |
| // Represents a directional light resource in a session. |
| class DirectionalLight final : public Light { |
| public: |
| explicit DirectionalLight(Session* session); |
| DirectionalLight(DirectionalLight&& moved) noexcept; |
| ~DirectionalLight(); |
| |
| // Sets the light's direction. |
| void SetDirection(float dx, float dy, float dz) { SetDirection({dx, dy, dz}); } |
| void SetDirection(const std::array<float, 3>& direction); |
| void SetDirection(uint32_t variable_id); |
| }; |
| |
| // Represents a point light resource in a session. |
| class PointLight final : public Light { |
| public: |
| explicit PointLight(Session* session); |
| PointLight(PointLight&& moved) noexcept; |
| ~PointLight(); |
| |
| // Sets the light's direction. |
| void SetPosition(float dx, float dy, float dz) { SetPosition({dx, dy, dz}); } |
| void SetPosition(const std::array<float, 3>& position); |
| void SetPosition(uint32_t variable_id); |
| |
| // Set the light's falloff. |
| void SetFalloff(float falloff); |
| }; |
| |
| // Represents a scene resource in a session. |
| class Scene final : public ContainerNode { |
| public: |
| explicit Scene(Session* session); |
| Scene(Scene&& moved) noexcept; |
| ~Scene(); |
| |
| void AddLight(const Light& light) { |
| ZX_DEBUG_ASSERT(session() == light.session()); |
| AddLight(light.id()); |
| } |
| void AddLight(uint32_t light_id); |
| |
| void AddAmbientLight(const AmbientLight& light) { |
| ZX_DEBUG_ASSERT(session() == light.session()); |
| AddAmbientLight(light.id()); |
| } |
| void AddAmbientLight(uint32_t light_id); |
| |
| void AddDirectionalLight(const DirectionalLight& light) { |
| ZX_DEBUG_ASSERT(session() == light.session()); |
| AddDirectionalLight(light.id()); |
| } |
| void AddDirectionalLight(uint32_t light_id); |
| |
| void AddPointLight(const PointLight& light) { |
| ZX_DEBUG_ASSERT(session() == light.session()); |
| AddPointLight(light.id()); |
| } |
| void AddPointLight(uint32_t light_id); |
| |
| void DetachLights(); |
| |
| private: |
| void Detach() = delete; |
| }; |
| |
| class CameraBase : public Resource { |
| public: |
| CameraBase(Session* session) : Resource(session) {} |
| CameraBase(CameraBase&& moved) noexcept : Resource(std::move(moved)) {} |
| ~CameraBase() {} |
| // Sets the camera's view parameters. |
| void SetTransform(const std::array<float, 3>& eye_position, |
| const std::array<float, 3>& eye_look_at, const std::array<float, 3>& eye_up); |
| // Sets the camera's 2-D clip-space transform. Translation is in Vulkan NDC ([-1, 1]^2), after |
| // scaling, so for example, under a scale of 3, (-3, -3) would translate to center the lower right |
| // corner, whereas (-2, -2) would align the lower right corner with that of the clipping volume. |
| // Scaling occurs on the x/y plane. z is unaffected. |
| void SetClipSpaceTransform(float x, float y, float scale); |
| // Sets the camera pose buffer |
| void SetPoseBuffer(const Buffer& buffer, uint32_t num_entries, int64_t base_time, |
| uint64_t time_interval); |
| // Overloaded version of |SetPoseBuffer()| using `zx::time` and `zx::duration`. |
| void SetPoseBuffer(const Buffer& buffer, uint32_t num_entries, zx::time base_time, |
| zx::duration time_interval); |
| }; |
| |
| // Represents a camera resource in a session. |
| class Camera : public CameraBase { |
| public: |
| explicit Camera(const Scene& scene); |
| Camera(Session* session, uint32_t scene_id); |
| Camera(Camera&& moved) noexcept; |
| ~Camera(); |
| |
| // Sets the camera's projection parameters. |
| void SetProjection(const float fovy); |
| }; |
| |
| // Represents a StereoCamera resource in a session. |
| class StereoCamera final : public CameraBase { |
| public: |
| explicit StereoCamera(const Scene& scene); |
| StereoCamera(Session* session, uint32_t scene_id); |
| StereoCamera(StereoCamera&& moved) noexcept; |
| ~StereoCamera(); |
| |
| // Sets the camera's projection parameters. |
| void SetStereoProjection(const std::array<float, 4 * 4>& left_projection, |
| const std::array<float, 4 * 4>& right_projection); |
| }; |
| |
| // Represents a renderer resource in a session. |
| class Renderer final : public Resource { |
| public: |
| explicit Renderer(Session* session); |
| Renderer(Renderer&& moved) noexcept; |
| ~Renderer(); |
| |
| // Sets the camera whose view will be rendered. |
| void SetCamera(const Camera& camera) { |
| ZX_DEBUG_ASSERT(session() == camera.session()); |
| SetCamera(camera.id()); |
| } |
| void SetCamera(uint32_t camera_id); |
| |
| void SetParam(fuchsia::ui::gfx::RendererParam param); |
| |
| // Convenient wrapper for SetParam(). |
| void SetShadowTechnique(fuchsia::ui::gfx::ShadowTechnique technique); |
| |
| // Set whether clipping is disabled for this renderer. |
| // NOTE: disabling clipping only has a visual effect; hit-testing is not |
| // affected. |
| void SetDisableClipping(bool disable_clipping); |
| |
| // Set whether debug visualization is enabled for this renderer. |
| void SetEnableDebugging(bool enable_debugging); |
| }; |
| |
| // Represents a layer resource in a session. |
| class Layer final : public Resource { |
| public: |
| explicit Layer(Session* session); |
| Layer(Layer&& moved) noexcept; |
| ~Layer(); |
| |
| // Sets the layer's XY translation and Z-order. |
| void SetTranslation(float tx, float ty, float tz) { SetTranslation({tx, ty, tz}); } |
| void SetTranslation(const std::array<float, 3>& translation); |
| |
| void SetSize(float width, float height) { SetSize({width, height}); } |
| void SetSize(const std::array<float, 2>& size); |
| |
| void SetRenderer(const Renderer& renderer) { |
| ZX_DEBUG_ASSERT(session() == renderer.session()); |
| SetRenderer(renderer.id()); |
| } |
| void SetRenderer(uint32_t renderer_id); |
| }; |
| |
| // Represents a layer-stack resource in a session. |
| class LayerStack final : public Resource { |
| public: |
| explicit LayerStack(Session* session); |
| LayerStack(LayerStack&& moved) noexcept; |
| ~LayerStack(); |
| |
| void AddLayer(const Layer& layer) { |
| ZX_DEBUG_ASSERT(session() == layer.session()); |
| AddLayer(layer.id()); |
| } |
| void AddLayer(uint32_t layer_id); |
| void RemoveLayer(const Layer& layer) { |
| ZX_DEBUG_ASSERT(session() == layer.session()); |
| RemoveLayer(layer.id()); |
| } |
| void RemoveLayer(uint32_t layer_id); |
| void RemoveAllLayers(); |
| }; |
| |
| // Represents a display-compositor resource in a session. |
| class DisplayCompositor final : public Resource { |
| public: |
| explicit DisplayCompositor(Session* session); |
| DisplayCompositor(DisplayCompositor&& moved) noexcept; |
| ~DisplayCompositor(); |
| |
| // Sets the layer-stack that is to be composited. |
| void SetLayerStack(const LayerStack& layer_stack) { |
| ZX_DEBUG_ASSERT(session() == layer_stack.session()); |
| SetLayerStack(layer_stack.id()); |
| } |
| void SetLayerStack(uint32_t layer_stack_id); |
| |
| void SetColorConversion(const std::array<float, 3>& preoffsets, |
| const std::array<float, 3 * 3>& matrix, |
| const std::array<float, 3>& postoffsets); |
| |
| void SetLayoutRotation(uint32_t rotation_degrees); |
| }; |
| |
| // Represents a display-less compositor resource in a session. |
| class Compositor final : public Resource { |
| public: |
| explicit Compositor(Session* session); |
| Compositor(Compositor&& moved) noexcept; |
| ~Compositor(); |
| |
| // Sets the layer-stack that is to be composited. |
| void SetLayerStack(const LayerStack& layer_stack) { |
| ZX_DEBUG_ASSERT(session() == layer_stack.session()); |
| SetLayerStack(layer_stack.id()); |
| } |
| void SetLayerStack(uint32_t layer_stack_id); |
| |
| void SetLayoutRotation(uint32_t rotation_degrees); |
| }; |
| |
| } // namespace scenic |
| |
| #endif // LIB_UI_SCENIC_CPP_RESOURCES_H_ |