blob: 32f55de0f3303d9b137f21b545717006c2c34fb7 [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_FRAME_SCHEDULER_H_
#define GARNET_LIB_UI_GFX_ENGINE_FRAME_SCHEDULER_H_
#include <vector>
#include "garnet/lib/ui/gfx/id.h"
#include <lib/fxl/memory/weak_ptr.h>
#include <lib/zx/time.h>
namespace scenic_impl {
namespace gfx {
class FrameTimings;
using FrameTimingsPtr = fxl::RefPtr<FrameTimings>;
using PresentationTime = zx_time_t;
// Interface for performing session updates.
class SessionUpdater {
public:
struct SessionUpdate {
SessionId session_id;
PresentationTime requested_presentation_time;
};
virtual ~SessionUpdater() = default;
// Applies all updates scheduled before or at |presentation_time|, for each
// session in |sessions|. Returns true if any updates were applied, false
// otherwise.
virtual bool UpdateSessions(std::vector<SessionUpdate> sessions_to_update,
uint64_t frame_number,
zx_time_t presentation_time,
zx_duration_t presentation_interval) = 0;
};
// Interface for rendering frames.
class FrameRenderer {
public:
virtual ~FrameRenderer() = default;
// Called when it's time to render a new frame. The FrameTimings object is
// used to accumulate timing for all swapchains that are used as render
// targets in that frame.
//
// If RenderFrame() returns true, the delegate is responsible for calling
// FrameTimings::OnFrameRendered/Presented/Dropped(). Otherwise, rendering
// did not occur for some reason, and the FrameScheduler should not expect to
// receive any timing information for that frame.
// TODO(SCN-1089): these return value semantics are not ideal. See comments
// in Engine::RenderFrame() regarding this same issue.
virtual bool RenderFrame(const FrameTimingsPtr& frame_timings,
zx_time_t presentation_time,
zx_duration_t presentation_interval) = 0;
};
struct FrameSchedulerDelegate {
fxl::WeakPtr<FrameRenderer> frame_renderer;
fxl::WeakPtr<SessionUpdater> session_updater;
};
// The FrameScheduler is responsible for scheduling frames to be drawn in
// response to requests from clients. When a frame is requested, the
// FrameScheduler will decide at which Vsync the frame should be displayed at.
// This time will be no earlier than the requested time, and will be as close
// as possible to the requested time, subject to various constraints. For
// example, if the requested time is earlier than the time that rendering would
// finish, were it started immediately, then the frame will be scheduled for a
// later Vsync.
class FrameScheduler {
public:
virtual ~FrameScheduler() = default;
virtual void SetDelegate(FrameSchedulerDelegate delegate) = 0;
// If |render_continuously|, we keep scheduling new frames immediately after
// each presented frame, regardless of whether they're explicitly requested
// using RequestFrame().
virtual void SetRenderContinuously(bool render_continuously) = 0;
// Tell the FrameScheduler to schedule a frame. This is also used for
// updates triggered by something other than a Session update i.e. an
// ImagePipe with a new Image to present.
virtual void ScheduleUpdateForSession(zx_time_t presentation_time,
scenic_impl::SessionId session) = 0;
protected:
friend class FrameTimings;
// Called when the frame drawn by RenderFrame() has been
// presented to the display.
virtual void OnFramePresented(const FrameTimings& timings) = 0;
// Called when the frame drawn by RenderFrame() has finished rendering.
virtual void OnFrameRendered(const FrameTimings& timings) = 0;
};
} // namespace gfx
} // namespace scenic_impl
#endif // GARNET_LIB_UI_GFX_ENGINE_FRAME_SCHEDULER_H_