blob: 6bc54e16cdde943cde2d26ffec7d423792d0b1ef [file] [log] [blame]
// Copyright 2019 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 SRC_UI_SCENIC_LIB_GFX_ENGINE_IMAGE_PIPE_UPDATER_H_
#define SRC_UI_SCENIC_LIB_GFX_ENGINE_IMAGE_PIPE_UPDATER_H_
#include <lib/zx/time.h>
#include <queue>
#include "src/lib/fxl/memory/weak_ptr.h"
#include "src/ui/lib/escher/flib/fence_set_listener.h"
#include "src/ui/scenic/lib/scheduling/frame_scheduler.h"
namespace scenic_impl {
namespace gfx {
namespace test {
class MockImagePipeUpdater;
} // namespace test
class ImagePipeBase;
using ImagePipeBasePtr = fxl::RefPtr<ImagePipeBase>;
using PresentImageCallback = fuchsia::images::ImagePipe::PresentImageCallback;
// ImagePipeUpdater is a helper class responsible for the scheduling and application of ImagePipe
// updates. There is one ImagePipeUpdater per Session, which is used for all ImagePipes in the
// Session. ImagePipeUpdater has two clients, Session and ImagePipe, who interact with it as
// follows:
// - ImagePipe calls ScheduleImagePipeUpdate() whenever a new image is ready to display (i.e. all
// of the fences associated with the image have been signalled). This adds an "update" to a
// priority queue sorted by target presentation time.
// - Session calls ApplyScheduledUpdates() when a frame is to be rendered. At this time, all
// updates (from all ImagePipes in the Session) are applied, by calling ImagePipe::Update() on
// the corresponding ImagePipe.
class ImagePipeUpdater : public scheduling::SessionUpdater {
public:
ImagePipeUpdater(const std::shared_ptr<scheduling::FrameScheduler>& frame_scheduler);
~ImagePipeUpdater();
// Called by ImagePipe::PresentImage(). Stashes the arguments without applying them; they will
// later be applied by ApplyScheduledUpdates(). This method can also be used to clean up after an
// ImagePipe when it is being closed/cleaned-up; in this case, pass in a null ImagePipe.
// Virtual for testing.
virtual scheduling::PresentId ScheduleImagePipeUpdate(
zx::time presentation_time, fxl::WeakPtr<ImagePipeBase> image_pipe,
std::vector<zx::event> acquire_fences, std::vector<zx::event> release_fences,
fuchsia::images::ImagePipe::PresentImageCallback callback);
// |scheduling::SessionUpdater|
UpdateResults UpdateSessions(
const std::unordered_map<scheduling::SessionId, scheduling::PresentId>& sessions_to_update,
uint64_t trace_id) override;
// |scheduling::SessionUpdater|
void PrepareFrame(uint64_t trace_id) override{};
// For tests.
scheduling::SessionId GetSchedulingId() { return scheduling_id_; }
private:
friend class test::MockImagePipeUpdater;
// Constructor for test.
ImagePipeUpdater();
// Map of fence listeners per present call. Listeners are removed when they are either signalled,
// or when an UpdateSessions call for the corresponding SchedulingIdPair or a subsequent one is
// made.
std::map<scheduling::SchedulingIdPair, escher::FenceSetListener> fence_listeners_;
// Map from SessionId to ImagePipe. Currently only has a single value in it, since
// ImagePipeUpdater is mapped one to one with ImagePipes.
std::map<scheduling::SessionId, fxl::WeakPtr<ImagePipeBase>> image_pipes_;
const scheduling::SessionId scheduling_id_;
std::weak_ptr<scheduling::FrameScheduler> frame_scheduler_;
fxl::WeakPtrFactory<ImagePipeUpdater> weak_factory_;
};
} // namespace gfx
} // namespace scenic_impl
#endif // SRC_UI_SCENIC_LIB_GFX_ENGINE_IMAGE_PIPE_UPDATER_H_