blob: bd2baaac17f0f66a967122342d439587a0720cbd [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 GARNET_LIB_UI_GFX_ENGINE_SESSION_H_
#define GARNET_LIB_UI_GFX_ENGINE_SESSION_H_
#include <vector>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include "garnet/lib/ui/gfx/engine/gfx_command_applier.h"
#include "garnet/lib/ui/gfx/engine/resource_map.h"
#include "garnet/lib/ui/gfx/engine/session_context.h"
#include "garnet/lib/ui/gfx/engine/session_manager.h"
#include "garnet/lib/ui/gfx/id.h"
#include "garnet/lib/ui/gfx/resources/memory.h"
#include "garnet/lib/ui/gfx/resources/resource_context.h"
#include "garnet/lib/ui/scenic/event_reporter.h"
#include "garnet/lib/ui/scenic/util/error_reporter.h"
#include "garnet/lib/ui/scenic/util/print_command.h"
#include "lib/escher/flib/fence_set_listener.h"
#include "lib/fxl/memory/weak_ptr.h"
#include "lib/fxl/tasks/task_runner.h"
namespace scenic_impl {
namespace gfx {
class ImagePipe;
using ImagePipePtr = fxl::RefPtr<ImagePipe>;
class CommandContext;
class Engine;
class Resource;
// gfx::Session is the internal endpoint of the scenic::Session channel.
// It owns, and is responsible for, all graphics state on the channel
class Session {
public:
// Return type for ApplyScheduledUpdate
struct ApplyUpdateResult {
bool success;
bool needs_render;
};
Session(SessionId id, SessionContext context,
EventReporter* event_reporter = EventReporter::Default(),
ErrorReporter* error_reporter = ErrorReporter::Default());
virtual ~Session();
// Apply the operation to the current session state. Return true if
// successful, and false if the op is somehow invalid. In the latter case,
// the Session is left unchanged.
bool ApplyCommand(CommandContext* command_context,
fuchsia::ui::gfx::Command command) {
return GfxCommandApplier::ApplyCommand(this, command_context,
std::move(command));
}
SessionId id() const { return id_; }
const fxl::WeakPtr<Session> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
const SessionContext& session_context() const { return session_context_; }
const ResourceContext& resource_context() const { return resource_context_; }
// Return the total number of existing resources associated with this Session.
size_t GetTotalResourceCount() const { return resource_count_; }
// Return the number of resources that a client can identify via a
// ResourceId. This number is decremented when a
// ReleaseResourceCmd is applied. However, the resource may continue to
// exist if it is referenced by other resources.
size_t GetMappedResourceCount() const { return resources_.size(); }
ErrorReporter* error_reporter() const; // Never nullptr.
EventReporter* event_reporter() const; // Never nullptr.
ResourceMap* resources() { return &resources_; }
// Called by SessionHandler::Present(). Stashes the arguments without
// applying them; they will later be applied by ApplyScheduledUpdates().
bool ScheduleUpdate(uint64_t presentation_time,
std::vector<::fuchsia::ui::gfx::Command> commands,
std::vector<zx::event> acquire_fences,
std::vector<zx::event> release_fences,
fuchsia::ui::scenic::Session::PresentCallback callback);
// Called by ImagePipe::PresentImage(). Stashes the arguments without
// applying them; they will later be applied by ApplyScheduledUpdates().
void ScheduleImagePipeUpdate(uint64_t presentation_time,
ImagePipePtr image_pipe);
// Called by Engine() when it is notified by the FrameScheduler that
// a frame should be rendered for the specified |presentation_time|.
// Returns ApplyUpdateResult.success as true if updates were successfully
// applied, false if updates failed to be applied.
// Returns ApplyUpdateResult.needs_render as true if any changes were
// applied, false if none were.
ApplyUpdateResult ApplyScheduledUpdates(CommandContext* command_context,
uint64_t presentation_time,
uint64_t presentation_interval);
// Convenience. Forwards an event to the EventReporter.
void EnqueueEvent(::fuchsia::ui::gfx::Event event);
void EnqueueEvent(::fuchsia::ui::input::InputEvent event);
// Called by SessionHandler::HitTest().
void HitTest(uint32_t node_id, fuchsia::ui::gfx::vec3 ray_origin,
fuchsia::ui::gfx::vec3 ray_direction,
fuchsia::ui::scenic::Session::HitTestCallback callback);
// Called by SessionHandler::HitTestDeviceRay().
void HitTestDeviceRay(::fuchsia::ui::gfx::vec3 ray_origin,
fuchsia::ui::gfx::vec3 ray_direction,
fuchsia::ui::scenic::Session::HitTestCallback callback);
void SetDebugName(const std::string& debug_name) { debug_name_ = debug_name; }
private:
friend class Resource;
void IncrementResourceCount() { ++resource_count_; }
void DecrementResourceCount() { --resource_count_; }
struct Update {
uint64_t presentation_time;
std::vector<::fuchsia::ui::gfx::Command> commands;
std::unique_ptr<escher::FenceSetListener> acquire_fences;
std::vector<zx::event> release_fences;
// Callback to report when the update has been applied in response to
// an invocation of |Session.Present()|.
fuchsia::ui::scenic::Session::PresentCallback present_callback;
};
bool ApplyUpdate(CommandContext* command_context,
std::vector<::fuchsia::ui::gfx::Command> commands);
std::queue<Update> scheduled_updates_;
std::vector<zx::event> fences_to_release_on_next_update_;
uint64_t last_applied_update_presentation_time_ = 0;
uint64_t last_presentation_time_ = 0;
struct ImagePipeUpdate {
uint64_t presentation_time;
ImagePipePtr image_pipe;
bool operator>(const ImagePipeUpdate& rhs) const {
return presentation_time > rhs.presentation_time;
}
};
// The least element should be on top.
std::priority_queue<ImagePipeUpdate, std::vector<ImagePipeUpdate>,
std::greater<ImagePipeUpdate>>
scheduled_image_pipe_updates_;
const SessionId id_;
std::string debug_name_;
ErrorReporter* error_reporter_ = nullptr;
EventReporter* event_reporter_ = nullptr;
// Context objects should be above ResourceMap so they are destroyed after
// Resources; their lifecycle must exceed that of the Resources.
SessionContext session_context_;
ResourceContext resource_context_;
ResourceMap resources_;
size_t resource_count_ = 0;
fxl::WeakPtrFactory<Session> weak_factory_; // must be last
};
} // namespace gfx
} // namespace scenic_impl
#endif // GARNET_LIB_UI_GFX_ENGINE_SESSION_H_