mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 16:01:52 +01:00
Add Performance Statistics to EmulationActivity
This commit adds performance statistics to the emulator that can be toggled in preferences. The layout of `EmulationActivity` was also changed from `ConstraintLayout` to `RelativeLayout` due to poor performance of the former.
This commit is contained in:
parent
fb1a158e8f
commit
7f78a679c3
@ -11,6 +11,8 @@ bool Halt;
|
||||
jobject Surface;
|
||||
uint FaultCount;
|
||||
skyline::GroupMutex JniMtx;
|
||||
skyline::u16 fps;
|
||||
skyline::u32 frametime;
|
||||
|
||||
void signalHandler(int signal) {
|
||||
syslog(LOG_ERR, "Halting program due to signal: %s", strsignal(signal));
|
||||
@ -74,3 +76,11 @@ extern "C" JNIEXPORT void Java_emu_skyline_EmulationActivity_setSurface(JNIEnv *
|
||||
Surface = surface;
|
||||
JniMtx.unlock();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint Java_emu_skyline_EmulationActivity_getFps(JNIEnv *env, jobject thiz) {
|
||||
return fps;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat Java_emu_skyline_EmulationActivity_getFrametime(JNIEnv *env, jobject thiz) {
|
||||
return static_cast<float>(frametime) / 100;
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
extern bool Halt;
|
||||
extern jobject Surface;
|
||||
extern skyline::u16 fps;
|
||||
extern skyline::u32 frametime;
|
||||
|
||||
namespace skyline::gpu {
|
||||
GPU::GPU(const DeviceState &state) : state(state), window(ANativeWindow_fromSurface(state.jvm->GetEnv(), Surface)), vsyncEvent(std::make_shared<kernel::type::KEvent>(state)), bufferEvent(std::make_shared<kernel::type::KEvent>(state)) {
|
||||
@ -57,12 +59,16 @@ namespace skyline::gpu {
|
||||
vsyncEvent->Signal();
|
||||
texture->releaseCallback();
|
||||
|
||||
if (prevTime != 0) {
|
||||
auto now = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
state.logger->Error("{} ms, {} FPS", (now - prevTime) / 1000, 1000000 / (now - prevTime));
|
||||
}
|
||||
if (frameTimestamp) {
|
||||
auto now = util::GetTimeNs();
|
||||
|
||||
prevTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
frametime = static_cast<u32>((now - frameTimestamp) / 10000); // frametime / 100 is the real ms value, this is to retain the first two decimals
|
||||
fps = static_cast<u16>(1000000000 / (now - frameTimestamp));
|
||||
|
||||
frameTimestamp = now;
|
||||
} else {
|
||||
frameTimestamp = util::GetTimeNs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ namespace skyline::gpu {
|
||||
ANativeWindow *window; //!< The ANativeWindow to render to
|
||||
const DeviceState &state; //!< The state of the device
|
||||
bool surfaceUpdate{}; //!< If the surface needs to be updated
|
||||
double prevTime{}; //!< The time passed from the last frame
|
||||
u64 frameTimestamp{}; //!< The timestamp of the last frame being shown
|
||||
|
||||
public:
|
||||
std::queue<std::shared_ptr<PresentationTexture>> presentationQueue; //!< A queue of all the PresentationTextures to be posted to the display
|
||||
|
@ -14,8 +14,9 @@ import android.view.Surface
|
||||
import android.view.SurfaceHolder
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.preference.PreferenceManager
|
||||
import emu.skyline.loader.getRomFormat
|
||||
import kotlinx.android.synthetic.main.app_activity.*
|
||||
import kotlinx.android.synthetic.main.emu_activity.*
|
||||
import java.io.File
|
||||
|
||||
class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
@ -78,6 +79,16 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
*/
|
||||
private external fun setSurface(surface: Surface?)
|
||||
|
||||
/**
|
||||
* This returns the current FPS of the application
|
||||
*/
|
||||
private external fun getFps(): Int
|
||||
|
||||
/**
|
||||
* This returns the current frame-time of the application
|
||||
*/
|
||||
private external fun getFrametime(): Float
|
||||
|
||||
/**
|
||||
* This executes the specified ROM, [preferenceFd] and [logFd] are assumed to be valid beforehand
|
||||
*
|
||||
@ -101,12 +112,14 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets up [preferenceFd] and [logFd] then calls [executeApplication] for executing the application
|
||||
* This makes the window fullscreen then sets up [preferenceFd] and [logFd], sets up the performance statistics and finally calls [executeApplication] for executing the application
|
||||
*/
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.app_activity)
|
||||
setContentView(R.layout.emu_activity)
|
||||
|
||||
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
|
||||
val preference = File("${applicationInfo.dataDir}/shared_prefs/${applicationInfo.packageName}_preferences.xml")
|
||||
preferenceFd = ParcelFileDescriptor.open(preference, ParcelFileDescriptor.MODE_READ_WRITE)
|
||||
@ -114,9 +127,21 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback {
|
||||
val log = File("${applicationInfo.dataDir}/skyline.log")
|
||||
logFd = ParcelFileDescriptor.open(log, ParcelFileDescriptor.MODE_CREATE or ParcelFileDescriptor.MODE_READ_WRITE)
|
||||
|
||||
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
|
||||
game_view.holder.addCallback(this)
|
||||
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
||||
if (sharedPreferences.getBoolean("perf_stats", false)) {
|
||||
lateinit var perfRunnable: Runnable
|
||||
|
||||
perfRunnable = Runnable {
|
||||
perf_stats.text = "${getFps()} FPS\n${getFrametime()}ms"
|
||||
perf_stats.postDelayed(perfRunnable, 250)
|
||||
}
|
||||
|
||||
perf_stats.postDelayed(perfRunnable, 250)
|
||||
}
|
||||
|
||||
executeApplication(intent.data!!)
|
||||
}
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".EmulationActivity">
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/game_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
25
app/src/main/res/layout/emu_activity.xml
Normal file
25
app/src/main/res/layout/emu_activity.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".EmulationActivity">
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/game_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/perf_stats"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:textColor="#5fffffff" />
|
||||
|
||||
</RelativeLayout>
|
@ -32,7 +32,7 @@
|
||||
<string name="log_level">Log Level</string>
|
||||
<string name="log_compact">Compact Logs</string>
|
||||
<string name="log_compact_desc_on">Logs will be displayed in a compact form factor</string>
|
||||
<string name="log_compact_desc_off">The logs will be displayed in a verbose form factor</string>
|
||||
<string name="log_compact_desc_off">Logs will be displayed in a verbose form factor</string>
|
||||
<string name="system">System</string>
|
||||
<string name="use_docked">Use Docked Mode</string>
|
||||
<string name="handheld_enabled">The system will emulate being in handheld mode</string>
|
||||
@ -59,4 +59,7 @@
|
||||
<string name="ktstd_description">We use Kotlin Standard Library for accessing convenience functions in Kotlin (Apache License 2.0)</string>
|
||||
<string name="mtico">Material Design Icons</string>
|
||||
<string name="mtico_description">We use Material Design Icons to have consistent iconography throughout the application</string>
|
||||
<string name="perf_stats">Show Performance Statistics</string>
|
||||
<string name="perf_stats_desc_off">Performance Statistics will not be shown</string>
|
||||
<string name="perf_stats_desc_on">Performance Statistics will be shown in the top-left corner</string>
|
||||
</resources>
|
||||
|
@ -43,6 +43,12 @@
|
||||
android:summaryOn="@string/select_action_desc_on"
|
||||
app:key="select_action"
|
||||
app:title="@string/select_action" />
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:summaryOff="@string/perf_stats_desc_off"
|
||||
android:summaryOn="@string/perf_stats_desc_on"
|
||||
app:key="perf_stats"
|
||||
app:title="@string/perf_stats" />
|
||||
<ListPreference
|
||||
android:defaultValue="2"
|
||||
android:entries="@array/log_level"
|
||||
|
Loading…
Reference in New Issue
Block a user