2023-01-30 10:36:25 +01:00
|
|
|
// Copyright 2023 Dolphin Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2024-04-10 01:57:32 +02:00
|
|
|
#include <string_view>
|
|
|
|
#include <vector>
|
|
|
|
|
2023-01-30 10:36:25 +01:00
|
|
|
#include "Common/CommonTypes.h"
|
2023-02-03 01:37:42 +01:00
|
|
|
#include "Common/HookableEvent.h"
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2024-01-31 19:12:06 +01:00
|
|
|
namespace Core
|
|
|
|
{
|
|
|
|
class System;
|
|
|
|
}
|
|
|
|
|
2023-01-30 10:36:25 +01:00
|
|
|
// Called when certain video config setting are changed
|
2023-02-03 01:37:42 +01:00
|
|
|
using ConfigChangedEvent = Common::HookableEvent<"ConfigChanged", u32>;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
|
|
|
// An event called just before the first draw call of a frame
|
2023-02-03 01:37:42 +01:00
|
|
|
using BeforeFrameEvent = Common::HookableEvent<"BeforeFrame">;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
|
|
|
// An event called after the frame XFB copy begins processing on the host GPU.
|
|
|
|
// Useful for "once per frame" usecases.
|
|
|
|
// Note: In a few rare cases, games do multiple XFB copies per frame and join them while presenting.
|
|
|
|
// If this matters to your usecase, you should use BeforePresent instead.
|
2024-01-31 19:12:06 +01:00
|
|
|
using AfterFrameEvent = Common::HookableEvent<"AfterFrame", Core::System&>;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
|
|
|
struct PresentInfo
|
|
|
|
{
|
2023-01-31 05:29:16 +01:00
|
|
|
enum class PresentReason
|
|
|
|
{
|
|
|
|
Immediate, // FIFO is Presenting the XFB immediately, straight after the XFB copy
|
|
|
|
VideoInterface, // VideoInterface has triggered a present with a new frame
|
|
|
|
VideoInterfaceDuplicate, // VideoInterface has triggered a present with a duplicate frame
|
|
|
|
};
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// The number of (unique) frames since the emulated console booted
|
2023-02-16 04:18:39 +01:00
|
|
|
u64 frame_count = 0;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// The number of presents since the video backend was initialized.
|
|
|
|
// never goes backwards.
|
2023-02-16 04:18:39 +01:00
|
|
|
u64 present_count = 0;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// The frame is identical to the previous frame
|
2023-02-16 04:18:39 +01:00
|
|
|
PresentReason reason = PresentReason::Immediate;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// The exact emulated time of the when real hardware would have presented this frame
|
|
|
|
// FIXME: Immediate should predict the timestamp of this present
|
2023-02-16 04:18:39 +01:00
|
|
|
u64 emulated_timestamp = 0;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// TODO:
|
2023-02-16 04:18:39 +01:00
|
|
|
// u64 intended_present_time = 0;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// AfterPresent only: The actual time the frame was presented
|
|
|
|
u64 actual_present_time = 0;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
enum class PresentTimeAccuracy
|
|
|
|
{
|
|
|
|
// The Driver/OS has given us an exact timestamp of when the first line of the frame started
|
|
|
|
// scanning out to the monitor
|
|
|
|
PresentOnScreenExact,
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// An approximate timestamp of scanout.
|
|
|
|
PresentOnScreen,
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// Dolphin doesn't have visibility of the present time. But the present operation has
|
|
|
|
// been queued with the GPU driver and will happen in the near future.
|
|
|
|
PresentInProgress,
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// Not implemented
|
|
|
|
Unimplemented,
|
|
|
|
};
|
2023-01-30 10:36:25 +01:00
|
|
|
|
2023-01-31 05:29:16 +01:00
|
|
|
// Accuracy of actual_present_time
|
|
|
|
PresentTimeAccuracy present_time_accuracy = PresentTimeAccuracy::Unimplemented;
|
2024-04-10 01:57:32 +02:00
|
|
|
|
|
|
|
std::vector<std::string_view> xfb_copy_hashes;
|
2023-01-30 10:36:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// An event called just as a frame is queued for presentation.
|
|
|
|
// The exact timing of this event depends on the "Immediately Present XFB" option.
|
|
|
|
//
|
|
|
|
// If enabled, this event will trigger immediately after AfterFrame
|
2023-01-31 05:29:16 +01:00
|
|
|
// If disabled, this event won't trigger until the emulated interface starts drawing out a new
|
|
|
|
// frame.
|
2023-01-30 10:36:25 +01:00
|
|
|
//
|
|
|
|
// frame_count: The number of frames
|
2023-02-03 01:37:42 +01:00
|
|
|
using BeforePresentEvent = Common::HookableEvent<"BeforePresent", PresentInfo&>;
|
2023-01-30 10:36:25 +01:00
|
|
|
|
|
|
|
// An event that is triggered after a frame is presented.
|
|
|
|
// The exact timing of this event depends on backend/driver support.
|
2023-02-03 01:37:42 +01:00
|
|
|
using AfterPresentEvent = Common::HookableEvent<"AfterPresent", PresentInfo&>;
|
2023-10-29 01:30:22 +02:00
|
|
|
|
|
|
|
// An end of frame event that runs on the CPU thread
|
|
|
|
using VIEndFieldEvent = Common::HookableEvent<"VIEndField">;
|