~eliasnaur/gio

bcb123a05ef2195d84397b71d12cfc2a4a6b61a9 — Ilia Demianenko 1 year, 3 months ago 816bda7
app: [Android] Set high refresh rate on startup

Some devices with high refresh rates limit SurfaceView apps to 60hz
and need a specific API call to set it back. Same approach is used by
https://github.com/ajinasokan/flutter_displaymode. The extra work is
skipped on the devices that don't need it.

Signed-off-by: Ilia Demianenko <ilia.demianenko@gmail.com>
1 files changed, 56 insertions(+), 0 deletions(-)

M app/GioView.java
M app/GioView.java => app/GioView.java +56 -0
@@ 26,6 26,7 @@ import android.text.SpannableStringBuilder;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Choreographer;
import android.view.Display;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;


@@ 105,6 106,8 @@ public final class GioView extends SurfaceView implements Choreographer.FrameCal
			scrollYScale = px;
		}

		setHighRefreshRate();

		accessManager = (AccessibilityManager)context.getSystemService(Context.ACCESSIBILITY_SERVICE);
		imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
		nhandle = onCreateView(this);


@@ 255,6 258,59 @@ public final class GioView extends SurfaceView implements Choreographer.FrameCal
		this.setBarColor(Bar.NAVIGATION, color, luminance);
	}

	private void setHighRefreshRate() {
		Context context = getContext();
		Display display = context.getDisplay();
		Display.Mode[] supportedModes = display.getSupportedModes();
		if (supportedModes.length <= 1) {
			// Nothing to set
			return;
		}

		Display.Mode currentMode = display.getMode();
		int currentWidth = currentMode.getPhysicalWidth();
		int currentHeight = currentMode.getPhysicalHeight();

		float minRefreshRate = -1;
		float maxRefreshRate = -1;
		float bestRefreshRate = -1;
		int bestModeId = -1;
		for (Display.Mode mode : supportedModes) {
			float refreshRate = mode.getRefreshRate();
			float width = mode.getPhysicalWidth();
			float height = mode.getPhysicalHeight();

			if (minRefreshRate == -1 || refreshRate < minRefreshRate) {
				minRefreshRate = refreshRate;
			}
			if (maxRefreshRate == -1 || refreshRate > maxRefreshRate) {
				maxRefreshRate = refreshRate;
			}

			boolean refreshRateIsBetter = bestRefreshRate == -1 || refreshRate > bestRefreshRate;
			if (width == currentWidth && height == currentHeight && refreshRateIsBetter) {
				int modeId = mode.getModeId();
				bestRefreshRate = refreshRate;
				bestModeId = modeId;
			}
		}

		if (bestModeId == -1) {
			// Not expecting this but just in case
			return;
		}

		if (minRefreshRate == maxRefreshRate) {
			// Can't improve the refresh rate
			return;
		}

		Window window = ((Activity) context).getWindow();
		WindowManager.LayoutParams layoutParams = window.getAttributes();
		layoutParams.preferredDisplayModeId = bestModeId;
		window.setAttributes(layoutParams);
	}

	@Override protected boolean dispatchHoverEvent(MotionEvent event) {
		if (!accessManager.isTouchExplorationEnabled()) {
			return super.dispatchHoverEvent(event);