blob: 782a7153155fa79f855e5cd2a98204dad1294185 [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.
#ifndef LIB_UI_SCENIC_CPP_SESSION_H_
#define LIB_UI_SCENIC_CPP_SESSION_H_
#include <fuchsia/images/cpp/fidl.h>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fit/function.h>
#include <lib/zx/event.h>
#include <lib/zx/time.h>
#include <utility>
namespace scenic {
// Records the number of bytes occupied by enqueue requests without any commands.
//
// As commands are accumulated, they are measured the number of bytes and handles
// added to this base. See |Flush|, |commands_num_bytes_|, and
// |commands_num_handles_|.
constexpr int64_t kEnqueueRequestBaseNumBytes =
sizeof(fidl_message_header_t) + sizeof(fidl_vector_t);
// Connect to Scenic and establish a new Session, as well as an InterfaceRequest
// for a SessionListener that can be hooked up as desired.
//
// Callbacks will be run on the async dispatcher specified by |dispatcher|,
// or the default dispatcher for the current thread if unspecified.
using SessionPtrAndListenerRequest =
std::pair<fuchsia::ui::scenic::SessionPtr,
fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>>;
SessionPtrAndListenerRequest CreateScenicSessionPtrAndListenerRequest(
fuchsia::ui::scenic::Scenic* scenic, async_dispatcher_t* dispatcher = nullptr);
// Wraps a Scenic session.
// Maintains a queue of pending operations and assists with allocation of
// resource ids.
class Session : private fuchsia::ui::scenic::SessionListener {
public:
// Provides timing information about a presentation request which has
// been applied by the scene manager.
using PresentCallback = fit::function<void(fuchsia::images::PresentationInfo info)>;
// Provides immediate information about predicted future latch and presentation times.
using Present2Callback =
fit::function<void(fuchsia::scenic::scheduling::FuturePresentationTimes info)>;
// Provides immediate information about predicted future latch and presentation times.
using RequestPresentationTimesCallback =
fit::function<void(fuchsia::scenic::scheduling::FuturePresentationTimes info)>;
// Called when session events are received.
using EventHandler = fit::function<void(std::vector<fuchsia::ui::scenic::Event>)>;
// Called when one or more Present2s are presented.
using OnFramePresentedCallback =
fit::function<void(fuchsia::scenic::scheduling::FramePresentedInfo info)>;
// Wraps the provided session and session listener.
// The listener is optional.
//
// Callbacks for |session_listener| will be run on the async dispatcher
// specified by |dispatcher|, or the default dispatcher for the current thread
// if unspecified. Callbacks for |session| will be run on the dispatcher to
// which it was bound before being passed in.
explicit Session(
fuchsia::ui::scenic::SessionPtr session,
fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener> session_listener = nullptr,
async_dispatcher_t* dispatcher = nullptr);
// Creates a new session using the provided Scenic and binds the listener to
// this object. The Scenic itself is not retained after construction.
//
// Callbacks will be run on the async dispatcher specified by |dispatcher|, or
// the default dispatcher for the current thread if unspecified.
explicit Session(fuchsia::ui::scenic::Scenic* scenic, async_dispatcher_t* dispatcher = nullptr);
explicit Session(fuchsia::ui::scenic::Scenic* scenic,
fidl::InterfaceRequest<fuchsia::ui::views::Focuser> view_focuser,
async_dispatcher_t* dispatcher = nullptr);
// Callbacks for SessionListener will be run on the async dispatcher specified
// by |dispatcher|, or the default dispatcher for the current thread if
// unspecified. Callbacks for SesssionPtr will be run on the dispatcher to
// which it was bound before being passed in.
explicit Session(SessionPtrAndListenerRequest session_and_listener,
async_dispatcher_t* dispatcher = nullptr);
Session(const Session&) = delete;
Session& operator=(const Session&) = delete;
// Destroys the session.
// All resources must be released prior to destruction.
~Session();
void set_error_handler(fit::function<void(zx_status_t)> closure) {
session_.set_error_handler(std::move(closure));
}
// Sets a callback which is invoked when events are received.
void set_event_handler(EventHandler event_handler) { event_handler_ = std::move(event_handler); }
// Sets the callback invoked when frames are presented.
void set_on_frame_presented_handler(OnFramePresentedCallback callback);
// Gets a pointer to the underlying session interface.
fuchsia::ui::scenic::Session* session() { return session_.get(); }
// Gets the next resource id which will be provided when |AllocResourceId| is
// called.
uint32_t next_resource_id() const { return next_resource_id_; }
// Allocates a new unique resource id.
uint32_t AllocResourceId();
// Enqueues an operation to release a resource.
void ReleaseResource(uint32_t resource_id);
// Enqueues an operation.
// The session will queue operations locally to batch submission of operations
// until |Flush()| or |Present()| is called.
void Enqueue(fuchsia::ui::scenic::Command command);
void Enqueue(fuchsia::ui::gfx::Command command);
void Enqueue(fuchsia::ui::input::Command command);
// Registers an acquire fence to be submitted during the subsequent call to
// |Present()|.
void EnqueueAcquireFence(zx::event fence);
// Registers a release fence to be submitted during the subsequent call to
// |Present()|.
void EnqueueReleaseFence(zx::event fence);
// Flushes queued operations to the session.
// Virtual for testing.
virtual void Flush();
// Presents all previously enqueued operations.
// Implicitly flushes all queued operations to the session.
// Invokes the callback when the scene manager applies the presentation.
void Present(uint64_t presentation_time, PresentCallback callback);
// Overloaded |Present()| using zx::time.
void Present(zx::time presentation_time, PresentCallback callback);
// Immediately invokes the callback, providing predicted information back to the client.
// Presents all previously enqueued operations.
// Implicitly flushes all queued operations to the session.
void Present2(zx_duration_t requested_presentation_time, zx_duration_t requested_prediction_span,
Present2Callback immediate_callback);
// Immediately invokes the callback, providing predicted information back to the client.
void RequestPresentationTimes(zx_duration_t requested_prediction_span,
RequestPresentationTimesCallback callback);
// Unbinds the internal SessionPtr; this allows moving this across threads.
void Unbind();
// Rebinds the Session interface internally; this must be called after a call
// to Unbind().
void Rebind();
void SetDebugName(const std::string& debug_name);
protected:
std::vector<fuchsia::ui::scenic::Command> commands_;
int64_t commands_num_bytes_ = kEnqueueRequestBaseNumBytes;
int64_t commands_num_handles_ = 0;
private:
// |fuchsia::ui::scenic::SessionListener|
void OnScenicError(std::string error) override;
void OnScenicEvent(std::vector<fuchsia::ui::scenic::Event> events) override;
fuchsia::ui::scenic::SessionPtr session_;
// |session_handle_| is stored only when |session_| is unbound/invalid.
fidl::InterfaceHandle<fuchsia::ui::scenic::Session> session_handle_;
uint32_t next_resource_id_ = 1u;
uint32_t resource_count_ = 0u;
std::vector<zx::event> acquire_fences_;
std::vector<zx::event> release_fences_;
EventHandler event_handler_;
fidl::Binding<fuchsia::ui::scenic::SessionListener> session_listener_binding_;
};
} // namespace scenic
#endif // LIB_UI_SCENIC_CPP_SESSION_H_