mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-03 08:15:33 +00:00
Use setFrameRate() instead of preferredDisplayModeId if the modes differ only by refresh rate
This seems to avoid a bug on the Chromecast 4K where it can decide to switch to 4K24 instead of 4K60 Fixes #1151
This commit is contained in:
parent
2d7493fd1e
commit
970423f873
@ -809,6 +809,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
boolean refreshRateIsGood = isRefreshRateGoodMatch(bestMode.getRefreshRate());
|
boolean refreshRateIsGood = isRefreshRateGoodMatch(bestMode.getRefreshRate());
|
||||||
boolean refreshRateIsEqual = isRefreshRateEqualMatch(bestMode.getRefreshRate());
|
boolean refreshRateIsEqual = isRefreshRateEqualMatch(bestMode.getRefreshRate());
|
||||||
|
|
||||||
|
LimeLog.info("Current display mode: "+bestMode.getPhysicalWidth()+"x"+
|
||||||
|
bestMode.getPhysicalHeight()+"x"+bestMode.getRefreshRate());
|
||||||
|
|
||||||
for (Display.Mode candidate : display.getSupportedModes()) {
|
for (Display.Mode candidate : display.getSupportedModes()) {
|
||||||
boolean refreshRateReduced = candidate.getRefreshRate() < bestMode.getRefreshRate();
|
boolean refreshRateReduced = candidate.getRefreshRate() < bestMode.getRefreshRate();
|
||||||
boolean resolutionReduced = candidate.getPhysicalWidth() < bestMode.getPhysicalWidth() ||
|
boolean resolutionReduced = candidate.getPhysicalWidth() < bestMode.getPhysicalWidth() ||
|
||||||
@ -885,9 +888,30 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
refreshRateIsGood = isRefreshRateGoodMatch(candidate.getRefreshRate());
|
refreshRateIsGood = isRefreshRateGoodMatch(candidate.getRefreshRate());
|
||||||
refreshRateIsEqual = isRefreshRateEqualMatch(candidate.getRefreshRate());
|
refreshRateIsEqual = isRefreshRateEqualMatch(candidate.getRefreshRate());
|
||||||
}
|
}
|
||||||
LimeLog.info("Selected display mode: "+bestMode.getPhysicalWidth()+"x"+
|
|
||||||
|
LimeLog.info("Best display mode: "+bestMode.getPhysicalWidth()+"x"+
|
||||||
bestMode.getPhysicalHeight()+"x"+bestMode.getRefreshRate());
|
bestMode.getPhysicalHeight()+"x"+bestMode.getRefreshRate());
|
||||||
|
|
||||||
|
// Only apply new window layout parameters if we've actually changed the display mode
|
||||||
|
if (display.getMode().getModeId() != bestMode.getModeId()) {
|
||||||
|
// If we only changed refresh rate and we're on an OS that supports Surface.setFrameRate()
|
||||||
|
// use that instead of using preferredDisplayModeId to avoid the possibility of triggering
|
||||||
|
// bugs that can cause the system to switch from 4K60 to 4K24 on Chromecast 4K.
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S ||
|
||||||
|
display.getMode().getPhysicalWidth() != bestMode.getPhysicalWidth() ||
|
||||||
|
display.getMode().getPhysicalHeight() != bestMode.getPhysicalHeight()) {
|
||||||
|
// Apply the display mode change
|
||||||
windowLayoutParams.preferredDisplayModeId = bestMode.getModeId();
|
windowLayoutParams.preferredDisplayModeId = bestMode.getModeId();
|
||||||
|
getWindow().setAttributes(windowLayoutParams);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LimeLog.info("Using setFrameRate() instead of preferredDisplayModeId due to matching resolution");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LimeLog.info("Current display mode is already the best display mode");
|
||||||
|
}
|
||||||
|
|
||||||
displayRefreshRate = bestMode.getRefreshRate();
|
displayRefreshRate = bestMode.getRefreshRate();
|
||||||
}
|
}
|
||||||
// On L, we can at least tell the OS that we want a refresh rate
|
// On L, we can at least tell the OS that we want a refresh rate
|
||||||
@ -907,9 +931,13 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
bestRefreshRate = candidate;
|
bestRefreshRate = candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LimeLog.info("Selected refresh rate: "+bestRefreshRate);
|
LimeLog.info("Selected refresh rate: "+bestRefreshRate);
|
||||||
windowLayoutParams.preferredRefreshRate = bestRefreshRate;
|
windowLayoutParams.preferredRefreshRate = bestRefreshRate;
|
||||||
displayRefreshRate = bestRefreshRate;
|
displayRefreshRate = bestRefreshRate;
|
||||||
|
|
||||||
|
// Apply the refresh rate change
|
||||||
|
getWindow().setAttributes(windowLayoutParams);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Otherwise, the active display refresh rate is just
|
// Otherwise, the active display refresh rate is just
|
||||||
@ -917,14 +945,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
displayRefreshRate = display.getRefreshRate();
|
displayRefreshRate = display.getRefreshRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable HDMI ALLM (game mode) on Android R
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
||||||
windowLayoutParams.preferMinimalPostProcessing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the display mode change
|
|
||||||
getWindow().setAttributes(windowLayoutParams);
|
|
||||||
|
|
||||||
// From 4.4 to 5.1 we can't ask for a 4K display mode, so we'll
|
// From 4.4 to 5.1 we can't ask for a 4K display mode, so we'll
|
||||||
// need to hint the OS to provide one.
|
// need to hint the OS to provide one.
|
||||||
boolean aspectRatioMatch = false;
|
boolean aspectRatioMatch = false;
|
||||||
@ -2079,8 +2099,16 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
public void surfaceCreated(SurfaceHolder holder) {
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
surfaceCreated = true;
|
surfaceCreated = true;
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
|
||||||
// Tell the OS about our frame rate to allow it to adapt the display refresh rate appropriately
|
// Tell the OS about our frame rate to allow it to adapt the display refresh rate appropriately
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
// We want to change frame rate even if it's not seamless, since prepareDisplayForRendering()
|
||||||
|
// will not set the display mode on S+ if it only differs by the refresh rate. It depends
|
||||||
|
// on us to trigger the frame rate switch here.
|
||||||
|
holder.getSurface().setFrameRate(prefConfig.fps,
|
||||||
|
Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
|
||||||
|
Surface.CHANGE_FRAME_RATE_ALWAYS);
|
||||||
|
}
|
||||||
|
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
holder.getSurface().setFrameRate(prefConfig.fps, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
|
holder.getSurface().setFrameRate(prefConfig.fps, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user