Add option in dev tools to ask Android for 60hz display using Surface.setFrameRate

Might help #18514 and #18480 if we're lucky.
This commit is contained in:
Henrik Rydgård
2023-04-28 13:39:01 +02:00
parent a80f590714
commit a6d717cb39
14 changed files with 94 additions and 11 deletions
+2 -1
View File
@@ -568,7 +568,7 @@ static int FastForwardModeFromString(const std::string &s) {
return DefaultFastForwardMode();
}
std::string FastForwardModeToString(int v) {
static std::string FastForwardModeToString(int v) {
switch (FastForwardMode(v)) {
case FastForwardMode::CONTINUOUS:
return "CONTINUOUS";
@@ -592,6 +592,7 @@ static const ConfigSetting graphicsSettings[] = {
ConfigSetting("D3D11Device", &g_Config.sD3D11Device, "", CfgFlag::DEFAULT),
#endif
ConfigSetting("CameraDevice", &g_Config.sCameraDevice, "", CfgFlag::DEFAULT),
ConfigSetting("DisplayFramerateMode", &g_Config.iDisplayFramerateMode, 0, CfgFlag::DEFAULT),
ConfigSetting("VendorBugChecksEnabled", &g_Config.bVendorBugChecksEnabled, true, CfgFlag::DONT_SAVE),
ConfigSetting("UseGeometryShader", &g_Config.bUseGeometryShader, false, CfgFlag::PER_GAME),
ConfigSetting("SkipBufferEffects", &g_Config.bSkipBufferEffects, false, CfgFlag::PER_GAME | CfgFlag::REPORT),
+1
View File
@@ -155,6 +155,7 @@ public:
std::string sD3D11Device; // Windows only
std::string sCameraDevice;
std::string sMicDevice;
int iDisplayFramerateMode; // enum DisplayFramerateMode. Android-only.
bool bSoftwareRendering;
bool bSoftwareRenderingJit;
+8
View File
@@ -168,3 +168,11 @@ enum class DebugOverlay : int {
GPU_ALLOCATOR,
FRAMEBUFFER_LIST,
};
// Android-only for now
enum class DisplayFramerateMode : int {
DEFAULT,
REQUEST_60HZ,
FORCE_60HZ_METHOD1,
FORCE_60HZ_METHOD2,
};
+4
View File
@@ -598,6 +598,10 @@ void __DisplayFlip(int cyclesLate) {
postEffectRequiresFlip = duplicateFrames || g_Config.bShaderChainRequires60FPS;
}
if (!FrameTimingThrottled()) {
NOTICE_LOG(SYSTEM, "Throttle: %d %d", (int)fastForwardSkipFlip, (int)postEffectRequiresFlip);
}
const bool fbDirty = gpu->FramebufferDirty();
bool needFlip = fbDirty || noRecentFlip || postEffectRequiresFlip;
+11 -7
View File
@@ -716,6 +716,10 @@ void TouchTestScreen::axis(const AxisInput &axis) {
void TouchTestScreen::DrawForeground(UIContext &dc) {
Bounds bounds = dc.GetLayoutBounds();
double now = time_now_d();
double delta = now - lastFrameTime_;
lastFrameTime_ = now;
dc.BeginNoTex();
for (int i = 0; i < MAX_TOUCH_POINTS; i++) {
if (touches_[i].id != -1) {
@@ -747,19 +751,19 @@ void TouchTestScreen::DrawForeground(UIContext &dc) {
#endif
"dp_res: %dx%d pixel_res: %dx%d\n"
"g_dpi: %0.3f g_dpi_scale: %0.3fx%0.3f\n"
"g_dpi_scale_real: %0.3fx%0.3f\n%s",
"g_dpi_scale_real: %0.3fx%0.3f\n"
"delta: %0.2f ms fps: %0.3f\n%s",
#if PPSSPP_PLATFORM(ANDROID)
System_GetPropertyInt(SYSPROP_DISPLAY_XRES), System_GetPropertyInt(SYSPROP_DISPLAY_YRES),
#endif
g_display.dp_xres, g_display.dp_yres,
g_display.pixel_xres, g_display.pixel_yres,
g_display.dpi,
g_display.dpi_scale_x, g_display.dpi_scale_y,
g_display.dpi_scale_real_x, g_display.dpi_scale_real_y, extra_debug);
g_display.dp_xres, g_display.dp_yres, g_display.pixel_xres, g_display.pixel_yres,
g_display.dpi, g_display.dpi_scale_x, g_display.dpi_scale_y,
g_display.dpi_scale_real_x, g_display.dpi_scale_real_y,
delta * 1000.0, 1.0 / delta,
extra_debug);
// On Android, also add joystick debug data.
dc.DrawTextShadow(buffer, bounds.centerX(), bounds.y + 20.0f, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII);
dc.Flush();
}
+2
View File
@@ -169,6 +169,8 @@ protected:
UI::TextView *lastKeyEvents_ = nullptr;
double lastFrameTime_ = 0.0;
void CreateViews() override;
void UpdateLogView();
+13
View File
@@ -1731,6 +1731,19 @@ void DeveloperToolsScreen::CreateViews() {
list->Add(new CheckBox(&g_Config.bGpuLogProfiler, dev->T("GPU log profiler")));
}
#if PPSSPP_PLATFORM(ANDROID)
static const char *framerateModes[] = { "Default", "Request 60Hz", "Force 60Hz 1", "Force 60Hz 2" };
PopupMultiChoice *framerateMode = list->Add(new PopupMultiChoice(&g_Config.iDisplayFramerateMode, gr->T("Framerate mode"), framerateModes, 0, ARRAY_SIZE(framerateModes), I18NCat::GRAPHICS, screenManager()));
framerateMode->SetEnabledFunc([]() { return System_GetPropertyInt(SYSPROP_SYSTEMVERSION) >= 30; });
if (System_GetPropertyInt(SYSPROP_SYSTEMVERSION) < 31) {
framerateMode->HideChoice(3); // not available
}
framerateMode->OnChoice.Add([this](UI::EventParams &e) {
System_Notify(SystemNotification::FORCE_RECREATE_ACTIVITY);
return UI::EVENT_DONE;
});
#endif
static const char *ffModes[] = { "Render all frames", "", "Frame Skipping" };
PopupMultiChoice *ffMode = list->Add(new PopupMultiChoice(&g_Config.iFastForwardMode, dev->T("Fast-forward mode"), ffModes, 0, ARRAY_SIZE(ffModes), I18NCat::GRAPHICS, screenManager()));
ffMode->SetEnabledFunc([]() { return !g_Config.bVSync; });
+4
View File
@@ -1464,6 +1464,10 @@ extern "C" jint JNICALL Java_org_ppsspp_ppsspp_NativeApp_getDesiredBackbufferHei
return desiredBackbufferSizeY;
}
extern "C" jint JNICALL Java_org_ppsspp_ppsspp_NativeApp_getDisplayFramerateMode(JNIEnv *, jclass) {
return g_Config.iDisplayFramerateMode;
}
std::vector<std::string> System_GetCameraDeviceList() {
jclass cameraClass = findClass("org/ppsspp/ppsspp/CameraHelper");
jmethodID deviceListMethod = getEnv()->GetStaticMethodID(cameraClass, "getDeviceList", "()Ljava/util/ArrayList;");
@@ -636,6 +636,7 @@ public abstract class NativeActivity extends Activity {
// mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 8);
// }
}
mGLSurfaceView.setRenderer(nativeRenderer);
setContentView(mGLSurfaceView);
} else {
@@ -661,6 +662,37 @@ public abstract class NativeActivity extends Activity {
}
}
private void applyFrameRate(Surface surface, float frameRateHz) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
return;
if (mSurface != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
try {
int method = NativeApp.getDisplayFramerateMode();
if (method > 0) {
Log.i(TAG, "Setting desired framerate to " + frameRateHz + " Hz method=" + method);
switch (method) {
case 1:
mSurface.setFrameRate(frameRateHz, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT);
break;
case 2:
mSurface.setFrameRate(frameRateHz, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
break;
case 3:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
mSurface.setFrameRate(frameRateHz, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, Surface.CHANGE_FRAME_RATE_ALWAYS);
}
break;
default:
break;
}
}
} catch (Exception e) {
Log.e(TAG, "Failed to set framerate: " + e.toString());
}
}
}
public void notifySurface(Surface surface) {
mSurface = surface;
@@ -676,6 +708,8 @@ public abstract class NativeActivity extends Activity {
} else {
startRenderLoopThread();
}
} else if (mSurface != null) {
applyFrameRate(mSurface, 60.0f);
}
updateSustainedPerformanceMode();
}
@@ -692,6 +726,8 @@ public abstract class NativeActivity extends Activity {
}
Log.w(TAG, "startRenderLoopThread: Starting thread");
applyFrameRate(mSurface, 60.0f);
runVulkanRenderLoop(mSurface);
}
@@ -56,6 +56,7 @@ public class NativeApp {
public static native String queryConfig(String queryName);
public static native int getSelectedCamera();
public static native int getDisplayFramerateMode();
public static native void setGpsDataAndroid(long time, float hdop, float latitude, float longitude, float altitude, float speed, float bearing);
public static native void setSatInfoAndroid(short index, short id, short elevation, short azimuth, short snr, short good);
public static native void pushCameraImageAndroid(byte[] image);
@@ -18,6 +18,8 @@ import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
import com.bda.controller.Controller;
import com.bda.controller.ControllerListener;
@@ -43,6 +45,7 @@ public class NativeGLView extends GLSurfaceView implements SensorEventListener,
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mController = Controller.getInstance(activity);
try {
MogaHack.init(mController, activity);
Log.i(TAG, "MOGA initialized");
@@ -17,6 +17,8 @@ import android.os.Handler;
import android.util.Log;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceView;
import com.bda.controller.Controller;
@@ -45,8 +47,6 @@ public class NativeSurfaceView extends SurfaceView implements SensorEventListene
mController = Controller.getInstance(activity);
// this.getHolder().setFormat(PixelFormat.RGBA_8888);
try {
MogaHack.init(mController, activity);
Log.i(TAG, "MOGA initialized");
@@ -1,5 +1,6 @@
package org.ppsspp.ppsspp;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.Intent;
import android.net.Uri;
@@ -150,6 +151,7 @@ public class PpssppActivity extends NativeActivity {
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
public int openContentUri(String uriString, String mode) {
try {
Uri uri = Uri.parse(uriString);
@@ -91,7 +91,11 @@ public class SizeManager implements SurfaceHolder.Callback {
Log.i(TAG, "Bad orientation detected but ignored" + (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT ? " (sdk version)" : ""));
}
Log.d(TAG, "Surface created. pixelWidth=" + pixelWidth + ", pixelHeight=" + pixelHeight + " holder: " + holder.toString() + " or: " + requestedOr);
Display display = activity.getWindowManager().getDefaultDisplay();
refreshRate = display.getRefreshRate();
Log.d(TAG, "Surface created. pixelWidth=" + pixelWidth + ", pixelHeight=" + pixelHeight + " holder: " + holder.toString() + " or: " + requestedOr + " " + refreshRate + "Hz");
NativeApp.setDisplayParameters(pixelWidth, pixelHeight, (int)densityDpi, refreshRate);
getDesiredBackbufferSize(desiredSize);