blob: 4d9ec47626ab20eb404c39e8017aedb1fb066530 [file] [log] [blame]
// 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