|
|
|
@ -38,9 +38,7 @@ |
|
|
|
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
|
|
|
#include "video_core/vulkan_common/vulkan_surface.h"
|
|
|
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
|
|
|
#ifdef __ANDROID__
|
|
|
|
#include <jni.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace Vulkan { |
|
|
|
namespace { |
|
|
|
|
|
|
|
@ -189,40 +187,7 @@ RendererVulkan::~RendererVulkan() { |
|
|
|
void(device.GetLogical().WaitIdle()); |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef __ANDROID__
|
|
|
|
class BooleanSetting { |
|
|
|
public: |
|
|
|
// static BooleanSetting FRAME_SKIPPING;
|
|
|
|
static BooleanSetting FRAME_INTERPOLATION; |
|
|
|
explicit BooleanSetting(bool initial_value = false) : value(initial_value) {} |
|
|
|
|
|
|
|
[[nodiscard]] bool getBoolean() const { |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
void setBoolean(bool new_value) { |
|
|
|
value = new_value; |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
bool value; |
|
|
|
}; |
|
|
|
|
|
|
|
// Initialize static members
|
|
|
|
// BooleanSetting BooleanSetting::FRAME_SKIPPING(false);
|
|
|
|
BooleanSetting BooleanSetting::FRAME_INTERPOLATION(false); |
|
|
|
|
|
|
|
// extern "C" JNIEXPORT jboolean JNICALL
|
|
|
|
// Java_org_yuzu_yuzu_1emu_features_settings_model_BooleanSetting_isFrameSkippingEnabled(JNIEnv* env, jobject /* this */) {
|
|
|
|
// return static_cast<jboolean>(BooleanSetting::FRAME_SKIPPING.getBoolean());
|
|
|
|
// }
|
|
|
|
|
|
|
|
extern "C" JNIEXPORT jboolean JNICALL |
|
|
|
Java_org_yuzu_yuzu_1emu_features_settings_model_BooleanSetting_isFrameInterpolationEnabled(JNIEnv* env, jobject /* this */) { |
|
|
|
return static_cast<jboolean>(BooleanSetting::FRAME_INTERPOLATION.getBoolean()); |
|
|
|
} |
|
|
|
|
|
|
|
void RendererVulkan::InterpolateFrames(Frame* prev_frame, Frame* interpolated_frame) { |
|
|
|
void RendererVulkan::InterpolateFrames(Frame* prev_frame, Frame* interpolated_frame) { |
|
|
|
if (!prev_frame || !interpolated_frame || !prev_frame->image || !interpolated_frame->image) { |
|
|
|
return; |
|
|
|
} |
|
|
|
@ -291,31 +256,26 @@ class BooleanSetting { |
|
|
|
TransitionImageLayout(cmdbuf, *prev_frame->image, VK_IMAGE_LAYOUT_GENERAL); |
|
|
|
TransitionImageLayout(cmdbuf, *interpolated_frame->image, VK_IMAGE_LAYOUT_GENERAL); |
|
|
|
}); |
|
|
|
} |
|
|
|
#endif
|
|
|
|
} |
|
|
|
|
|
|
|
void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebuffers) { |
|
|
|
#ifdef __ANDROID__
|
|
|
|
static int frame_counter = 0; |
|
|
|
static int target_fps = 60; // Target FPS (30 or 60)
|
|
|
|
int frame_skip_threshold = 1; |
|
|
|
|
|
|
|
bool frame_skipping = false; //BooleanSetting::FRAME_SKIPPING.getBoolean();
|
|
|
|
bool frame_interpolation = BooleanSetting::FRAME_INTERPOLATION.getBoolean(); |
|
|
|
#endif
|
|
|
|
bool frame_skipping = true; |
|
|
|
|
|
|
|
if (framebuffers.empty()) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef __ANDROID__
|
|
|
|
if (frame_skipping) { |
|
|
|
frame_skip_threshold = (target_fps == 30) ? 2 : 2; |
|
|
|
} |
|
|
|
|
|
|
|
frame_counter++; |
|
|
|
if (frame_counter % frame_skip_threshold != 0) { |
|
|
|
if (frame_interpolation && previous_frame) { |
|
|
|
if (Settings::values.frame_interpolation.GetValue() && previous_frame) { |
|
|
|
Frame* interpolated_frame = present_manager.GetRenderFrame(); |
|
|
|
InterpolateFrames(previous_frame, interpolated_frame); |
|
|
|
blit_swapchain.DrawToFrame(rasterizer, interpolated_frame, framebuffers, |
|
|
|
@ -326,7 +286,6 @@ void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebu |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
#endif
|
|
|
|
|
|
|
|
SCOPE_EXIT { |
|
|
|
render_window.OnFrameDisplayed(); |
|
|
|
|