| // 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. |
| |
| #include "lib/ui/scenic/client/resources.h" |
| |
| #include "lib/fxl/logging.h" |
| #include "lib/ui/scenic/fidl_helpers.h" |
| |
| namespace scenic_lib { |
| |
| Resource::Resource(Session* session) |
| : session_(session), id_(session->AllocResourceId()) {} |
| |
| Resource::Resource(Resource&& moved) |
| : session_(moved.session_), id_(moved.id_) { |
| auto& moved_session = *const_cast<Session**>(&moved.session_); |
| auto& moved_id = *const_cast<uint32_t*>(&moved.id_); |
| moved_session = nullptr; |
| moved_id = 0; |
| } |
| |
| Resource::~Resource() { |
| // If this resource was moved, it is not responsible for releasing the ID. |
| if (session_) |
| session_->ReleaseResource(id_); |
| } |
| |
| void Resource::Export(zx::eventpair export_token) { |
| session_->Enqueue(NewExportResourceOp(id(), std::move(export_token))); |
| } |
| |
| void Resource::ExportAsRequest(zx::eventpair* out_import_token) { |
| session_->Enqueue(NewExportResourceOpAsRequest(id(), out_import_token)); |
| } |
| |
| void Resource::SetEventMask(uint32_t event_mask) { |
| session_->Enqueue(NewSetEventMaskOp(id(), event_mask)); |
| } |
| |
| void Resource::SetLabel(const std::string& label) { |
| session_->Enqueue(NewSetLabelOp(id(), label)); |
| } |
| |
| Shape::Shape(Session* session) : Resource(session) {} |
| |
| Shape::Shape(Shape&& moved) : Resource(std::move(moved)) {} |
| |
| Shape::~Shape() = default; |
| |
| Circle::Circle(Session* session, float radius) : Shape(session) { |
| session->Enqueue(NewCreateCircleOp(id(), radius)); |
| } |
| |
| Circle::Circle(Circle&& moved) : Shape(std::move(moved)) {} |
| |
| Circle::~Circle() = default; |
| |
| Rectangle::Rectangle(Session* session, float width, float height) |
| : Shape(session) { |
| session->Enqueue(NewCreateRectangleOp(id(), width, height)); |
| } |
| |
| Rectangle::Rectangle(Rectangle&& moved) : Shape(std::move(moved)) {} |
| |
| Rectangle::~Rectangle() = default; |
| |
| RoundedRectangle::RoundedRectangle(Session* session, |
| float width, |
| float height, |
| float top_left_radius, |
| float top_right_radius, |
| float bottom_right_radius, |
| float bottom_left_radius) |
| : Shape(session) { |
| session->Enqueue(NewCreateRoundedRectangleOp( |
| id(), width, height, top_left_radius, top_right_radius, |
| bottom_right_radius, bottom_left_radius)); |
| } |
| |
| RoundedRectangle::RoundedRectangle(RoundedRectangle&& moved) |
| : Shape(std::move(moved)) {} |
| |
| RoundedRectangle::~RoundedRectangle() = default; |
| |
| Image::Image(const Memory& memory, |
| off_t memory_offset, |
| scenic::ImageInfoPtr info) |
| : Image(memory.session(), memory.id(), memory_offset, std::move(info)) {} |
| |
| Image::Image(Session* session, |
| uint32_t memory_id, |
| off_t memory_offset, |
| scenic::ImageInfoPtr info) |
| : Resource(session), memory_offset_(memory_offset), info_(*info) { |
| session->Enqueue( |
| NewCreateImageOp(id(), memory_id, memory_offset_, std::move(info))); |
| } |
| |
| Image::Image(Image&& moved) |
| : Resource(std::move(moved)), |
| memory_offset_(moved.memory_offset_), |
| info_(moved.info_) {} |
| |
| Image::~Image() = default; |
| |
| size_t Image::ComputeSize(const scenic::ImageInfo& image_info) { |
| FXL_DCHECK(image_info.tiling == scenic::ImageInfo::Tiling::LINEAR); |
| |
| switch (image_info.pixel_format) { |
| case scenic::ImageInfo::PixelFormat::BGRA_8: |
| return image_info.height * image_info.stride; |
| case scenic::ImageInfo::PixelFormat::YUY2: |
| return image_info.height * image_info.stride; |
| } |
| |
| FXL_NOTREACHED(); |
| } |
| |
| Buffer::Buffer(const Memory& memory, off_t memory_offset, size_t num_bytes) |
| : Buffer(memory.session(), memory.id(), memory_offset, num_bytes) {} |
| |
| Buffer::Buffer(Session* session, |
| uint32_t memory_id, |
| off_t memory_offset, |
| size_t num_bytes) |
| : Resource(session) { |
| session->Enqueue( |
| NewCreateBufferOp(id(), memory_id, memory_offset, num_bytes)); |
| } |
| |
| Buffer::Buffer(Buffer&& moved) : Resource(std::move(moved)) {} |
| |
| Buffer::~Buffer() = default; |
| |
| Memory::Memory(Session* session, zx::vmo vmo, scenic::MemoryType memory_type) |
| : Resource(session), memory_type_(memory_type) { |
| session->Enqueue(NewCreateMemoryOp(id(), std::move(vmo), memory_type)); |
| } |
| |
| Memory::Memory(Memory&& moved) |
| : Resource(std::move(moved)), memory_type_(moved.memory_type_) {} |
| |
| Memory::~Memory() = default; |
| |
| Mesh::Mesh(Session* session) : Shape(session) { |
| session->Enqueue(NewCreateMeshOp(id())); |
| } |
| |
| Mesh::Mesh(Mesh&& moved) : Shape(std::move(moved)) {} |
| |
| Mesh::~Mesh() = default; |
| |
| void Mesh::BindBuffers(const Buffer& index_buffer, |
| scenic::MeshIndexFormat index_format, |
| uint64_t index_offset, |
| uint32_t index_count, |
| const Buffer& vertex_buffer, |
| scenic::MeshVertexFormatPtr vertex_format, |
| uint64_t vertex_offset, |
| uint32_t vertex_count, |
| const float bounding_box_min[3], |
| const float bounding_box_max[3]) { |
| session()->Enqueue(NewBindMeshBuffersOp( |
| id(), index_buffer.id(), index_format, index_offset, index_count, |
| vertex_buffer.id(), std::move(vertex_format), vertex_offset, vertex_count, |
| bounding_box_min, bounding_box_max)); |
| } |
| |
| Material::Material(Session* session) : Resource(session) { |
| session->Enqueue(NewCreateMaterialOp(id())); |
| } |
| |
| Material::Material(Material&& moved) : Resource(std::move(moved)) {} |
| |
| Material::~Material() = default; |
| |
| void Material::SetTexture(uint32_t image_id) { |
| session()->Enqueue(NewSetTextureOp(id(), image_id)); |
| } |
| |
| void Material::SetColor(uint8_t red, |
| uint8_t green, |
| uint8_t blue, |
| uint8_t alpha) { |
| session()->Enqueue(NewSetColorOp(id(), red, green, blue, alpha)); |
| } |
| |
| Node::Node(Session* session) : Resource(session) {} |
| |
| Node::Node(Node&& moved) : Resource(std::move(moved)) {} |
| |
| Node::~Node() = default; |
| |
| void Node::SetTranslation(const float translation[3]) { |
| session()->Enqueue(NewSetTranslationOp(id(), translation)); |
| } |
| |
| void Node::SetTranslation(uint32_t variable_id) { |
| session()->Enqueue(NewSetTranslationOp(id(), variable_id)); |
| } |
| |
| void Node::SetScale(const float scale[3]) { |
| session()->Enqueue(NewSetScaleOp(id(), scale)); |
| } |
| |
| void Node::SetScale(uint32_t variable_id) { |
| session()->Enqueue(NewSetScaleOp(id(), variable_id)); |
| } |
| |
| void Node::SetRotation(const float quaternion[4]) { |
| session()->Enqueue(NewSetRotationOp(id(), quaternion)); |
| } |
| |
| void Node::SetRotation(uint32_t variable_id) { |
| session()->Enqueue(NewSetRotationOp(id(), variable_id)); |
| } |
| |
| void Node::SetAnchor(const float anchor[3]) { |
| session()->Enqueue(NewSetAnchorOp(id(), anchor)); |
| } |
| |
| void Node::SetAnchor(uint32_t variable_id) { |
| session()->Enqueue(NewSetAnchorOp(id(), variable_id)); |
| } |
| |
| void Node::SetTag(uint32_t tag_value) { |
| session()->Enqueue(NewSetTagOp(id(), tag_value)); |
| } |
| |
| void Node::SetHitTestBehavior(scenic::HitTestBehavior hit_test_behavior) { |
| session()->Enqueue(NewSetHitTestBehaviorOp(id(), hit_test_behavior)); |
| } |
| |
| void Node::Detach() { |
| session()->Enqueue(NewDetachOp(id())); |
| } |
| |
| ShapeNode::ShapeNode(Session* session) : Node(session) { |
| session->Enqueue(NewCreateShapeNodeOp(id())); |
| } |
| |
| ShapeNode::ShapeNode(ShapeNode&& moved) : Node(std::move(moved)) {} |
| |
| ShapeNode::~ShapeNode() = default; |
| |
| void ShapeNode::SetShape(uint32_t shape_id) { |
| session()->Enqueue(NewSetShapeOp(id(), shape_id)); |
| } |
| |
| void ShapeNode::SetMaterial(uint32_t material_id) { |
| session()->Enqueue(NewSetMaterialOp(id(), material_id)); |
| } |
| |
| ContainerNode::ContainerNode(Session* session) : Node(session) {} |
| |
| ContainerNode::ContainerNode(ContainerNode&& moved) : Node(std::move(moved)) {} |
| |
| ContainerNode::~ContainerNode() = default; |
| |
| void ContainerNode::AddChild(uint32_t child_node_id) { |
| session()->Enqueue(NewAddChildOp(id(), child_node_id)); |
| } |
| |
| void ContainerNode::AddPart(uint32_t part_node_id) { |
| session()->Enqueue(NewAddPartOp(id(), part_node_id)); |
| } |
| |
| void ContainerNode::DetachChildren() { |
| session()->Enqueue(NewDetachChildrenOp(id())); |
| } |
| |
| EntityNode::EntityNode(Session* session) : ContainerNode(session) { |
| session->Enqueue(NewCreateEntityNodeOp(id())); |
| } |
| |
| EntityNode::~EntityNode() = default; |
| |
| void EntityNode::SetClip(uint32_t clip_id, bool clip_to_self) { |
| session()->Enqueue(NewSetClipOp(id(), clip_id, clip_to_self)); |
| } |
| |
| ImportNode::ImportNode(Session* session) : ContainerNode(session) {} |
| |
| ImportNode::ImportNode(ImportNode&& moved) : ContainerNode(std::move(moved)) {} |
| |
| ImportNode::~ImportNode() { |
| FXL_DCHECK(is_bound_) << "Import was never bound."; |
| } |
| |
| void ImportNode::Bind(zx::eventpair import_token) { |
| FXL_DCHECK(!is_bound_); |
| session()->Enqueue(NewImportResourceOp(id(), scenic::ImportSpec::NODE, |
| std::move(import_token))); |
| is_bound_ = true; |
| } |
| |
| void ImportNode::BindAsRequest(zx::eventpair* out_export_token) { |
| FXL_DCHECK(!is_bound_); |
| session()->Enqueue(NewImportResourceOpAsRequest( |
| id(), scenic::ImportSpec::NODE, out_export_token)); |
| is_bound_ = true; |
| } |
| |
| ClipNode::ClipNode(Session* session) : ContainerNode(session) { |
| session->Enqueue(NewCreateClipNodeOp(id())); |
| } |
| |
| ClipNode::ClipNode(ClipNode&& moved) : ContainerNode(std::move(moved)) {} |
| |
| ClipNode::~ClipNode() = default; |
| |
| OpacityNode::OpacityNode(Session* session) : ContainerNode(session) { |
| // TODO(MZ-139): Opacities are not currently implemented. Create an entity |
| // node for now. |
| session->Enqueue(NewCreateEntityNodeOp(id())); |
| } |
| |
| OpacityNode::OpacityNode(OpacityNode&& moved) |
| : ContainerNode(std::move(moved)) {} |
| |
| OpacityNode::~OpacityNode() = default; |
| |
| void OpacityNode::SetOpacity(double opacity) { |
| if (opacity < 0.0) { |
| opacity = 0.0; |
| } else if (opacity > 1.0) { |
| opacity = 1.0; |
| } |
| // TODO(MZ-139): Opacities are not currently implemented. |
| } |
| |
| Variable::Variable(Session* session, scenic::ValuePtr initial_value) |
| : Resource(session) { |
| session->Enqueue(NewCreateVariableOp(id(), std::move(initial_value))); |
| } |
| |
| Variable::Variable(Variable&& moved) : Resource(std::move(moved)) {} |
| |
| Variable::~Variable() = default; |
| |
| Scene::Scene(Session* session) : ContainerNode(session) { |
| session->Enqueue(NewCreateSceneOp(id())); |
| } |
| |
| Scene::Scene(Scene&& moved) : ContainerNode(std::move(moved)) {} |
| |
| Scene::~Scene() = default; |
| |
| void Scene::AddLight(uint32_t light_id) { |
| session()->Enqueue(NewAddLightOp(id(), light_id)); |
| } |
| |
| void Scene::DetachLights() { |
| session()->Enqueue(NewDetachLightsOp(id())); |
| } |
| |
| Camera::Camera(const Scene& scene) : Camera(scene.session(), scene.id()) {} |
| |
| Camera::Camera(Session* session, uint32_t scene_id) : Resource(session) { |
| session->Enqueue(NewCreateCameraOp(id(), scene_id)); |
| } |
| |
| Camera::Camera(Camera&& moved) : Resource(std::move(moved)) {} |
| |
| Camera::~Camera() = default; |
| |
| void Camera::SetProjection(const float eye_position[3], |
| const float eye_look_at[3], |
| const float eye_up[3], |
| float fovy) { |
| session()->Enqueue( |
| NewSetCameraProjectionOp(id(), eye_position, eye_look_at, eye_up, fovy)); |
| } |
| |
| void Camera::SetPoseBuffer(const Buffer& buffer, |
| uint32_t num_entries, |
| uint64_t base_time, |
| uint64_t time_interval) { |
| session()->Enqueue(scenic_lib::NewSetCameraPoseBufferOp( |
| id(), buffer.id(), num_entries, base_time, time_interval)); |
| } |
| |
| Renderer::Renderer(Session* session) : Resource(session) { |
| session->Enqueue(NewCreateRendererOp(id())); |
| } |
| |
| Renderer::Renderer(Renderer&& moved) : Resource(std::move(moved)) {} |
| |
| Renderer::~Renderer() = default; |
| |
| void Renderer::SetCamera(uint32_t camera_id) { |
| session()->Enqueue(NewSetCameraOp(id(), camera_id)); |
| } |
| |
| void Renderer::SetParam(scenic::RendererParamPtr param) { |
| session()->Enqueue(NewSetRendererParamOp(id(), std::move(param))); |
| } |
| |
| void Renderer::SetShadowTechnique(scenic::ShadowTechnique technique) { |
| auto param = scenic::RendererParam::New(); |
| param->set_shadow_technique(technique); |
| SetParam(std::move(param)); |
| } |
| |
| void Renderer::SetDisableClipping(bool disable_clipping) { |
| session()->Enqueue(NewSetDisableClippingOp(id(), disable_clipping)); |
| } |
| |
| Layer::Layer(Session* session) : Resource(session) { |
| session->Enqueue(NewCreateLayerOp(id())); |
| } |
| |
| Layer::Layer(Layer&& moved) : Resource(std::move(moved)) {} |
| |
| Layer::~Layer() = default; |
| |
| void Layer::SetRenderer(uint32_t renderer_id) { |
| session()->Enqueue(NewSetRendererOp(id(), renderer_id)); |
| } |
| |
| void Layer::SetSize(const float size[2]) { |
| session()->Enqueue(NewSetSizeOp(id(), size)); |
| } |
| |
| LayerStack::LayerStack(Session* session) : Resource(session) { |
| session->Enqueue(NewCreateLayerStackOp(id())); |
| } |
| |
| LayerStack::LayerStack(LayerStack&& moved) : Resource(std::move(moved)) {} |
| |
| LayerStack::~LayerStack() = default; |
| |
| void LayerStack::AddLayer(uint32_t layer_id) { |
| session()->Enqueue(NewAddLayerOp(id(), layer_id)); |
| } |
| |
| DisplayCompositor::DisplayCompositor(Session* session) : Resource(session) { |
| session->Enqueue(NewCreateDisplayCompositorOp(id())); |
| } |
| |
| DisplayCompositor::DisplayCompositor(DisplayCompositor&& moved) |
| : Resource(std::move(moved)) {} |
| |
| DisplayCompositor::~DisplayCompositor() = default; |
| |
| void DisplayCompositor::SetLayerStack(uint32_t layer_stack_id) { |
| session()->Enqueue(NewSetLayerStackOp(id(), layer_stack_id)); |
| } |
| |
| Light::Light(Session* session) : Resource(session) {} |
| |
| Light::Light(Light&& moved) : Resource(std::move(moved)) {} |
| |
| Light::~Light() = default; |
| |
| void Light::SetColor(const float rgb[3]) { |
| session()->Enqueue(NewSetLightColorOp(id(), rgb)); |
| } |
| |
| void Light::SetColor(uint32_t variable_id) { |
| session()->Enqueue(NewSetLightColorOp(id(), variable_id)); |
| } |
| |
| void Light::Detach() { |
| session()->Enqueue(NewDetachLightOp(id())); |
| } |
| |
| AmbientLight::AmbientLight(Session* session) : Light(session) { |
| session->Enqueue(NewCreateAmbientLightOp(id())); |
| } |
| |
| AmbientLight::AmbientLight(AmbientLight&& moved) : Light(std::move(moved)) {} |
| |
| AmbientLight::~AmbientLight() = default; |
| |
| DirectionalLight::DirectionalLight(Session* session) : Light(session) { |
| session->Enqueue(NewCreateDirectionalLightOp(id())); |
| } |
| |
| DirectionalLight::DirectionalLight(DirectionalLight&& moved) |
| : Light(std::move(moved)) {} |
| |
| DirectionalLight::~DirectionalLight() = default; |
| |
| void DirectionalLight::SetDirection(const float direction[3]) { |
| session()->Enqueue(NewSetLightDirectionOp(id(), direction)); |
| } |
| |
| void DirectionalLight::SetDirection(uint32_t variable_id) { |
| session()->Enqueue(NewSetLightDirectionOp(id(), variable_id)); |
| } |
| |
| } // namespace scenic_lib |