blob: 017a780dece6adc923e086a22882c8496de6af29 [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_SWAPCHAIN_DISPLAY_SWAPCHAIN_H_
#define GARNET_LIB_UI_GFX_SWAPCHAIN_DISPLAY_SWAPCHAIN_H_
#include "garnet/lib/ui/gfx/swapchain/swapchain.h"
#include <lib/zx/event.h>
#include <lib/zx/handle.h>
#include <lib/zx/vmo.h>
#include <vulkan/vulkan.hpp>
#include "garnet/lib/ui/gfx/util/event_timestamper.h"
#include "lib/escher/flib/fence_listener.h"
#include "lib/escher/resources/resource_manager.h"
#include "lib/escher/resources/resource_recycler.h"
#include "lib/escher/vk/vulkan_device_queues.h"
#include "lib/fxl/memory/weak_ptr.h"
namespace scenic_impl {
namespace gfx {
class Display;
class DisplayManager;
class EventTimestamper;
// DisplaySwapchain implements the Swapchain interface by using a Vulkan
// swapchain to present images to a physical display using the Zircon
// display controller API.
class DisplaySwapchain : public Swapchain {
public:
DisplaySwapchain(DisplayManager* display_manager, Display* display,
EventTimestamper* timestamper, escher::Escher* escher);
~DisplaySwapchain() override;
// |Swapchain|
bool DrawAndPresentFrame(const FrameTimingsPtr& frame_timings,
const HardwareLayerAssignment& hla,
DrawCallback draw_callback) override;
private:
struct Framebuffer {
zx::vmo vmo;
escher::GpuMemPtr device_memory;
escher::ImagePtr escher_image;
uint64_t fb_id;
};
struct FrameRecord {
FrameTimingsPtr frame_timings;
size_t swapchain_index;
escher::SemaphorePtr render_finished_escher_semaphore;
uint64_t render_finished_event_id;
EventTimestamper::Watch render_finished_watch;
// Event is signaled when the display is done using a frame.
zx::event retired_event;
uint64_t retired_event_id;
bool presented = false;
};
std::unique_ptr<FrameRecord> NewFrameRecord(
const FrameTimingsPtr& frame_timings);
bool InitializeFramebuffers(escher::ResourceRecycler* resource_recycler);
// When a frame is presented, the previously-presented frame becomes available
// as a render target.
void OnFrameRendered(size_t frame_index, zx_time_t render_finished_time);
void OnVsync(zx_time_t timestamp, const std::vector<uint64_t>& image_ids);
// A nullable Escher (good for testing) means some resources must be accessed
// through its (valid) pointer.
escher::Escher* const escher_ = nullptr;
DisplayManager* display_manager_;
Display* const display_;
size_t next_frame_index_ = 0;
size_t presented_frame_idx_ = 0;
size_t outstanding_frame_count_ = 0;
EventTimestamper* const timestamper_;
std::vector<Framebuffer> swapchain_buffers_;
std::vector<std::unique_ptr<FrameRecord>> frames_;
vk::Format format_;
vk::Device device_;
vk::Queue queue_;
FXL_DISALLOW_COPY_AND_ASSIGN(DisplaySwapchain);
};
} // namespace gfx
} // namespace scenic_impl
#endif // GARNET_LIB_UI_GFX_SWAPCHAIN_DISPLAY_SWAPCHAIN_H_