blob: a2ecf6bfc5c1bdbb0479bb5ed65e5b60c7ceb4b5 [file] [log] [blame]
// Copyright 2018 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 "garnet/lib/ui/gfx/resources/view.h"
#include "garnet/lib/ui/gfx/engine/engine.h"
#include "garnet/lib/ui/gfx/engine/object_linker.h"
#include "garnet/lib/ui/gfx/engine/session.h"
#include "garnet/lib/ui/gfx/resources/nodes/node.h"
#include "garnet/lib/ui/gfx/util/validate_eventpair.h"
#include "src/lib/fxl/logging.h"
namespace scenic_impl {
namespace gfx {
const ResourceTypeInfo View::kTypeInfo = {ResourceType::kView, "View"};
View::View(Session* session, ResourceId id, ViewLinker::ImportLink link,
fuchsia::ui::views::ViewRefControl control_ref,
fuchsia::ui::views::ViewRef view_ref)
: Resource(session, id, View::kTypeInfo),
link_(std::move(link)),
control_ref_(std::move(control_ref)),
view_ref_(std::move(view_ref)),
weak_factory_(this) {
node_ = fxl::AdoptRef<ViewNode>(new ViewNode(session, id));
FXL_DCHECK(link_.valid());
FXL_DCHECK(!link_.initialized());
FXL_DCHECK(validate_viewref(control_ref_, view_ref_));
}
View::~View() {
// Explicitly detach the phantom node to ensure it is cleaned up.
node_->Detach();
}
void View::Connect() {
link_.Initialize(this, fit::bind_member(this, &View::LinkResolved),
fit::bind_member(this, &View::LinkDisconnected));
}
void View::SignalRender() {
if (!render_handle_) {
return;
}
// Verify the render_handle_ is still valid before attempting to signal it.
if (zx_object_get_info(render_handle_, ZX_INFO_HANDLE_VALID, /*buffer=*/NULL,
/*buffer_size=*/0, /*actual=*/NULL,
/*avail=*/NULL) == ZX_OK) {
zx_status_t status =
zx_object_signal(render_handle_, /*clear_mask=*/0u, ZX_EVENT_SIGNALED);
ZX_ASSERT(status == ZX_OK);
}
}
void View::LinkResolved(ViewHolder* view_holder) {
FXL_DCHECK(!view_holder_);
view_holder_ = view_holder;
view_holder_->AddChild(node_);
SendViewHolderConnectedEvent();
}
void View::LinkDisconnected() {
// The connection ViewHolder no longer exists, detach the phantom node from
// the ViewHolder.
node_->Detach();
view_holder_ = nullptr;
// ViewHolder was disconnected. There are no guarantees on liveness of the
// render event, so invalidate the handle.
InvalidateRenderEventHandle();
SendViewHolderDisconnectedEvent();
}
void View::SendViewHolderConnectedEvent() {
fuchsia::ui::gfx::Event event;
event.set_view_holder_connected({.view_id = id()});
session()->EnqueueEvent(std::move(event));
}
void View::SendViewHolderDisconnectedEvent() {
fuchsia::ui::gfx::Event event;
event.set_view_holder_disconnected({.view_id = id()});
session()->EnqueueEvent(std::move(event));
}
} // namespace gfx
} // namespace scenic_impl