blob: d00820df90b52eca5a150b36a5970665a279d546 [file] [log] [blame] [edit]
// 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 SRC_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_DISPLAY_H_
#define SRC_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_DISPLAY_H_
#include <fidl/fuchsia.hardware.display.types/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <zircon/compiler.h>
#include <atomic>
#include <memory>
#include <mutex>
#include <queue>
#include <unordered_set>
#include "src/lib/vulkan/swapchain/display_coordinator_listener.h"
#include "src/lib/vulkan/swapchain/image_pipe_surface.h"
#include "vulkan/vulkan_core.h"
namespace image_pipe_swapchain {
// An implementation of ImagePipeSurface based on the display and sysmem APIs.
class ImagePipeSurfaceDisplay final
: public ImagePipeSurface,
public fidl::AsyncEventHandler<fuchsia_hardware_display::Coordinator> {
public:
ImagePipeSurfaceDisplay();
~ImagePipeSurfaceDisplay() override;
bool Init() override;
bool CreateImage(VkDevice device, VkLayerDispatchTable* pDisp, VkFormat format,
VkImageUsageFlags usage, VkSwapchainCreateFlagsKHR swapchain_flags,
VkExtent2D extent, uint32_t image_count, VkCompositeAlphaFlagBitsKHR alpha_flags,
const VkAllocationCallbacks* pAllocator,
std::vector<ImageInfo>* image_info_out) override;
bool CanPresentPendingImage() override { return false; }
bool GetSize(uint32_t* width_out, uint32_t* height_out) override;
void RemoveImage(uint32_t image_id) override;
void PresentImage(bool immediate, uint32_t image_id,
std::vector<std::unique_ptr<PlatformEvent>> acquire_fences,
std::vector<std::unique_ptr<PlatformEvent>> release_fences,
VkQueue queue) override;
SupportedImageProperties& GetSupportedImageProperties() override;
// fidl::AsyncEventHandler<fuchsia_hardware_display::Coordinator>
void on_fidl_error(fidl::UnbindInfo error) override;
private:
// `release_fence` will be signaled when a vsync is received with a larger/later config stamp.
struct ReleaseFenceEntry {
fuchsia_hardware_display::ConfigStamp config_stamp;
zx::event release_fence;
};
void ControllerOnDisplaysChanged(std::vector<fuchsia_hardware_display::Info>,
std::vector<fuchsia_hardware_display_types::DisplayId>);
void ControllerOnVsync(fuchsia_hardware_display_types::DisplayId, zx::time timestamp,
fuchsia_hardware_display::ConfigStamp applied_config_stamp,
fuchsia_hardware_display::VsyncAckCookie cookie);
// TODO(https://fxbug.dev/377322342): consider making `display_coordinator_` a sync client,
// so that it isn't necessary to call `WaitForAsyncMessage()`.
bool WaitForAsyncMessage();
fuchsia_hardware_display::ConfigStamp NextConfigStamp() {
return fuchsia_hardware_display::ConfigStamp(++last_applied_config_stamp_);
}
// This loop is manually pumped in method calls and doesn't have its own
// thread.
async::Loop client_loop_;
async::Loop listener_loop_;
std::unordered_set<uint64_t> image_ids;
bool display_connection_exited_ = false;
bool got_message_response_ = false;
std::atomic_bool have_display_ = false;
uint32_t width_ = 0;
uint32_t height_ = 0;
// ID of the first display returned, whenever the displays are updated.
fuchsia_hardware_display_types::DisplayId display_id_ = {
fuchsia_hardware_display_types::kInvalidDispId};
// Initialized in `CreateImage()`; doesn't change.
fuchsia_hardware_display::LayerId layer_id_{fuchsia_hardware_display_types::kInvalidDispId};
std::atomic_uint64_t last_applied_config_stamp_ =
fuchsia_hardware_display::kInvalidConfigStampValue;
std::queue<ReleaseFenceEntry> pending_release_fences_ __TA_GUARDED(mutex_);
fidl::SharedClient<fuchsia_hardware_display::Coordinator> display_coordinator_;
std::unique_ptr<DisplayCoordinatorListener> display_coordinator_listener_;
fidl::SyncClient<fuchsia_sysmem2::Allocator> sysmem_allocator_;
SupportedImageProperties supported_image_properties_;
std::mutex mutex_;
};
} // namespace image_pipe_swapchain
#endif // SRC_LIB_VULKAN_SWAPCHAIN_IMAGE_PIPE_SURFACE_DISPLAY_H_